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.
This commit is contained in:
nicm
2026-06-01 08:27:37 +00:00
parent a9721ea268
commit 3bff7a9e62
3 changed files with 37 additions and 7 deletions

View File

@@ -44,9 +44,9 @@ const struct cmd_entry cmd_run_shell_entry = {
.name = "run-shell", .name = "run-shell",
.alias = "run", .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 .usage = "[-bCE] [-c start-directory] [-d delay] " CMD_TARGET_PANE_USAGE
" [shell-command]", " [shell-command [argument ...]]",
.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, .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 session *s = target->s;
struct window_pane *wp = target->wp; struct window_pane *wp = target->wp;
const char *delay, *cmd; const char *delay, *cmd;
struct format_tree *ft;
double d; double d;
struct timeval tv; struct timeval tv;
char *end; char *end, key[16];
u_int i;
int wait = !args_has(args, 'b'); int wait = !args_has(args, 'b');
if ((delay = args_get(args, 'd')) != NULL) { 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); cdata = xcalloc(1, sizeof *cdata);
if (!args_has(args, 'C')) { if (!args_has(args, 'C')) {
cmd = args_string(args, 0); cmd = args_string(args, 0);
if (cmd != NULL) if (cmd != NULL) {
cdata->cmd = format_single_from_target(item, cmd); 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 { } else {
cdata->state = args_make_commands_prepare(self, item, 0, NULL, cdata->state = args_make_commands_prepare(self, item, 0, NULL,
wait, 1); wait, 1);

View File

@@ -5560,7 +5560,7 @@ format_expand1(struct format_expand_state *es, const char *fmt)
const char *ptr, *s, *style_end = NULL; const char *ptr, *s, *style_end = NULL;
size_t off, len, n, outlen; size_t off, len, n, outlen;
int ch, brackets; int ch, brackets;
char expanded[8192]; char expanded[8192], number[2] = { 0 };
if (fmt == NULL || *fmt == '\0' || !format_check_time(es)) if (fmt == NULL || *fmt == '\0' || !format_check_time(es))
return (xstrdup("")); return (xstrdup(""));
@@ -5689,6 +5689,13 @@ format_expand1(struct format_expand_state *es, const char *fmt)
continue; continue;
default: default:
s = NULL; 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 (fmt > style_end) { /* skip inside #[] */
if (ch >= 'A' && ch <= 'Z') if (ch >= 'A' && ch <= 'Z')
s = format_upper[ch - 'A']; s = format_upper[ch - 'A'];

16
tmux.1
View File

@@ -7844,7 +7844,7 @@ option.
.Op Fl c Ar start\-directory .Op Fl c Ar start\-directory
.Op Fl d Ar delay .Op Fl d Ar delay
.Op Fl t Ar target\-pane .Op Fl t Ar target\-pane
.Op Ar shell\-command .Op Ar shell\-command Op Ar argument ...
.Xc .Xc
.D1 Pq alias: Ic run .D1 Pq alias: Ic run
Execute Execute
@@ -7861,6 +7861,20 @@ Before being executed,
is expanded using the rules specified in the is expanded using the rules specified in the
.Sx FORMATS .Sx FORMATS
section. 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 With
.Fl b , .Fl b ,
the command is run in the background. the command is run in the background.