macosapplescriptshiterm.app

MacOS Getting the file path inside a shell script when opening a file as an application


I'd like to be able to have an option to open a file inside NeoVim in the "Open With" list. That is to open a new terminal window (ITerm in my case), and execute a command that launches NeoVim on the file that I selected.

I'd like to have the option display here

The problem is that I'm unable to get past the last part of getting the file path inside the shell script.

I created a new .app file and put it inside the /Applications folder. The .app structure is very typical with the executable being a shell script:

#!/bin/sh

osascript <<EOF
tell application "iTerm"
    activate
    set new_window to (create window with default profile)
    set cSession to current session of new_window
    tell new_window
        tell cSession
            delay 0.1
            write text "\"echo it's working\""
            delay 2
            repeat
                delay 0.1
                --          display dialog cSession is at shell prompt
                set isdone to is at shell prompt
                if isdone then exit repeat
            end repeat
        end tell
    end tell
end tell
EOF

The script above launches the terminal and executes the command as expected: The result of the script execution

But at this point I'm not sure how to get the path of the selected file. I tried out using the command line arguments such as $1, $2 etc but to no success. I tried running declare -p inside the script to show all variables and their values but the file path I'm looking for is nowhere to be found. I'm not really sure what else I can try and I couldn't find the answer online (or at least I couldn't find the right search terms). Perhaps there is a better way of doing what I want to do. If that's the case then please tell me about it (Also I'm aware that NeoVim Qt exists but it is not a solution that I'm looking for. I'd like to have the behaviour that I described earlier).

Update: I managed to make it work the way I wanted by ditching the shell script and using apple's Script Editor instead. This is the AppleScript code that I used:

on run -- app double-clicked or script run from editor
    open (choose file with multiple selections allowed)
end run

on open theItems -- droplet
    -- Form a string with all the files in quotation marks
    set pathList to {}
    repeat with itemPath in theItems
        set end of pathList to quoted form of POSIX path of itemPath
    end repeat
    
    set AppleScript's text item delimiters to space
    set pathString to pathList as text
    set AppleScript's text item delimiters to ""
    
    doStuff(pathString)
end open

on doStuff(pathString) -- main handler to do stuff
    tell application "iTerm"
        activate
        set new_window to (create window with default profile)
        set cSession to current session of new_window
        tell new_window
            tell cSession
                delay 0.1
                write text "nvim " & pathString
            end tell
        end tell
    end tell
end doStuff

Solution

  • Instead of using a shell script to call osascript to run an AppleScript, an AppleScript application (applet) can be created directly from the Script Editor. A droplet can be created by adding an open handler, which will be passed the items dropped onto the application or the file arguments used with the open command from the command line.

    on run -- app double-clicked or script run from editor
       open (choose file with multiple selections allowed)
    end run
    
    on open theItems -- droplet
       repeat with anItem in theItems
          doStuff(anItem) -- do something with individual file item
       end repeat
    end open
    
    on doStuff(fileItem) -- main handler to do stuff
       display dialog (POSIX path of fileItem) -- or whatever
    end doStuff