Open tridactyl's external editor in a new tmux window

415 words 2 min read

Tridactyl has been a decent replacement for Vimperator or Pentadactyl for me since I said goodbye to the XUL extensions. It supports the invocation of external editor (I mean Vim, of course) in its own insert mode pretty well, but the default behavior is to open Vim in a new terminal emulator window. Considering that I’m using tmux for most of the time, I start to wondering if I could do some tweak with the editorcmd so that instead of a new terminal emulator window, a termporary tmux window will be opened.

First attempt

How editorcmd works is pretty simple: once the user invokes editor(), tridactyl will expand the first occurrence of %f into the filepath for the tempfile, or just append the filepath at the end if %f is not found (see this for details). So we could easily come up with the following code:

set editorcmd tmux new-window -n firefox 'nvim -f %f'

However, this actually doesn’t work the way we want. What happens is that tmux new-window doesn’t block until the window is closed. As a result, once the given command has returned, tridactyl will go straight to read from the provided tempfile, which will turn out to be empty since it’s just opened by the Neovim in the new tmux window. We need to find a way to block the command until the window is closed.


A StackExchange answer points out the solution: to use tmux wait-for. tmux wait-for <CHANNEL> will block until receiving the signal on the given CHANNEL, while tmux wait-for -S <CHANNEL> will send such a signal to the CHANNEL. Thus, the solution will be:

set editorcmd tmux new-window -n firefox 'nvim -f %f; tmux wait-for -S firefox-neww-done' \; wait-for firefox-neww-done

This binding divides into two sequential command:

new-window -n firefox 'nvim -f %f; tmux wait-for -S firefox-neww-done'
wait-for firefox-neww-done

\; is to make sure the shell will not interpret this ; so that it can be passed to tmux, where it also serves the purpose of dividing the commands (see the manpage for details).

So in this new version, the second line will block until the first line returned, where in the first line the signal will not be sent until Neovim is closed. Once the signal is sent, the new tmux window will also be closed too. Everything works as expected!