Sending commands to parent tmux session from vim

I have a split window setup with vim and Lynx in tmux. I'm trying to build a script so that I can send a custom command to vim which will save the script I'm working on, switch focus to the Lynx pane, refresh the Lynx page, and then switch back to the vim pane.

Is there an existing script that does this? If not, what would be the best approach for building this script?


Solution 1:

You can probably use a Vim :! command to run tmux send-keys to send a Control-R to your other pane. Since send-keys can send keystrokes to any pane (not just the active one), you do not even need to switch active panes back and forth.

Here it is a Vim mapping (you could put it in your .vimrc or just paste it into : prompt to try it):

:map <Leader>rl :w<Bar>execute 'silent !tmux send-keys -t bottom C-r'<Bar>redraw!<C-M>

This maps the \rl key sequence (<Leader> defaults to \, but it can be customized), to the following sequence of Vim commands (separated by <Bar>; see :help map_bar):

  1. Write the current buffer to its file.
  2. Run the tmux command to send the Control-R to the bottom pane.
    We use execute here so that the next Vim command (redraw) is not taken as part of the :! shell command.
    We use the silent prefix command to avoid the “Press ENTER to continue” prompt.
    You can omit slient if you want the prompt or want to see the output of the :! command (e.g. the tmux command is not working, and you want to see if it is giving an error message).
  3. Redraw the screen.
    This would normally happen after the “Press ENTER” prompt, but we are suppressing it with silent.

I do not have lynx at hand, but Control-R seems to be the reload key based on my search for “lynx reload” (i.e. “Reloading files and refreshing the display” of the user guide).

Besides bottom, there are other ways of specifying the target pane (search for “target-pane” in the tmux man page):

  • .+1, .-1: next, previous pane in this window
  • top, bottom, left, right, and combinations of top/bottom with left/right
    (i.e. bottom-left)
  • %42 (tmux 1.5+): a %-prefixed pane number from the TMUX_PANE environment variable of the target pane

    This last form might be handy if your Lynx pane is not always in the same tmux window as your instance of Vim. Before launching Lynx, save the value of TMUX_PANE into a temporary file, then read the file to form the target-pane argument:

    # before running Lynx (anytime really, but "before" is usually scriptable)
    echo "$TMUX_PANE" > /tmp/my-lynx-pane
    
    # in the Vim :! command in the mapping:
    tmux send-keys -t "$(cat /tmp/my-lynx-pane)" C-r
    

Solution 2:

You should start with the tslime.vim plugin, which interacts with a manually selected tmux session and sends a buffer to it. You would be writing a nearly-identical plugin; however instead of sending a buffer, you would be issuing commands (refer to man 1 tmux).

tslime.vim @ vimscripts