Add a -d flag to run-shell to wait for delay before running the command,

also allow run-shell to accept no command to just delay.
pull/2097/head^2
nicm 2020-03-12 13:25:45 +00:00
parent 7863445e5d
commit 516f6099fc
2 changed files with 59 additions and 12 deletions

View File

@ -31,6 +31,7 @@
static enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmdq_item *); static enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmdq_item *);
static void cmd_run_shell_timer(int, short, void *);
static void cmd_run_shell_callback(struct job *); static void cmd_run_shell_callback(struct job *);
static void cmd_run_shell_free(void *); static void cmd_run_shell_free(void *);
static void cmd_run_shell_print(struct job *, const char *); static void cmd_run_shell_print(struct job *, const char *);
@ -39,8 +40,8 @@ const struct cmd_entry cmd_run_shell_entry = {
.name = "run-shell", .name = "run-shell",
.alias = "run", .alias = "run",
.args = { "bt:", 1, 1 }, .args = { "bd:t:", 0, 1 },
.usage = "[-b] " CMD_TARGET_PANE_USAGE " shell-command", .usage = "[-b] [-d delay] " CMD_TARGET_PANE_USAGE " [shell-command]",
.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
@ -50,8 +51,11 @@ const struct cmd_entry cmd_run_shell_entry = {
struct cmd_run_shell_data { struct cmd_run_shell_data {
char *cmd; char *cmd;
char *cwd;
struct cmdq_item *item; struct cmdq_item *item;
struct session *s;
int wp_id; int wp_id;
struct event timer;
}; };
static void static void
@ -91,9 +95,14 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item)
struct session *s = item->target.s; struct session *s = item->target.s;
struct winlink *wl = item->target.wl; struct winlink *wl = item->target.wl;
struct window_pane *wp = item->target.wp; struct window_pane *wp = item->target.wp;
const char *delay;
double d;
struct timeval tv;
char *end;
cdata = xcalloc(1, sizeof *cdata); cdata = xcalloc(1, sizeof *cdata);
cdata->cmd = format_single(item, args->argv[0], c, s, wl, wp); if (args->argc != 0)
cdata->cmd = format_single(item, args->argv[0], c, s, wl, wp);
if (args_has(args, 't') && wp != NULL) if (args_has(args, 't') && wp != NULL)
cdata->wp_id = wp->id; cdata->wp_id = wp->id;
@ -103,18 +112,48 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item)
if (!args_has(args, 'b')) if (!args_has(args, 'b'))
cdata->item = item; cdata->item = item;
if (job_run(cdata->cmd, s, server_client_get_cwd(item->client, s), NULL, cdata->cwd = xstrdup(server_client_get_cwd(item->client, s));
cmd_run_shell_callback, cmd_run_shell_free, cdata, 0) == NULL) { cdata->s = s;
cmdq_error(item, "failed to run command: %s", cdata->cmd); session_add_ref(s, __func__);
free(cdata);
return (CMD_RETURN_ERROR); evtimer_set(&cdata->timer, cmd_run_shell_timer, cdata);
}
if ((delay = args_get(args, 'd')) != NULL) {
d = strtod(delay, &end);
if (*end != '\0') {
cmdq_error(item, "invalid delay time: %s", delay);
cmd_run_shell_free(cdata);
return (CMD_RETURN_ERROR);
}
timerclear(&tv);
tv.tv_sec = (time_t)d;
tv.tv_usec = (d - (double)tv.tv_sec) * 1000000U;
evtimer_add(&cdata->timer, &tv);
} else
cmd_run_shell_timer(-1, 0, cdata);
if (args_has(args, 'b')) if (args_has(args, 'b'))
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT); return (CMD_RETURN_WAIT);
} }
static void
cmd_run_shell_timer(__unused int fd, __unused short events, void* arg)
{
struct cmd_run_shell_data *cdata = arg;
if (cdata->cmd != NULL) {
if (job_run(cdata->cmd, cdata->s, cdata->cwd, NULL,
cmd_run_shell_callback, cmd_run_shell_free, cdata,
0) == NULL)
cmd_run_shell_free(cdata);
} else {
if (cdata->item != NULL)
cmdq_continue(cdata->item);
cmd_run_shell_free(cdata);
}
}
static void static void
cmd_run_shell_callback(struct job *job) cmd_run_shell_callback(struct job *job)
{ {
@ -163,6 +202,9 @@ cmd_run_shell_free(void *data)
{ {
struct cmd_run_shell_data *cdata = data; struct cmd_run_shell_data *cdata = data;
evtimer_del(&cdata->timer);
session_remove_ref(cdata->s, __func__);
free(cdata->cwd);
free(cdata->cmd); free(cdata->cmd);
free(cdata); free(cdata);
} }

11
tmux.1
View File

@ -5202,8 +5202,9 @@ Lock each client individually by running the command specified by the
option. option.
.It Xo Ic run-shell .It Xo Ic run-shell
.Op Fl b .Op Fl b
.Op Fl d Ar delay
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Ar shell-command .Ar [shell-command]
.Xc .Xc
.D1 (alias: Ic run ) .D1 (alias: Ic run )
Execute Execute
@ -5216,8 +5217,12 @@ section.
With With
.Fl b , .Fl b ,
the command is run in the background. the command is run in the background.
After it finishes, any output to stdout is displayed in copy mode (in the pane .Fl d
specified by waits for
.Ar delay
seconds before starting the command.
After the command finishes, any output to stdout is displayed in view mode (in
the pane specified by
.Fl t .Fl t
or the current pane if omitted). or the current pane if omitted).
If the command doesn't return success, the exit status is also displayed. If the command doesn't return success, the exit status is also displayed.