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-$$ -- "$@"