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
Open Automator
Select to create an application
Locate “Run AppleScript” and double-click it
Paste this script, save it to /Applications
Select a file type of your choice, e.g. txt one, press Command-I, change “Open with” to your application, click “Change All”
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:
Open iTerm2
Close the window, but don’t quit the app itself
Double-click a .txt file. You will get the following error:
Sometimes there will be a terminal window with Neovim running
Sometimes there will be a terminal window without Neovim running
And sometimes there will be no terminal window opened
How do you typically open files in Neovim?
As I said earlier, I prefer to browse files using Finder. So, typically I first navigate to the target folder using Finder, then Control-click that folder in Finder path bar (which can be enabled by pressing Option-Command-P), and then select “Open in Terminal”:
The environment of applescript’s shell is bare bones and likely will not match what that of your terminal app. You can see what it is with this applescript command:
do shell script "env"
So in all likelihood, nvim is not in the PATH. So try by including the entire path to nvim.
I don’t have that on my system but here is the path to vim:
/opt/local/bin/vim
So, using the location of nvim on your machine, try:
do shell script "/opt/local/bin/nv " & filename
Incidentally, what I meant in my earlier post was how do you typically open files in nvim from the shell. Then we can take that process and apply it with do shell script.
on run {input, parameters}
set filename to quoted form of POSIX path of input
do shell script "/opt/homebrew/bin/nvim " & filename
end run
Now there is no error message, but nothing happens. The only thing that does happen is a spinning gear in my menu bar:
By the way, I don’t think nvim wasn’t in the PATH. I can open any text file in any folder by opening the terminal in that folder and typing nvim foobar.txt. No need to specify the full path!
Using do shell script works a little differently than typing it into a terminal, because it doesn’t inherit the terminal’s PATH. Which I forget on a regular basis, like tonight.
If you’re running Neovim purely as a CLI program, then do shell script by itself is just running it as a background task, which won’t help if you’re planning to view/edit the file. You’d still need to script the terminal.
I’d better install Neovim and recreate your Automator action before I open my mouth again.
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 "Terminal"
do script cmd
end tell
tell application "System Events"
tell process "Terminal"
set frontmost to true
end tell
end tell
end run
I left everything other than the terminal scripting as you had it.
First thing… @fuzzywan has a solution that worked for me (using vim). Of course, he’s completely right about running it as a CLI program. I wasn’t thinking.
But, to elaborate on the issue of paths…
The terminal has a different path than applescript’s shell does.
To focus just on the path:
In terminal, type: printf "$PATH"
In an applescript, enter this into a script and run it: do shell script "printf \"$PATH\""
Your terminal has had the path to nvim added to its path, likely when you installed homebrew. All of the utilities installed using homebrew will share the same path.
Since you can’t modify the applescript’s shell’s profile, you have to handle the issue in your command. You could add the directory to the path but it’s easier just to provide the full path to the utility you wish to run.
Finally, somewhere, probably in your home folder, you have a config or profile file that the terminal gets its settings from. It’s often called a startup file and it runs whenever you launch the terminal (or create a new tab or window) and the settings in it are applied. On a mac, if your default shell is zsh then it’s likely named ‘.zshrc’; if its bash then it’s likely named ‘.bash_profile’. If you can find the correct file for your system, you should be able to see that the directory which contains nvim is in the path, probably added in a line that begins with export PATH.
None of this matters in this particular case but if you did wish to use any of several other shell-based utilities, it might be helpful.
Could you help me once more, please? After quitting Vim (using :q), I got a warning:
cd: too many arguments
It seems the idea of the original script is to cd to the directory in which the file we double-click in Finder resides, so that after we quit Vim, we will be in shell in that exact directory. But it seems there is an error in how this idea was implemented. I tried to fix it by replacing
set cmd to "clear;cd `dirname " & filename & "`;nvim " & filename
with
set cmd to "clear;cd $(dirname " & filename & ");nvim " & filename
and it works for me.
on run {input, parameters}
set filename to quoted form of POSIX path of input
set cmd to "clear;cd $(dirname " & filename & ");nvim " & filename
display alert cmd
tell application "Terminal"
do script cmd
end tell
tell application "System Events"
tell process "Terminal"
set frontmost to true
end tell
end tell
end run
But I’m not really good in shell scripting, and even worse, I’m a 5-five year old kid in AppleScript.
Is that change really correct? And isn’t it bad I have removed the backticks (``)?
The command substitution can be done by either enclosing with backticks or using $(command), the main difference would be any escaping when used in an AppleScript string. The warning you got is probably related to word splitting if the path contains spaces, so you might try adding some quotes, for example:
set cmd to "clear; cd \"$(dirname " & filename & ")\"; nvim " & filename
Your cd command isn’t being fed the directory. dirname is being treated as a literal because it is also inside single quotes. As an aside, it means that there actually is a space… between ‘dirname’ and the file path.
Here is what you are likely generating as a command.
set filename to quoted form of POSIX path of input
set cmd to "foo=" & filename & "; cd \"$(dirname foo)\"; vim $foo "
tell application "Terminal"
activate
do script cmd
end tell
It sets a variable ‘foo’ for the quoted path. I think this is much easier to use. I also removed the clear as it’s redundant in a new window and in place of the frontmost code, I added an activate command for the terminal.
It’s kind of odd in that each of the backticks is enclosed in a different pair of double quotes, but I guess that the expansion takes that into account.
A string is declared using double quotes, but you can also put the substitution inside double quotes (which need to be escaped when used in an AppleScript string). When double quoting a command substitution, word splitting and filename expansion just won’t be performed.
I happen to use the Zsh shell on macOS Sequoia and have MacVim installed. This application also has a command-line tool in MacVim.app/Contents/bin which I soft-linked into my $HOME/bin folder as mvim.
My do shell script looks like this:
use scripting additions
do shell script "source ~/.zshrc;mvim & "~/cicero.txt"
The PATH export in that .zshrc file has $HOME/bin at the beginning of the PATH statement and that allows access to the command line mvim tool. If using a Bash shell, one can substitute the dot-file containing a PATH export statement for the Zsh dot-file.