Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mac57mac57

macrumors 6502a
Original poster
Aug 2, 2024
877
564
Myrtle Beach, SC
Hi, I feel rather silly posting this question, but the answer has completely eluded me.

I am using macOS Monterey on my M1 Max Mac Studio. I am trying to create a "launcher" for the vi text editor, so that I can put the launcher's icon in the Dock and then drop files that I want to edit in vi onto that icon. My question is not restricted to just vi; I would like to create drag n drop "launchers" for many different interactive command line apps, such as vi, nano, mc and so on.

This SHOULD be easy; this is what the Automator app is for... AppleScript too. I have read and read and read on Google and tried every combination of things I can think of but nothing works for me. I can create an Automator launcher app that will launch vi, but I cannot get vi to "see" the files that are dropped onto the launcher app. Ditto for AppleScript - I can successfully launch command line apps, but I cannot get those apps to "see" the files that are dragged onto the launcher.

There are LOTS of prescriptions for doing this sort of thing on the web, but NONE of them have worked for me, at least so far.

Does anyone have a known working way of creating a launcher for command line apps that will accept drag and drop files and pass them on to the launched application?

Thanks!
 
Does anyone have a known working way of creating a launcher for command line apps that will accept drag and drop files and pass them on to the launched application?
So timely.. I was actually researching such a thing myself this week. Haven't had the time to experiment yet...
 
I am trying to create a "launcher" for the vi text editor, so that I can put the launcher's icon in the Dock and then drop files that I want to edit in vi onto that icon.
Vi is a terminal based text editor. I suspect you would need to launch Terminal.app or iTerm2.app and execute a script which then executes vi with supplied command line arguments. Without knowing any specifics of your use case, some editors (ex. Visual Studio Code, Eclipse, BBedit, etc) have "vi" modes so you can edit using "vi" key-bindings. Perhaps your "launcher" is unnecessary?

Additionally, there is MacVim. Vim is basically vi but "improved".
 
So timely.. I was actually researching such a thing myself this week. Haven't had the time to experiment yet...
I used an older version of Platypus, and it didn't allow for interactive scripts. The only "inputs" you could feed it were files or folders that were dropped on the app's icon. Those were passed as command-line args to the script, i.e. as "$@".

Glancing at the linked page, I don't see it being any more interactive. In particular:
Apps can display graphical feedback of script execution as progress bar, text window with script output, droplet, WebKit HTML rendering or status item menu
All of those are non-interactive outputs, And the only meniton of inputs is still items dropped on app. No mention of keyboard, mouse, or interactive window output.

I think the suggestions to use an editor app like MacVim, or the vi key bindings in something like BBEdit, are probably the only practical solution.

A more roundabout approach might be something like a Platypus script that uses AppleScript to tell another app to open the set of dropped files. Seems like the long way round the barn.
 
I will not be able to test if it works until tomorrow, but it looks promising. I have tried scripts that are CLOSE to this one, but not exactly the same. There are a few syntax tricks Gemini uses that my very incomplete knowledge of AppleScript did not allow me to dream up, so I am hopeful.

BTW, I am not just looking for just a GUI version of vi - there are plenty of those out there - but rather a general capability that I can reuse for any command line app that I want to use drag and Drop with.

Of course I have a very specific application in mind right now - my own VE Text Editor, which I have now ported to macOS and am upgrading with several new features. I now have it running under ncurses, delivering something close to platform independence, with macOS Monterey and ARM64 being the first test case. I will then recompile it for Mac OS X Leopard and PPC32... and then, it is back to PCs and DOS, and finally, the Apple IIGS GS/OS environment.
 
AppleScript, save as Application, at first dragged file allow the app to control Teminal. (permission in System Settings – Privacy & Security - Automation)

AppleScript:
on open DroppedFiles
    repeat with DroppedFile in DroppedFiles
        set FilePath to POSIX path of DroppedFile
        set TheCommand to "/usr/bin/vi " & quoted form of FilePath
        tell application "Terminal"
            activate
            do script TheCommand
        end tell
    end repeat
end open
 
  • Like
Reactions: gilby101
Quick update to everyone - NOTHING from the above has worked. I can consistently start Terminal.app, but I just as consistently cannot get it to execute a command line command from the AppleScript, ANY command... I have tried both interactive and non-interactive (such as "ls") commands but it won't execute ANYTHING. I have been watching in Activity Monitor as I go... it is not running the command in a background shell. I have forced everything to the open Terminal window, but it just doesn't get anything.

I am working now on trying an Automator approach where I overwrite .bashrc with the command of interest and then start Terminal. If this works, it will have to be generalized to first save off the existing .bashrc, overwrite it with the command of interest, do the Terminal session and then restore the original .bashrc. I tried the AppleScript equivalent, but I couldn't get IT to modify .bashrc no matter what I tried.

What is really frustrating is that AppleScript seems to produce no error information, no logs, no messages, no anything.... no hint that anything is going wrong, and yet something must be.

The search continues!

EDIT: Below is my current AppleScript script, with the original dropped file command stuff still in place, but now proceeded by my attempt to have AppleScript write .bashrc with the dropped file command instead:

on open DroppedFiles
repeat with DroppedFile in DroppedFiles
set FilePath to POSIX path of DroppedFile
set TheCommand to "/usr/bin/vi " & quoted form of FilePath
set result to writeTextToFile(TheCommand, "/Users/mac57/.bashrc", true)
tell application "Terminal"
activate
display dialog TheCommand with title "TheCommand" buttons {"OK"} default button "OK"
do script with command TheCommand in front window
delay 5
end tell
end repeat
end
open

on
writeTextToFile(theText, theFile, overwriteExistingContent)
try
set theOpenedFile to open for access file theFile with write permission
if overwriteExistingContent is true then
set eof of theOpenedFile to 0
end if
write theText to theOpenedFile starting at eof as «class utf8»
close access theOpenedFile
return true
on error errMsg
try
close access file theFile
end try
return false
end try
end
writeTextToFile
 
Last edited:
After some time to think more about this, my gut tells me that something systemic is broken, not AppleScript or Automator individually. The total lack of error output suggests a security violation of some sort - I have written waaaay too much self-protection code of this sort not to recognize the behavior; when you detect a security violation, you fail silently, so that the "bad guys" don't learn anything they can use to more tightly tune their attack.

So I went looking using "Mr. Google" and sure enough there were a number of security changes in Monterey that impact AppleScript. I unearthed a laundry list of such changes and their workarounds. I will work through them and get back with what I find out. I am also going to test this whole area out on my trusty Power Mac G5 Quad under Leopard/Sorbet. My guess is that it all works perfectly there, while failing miserable under Monterey due to as yet unresolved "security violations".
 
Thanks @bogdanw. I did this, and checked over all the other permissions and they all seemed right.

Nonetheless, still no joy. Terminal reliably runs, but never gets the dropped files to the command line application being run.

Then a bit of serendipity. By mistake I discovered that if I already had previously started a Terminal session before I ran my AppleScript "launcher" script it worked! As long as I leave that initial Terminal window open, it will be used by the launcher successfully. BUT... if I run my launcher when no Terminal session is running, it starts a new Terminal session as expected, but that session steadfastly refuses to "see" the dropped filename(s).

So, there is something "magic" about having Terminal running before executing my AppleScript launcher. I thought ... ownership, execution rights, etc., but everything checks out. I cannot see any obvious differences between the Terminal session I start myself and the one that the launcher starts if there isn't one running when it is executed. Still, I am guessing that there is some sort of permissions/access rights/etc issue going on here.

For the moment then, I have a partial solution. As long as I start a copy of Terminal before I want to use my launcher, it works just fine, and will re-use that pre-started Terminal window each time. Of course, I would like the launcher to start its own Terminal window each time, do the editing session and then kill its Terminal application. In the meantime, I the shell script that is activated by the launcher hides the Terminal window when it is done, and re-shows it when executed. This ensures no on screen clutter, but it is less than optimal.

Does any of this suggest a way forward to anyone reading this? Specifically, I would really like to not need to have Terminal running ahead of time. It is an annoying detail.

Here is my current AppleScript launcher. In actual usage, I have named it ve.app, but for archival purposes, I rename it to ve.scpt.app to draw attention to the fact that it is an AppleScript app, not an Automator app:

ve.scpt.app.jpg

And here is the ve.sh shell script that it runs:

ve.sh.jpg
 
Does any of this suggest a way forward to anyone reading this?
Platypus worked for me using the following script... generate Application and drop editable file on it. Launches, runs shell script which uses oascript to launch Terminal with command to execute vi against dropped file's file path. Not sure what experience you want once user finished editing the file w/ vi, but looks like you have several options.
Bash:
#!/bin/bash
# Script to run the command line executable with arguments in a Terminal window.
# Usage: run_cli_pgm.sh filename
# Using AppleScript, tell Terminal to run command line exec with args
export COMMAND_LINE_EXEC="/usr/bin/vi"
export COMMAND_LINE_ARGS="$1"
osascript -e 'tell application "Terminal" to do script "$COMMAND_LINE_EXEC $COMMAND_LINE_ARGS"'
# Using AppleScript, make the now visible window active (give it focus)
osascript -e 'tell application "Terminal" to activate'
Screenshot 2026-01-11 at 4.13.09 PM.png

Screenshot 2026-01-11 at 4.13.26 PM.png

Screenshot 2026-01-11 at 4.22.18 PM.png
 
Here is my current AppleScript launcher. In actual usage, I have named it ve.app, but for archival purposes, I rename it to ve.scpt.app to draw attention to the fact that it is an AppleScript app, not an Automator app:
You are using AppleScript to run zsh script that runs AppleScript…
Here is how simple it can be:
 
Thanks again, @bogdanw. I will go through this in more detail tomorrow - am "busied out" today, and cannot get back to this until tomorrow at the earliest. In the meantime, I wanted to acknowledge your very helpful posts. Thanks again.
 
Well, I'm afraid I am still stuck. Neither Platypus nor AppleScript seem to be able to do the trick for me. Both continue to consistently open vi, but neither will pass the dropped files into the program.

Platypus looks interesting... I am going to spend more time with it... but it hasn't produced any magic yet. What happened there when I put your script and Platypus content into it and then dropped a file onto the resulting app was that it opened Terminal and injected the two items command items into it, but did not expand them. So, what I saw was a Terminal window with the command line loaded with:

$COMMAND_LINE_EXEC $COMMAND_LINE_ARGS

as the first command, but they were not expanded out to the intended contents. I tried playing around with all nature of variations, but all I got was all nature of errors.

I decided to try running the intended commands manually, and got the same result. I manually started a Terminal window, defined the two items $COMMAND_LINE_EXEC and $COMMAND_LINE_ARGS (to save typing, I called them CMD and ARGS) and then ran the osascript line:

% osascript -e 'tell application "Terminal" to do script "$CMD $ARGS"'. You can see all this below:

Script Setup.jpg


Here is the resulting Terminal window that the osascript command opened:

Resulting Terminal Window.jpg


Per my comments above, neither exported variable was recognized by the new Terminal window that was launched.

The search goes on...
 
The problem isn't the exported variables, it's the quotes you're using.

Within single quotes, no $VARNAME is expanded by the shell. Since the 'osascript' line uses single quotes, nothing is expanded.

One way to fix this is to use double-quotes, between which $VARNAME will be expanded. However, this means you'll also have to escape the double-quotes that are embedded in the osascript param. Try this:
Code:
osascript -e "tell application \"Terminal\" to do script \"$CMD $ARGS\""
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.