0

I use tmux for development, I have one task running in a window and another one in its own. I've set the convention that the base name of the project directory is the tmux session name.

export SESSION_NAME="my-project-name"
tmux kill-session -t "$SESSION_NAME"
tmux new-session -s "$SESSION_NAME" \
                "api.start --monitored" \; \
                split-window "ui.start --monitored" \; \
                select-layout tiled \; \
                set-option -w remain-on-exit on \; \
                set-option -w mouse on \; \
                set-option -g mouse on \; \
                bind-key -n C-c kill-session -t "$SESSION_NAME"

All seems to work properly, except if starting a different project with same convention, somehow the CTRL+c in first session thinks SESSION_NAME is the one of the most recent tmux spawned session, which is not what I was hoping.

1 Answer 1

0

In the snippet you posted, every appearance of $SESSION_NAME is expanded by the shell and each tmux gets the expanded value as a command line argument.

(Even if it didn't and you wanted to expand this $SESSION_NAME later inside tmux or inside a shell inside tmux, your export SESSION_NAME="my-project-name" may be futile because of how tmux builds the environment. The update-environment option or new-session -e … command may be useful.)

This includes $SESSION_NAME in bind-key -n C-c kill-session -t "$SESSION_NAME". Your tmux executes:

bind-key -n C-c kill-session -t my-project-name

Then for a different project the tmux command is like:

bind-key -n C-c kill-session -t different-name

The important thing is bind-key itself does not target a single session. bind-key -n C-c … changes the behavior of Ctrl+c for the entire tmux server. In your case the last bind-key overwrites the previous assignment and then Ctrl+c in any session will kill-session -t different-name.

I guess you could use the key-table option to set the default key table to something other than root, separately for each session. In each new key table you could set a different binding for C-c. I haven't tested this, I think it may be possible.

If I were you, I would do a simpler thing. I would do this:

tmux bind-key -n C-c kill-session

kill-session without -t targets the current session, so this binding should do what you want for my-project-name, different-name or any other session.

Frankly "any other session" is too much for me. I wouldn't want Ctrl+c to kill everything in my general purpose session(s). I would solve this:

  • either by leaving C-c alone and picking another keystroke as "global SIGINT", then advertently using one or the other;

  • or by explicitly "marking" sessions that should use Ctrl+c as "global SIGINT". It may be something like this:

    tmux new-session -e 'TMUX_GLOBAL_SIGINT=1' \; \
          bind-key -n C-c if-shell '[ -n "$TMUX_GLOBAL_SIGINT" ]' kill-session 'send-keys C-c'
    

    Now in every session that has nonempty TMUX_GLOBAL_SIGINT variable in its environment Ctrl+c will kill the session. In every session where TMUX_GLOBAL_SIGINT is empty or not set Ctrl+c will work as usual.

    Notes:

    • For an already started session you can change the setting with tmux set-environment -u TMUX_GLOBAL_SIGINT or tmux set-environment TMUX_GLOBAL_SIGINT 1 (use -t to target a specific session, not necessarily the current one).

    • A shell (or another program) started in tmux may inherit TMUX_GLOBAL_SIGINT. If it runs tmux new-session … then (depending on update-environment and such) the new session may also inherit the variable, even without explicit -e 'TMUX_GLOBAL_SIGINT=1'. Read man 1 tmux and learn about how tmux manages the environment.

You must log in to answer this question.

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