Tmux – Kill and Select Another Tmux Session

tmux

I am trying to bind X to do the following:

  • prompt the user whether the session should be killed
  • if y is entered, kill the session
  • after the session is killed select another session (last, previous, or next session)

Some similar commands that aren't quite right

  1. Kill the session and close the terminal:

    bind X confirm-before -p "Kill #S (y/n)?" kill-session
    
  2. Prompt the user for the name of the session to kill and select next session after kill:

    bind X command-prompt -p "kill:"  "switch-client -n \; kill-session -t '%%'"
    
  3. I haven't been able to find examples of similar commands. Here's a solution something that doesn't work:

    bind X confirm-before -p "Kill #S (y/n)?" "SESSION='#S' \; \
    switch-client -n \; kill-session -t \"$SESSION\""
    

Best Answer

I think this is close to what you want:

bind-key X confirm-before -p "Kill #S (y/n)?" "run-shell 'tmux switch-client -n \\\; kill-session -t \"#S\"'"

Your #3 approach is along the right lines, but the problem is that confirm-before does not do status-left-style substitutions (e.g. #S) in its command string.

A caveat for the above binding is that since everything is done in from run-shell, the commands are run outside the context of any particular client or session. It really only works because the “default” client (for switch-client) and “default” session (for #S) are the most recently active ones. This works out as you would expect as long as you only have a single active client (e.g. a single user that does not type into another tmux client until after the shell commands have finished running); it could fail dramatically if (e.g.) you trigger the binding in tmux client A, but new input is received by tmux client B before the shell started by run-shell has had a chance to run its commands.

This particular race condition seems like a nice motivation for providing client/session/window/pane information to run-shell commands. There is a TODO entry about getting if-shell and run-shell to support (optional?) status_replace() (i.e. status-left-style substitutions), though maybe a better choice would be format_expand(), which is kind of a newer super-set of status_replace (offers #{client_tty}, etc.).