This is a card in Dave's Virtual Box of Cards.

Tmux F5 for "replay" (plus bonus Vim!)

Page created: 2023-05-19
Updated: 2024-10-16

Back to: tmux, vim

I’ve been wanting to do this forever, but hadn’t gotten around to it until today. I can’t believe it was such an easy one-liner!

I often work in either two side-by-side terminals or two tmux panes. The layout is almost always:

My process is often:

Anyway, now I’ve finally automated the right pane process so I don’t have to leave the left pane at all with this:

# ~/.tmux.conf

# F5 runs last command in right pane
bind-key -n F5 send-keys -t right Up Enter

This is so great. The next hard part is training myself to use it.

"The Vim Version"

Okay, so I love and use the above. But it turns out my usage is even more specific because the editor in question is always Vim, which means the total key sequence to save the current file and replay is :w[ENTER]F5 which doesn’t look like much and isn’t on a full-size keyboard but is surprisingly awkward on "40%" keyboards, chording setups, and weird laptop layouts.

So it occurred to me that I could both save ("write") the file and do the Tmux replay thing from Vim by calling the tmux executable. The more Tmux I learn, the more I like it.

My keybinding for normal and insert mode looks like this:

" F5 saves and replays last cmd in right Tmux pane
function! TmuxReplay()
    write
    silent exec "!tmux send-keys -t right Up Enter"
    redraw!
endfunction
nnoremap <F5> :call TmuxReplay()<CR>
inoremap <F5> <ESC>:call TmuxReplay()<CR>

(Note that though these could be one-liners I much prefer putting longer bindings in functions to aid in readability.)

As you can see, I have the insert mode binding (inoremap) switch to normal mode but simulating the escape key, so the two bindings are essentially identical.

The only thing that I think really requires a little more explanation is the redraw! at the end of the function. If you don’t have that, the terminal gets weird and Vim doesn’t display correctly until you run a :redraw! or hit Ctrl+L to force a redraw. This is because Vim doesn’t redraw the screen after running a command with silent and the terminal is left in a weird halfway state. See :help silent! for more.

Anyway, it works beautifully. I like being able to make tiny little changes and see the effect (almost) immediately in the other pane.

Idle thought: I ought to experiment with using the watch program in the other pane and save my changes manually or automatically in Vim to get nearly instantaneous feedback as I type??? (See man watch.)