12

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\""
    

7 Answers 7

15

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.).

3
  • This seems to do exactly what I was looking for. I had tried a similar method after finding the tmux display-message -p "#S" trick in another answer. It seems like wrapping everything in run-shell was the key. Thanks! Commented Dec 16, 2012 at 9:57
  • How do you do this without confirm-before? I'm having trouble getting the escaping right.
    – Miles
    Commented Jul 16, 2015 at 8:11
  • 3
    @Miles: Try this one: bind-key X run-shell 'tmux switch-client -n \; kill-session -t "#S"' (tmux 1.8+ run-shell expands #S directly, so we get to omit the display-message and its extra quoting) Commented Jul 16, 2015 at 19:01
2

Just in case if someone stumbles upon this question - tmux-sessionist provides this functionality along with many others.

2

Also you can simply add set-option -g detach-on-destroy off to your config and kill session as usually.

1
  • 1
    After over a decade of using the currently accepted answer, I'm switching to this approach. Thanks! Commented Dec 13, 2023 at 22:36
1

Expanding from Chris Johnsen answer (in the comments) above, on how to do it without prompt or confirm-before:

bind-key X run-shell 'tmux switch-client -n \; kill-session -t "#S"'

If there's only 1 session left (the session you're currently in now) and you run the command, you'll receive an "error" message, and the session is not killed. Normally (if you are like me) you want the command to keep kill the session even though there's no other session it can switch to. So here's what I come up with:

bind-key X if-shell '[ $(tmux list-sessions | wc -l) -ne 1 ]' \
                    "run-shell 'tmux switch-client -n \\\; kill-session -t \"#S\"'" \
                    "run-shell 'tmux kill-session -t \"#S\"'"
1

A (subjectively) more robust and readable version of the answer from Chris I came up with:

bind-key X \
    if-shell '[ "$(tmux display -p "#{session_many_attached}")" -gt 0 ]' {
        # the session is attached to multiple clients, so we can just switch the client to a different session.
        choose-session
    } {
        # we are the last client attached to this session; kill it.
        # we need to use `run-shell` to ensure that the current session number is expanded *before* we switch to the new session.
        confirm -p 'Kill #S (y/n)?' {
            choose-tree -s {
                run-shell 'tmux switch-client -t "%%" \; kill-session -t "#S"'
            }
        }
    }
0

There is another question which asks a similar question but it is slightly different.

If you want the standard choose-session behaviour with the additional feature that kills the original session if no other clients remain attached to it then that question may also be of interest.

0

This worked for me:

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

I removed run-shell

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .