Binding a tmux key to multiple commands

Solution 1:

Todd Freed is right, the "correct" way to do this is using \;. Sort of. But there's a snag.

You see, you join a sequence of tmux commands together by giving tmux the conjunction ;. Thus, in a file sourced by tmux, you might say

new-session "monitor1" ; split-window -v "monitor2"

if, for some reason, you wanted that all on one line. Now, you can give that one-line compound statement to the tmux command from a shell also but the ; must be escaped so that the shell interprets it as another argument for tmux. Thus the equivalent of the above from the shell is

$ tmux new-session "monitor1" \; split-window -v "monitor2"

Similarly, the tmux bind-key command takes a series of arguments which are the tmux command and arguments to run when the key is pressed. If you wanted to bind C-q to the above sequence from inside a file sourced by tmux, you'd say

bind-key -n C-q new-session "monitor1" \; split-window -v "monitor2"

Here we've escaped the ; from tmux, so that tmux doesn't interpret it as the end of the bind-key command, but as another argument to bind-key telling it to form a compound command as the bound value of the C-q key.

So what happens when we want to make tmux do that from the shell? A whole lot of escaping.

$ tmux bind-key -n C-q new-session "monitor1" \\\; split-window -v "monitor2"

First, we have to escape the \ and the ; each from the shell, causing the shell to pass the two characters \; as an argument to tmux. This then escapes the ; from tmux, causing it to assign the entire compound statement as the binding of C-q.


Now, all that said, if you use a complex tmux setup like this repeatedly, I'd suggest that you create a tmux file to keep it in:

# In split-windows.tmux:
new-session "monitor1"
split-window -v "monitor2"
bind-key -n C-s new-window "monitor4"
# ...etc...

And then:

$ tmux source split-windows.tmux  # (or even make an alias for this)

It'll be a lot easier to maintain that way.

Solution 2:

So the real answer is : you chain commands with a backslash followed by a semicolon.

bind-key C send-keys foo \; send-keys bar

You would put that in your tmux.conf, or run from the tmux ":" prompt

Solution 3:

You are able to do this with a small workaround. Similar to the answer suggesting a script to run (which handles your case well), it can more generally be done by using "run-shell" and calling tmux itself as the shell command.

bind-key z run-shell "tmux send-keys "xyz" ; tmux clear-history; clear" 

which will send 'xyz' keys, tmux 'clear-history' command, and then call the 'clear' shell builtin.

The entire string is just a multiple shell command sequence.

Solution 4:

Everything shown here will not work, because this

bind q send-keys "command1" \; send-keys "command2"

will execute the command2 immediately and q will be bound only to send-keys "command1"

Here's the solution:

bind R source-file "$HOME/.tmux/reload.tmux"

In the file ~/.tmux/reload.tmux put multiple commands like:

source-file "$HOME/.tmux.conf" 
display-message "Configuration reloaded."