I suppose this patch isn't mature enough, so you are welcome. Content * added -m/-M command line options to demand/ignore multiplexer (using only -m option to toggle defaults isn't robust enough) * config options to specify exec wrapper and finalizing commands * sessions are named after the -n option (if specified) ~ adaptable to other multiplexers / etc. beside tmux (not tested)
Discussion * problems when using patch with other software (dvtm, byobu, etc) * other possible wrappers beside tmux (?) fitting overall idea * any opinion from alternative implementation till vars naming # FEATURE Behavior * killing terminal by WM cleanly kills the embedded tmux session => only created by the same terminal session is killed * detached session stays alive (terminal closes on detach) * attaching to the session from another terminal and closing former one will relocate the session without killing (however, now it behaves like any ordinary independent session) Advantage + using tmux by default or demand it explicitly by -m/-M + arguments after -e are used as command for tmux new-session + no need for additional monitoring script => cleaner process tree, lesser startup time + no need for arguable options in your ~/.tmux.conf => all your other tmux sessions aren't affected # ALTERNATIVES ## Tmux wrapper (bash only!) $ st -e r.tmux $ cat r.tmux #!/bin/bash -e trap "tmux list-clients -t st-$$ 2>/dev/null | { read -r _ && ! read -n1 -r _; } && tmux kill-session -t st-$$ " INT TERM EXIT tmux new-session -s st-$$ -- "$@" Comparison + works the same way as the patch in question (see Behavior) + can be used even with packaged 'st' (no src hacking required) - related WM shortcuts must be changed to $ st -e r.tmux ... - creates additional process, cluttering your process tree - shell on exit must propagate HUP to childs and call EXIT trap => so it only works in bash? (dash, etc. are out of question) ## Tmux native ~/.tmux.conf: set -g destroy-unattached on Comparison + easy (one option with support from the box) + no need to modify any st sources or WM shortcuts - works only with tmux - always destroys any unattached session (even on manual detach!) ~ useful if you use tmux for multiplexing only and rarely detach * you can switch option manually each time before detach * or bind it (with one-time-set guards) to 'pref d' * option can be guarded in config to be disabled for SSH * also for global tmux session you can use separate tmux.conf
98fae82da42d038b9ed0c87b557524fd03345191 tmux support diff --git a/config.def.h b/config.def.h index b41747f..ed4a329 100644 --- a/config.def.h +++ b/config.def.h @@ -20,6 +20,14 @@ static char shell[] = "/bin/sh"; static char *utmp = NULL; static char stty_args[] = "stty raw pass8 nl -echo -iexten -cstopb 38400"; +/* Multiplexer wrapper */ +static int use_mux = 0; +static char *mux_new[] = {"/usr/bin/tmux", "new-session", "-s", NULL, "--"}; +static char mux_post[] = + "tmux list-clients -t \"$MUX_NM\" 2>/dev/null" + "| { read -r _ && ! read -r _; }" + "&& tmux kill-session -t \"$MUX_NM\""; + /* identification sequence returned in DA and DECID */ static char vtiden[] = "\033[?6c"; diff --git a/st.c b/st.c index 2594c65..d41b805 100644 --- a/st.c +++ b/st.c @@ -560,6 +560,9 @@ typedef struct { static Fontcache frc[16]; static int frclen = 0; +/* Multiplexer session name */ +static char mux_nm[64] = {0}; + ssize_t xwrite(int fd, const char *s, size_t len) { @@ -1366,6 +1369,16 @@ execsh(void) signal(SIGTERM, SIG_DFL); signal(SIGALRM, SIG_DFL); + if (use_mux) { + int i = sizeof(mux_new)/sizeof(mux_new[0]), j = 0; + while(args[j++]); + char *margs[i + j]; + while(j--) { margs[i + j] = args[j]; } + while(i--) { margs[i] = mux_new[i] ? mux_new[i] : mux_nm; } + execvp(mux_new[0], margs); + _exit(1); + } + execvp(prog, args); _exit(1); } @@ -4177,6 +4190,11 @@ cmessage(XEvent *e) xw.state &= ~WIN_FOCUSED; } } else if (e->xclient.data.l[0] == xw.wmdeletewin) { + if (use_mux) { + setenv("MUX_NM", mux_nm, 1); + if (system(mux_post) != 0) + fprintf(stderr, "mux_post execution error\n"); + } /* Send SIGHUP to shell */ kill(pid, SIGHUP); exit(0); @@ -4325,7 +4343,7 @@ usage(void) die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]" " [-n name] [-o file]\n" " [-T title] [-t title] [-w windowid]" - " [[-e] command [args ...]]\n" + " [-m|-M] [[-e] command [args ...]]\n" " %s [-aiv] [-c class] [-f font] [-g geometry]" " [-n name] [-o file]\n" " [-T title] [-t title] [-w windowid] -l line" @@ -4368,6 +4386,12 @@ main(int argc, char *argv[]) case 'l': opt_line = EARGF(usage()); break; + case 'm': + use_mux = 1; + break; + case 'M': + use_mux = 0; + break; case 'n': opt_name = EARGF(usage()); break; @@ -4392,6 +4416,9 @@ run: if (!opt_title && !opt_line) opt_title = basename(xstrdup(argv[0])); } + if (use_mux) { + snprintf(mux_nm, sizeof(mux_nm), "%.43s-%d", (opt_name ? opt_name : "st"), getpid()); + } setlocale(LC_CTYPE, ""); XSetLocaleModifiers(""); tnew(MAX(cols, 1), MAX(rows, 1));
#!/bin/bash trap "tmux list-clients -t st-$$ 2>/dev/null | { read -r _ && ! read -n1 -r _; } && tmux kill-session -t st-$$ " INT TERM EXIT tmux new-session -s st-$$ -- "$@"