What you specify after
bind r should be one or more tmux commands (with or without arguments).
source-file ~/.tmux.conf is a valid tmux command.
source-file ~/.tmux.conf && echo reloaded. is not. To run more than one tmux command you need to use
; (sometimes in a form of
\;, see Binding a tmux key to multiple commands for details). But
echo is not a tmux command.
There is however the
run-shell tmux command that allows you to run arbitrary code in a shell. My tests tell me the shell is
sh (even if my command interpreter is not
sh). The manual confirms:
shell-command arguments are
source-file from a shell you need to call
tmux source-file …. This line in
.tmux.conf should work:
bind-key r run-shell 'tmux source-file ~/.tmux.conf && echo reloaded'
The output from the shell (i.e. from
echo in this case) will appear in view mode. Personally I would like the short message to appear in the status line, so I would rather use this variant:
bind-key r run-shell 'tmux source-file ~/.tmux.conf && tmux display-message reloaded'
It's quite educative to analyze what happens when you trigger this binding. You're in a tmux client that communicates with a tmux server. When the client receives a proper key sequence, prefixr, it informs the server and the server acts according to the binding: it runs a shell. The shell runs another tmux client that communicates with the same tmux server and makes it execute the
source-file … command. Then the shell runs yet another tmux client that communicates with the server and tells it to run
In other words the server runs some code that spawns clients that tell the same server to do something.
Your original working binding (
bind r source-file ~/.tmux.conf) is a lot simpler, the server runs
source-file … directly.
display-message are tmux commands, you can run them both upon a keystroke without spawning a shell:
bind-key r source-file ~/.tmux.conf \; display-message reloaded
One would expect
\; here to work like
; in a shell, but in fact it's more like
&&. The manual states:
Each command is terminated by a newline or a semicolon (
;). Commands separated by semicolons together form a command sequence - if a command in the sequence encounters an error, no subsequent commands are executed.
So this last binding seems just right in your case, it doesn't spawn any unnecessary shell. Still it's good to know you can run anything via
run-shell, even additional tmux clients.
You can mix the two approaches:
bind-key r source-file ~/.tmux.conf \; run-shell '#some complex logic here or whatever'
And there is
bind-key r if-shell 'tmux source-file ~/.tmux.conf' 'display-message reloaded' 'display-message "reload failed"'