From e03a937c71b9e415e1d74da85efbb6c5685d3c73 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 3 Jul 2026 16:10:25 +0000 Subject: [PATCH] Add a quoted pane_start_command_list which does not lose argument information. --- format.c | 37 ++++++++++++++++++++++++++++++++++++- tmux.1 | 16 +++++++++++++--- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/format.c b/format.c index 337fe18ec..e16a8e2c3 100644 --- a/format.c +++ b/format.c @@ -42,6 +42,7 @@ struct format_expand_state; static char *format_job_get(struct format_expand_state *, const char *); +static char *format_quote_shell_single(const char *); static char *format_expand1(struct format_expand_state *, const char *); static int format_replace(struct format_expand_state *, const char *, size_t, char **, size_t *, size_t *); @@ -865,6 +866,37 @@ format_cb_start_command(struct format_tree *ft) return (cmd_stringify_argv(wp->argc, wp->argv)); } +/* Callback for pane_start_command_list. */ +static void * +format_cb_start_command_list(struct format_tree *ft) +{ + struct window_pane *wp = ft->wp; + char *buf = NULL, *s; + size_t len = 0; + int i; + + if (wp == NULL) + return (NULL); + if (wp->argc == 0) + return (xstrdup("")); + + for (i = 0; i < wp->argc; i++) { + s = format_quote_shell_single(wp->argv[i]); + + len += strlen(s) + 1; + buf = xrealloc(buf, len); + + if (i == 0) + *buf = '\0'; + else + strlcat(buf, " ", len); + strlcat(buf, s, len); + + free(s); + } + return (buf); +} + /* Callback for pane_start_path. */ static void * format_cb_start_path(struct format_tree *ft) @@ -2293,7 +2325,7 @@ format_cb_pane_path(struct format_tree *ft) static void * format_cb_pane_pid(struct format_tree *ft) { - if (ft->wp != NULL) + if (ft->wp != NULL && ft->wp->fd != -1) return (format_printf("%ld", (long)ft->wp->pid)); return (NULL); } @@ -3540,6 +3572,9 @@ static const struct format_table_entry format_table[] = { { "pane_start_command", FORMAT_TABLE_STRING, format_cb_start_command }, + { "pane_start_command_list", FORMAT_TABLE_STRING, + format_cb_start_command_list + }, { "pane_start_path", FORMAT_TABLE_STRING, format_cb_start_path }, diff --git a/tmux.1 b/tmux.1 index def0780b8..f672c0202 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3523,7 +3523,7 @@ the option. .Tg neww .It Xo Ic new\-window -.Op Fl abdkPS +.Op Fl abdEkPS .Op Fl c Ar start\-directory .Op Fl e Ar environment .Op Fl F Ar format @@ -3547,6 +3547,9 @@ is the new window location. If .Fl d is given, the session does not make the new window the current window. +If +.Fl E +is given, the initial pane is created without a running command. .Ar target\-window represents the window to be created; if the target already exists an error is shown, unless the @@ -3846,7 +3849,7 @@ This command will automatically set to manual in the window options. .Tg respawnp .It Xo Ic respawn\-pane -.Op Fl k +.Op Fl Ek .Op Fl c Ar start\-directory .Op Fl e Ar environment .Op Fl t Ar target\-pane @@ -3863,6 +3866,9 @@ executed. The pane must be already inactive, unless .Fl k is given, in which case any existing command is killed. +If +.Fl E +is given, the pane is left without a running command. .Fl c specifies a new working directory for the pane. The @@ -3872,7 +3878,7 @@ option has the same meaning as for the command. .Tg respawnw .It Xo Ic respawn\-window -.Op Fl k +.Op Fl Ek .Op Fl c Ar start\-directory .Op Fl e Ar environment .Op Fl t Ar target\-window @@ -3889,6 +3895,9 @@ executed. The window must be already inactive, unless .Fl k is given, in which case any existing command is killed. +If +.Fl E +is given, the window is left with one pane and without a running command. .Fl c specifies a new working directory for the window. The @@ -7101,6 +7110,7 @@ The following variables are available, where appropriate: .It Li "pane_right" Ta "" Ta "Right of pane" .It Li "pane_search_string" Ta "" Ta "Last search string in copy mode" .It Li "pane_start_command" Ta "" Ta "Command pane started with" +.It Li "pane_start_command_list" Ta "" Ta "Command pane started with, quoted" .It Li "pane_start_path" Ta "" Ta "Path pane started with" .It Li "pane_synchronized" Ta "" Ta "1 if pane is synchronized" .It Li "pane_tabs" Ta "" Ta "Pane tab positions"