0

I prefer to browse files using Finder, but to open text files using command-line Neovim (well, in fact I prefer Helix...).

I found the following Automator script and it kinda works but not faultlessly.

on run {input, parameters}
  set filename to quoted form of POSIX path of input
  set cmd to "clear;cd `dirname " & filename & "`;nvim " & filename
  tell application "iTerm"
    tell the current window
      create tab with default profile
      tell the current session
        write text cmd
      end tell
    end tell
  end tell
  
  tell application "System Events"
    tell process "iTerm2"
      set frontmost to true
    end tell
  end tell
end run
  1. Open Automator
  2. Select to create an application
  3. Locate "Run AppleScript" and double-click it
  4. Paste this script, save it to /Applications
  5. Select a file type of your choice, e.g. txt one, press Command-I, change "Open with" to your application, click "Change All"
  6. Double-click any .txt file in Finder. It will be opened in iTerm2

Apart from I would prefer to use native Terminal instead of iTerm2, there is a bug:

Steps to reproduce:

  1. Open iTerm2

  2. Close the window, but don't quit the app itself

  3. Double-click a .txt file. You will get the following error:

    enter image description here

How it can be fixed?

4
  • Is there a particular reason for using Terminal/iTerm if you are just going to launch Helix/nvim? Commented Feb 23, 2025 at 17:50
  • @red_menace Helix doesn't have a GUI version, as far as I know. It's a command-line program. So I just don't understand how I can open a file from Finder in Helix without opening the terminal... Commented Feb 23, 2025 at 17:57
  • In other words: No, there is no particular reason. At least I don't see one currently. Commented Feb 23, 2025 at 18:15
  • You want to enclose that in a try block, so you can trap the error, and do something with it, like create the window that doesn't exist. Commented Feb 24, 2025 at 0:54

2 Answers 2

1

As already mentioned, the error is from targeting iTerm's current window, since there isn't one (you closed it). I don't have iTerm, but the solution for that would be to check if it has any windows, and if not, make or open one. Also note that Automator's input is a list.

If you use Terminal's do script command, it will open in a new window (unless otherwise specified) so you don't have to deal with that. If all you are using Automator for is the script and arguments, a regular AppleScript application can be used, which is a little more flexible. Since applications can be command-dragged to the Finder window's toolbar, you can also skip setting file types to open with the app, it can get the current selection.

The following is a regular AppleScript droplet that files can be dropped onto, it can be double-clicked to just ask for file items, and clicking the toolbar icon (if placed in the Finder window) will pass the current selection to the app. It can even be called from the command line, all of which will open a new Terminal window running Helix (or Neovim). Save the script as an application; I am assuming that you have Helix (or Neovim) configured.

use framework "Foundation"
use scripting additions

on run args
   try
      set selectedFiles to {}
      if args is in {current application} then -- app double-clicked or 'open -a' with --args option
         set processList to (current application's NSProcessInfo's processInfo's arguments) as list
         if (count processList) > 0 then set selectedFiles to rest of processList -- first item is the executable
      else if args is not in {"", {}, missing value} then -- osascript with arguments
         set selectedFiles to args
      end if
      if selectedFiles is {} then
         tell application "Finder" to if (get windows) is not {} then -- try current Finder selection
            set selectedFiles to get selection as alias list
         end if
         if selectedFiles is {} or (((path to me) is in selectedFiles) and ((count selectedFiles) is 1)) then -- choose dialog
            activate me
            set selectedFiles to (choose file of type "public.text" with multiple selections allowed)
         end if
      end if
      open selectedFiles
   on error errmess
      display alert "Error in 'run' handler" message errmess
   end try
end run

on open droppedFiles -- items dropped onto the app
   doStuff(droppedFiles)
end open

to doStuff(theFiles) -- main
   set arguments to ""
   repeat with anItem in theFiles -- a list of files will load in a common window
      try
         if (path to me) is not in {contents of anItem, POSIX path of anItem} then -- skip the app if path is in the list
            set anItem to quoted form of POSIX path of anItem
            set arguments to arguments & anItem & space -- build argument string
         end if
      on error errmess
         display alert "Error in 'doStuff' handler" message errmess
      end try
   end repeat
   tell application "Terminal"
      activate
      do script "hx " & arguments
   end tell
end doStuff
2

Using Terminal instead of iTerm would be difficult, iTerm has a much richer AppleScript dictionary than Terminal.

Fixing your "bug". It's not really a bug, the AppleScript code assumes an open window in iTerm and gets annoyed when there isn't one there.

The easiest fix for this is to go to Settings→Startup and make sure "Always open at least one terminal window at startup" is ticked, and go to "Closing" and tick "Quit when all windows are closed" and neither "Confirm closing multiple sessions" and "Confirm "Quit iTerm2"" are selected. Now when you close the last window iTerm will quit and the "tell application "iTerm" will open iTerm then open a terminal window.

The other fix (as suggested in a comment) would be to put the:

tell process "iTerm2"
  set frontmost to true
end tell

into a try block and handle the error by opening a window and trying again.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.