From 3bff7a9e62916cb7d2b73f28f19d73539599dbe8 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 1 Jun 2026 08:27:37 +0000 Subject: [PATCH] Allow run-shell arguments after a shell command to be expanded as #1, #2 and so on. From Rasmus Thystrup Karstensen in GitHub issue 5121. --- cmd-run-shell.c | 19 ++++++++++++++----- format.c | 9 ++++++++- tmux.1 | 16 +++++++++++++++- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/cmd-run-shell.c b/cmd-run-shell.c index a9f1c1fe..6114f68a 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -44,9 +44,9 @@ const struct cmd_entry cmd_run_shell_entry = { .name = "run-shell", .alias = "run", - .args = { "bd:Ct:Es:c:", 0, 1, cmd_run_shell_args_parse }, + .args = { "bd:Ct:Es:c:", 0, -1, cmd_run_shell_args_parse }, .usage = "[-bCE] [-c start-directory] [-d delay] " CMD_TARGET_PANE_USAGE - " [shell-command]", + " [shell-command [argument ...]]", .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, @@ -115,9 +115,11 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) struct session *s = target->s; struct window_pane *wp = target->wp; const char *delay, *cmd; + struct format_tree *ft; double d; struct timeval tv; - char *end; + char *end, key[16]; + u_int i; int wait = !args_has(args, 'b'); if ((delay = args_get(args, 'd')) != NULL) { @@ -132,8 +134,15 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) cdata = xcalloc(1, sizeof *cdata); if (!args_has(args, 'C')) { cmd = args_string(args, 0); - if (cmd != NULL) - cdata->cmd = format_single_from_target(item, cmd); + if (cmd != NULL) { + ft = format_create_from_target(item); + for (i = 1; i < args_count(args); i++) { + xsnprintf(key, sizeof key, "%u", i); + format_add(ft, key, "%s", args_string(args, i)); + } + cdata->cmd = format_expand(ft, cmd); + format_free(ft); + } } else { cdata->state = args_make_commands_prepare(self, item, 0, NULL, wait, 1); diff --git a/format.c b/format.c index b7539c2d..f81d807d 100644 --- a/format.c +++ b/format.c @@ -5560,7 +5560,7 @@ format_expand1(struct format_expand_state *es, const char *fmt) const char *ptr, *s, *style_end = NULL; size_t off, len, n, outlen; int ch, brackets; - char expanded[8192]; + char expanded[8192], number[2] = { 0 }; if (fmt == NULL || *fmt == '\0' || !format_check_time(es)) return (xstrdup("")); @@ -5689,6 +5689,13 @@ format_expand1(struct format_expand_state *es, const char *fmt) continue; default: s = NULL; + if (ch >= '1' && ch <= '9') { + number[0] = ch; + if (format_replace(es, number, 1, &buf, &len, + &off) != 0) + break; + continue; + } if (fmt > style_end) { /* skip inside #[] */ if (ch >= 'A' && ch <= 'Z') s = format_upper[ch - 'A']; diff --git a/tmux.1 b/tmux.1 index b29d5c80..decd945b 100644 --- a/tmux.1 +++ b/tmux.1 @@ -7844,7 +7844,7 @@ option. .Op Fl c Ar start\-directory .Op Fl d Ar delay .Op Fl t Ar target\-pane -.Op Ar shell\-command +.Op Ar shell\-command Op Ar argument ... .Xc .D1 Pq alias: Ic run Execute @@ -7861,6 +7861,20 @@ Before being executed, is expanded using the rules specified in the .Sx FORMATS section. +If +.Ar argument +values are given, they are available as +.Ql #1 , +.Ql #2 +or +.Ql #{1} , +.Ql #{2} +and so on. +For example: +.Bd -literal -offset indent +run-shell 'myscript.sh #1 #2' foo bar +.Ed +.Pp With .Fl b , the command is run in the background.