From 20636d956dd36c1f14152569a4d44a50eea9083d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 24 Mar 2013 09:54:10 +0000 Subject: Add a command queue to standardize and simplify commands that call other commands and allow a command to block execution of subsequent commands. This allows run-shell and if-shell to be synchronous which has been much requested. Each client has a default command queue and commands are consumed one at a time from it. A command may suspend execution from the queue by returning CMD_RETURN_WAIT and then resume it by calling cmd_continue() - for example run-shell does this from the callback that is fired after the job is freed. When the command queue becomes empty, command clients are automatically exited (unless attaching). A callback is also fired - this is used for nested commands in, for example, if-shell which can block execution of the client's cmdq until a new cmdq becomes empty. Also merge all the old error/info/print functions together and lose the old curclient/cmdclient distinction - a cmdq is bound to one client (or none if in the configuration file), this is a command client if c->session is NULL otherwise an attached client. --- Makefile | 3 +- cfg.c | 126 +++++++----------------- client.c | 3 +- cmd-attach-session.c | 43 +++++---- cmd-bind-key.c | 25 ++--- cmd-break-pane.c | 12 +-- cmd-capture-pane.c | 19 ++-- cmd-choose-buffer.c | 10 +- cmd-choose-client.c | 12 +-- cmd-choose-list.c | 10 +- cmd-choose-tree.c | 10 +- cmd-clear-history.c | 6 +- cmd-clock-mode.c | 6 +- cmd-command-prompt.c | 17 +--- cmd-confirm-before.c | 44 ++++----- cmd-copy-mode.c | 6 +- cmd-delete-buffer.c | 8 +- cmd-detach-client.c | 10 +- cmd-display-message.c | 16 +-- cmd-display-panes.c | 6 +- cmd-find-window.c | 12 +-- cmd-has-session.c | 6 +- cmd-if-shell.c | 77 +++++++++++---- cmd-join-pane.c | 24 ++--- cmd-kill-pane.c | 6 +- cmd-kill-server.c | 4 +- cmd-kill-session.c | 6 +- cmd-kill-window.c | 6 +- cmd-link-window.c | 10 +- cmd-list-buffers.c | 6 +- cmd-list-clients.c | 8 +- cmd-list-commands.c | 8 +- cmd-list-keys.c | 16 +-- cmd-list-panes.c | 32 +++--- cmd-list-sessions.c | 6 +- cmd-list-windows.c | 22 ++--- cmd-list.c | 73 ++------------ cmd-load-buffer.c | 30 +++--- cmd-lock-server.c | 10 +- cmd-move-window.c | 12 +-- cmd-new-session.c | 148 ++++++++++++---------------- cmd-new-window.c | 20 ++-- cmd-paste-buffer.c | 10 +- cmd-pipe-pane.c | 12 +-- cmd-queue.c | 258 +++++++++++++++++++++++++++++++++++++++++++++++++ cmd-refresh-client.c | 14 +-- cmd-rename-session.c | 10 +- cmd-rename-window.c | 6 +- cmd-resize-pane.c | 12 +-- cmd-respawn-pane.c | 10 +- cmd-respawn-window.c | 10 +- cmd-rotate-window.c | 6 +- cmd-run-shell.c | 45 +++++---- cmd-save-buffer.c | 136 +++++++++++++++++--------- cmd-select-layout.c | 14 +-- cmd-select-pane.c | 14 +-- cmd-select-window.c | 16 +-- cmd-send-keys.c | 25 ++++- cmd-server-info.c | 54 +++++------ cmd-set-buffer.c | 8 +- cmd-set-environment.c | 16 +-- cmd-show-environment.c | 16 +-- cmd-show-messages.c | 8 +- cmd-show-options.c | 42 ++++---- cmd-source-file.c | 84 +++++++++++----- cmd-split-window.c | 16 +-- cmd-start-server.c | 4 +- cmd-string.c | 5 +- cmd-suspend-client.c | 6 +- cmd-swap-pane.c | 8 +- cmd-swap-window.c | 10 +- cmd-switch-client.c | 18 ++-- cmd-unbind-key.c | 14 +-- cmd-unlink-window.c | 8 +- cmd.c | 156 ++++++++++++------------------ control.c | 51 +--------- format.c | 6 +- key-bindings.c | 79 ++------------- server-client.c | 83 +++------------- server-fn.c | 4 +- server.c | 42 ++++---- tmux.c | 2 - tmux.h | 136 ++++++++++++++------------ window-choose.c | 15 +-- 84 files changed, 1238 insertions(+), 1185 deletions(-) create mode 100644 cmd-queue.c diff --git a/Makefile b/Makefile index cebcac8e..f78b1615 100644 --- a/Makefile +++ b/Makefile @@ -60,12 +60,10 @@ SRCS= arguments.c \ cmd-select-pane.c \ cmd-select-window.c \ cmd-send-keys.c \ - cmd-send-prefix.c \ cmd-server-info.c \ cmd-set-buffer.c \ cmd-set-environment.c \ cmd-set-option.c \ - cmd-show-buffer.c \ cmd-show-environment.c \ cmd-show-messages.c \ cmd-show-options.c \ @@ -80,6 +78,7 @@ SRCS= arguments.c \ cmd-unbind-key.c \ cmd-unlink-window.c \ cmd.c \ + cmd-queue.c \ colour.c \ control.c \ control-notify.c \ diff --git a/cfg.c b/cfg.c index b7b0ec78..e4069d68 100644 --- a/cfg.c +++ b/cfg.c @@ -27,80 +27,27 @@ #include "tmux.h" -/* - * Config file parser. Pretty quick and simple, each line is parsed into a - * argv array and executed as a command. - */ - -void printflike2 cfg_print(struct cmd_ctx *, const char *, ...); -void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); - -char *cfg_cause; +struct cmd_q *cfg_cmd_q; int cfg_finished; -int cfg_references; +int cfg_references; struct causelist cfg_causes; -void printflike2 -cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...) -{ -} - -void printflike2 -cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - xvasprintf(&cfg_cause, fmt, ap); - va_end(ap); -} - -void printflike2 -cfg_add_cause(struct causelist *causes, const char *fmt, ...) -{ - char *cause; - va_list ap; - - va_start(ap, fmt); - xvasprintf(&cause, fmt, ap); - va_end(ap); - - ARRAY_ADD(causes, cause); -} - -/* - * Load configuration file. Returns -1 for an error with a list of messages in - * causes. Note that causes must be initialised by the caller! - */ -enum cmd_retval -load_cfg(const char *path, struct cmd_ctx *ctx, struct causelist *causes) +int +load_cfg(const char *path, struct cmd_q *cmdq, char **cause) { FILE *f; - u_int n; - char *buf, *copy, *line, *cause; + u_int n, found; + char *buf, *copy, *line, *cause1, *msg; size_t len, oldlen; struct cmd_list *cmdlist; - enum cmd_retval retval; if ((f = fopen(path, "rb")) == NULL) { - cfg_add_cause(causes, "%s: %s", path, strerror(errno)); - return (CMD_RETURN_ERROR); - } - - cfg_references++; - - if (ctx != NULL) - cmd_ref_ctx(ctx); - else { - ctx = cmd_get_ctx(NULL, NULL); - ctx->error = cfg_error; - ctx->print = cfg_print; - ctx->info = cfg_print; + xasprintf(cause, "%s: %s", path, strerror(errno)); + return (-1); } - n = 0; + n = found = 0; line = NULL; - retval = CMD_RETURN_NORMAL; while ((buf = fgetln(f, &len))) { /* Trim \n. */ if (buf[len - 1] == '\n') @@ -142,53 +89,47 @@ load_cfg(const char *path, struct cmd_ctx *ctx, struct causelist *causes) continue; } - if (cmd_string_parse(buf, &cmdlist, &cause) != 0) { + /* Parse and run the command. */ + if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) { free(copy); - if (cause == NULL) + if (cause1 == NULL) continue; - cfg_add_cause(causes, "%s: %u: %s", path, n, cause); - free(cause); + xasprintf(&msg, "%s:%u: %s", path, n, cause1); + ARRAY_ADD(&cfg_causes, msg); + free(cause1); continue; } free(copy); + if (cmdlist == NULL) continue; - - cfg_cause = NULL; - switch (cmd_list_exec(cmdlist, ctx)) { - case CMD_RETURN_YIELD: - if (retval != CMD_RETURN_ATTACH) - retval = CMD_RETURN_YIELD; - break; - case CMD_RETURN_ATTACH: - retval = CMD_RETURN_ATTACH; - break; - case CMD_RETURN_ERROR: - case CMD_RETURN_NORMAL: - break; - } + cmdq_append(cmdq, cmdlist); cmd_list_free(cmdlist); - if (cfg_cause != NULL) { - cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause); - free(cfg_cause); - } + found++; } - if (line != NULL) { - cfg_add_cause(causes, - "%s: %d: line continuation at end of file", path, n); + if (line != NULL) free(line); - } fclose(f); - cmd_free_ctx(ctx); + return (found); +} + +void +cfg_default_done(unused struct cmd_q *cmdq) +{ + if (--cfg_references != 0) + return; + cfg_finished = 1; - cfg_references--; + if (!RB_EMPTY(&sessions)) + cfg_show_causes(RB_MIN(sessions, &sessions)); - return (retval); + cmdq_free(cfg_cmd_q); + cfg_cmd_q = NULL; } void -show_cfg_causes(struct session *s) +cfg_show_causes(struct session *s) { struct window_pane *wp; char *cause; @@ -196,7 +137,6 @@ show_cfg_causes(struct session *s) if (s == NULL || ARRAY_EMPTY(&cfg_causes)) return; - wp = s->curw->window->active; window_pane_set_mode(wp, &window_copy_mode); diff --git a/client.c b/client.c index 92c3fca3..8693afeb 100644 --- a/client.c +++ b/client.c @@ -188,7 +188,8 @@ client_main(int argc, char **argv, int flags) * later in server) but it is necessary to get the start server * flag. */ - if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) { + cmdlist = cmd_list_parse(argc, argv, NULL, 0, &cause); + if (cmdlist == NULL) { fprintf(stderr, "%s\n", cause); return (1); } diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 30451389..0298dda1 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -26,7 +26,7 @@ * Attach existing session to the current terminal. */ -enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_attach_session_entry = { "attach-session", "attach", @@ -39,7 +39,7 @@ const struct cmd_entry cmd_attach_session_entry = { }; enum cmd_retval -cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_attach_session_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s; @@ -49,17 +49,17 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) u_int i; if (RB_EMPTY(&sessions)) { - ctx->error(ctx, "no sessions"); + cmdq_error(cmdq, "no sessions"); return (CMD_RETURN_ERROR); } - if ((s = cmd_find_session(ctx, args_get(args, 't'), 1)) == NULL) + if ((s = cmd_find_session(cmdq, args_get(args, 't'), 1)) == NULL) return (CMD_RETURN_ERROR); - if (ctx->cmdclient == NULL && ctx->curclient == NULL) + if (cmdq->client == NULL) return (CMD_RETURN_NORMAL); - if (ctx->cmdclient == NULL) { + if (cmdq->client->session != NULL) { if (args_has(self->args, 'd')) { /* * Can't use server_write_session in case attaching to @@ -69,43 +69,44 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) c = ARRAY_ITEM(&clients, i); if (c == NULL || c->session != s) continue; - if (c == ctx->curclient) + if (c == cmdq->client) continue; server_write_client(c, MSG_DETACH, NULL, 0); } } - ctx->curclient->session = s; - notify_attached_session_changed(ctx->curclient); + cmdq->client->session = s; + notify_attached_session_changed(cmdq->client); session_update_activity(s); - server_redraw_client(ctx->curclient); + server_redraw_client(cmdq->client); s->curw->flags &= ~WINLINK_ALERTFLAGS; } else { - if (server_client_open(ctx->cmdclient, s, &cause) != 0) { - ctx->error(ctx, "open terminal failed: %s", cause); + if (server_client_open(cmdq->client, s, &cause) != 0) { + cmdq_error(cmdq, "open terminal failed: %s", cause); free(cause); return (CMD_RETURN_ERROR); } if (args_has(self->args, 'r')) - ctx->cmdclient->flags |= CLIENT_READONLY; + cmdq->client->flags |= CLIENT_READONLY; if (args_has(self->args, 'd')) server_write_session(s, MSG_DETACH, NULL, 0); - ctx->cmdclient->session = s; - notify_attached_session_changed(ctx->cmdclient); - session_update_activity(s); - server_write_ready(ctx->cmdclient); - update = options_get_string(&s->options, "update-environment"); - environ_update(update, &ctx->cmdclient->environ, &s->environ); + environ_update(update, &cmdq->client->environ, &s->environ); - server_redraw_client(ctx->cmdclient); + cmdq->client->session = s; + notify_attached_session_changed(cmdq->client); + session_update_activity(s); + server_redraw_client(cmdq->client); s->curw->flags &= ~WINLINK_ALERTFLAGS; + + server_write_ready(cmdq->client); + cmdq->client_exit = 0; } recalculate_sizes(); server_update_socket(); - return (CMD_RETURN_ATTACH); + return (CMD_RETURN_NORMAL); } diff --git a/cmd-bind-key.c b/cmd-bind-key.c index 086ac4ec..d9b65bec 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -28,9 +28,9 @@ */ enum cmd_retval cmd_bind_key_check(struct args *); -enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_q *); -enum cmd_retval cmd_bind_key_table(struct cmd *, struct cmd_ctx *, int); +enum cmd_retval cmd_bind_key_table(struct cmd *, struct cmd_q *, int); const struct cmd_entry cmd_bind_key_entry = { "bind-key", "bind", @@ -56,7 +56,7 @@ cmd_bind_key_check(struct args *args) } enum cmd_retval -cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; char *cause; @@ -65,16 +65,17 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx) key = key_string_lookup_string(args->argv[0]); if (key == KEYC_NONE) { - ctx->error(ctx, "unknown key: %s", args->argv[0]); + cmdq_error(cmdq, "unknown key: %s", args->argv[0]); return (CMD_RETURN_ERROR); } if (args_has(args, 't')) - return (cmd_bind_key_table(self, ctx, key)); + return (cmd_bind_key_table(self, cmdq, key)); - cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, &cause); + cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0, + &cause); if (cmdlist == NULL) { - ctx->error(ctx, "%s", cause); + cmdq_error(cmdq, "%s", cause); free(cause); return (CMD_RETURN_ERROR); } @@ -86,7 +87,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx) } enum cmd_retval -cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key) +cmd_bind_key_table(struct cmd *self, struct cmd_q *cmdq, int key) { struct args *args = self->args; const char *tablename; @@ -97,25 +98,25 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key) tablename = args_get(args, 't'); if ((mtab = mode_key_findtable(tablename)) == NULL) { - ctx->error(ctx, "unknown key table: %s", tablename); + cmdq_error(cmdq, "unknown key table: %s", tablename); return (CMD_RETURN_ERROR); } cmd = mode_key_fromstring(mtab->cmdstr, args->argv[1]); if (cmd == MODEKEY_NONE) { - ctx->error(ctx, "unknown command: %s", args->argv[1]); + cmdq_error(cmdq, "unknown command: %s", args->argv[1]); return (CMD_RETURN_ERROR); } if (cmd != MODEKEYCOPY_COPYPIPE) { if (args->argc != 2) { - ctx->error(ctx, "no argument allowed"); + cmdq_error(cmdq, "no argument allowed"); return (CMD_RETURN_ERROR); } arg = NULL; } else { if (args->argc != 3) { - ctx->error(ctx, "no argument given"); + cmdq_error(cmdq, "no argument given"); return (CMD_RETURN_ERROR); } arg = args->argv[2]; diff --git a/cmd-break-pane.c b/cmd-break-pane.c index a5a78077..27ae1624 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -26,7 +26,7 @@ * Break pane off into a window. */ -enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_break_pane_entry = { "break-pane", "breakp", @@ -39,7 +39,7 @@ const struct cmd_entry cmd_break_pane_entry = { }; enum cmd_retval -cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct winlink *wl; @@ -54,11 +54,11 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) const char *template; char *cp; - if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL) + if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) return (CMD_RETURN_ERROR); if (window_count_panes(wl->window) == 1) { - ctx->error(ctx, "can't break with only one pane"); + cmdq_error(cmdq, "can't break with only one pane"); return (CMD_RETURN_ERROR); } @@ -97,14 +97,14 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) template = BREAK_PANE_TEMPLATE; ft = format_create(); - if ((c = cmd_find_client(ctx, NULL, 1)) != NULL) + if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL) format_client(ft, c); format_session(ft, s); format_winlink(ft, s, wl); format_window_pane(ft, wp); cp = format_expand(ft, template); - ctx->print(ctx, "%s", cp); + cmdq_print(cmdq, "%s", cp); free(cp); format_free(ft); diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c index 6a10b7c9..aa032ce8 100644 --- a/cmd-capture-pane.c +++ b/cmd-capture-pane.c @@ -27,7 +27,7 @@ * Write the entire contents of a pane to a buffer or stdout. */ -enum cmd_retval cmd_capture_pane_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_capture_pane_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_capture_pane_entry = { "capture-pane", "capturep", @@ -41,7 +41,7 @@ const struct cmd_entry cmd_capture_pane_entry = { }; enum cmd_retval -cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; @@ -55,7 +55,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx) struct grid_cell *gc; const struct grid_line *gl; - if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) + if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) return (CMD_RETURN_ERROR); s = &wp->base; gd = s->grid; @@ -113,11 +113,10 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx) } if (args_has(args, 'p')) { - c = ctx->curclient; - if (c == NULL || !(c->flags & CLIENT_CONTROL)) - c = ctx->cmdclient; - if (c == NULL) { - ctx->error(ctx, "can't write to stdout"); + c = cmdq->client; + if (c == NULL || + (c->session != NULL && !(c->flags & CLIENT_CONTROL))) { + cmdq_error(cmdq, "can't write to stdout"); return (CMD_RETURN_ERROR); } evbuffer_add(c->stdout_data, buf, len); @@ -131,14 +130,14 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx) buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { - ctx->error(ctx, "buffer %s", cause); + cmdq_error(cmdq, "buffer %s", cause); free(buf); free(cause); return (CMD_RETURN_ERROR); } if (paste_replace(&global_buffers, buffer, buf, len) != 0) { - ctx->error(ctx, "no buffer %d", buffer); + cmdq_error(cmdq, "no buffer %d", buffer); free(buf); return (CMD_RETURN_ERROR); } diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c index a58e38b7..8713815d 100644 --- a/cmd-choose-buffer.c +++ b/cmd-choose-buffer.c @@ -27,7 +27,7 @@ * Enter choice mode to choose a buffer. */ -enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_choose_buffer_entry = { "choose-buffer", NULL, @@ -40,7 +40,7 @@ const struct cmd_entry cmd_choose_buffer_entry = { }; enum cmd_retval -cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; @@ -51,15 +51,15 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) const char *template; u_int idx; - if ((c = cmd_current_client(ctx)) == NULL) { - ctx->error(ctx, "no client available"); + if ((c = cmd_current_client(cmdq)) == NULL) { + cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } if ((template = args_get(args, 'F')) == NULL) template = CHOOSE_BUFFER_TEMPLATE; - if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) + if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) return (CMD_RETURN_ERROR); if (paste_get_top(&global_buffers) == NULL) diff --git a/cmd-choose-client.c b/cmd-choose-client.c index 962aefca..b32703c4 100644 --- a/cmd-choose-client.c +++ b/cmd-choose-client.c @@ -27,7 +27,7 @@ * Enter choice mode to choose a client. */ -enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_q *); void cmd_choose_client_callback(struct window_choose_data *); @@ -46,7 +46,7 @@ struct cmd_choose_client_data { }; enum cmd_retval -cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; @@ -57,12 +57,12 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) char *action; u_int i, idx, cur; - if ((c = cmd_current_client(ctx)) == NULL) { - ctx->error(ctx, "no client available"); + if ((c = cmd_current_client(cmdq)) == NULL) { + cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } - if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) + if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) return (CMD_RETURN_ERROR); if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) @@ -81,7 +81,7 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) c1 = ARRAY_ITEM(&clients, i); if (c1 == NULL || c1->session == NULL) continue; - if (c1 == ctx->curclient) + if (c1 == cmdq->client) cur = idx; idx++; diff --git a/cmd-choose-list.c b/cmd-choose-list.c index 9634fef4..15f87294 100644 --- a/cmd-choose-list.c +++ b/cmd-choose-list.c @@ -31,7 +31,7 @@ * Enter choose mode to choose a custom list. */ -enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_choose_list_entry = { "choose-list", NULL, @@ -44,7 +44,7 @@ const struct cmd_entry cmd_choose_list_entry = { }; enum cmd_retval -cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_choose_list_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; @@ -53,15 +53,15 @@ cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx) char *template, *item, *copy, *list; u_int idx; - if ((c = cmd_current_client(ctx)) == NULL) { - ctx->error(ctx, "no client available"); + if ((c = cmd_current_client(cmdq)) == NULL) { + cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } if ((list1 = args_get(args, 'l')) == NULL) return (CMD_RETURN_ERROR); - if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) + if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) return (CMD_RETURN_ERROR); if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index af85a3bf..f22f17c2 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -32,7 +32,7 @@ * Enter choice mode to choose a session and/or window. */ -enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_choose_tree_entry = { "choose-tree", NULL, @@ -66,7 +66,7 @@ const struct cmd_entry cmd_choose_window_entry = { }; enum cmd_retval -cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct winlink *wl, *wm; @@ -84,15 +84,15 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx) ses_template = win_template = NULL; ses_action = win_action = NULL; - if ((c = cmd_current_client(ctx)) == NULL) { - ctx->error(ctx, "no client available"); + if ((c = cmd_current_client(cmdq)) == NULL) { + cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } if ((s = c->session) == NULL) return (CMD_RETURN_ERROR); - if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) + if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) return (CMD_RETURN_ERROR); if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) diff --git a/cmd-clear-history.c b/cmd-clear-history.c index 8a88e46c..768ba86d 100644 --- a/cmd-clear-history.c +++ b/cmd-clear-history.c @@ -24,7 +24,7 @@ * Clear pane history. */ -enum cmd_retval cmd_clear_history_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_clear_history_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_clear_history_entry = { "clear-history", "clearhist", @@ -37,13 +37,13 @@ const struct cmd_entry cmd_clear_history_entry = { }; enum cmd_retval -cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_clear_history_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp; struct grid *gd; - if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) + if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) return (CMD_RETURN_ERROR); gd = wp->base.grid; diff --git a/cmd-clock-mode.c b/cmd-clock-mode.c index f1d9eceb..b1837004 100644 --- a/cmd-clock-mode.c +++ b/cmd-clock-mode.c @@ -24,7 +24,7 @@ * Enter clock mode. */ -enum cmd_retval cmd_clock_mode_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_clock_mode_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_clock_mode_entry = { "clock-mode", NULL, @@ -37,12 +37,12 @@ const struct cmd_entry cmd_clock_mode_entry = { }; enum cmd_retval -cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_clock_mode_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp; - if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) + if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) return (CMD_RETURN_ERROR); window_pane_set_mode(wp, &window_clock_mode); diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index 3a43b24f..3b773316 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -31,7 +31,7 @@ void cmd_command_prompt_key_binding(struct cmd *, int); int cmd_command_prompt_check(struct args *); -enum cmd_retval cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_command_prompt_exec(struct cmd *, struct cmd_q *); int cmd_command_prompt_callback(void *, const char *); void cmd_command_prompt_free(void *); @@ -85,7 +85,7 @@ cmd_command_prompt_key_binding(struct cmd *self, int key) } enum cmd_retval -cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; const char *inputs, *prompts; @@ -94,7 +94,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx) char *prompt, *ptr, *input = NULL; size_t n; - if ((c = cmd_find_client(ctx, args_get(args, 't'), 0)) == NULL) + if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) return (CMD_RETURN_ERROR); if (c->prompt_string != NULL) @@ -150,7 +150,6 @@ cmd_command_prompt_callback(void *data, const char *s) struct cmd_command_prompt_cdata *cdata = data; struct client *c = cdata->c; struct cmd_list *cmdlist; - struct cmd_ctx *ctx; char *cause, *new_template, *prompt, *ptr; char *input = NULL; @@ -175,7 +174,7 @@ cmd_command_prompt_callback(void *data, const char *s) return (1); } - if (cmd_string_parse(new_template, &cmdlist, &cause) != 0) { + if (cmd_string_parse(new_template, &cmdlist, NULL, 0, &cause) != 0) { if (cause != NULL) { *cause = toupper((u_char) *cause); status_message_set(c, "%s", cause); @@ -184,14 +183,8 @@ cmd_command_prompt_callback(void *data, const char *s) return (0); } - ctx = cmd_get_ctx(NULL, c); - ctx->error = key_bindings_error; - ctx->print = key_bindings_print; - ctx->info = key_bindings_info; - - cmd_list_exec(cmdlist, ctx); + cmdq_run(c->cmdq, cmdlist); cmd_list_free(cmdlist); - cmd_free_ctx(ctx); if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback) return (1); diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c index 765f58df..6282be2e 100644 --- a/cmd-confirm-before.c +++ b/cmd-confirm-before.c @@ -27,7 +27,7 @@ */ void cmd_confirm_before_key_binding(struct cmd *, int); -enum cmd_retval cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_confirm_before_exec(struct cmd *, struct cmd_q *); int cmd_confirm_before_callback(void *, const char *); void cmd_confirm_before_free(void *); @@ -43,8 +43,8 @@ const struct cmd_entry cmd_confirm_before_entry = { }; struct cmd_confirm_before_data { - struct client *c; char *cmd; + struct client *client; }; void @@ -66,7 +66,7 @@ cmd_confirm_before_key_binding(struct cmd *self, int key) } enum cmd_retval -cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct cmd_confirm_before_data *cdata; @@ -74,12 +74,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx) char *cmd, *copy, *new_prompt, *ptr; const char *prompt; - if (ctx->curclient == NULL) { - ctx->error(ctx, "must be run interactively"); - return (CMD_RETURN_ERROR); - } - - if ((c = cmd_find_client(ctx, args_get(args, 't'), 0)) == NULL) + if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) return (CMD_RETURN_ERROR); if ((prompt = args_get(args, 'p')) != NULL) @@ -93,46 +88,44 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx) cdata = xmalloc(sizeof *cdata); cdata->cmd = xstrdup(args->argv[0]); - cdata->c = c; - status_prompt_set(cdata->c, new_prompt, NULL, + + cdata->client = c; + cdata->client->references++; + + status_prompt_set(c, new_prompt, NULL, cmd_confirm_before_callback, cmd_confirm_before_free, cdata, PROMPT_SINGLE); free(new_prompt); - return (CMD_RETURN_YIELD); + return (CMD_RETURN_NORMAL); } int cmd_confirm_before_callback(void *data, const char *s) { struct cmd_confirm_before_data *cdata = data; - struct client *c = cdata->c; + struct client *c = cdata->client; struct cmd_list *cmdlist; - struct cmd_ctx *ctx; char *cause; + if (c->flags & CLIENT_DEAD) + return (0); + if (s == NULL || *s == '\0') return (0); if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') return (0); - if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) { + if (cmd_string_parse(cdata->cmd, &cmdlist, NULL, 0, &cause) != 0) { if (cause != NULL) { - *cause = toupper((u_char) *cause); - status_message_set(c, "%s", cause); + cmdq_error(c->cmdq, "%s", cause); free(cause); } return (0); } - ctx = cmd_get_ctx(NULL, c); - ctx->error = key_bindings_error; - ctx->print = key_bindings_print; - ctx->info = key_bindings_info; - - cmd_list_exec(cmdlist, ctx); + cmdq_run(c->cmdq, cmdlist); cmd_list_free(cmdlist); - cmd_free_ctx(ctx); return (0); } @@ -141,6 +134,9 @@ void cmd_confirm_before_free(void *data) { struct cmd_confirm_before_data *cdata = data; + struct client *c = cdata->client; + + c->references--; free(cdata->cmd); free(cdata); diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index 3f80cd8c..59b5a9e5 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -25,7 +25,7 @@ */ void cmd_copy_mode_key_binding(struct cmd *, int); -enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_copy_mode_entry = { "copy-mode", NULL, @@ -46,12 +46,12 @@ cmd_copy_mode_key_binding(struct cmd *self, int key) } enum cmd_retval -cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp; - if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) + if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) return (CMD_RETURN_ERROR); if (window_pane_set_mode(wp, &window_copy_mode) != 0) diff --git a/cmd-delete-buffer.c b/cmd-delete-buffer.c index c3f8776a..6e425b57 100644 --- a/cmd-delete-buffer.c +++ b/cmd-delete-buffer.c @@ -26,7 +26,7 @@ * Delete a paste buffer. */ -enum cmd_retval cmd_delete_buffer_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_delete_buffer_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_delete_buffer_entry = { "delete-buffer", "deleteb", @@ -39,7 +39,7 @@ const struct cmd_entry cmd_delete_buffer_entry = { }; enum cmd_retval -cmd_delete_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_delete_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; char *cause; @@ -52,13 +52,13 @@ cmd_delete_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { - ctx->error(ctx, "buffer %s", cause); + cmdq_error(cmdq, "buffer %s", cause); free(cause); return (CMD_RETURN_ERROR); } if (paste_free_index(&global_buffers, buffer) != 0) { - ctx->error(ctx, "no buffer %d", buffer); + cmdq_error(cmdq, "no buffer %d", buffer); return (CMD_RETURN_ERROR); } diff --git a/cmd-detach-client.c b/cmd-detach-client.c index a1d3a386..17b437ab 100644 --- a/cmd-detach-client.c +++ b/cmd-detach-client.c @@ -24,7 +24,7 @@ * Detach a client. */ -enum cmd_retval cmd_detach_client_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_detach_client_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_detach_client_entry = { "detach-client", "detach", @@ -37,7 +37,7 @@ const struct cmd_entry cmd_detach_client_entry = { }; enum cmd_retval -cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c, *c2; @@ -51,7 +51,7 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx) msgtype = MSG_DETACH; if (args_has(args, 's')) { - s = cmd_find_session(ctx, args_get(args, 's'), 0); + s = cmd_find_session(cmdq, args_get(args, 's'), 0); if (s == NULL) return (CMD_RETURN_ERROR); @@ -61,7 +61,7 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx) server_write_client(c, msgtype, NULL, 0); } } else { - c = cmd_find_client(ctx, args_get(args, 't'), 0); + c = cmd_find_client(cmdq, args_get(args, 't'), 0); if (c == NULL) return (CMD_RETURN_ERROR); @@ -76,5 +76,5 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx) server_write_client(c, msgtype, NULL, 0); } - return (CMD_RETURN_NORMAL); + return (CMD_RETURN_STOP); } diff --git a/cmd-display-message.c b/cmd-display-message.c index 05c3a408..7f31d7e2 100644 --- a/cmd-display-message.c +++ b/cmd-display-message.c @@ -27,7 +27,7 @@ * Displays a message in the status line. */ -enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_display_message_entry = { "display-message", "display", @@ -41,7 +41,7 @@ const struct cmd_entry cmd_display_message_entry = { }; enum cmd_retval -cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; @@ -56,17 +56,17 @@ cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx) size_t len; if (args_has(args, 't')) { - wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp); + wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); if (wl == NULL) return (CMD_RETURN_ERROR); } else { - wl = cmd_find_pane(ctx, NULL, &s, &wp); + wl = cmd_find_pane(cmdq, NULL, &s, &wp); if (wl == NULL) return (CMD_RETURN_ERROR); } if (args_has(args, 'F') && args->argc != 0) { - ctx->error(ctx, "only one of -F or argument must be given"); + cmdq_error(cmdq, "only one of -F or argument must be given"); return (CMD_RETURN_ERROR); } @@ -77,7 +77,7 @@ cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx) template = DISPLAY_MESSAGE_TEMPLATE; ft = format_create(); - if ((c = cmd_find_client(ctx, args_get(args, 'c'), 1)) != NULL) + if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 1)) != NULL) format_client(ft, c); format_session(ft, s); format_winlink(ft, s, wl); @@ -89,11 +89,11 @@ cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx) msg = format_expand(ft, out); if (args_has(self->args, 'p')) - ctx->print(ctx, "%s", msg); + cmdq_print(cmdq, "%s", msg); else status_message_set(c, "%s", msg); - free(msg); format_free(ft); + return (CMD_RETURN_NORMAL); } diff --git a/cmd-display-panes.c b/cmd-display-panes.c index b3e67fd2..a97a1809 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -24,7 +24,7 @@ * Display panes on a client. */ -enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_display_panes_entry = { "display-panes", "displayp", @@ -37,12 +37,12 @@ const struct cmd_entry cmd_display_panes_entry = { }; enum cmd_retval -cmd_display_panes_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; - if ((c = cmd_find_client(ctx, args_get(args, 't'), 0)) == NULL) + if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) return (CMD_RETURN_ERROR); server_set_identify(c); diff --git a/cmd-find-window.c b/cmd-find-window.c index acd63c84..f757d10f 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -28,7 +28,7 @@ * Find window containing text. */ -enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmd_q *); void cmd_find_window_callback(struct window_choose_data *); @@ -127,7 +127,7 @@ cmd_find_window_match(struct cmd_find_window_data_list *find_list, } enum cmd_retval -cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; @@ -139,13 +139,13 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) const char *template; u_int i, match_flags; - if ((c = cmd_current_client(ctx)) == NULL) { - ctx->error(ctx, "no client available"); + if ((c = cmd_current_client(cmdq)) == NULL) { + cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } s = c->session; - if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) + if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) return (CMD_RETURN_ERROR); if ((template = args_get(args, 'F')) == NULL) @@ -162,7 +162,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) free(searchstr); if (ARRAY_LENGTH(&find_list) == 0) { - ctx->error(ctx, "no windows matching: %s", str); + cmdq_error(cmdq, "no windows matching: %s", str); ARRAY_FREE(&find_list); return (CMD_RETURN_ERROR); } diff --git a/cmd-has-session.c b/cmd-has-session.c index 8e77942a..28e3aea3 100644 --- a/cmd-has-session.c +++ b/cmd-has-session.c @@ -24,7 +24,7 @@ * Cause client to report an error and exit with 1 if session doesn't exist. */ -enum cmd_retval cmd_has_session_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_has_session_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_has_session_entry = { "has-session", "has", @@ -37,11 +37,11 @@ const struct cmd_entry cmd_has_session_entry = { }; enum cmd_retval -cmd_has_session_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_has_session_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - if (cmd_find_session(ctx, args_get(args, 't'), 0) == NULL) + if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL) return (CMD_RETURN_ERROR); return (CMD_RETURN_NORMAL); diff --git a/cmd-if-shell.c b/cmd-if-shell.c index e0e2c230..e2a45972 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -29,15 +29,16 @@ * Executes a tmux command if a shell command returns true or false. */ -enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmd_q *); void cmd_if_shell_callback(struct job *); +void cmd_if_shell_done(struct cmd_q *); void cmd_if_shell_free(void *); const struct cmd_entry cmd_if_shell_entry = { "if-shell", "if", - "t:", 2, 3, - CMD_TARGET_PANE_USAGE " shell-command command [command]", + "bt:", 2, 3, + "[-b] " CMD_TARGET_PANE_USAGE " shell-command command [command]", 0, NULL, NULL, @@ -47,11 +48,13 @@ const struct cmd_entry cmd_if_shell_entry = { struct cmd_if_shell_data { char *cmd_if; char *cmd_else; - struct cmd_ctx *ctx; + struct cmd_q *cmdq; + int bflag; + int started; }; enum cmd_retval -cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct cmd_if_shell_data *cdata; @@ -61,7 +64,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) struct window_pane *wp; struct format_tree *ft; - wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp); + wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); if (wl == NULL) return (CMD_RETURN_ERROR); @@ -78,51 +81,83 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) cdata->cmd_else = xstrdup(args->argv[2]); else cdata->cmd_else = NULL; + cdata->bflag = args_has(args, 'b'); - cdata->ctx = ctx; - cmd_ref_ctx(ctx); + cdata->started = 0; + cdata->cmdq = cmdq; + cmdq->references++; job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata); free(shellcmd); - return (CMD_RETURN_YIELD); /* don't let client exit */ + if (cdata->bflag) + return (CMD_RETURN_NORMAL); + return (CMD_RETURN_WAIT); } void cmd_if_shell_callback(struct job *job) { struct cmd_if_shell_data *cdata = job->data; - struct cmd_ctx *ctx = cdata->ctx; + struct cmd_q *cmdq = cdata->cmdq, *cmdq1; struct cmd_list *cmdlist; char *cause, *cmd; - if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) { + if (cmdq->dead) + return; + + if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) cmd = cdata->cmd_else; - if (cmd == NULL) - return; - } else + else cmd = cdata->cmd_if; - if (cmd_string_parse(cmd, &cmdlist, &cause) != 0) { + if (cmd == NULL) + return; + + if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) { if (cause != NULL) { - ctx->error(ctx, "%s", cause); + cmdq_error(cmdq, "%s", cause); free(cause); } return; } - cmd_list_exec(cmdlist, ctx); + cdata->started = 1; + + cmdq1 = cmdq_new(cmdq->client); + cmdq1->emptyfn = cmd_if_shell_done; + cmdq1->data = cdata; + + cmdq_run(cmdq1, cmdlist); cmd_list_free(cmdlist); } +void +cmd_if_shell_done(struct cmd_q *cmdq1) +{ + struct cmd_if_shell_data *cdata = cmdq1->data; + struct cmd_q *cmdq = cdata->cmdq; + + if (!cmdq_free(cmdq) && !cdata->bflag) + cmdq_continue(cmdq); + + cmdq_free(cmdq1); + + free(cdata->cmd_else); + free(cdata->cmd_if); + free(cdata); +} + void cmd_if_shell_free(void *data) { struct cmd_if_shell_data *cdata = data; - struct cmd_ctx *ctx = cdata->ctx; + struct cmd_q *cmdq = cdata->cmdq; + + if (cdata->started) + return; - if (ctx->cmdclient != NULL) - ctx->cmdclient->flags |= CLIENT_EXIT; - cmd_free_ctx(ctx); + if (!cmdq_free(cmdq) && !cdata->bflag) + cmdq_continue(cmdq); free(cdata->cmd_else); free(cdata->cmd_if); diff --git a/cmd-join-pane.c b/cmd-join-pane.c index c792948c..2e7a59cd 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -30,9 +30,9 @@ */ void cmd_join_pane_key_binding(struct cmd *, int); -enum cmd_retval cmd_join_pane_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_join_pane_exec(struct cmd *, struct cmd_q *); -enum cmd_retval join_pane(struct cmd *, struct cmd_ctx *, int); +enum cmd_retval join_pane(struct cmd *, struct cmd_q *, int); const struct cmd_entry cmd_join_pane_entry = { "join-pane", "joinp", @@ -69,13 +69,13 @@ cmd_join_pane_key_binding(struct cmd *self, int key) } enum cmd_retval -cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_join_pane_exec(struct cmd *self, struct cmd_q *cmdq) { - return (join_pane(self, ctx, self->entry == &cmd_join_pane_entry)); + return (join_pane(self, cmdq, self->entry == &cmd_join_pane_entry)); } enum cmd_retval -join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window) +join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window) { struct args *args = self->args; struct session *dst_s; @@ -87,23 +87,23 @@ join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window) enum layout_type type; struct layout_cell *lc; - dst_wl = cmd_find_pane(ctx, args_get(args, 't'), &dst_s, &dst_wp); + dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), &dst_s, &dst_wp); if (dst_wl == NULL) return (CMD_RETURN_ERROR); dst_w = dst_wl->window; dst_idx = dst_wl->idx; - src_wl = cmd_find_pane(ctx, args_get(args, 's'), NULL, &src_wp); + src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp); if (src_wl == NULL) return (CMD_RETURN_ERROR); src_w = src_wl->window; if (not_same_window && src_w == dst_w) { - ctx->error(ctx, "can't join a pane to its own window"); + cmdq_error(cmdq, "can't join a pane to its own window"); return (CMD_RETURN_ERROR); } if (!not_same_window && src_wp == dst_wp) { - ctx->error(ctx, "source and target panes must be different"); + cmdq_error(cmdq, "source and target panes must be different"); return (CMD_RETURN_ERROR); } @@ -115,14 +115,14 @@ join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window) if (args_has(args, 'l')) { size = args_strtonum(args, 'l', 0, INT_MAX, &cause); if (cause != NULL) { - ctx->error(ctx, "size %s", cause); + cmdq_error(cmdq, "size %s", cause); free(cause); return (CMD_RETURN_ERROR); } } else if (args_has(args, 'p')) { percentage = args_strtonum(args, 'p', 0, 100, &cause); if (cause != NULL) { - ctx->error(ctx, "percentage %s", cause); + cmdq_error(cmdq, "percentage %s", cause); free(cause); return (CMD_RETURN_ERROR); } @@ -133,7 +133,7 @@ join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window) } lc = layout_split_pane(dst_wp, type, size, args_has(args, 'b')); if (lc == NULL) { - ctx->error(ctx, "create pane failed: pane too small"); + cmdq_error(cmdq, "create pane failed: pane too small"); return (CMD_RETURN_ERROR); } diff --git a/cmd-kill-pane.c b/cmd-kill-pane.c index 51989768..1aa776d9 100644 --- a/cmd-kill-pane.c +++ b/cmd-kill-pane.c @@ -26,7 +26,7 @@ * Kill pane. */ -enum cmd_retval cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_kill_pane_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_kill_pane_entry = { "kill-pane", "killp", @@ -39,13 +39,13 @@ const struct cmd_entry cmd_kill_pane_entry = { }; enum cmd_retval -cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_kill_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct winlink *wl; struct window_pane *loopwp, *tmpwp, *wp; - if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL) + if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL) return (CMD_RETURN_ERROR); if (window_count_panes(wl->window) == 1) { diff --git a/cmd-kill-server.c b/cmd-kill-server.c index fcf1e25c..808dca59 100644 --- a/cmd-kill-server.c +++ b/cmd-kill-server.c @@ -27,7 +27,7 @@ * Kill the server and do nothing else. */ -enum cmd_retval cmd_kill_server_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_kill_server_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_kill_server_entry = { "kill-server", NULL, @@ -40,7 +40,7 @@ const struct cmd_entry cmd_kill_server_entry = { }; enum cmd_retval -cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx) +cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_q *cmdq) { kill(getpid(), SIGTERM); diff --git a/cmd-kill-session.c b/cmd-kill-session.c index 9ee6a928..095fb9bb 100644 --- a/cmd-kill-session.c +++ b/cmd-kill-session.c @@ -27,7 +27,7 @@ * Note this deliberately has no alias to make it hard to hit by accident. */ -enum cmd_retval cmd_kill_session_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_kill_session_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_kill_session_entry = { "kill-session", NULL, @@ -40,12 +40,12 @@ const struct cmd_entry cmd_kill_session_entry = { }; enum cmd_retval -cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_kill_session_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s, *s2, *s3; - if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL) + if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) return (CMD_RETURN_ERROR); if (args_has(args, 'a')) { diff --git a/cmd-kill-window.c b/cmd-kill-window.c index 01587fc8..dcb1fd28 100644 --- a/cmd-kill-window.c +++ b/cmd-kill-window.c @@ -24,7 +24,7 @@ * Destroy window. */ -enum cmd_retval cmd_kill_window_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_kill_window_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_kill_window_entry = { "kill-window", "killw", @@ -37,13 +37,13 @@ const struct cmd_entry cmd_kill_window_entry = { }; enum cmd_retval -cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct winlink *wl, *wl2, *wl3; struct session *s; - if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL) + if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) return (CMD_RETURN_ERROR); if (args_has(args, 'a')) { diff --git a/cmd-link-window.c b/cmd-link-window.c index 5c050904..c7dfa5aa 100644 --- a/cmd-link-window.c +++ b/cmd-link-window.c @@ -26,7 +26,7 @@ * Link a window into another session. */ -enum cmd_retval cmd_link_window_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_link_window_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_link_window_entry = { "link-window", "linkw", @@ -39,7 +39,7 @@ const struct cmd_entry cmd_link_window_entry = { }; enum cmd_retval -cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_link_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *src, *dst; @@ -47,15 +47,15 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx) char *cause; int idx, kflag, dflag; - if ((wl = cmd_find_window(ctx, args_get(args, 's'), &src)) == NULL) + if ((wl = cmd_find_window(cmdq, args_get(args, 's'), &src)) == NULL) return (CMD_RETURN_ERROR); - if ((idx = cmd_find_index(ctx, args_get(args, 't'), &dst)) == -2) + if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst)) == -2) return (CMD_RETURN_ERROR); kflag = args_has(self->args, 'k'); dflag = args_has(self->args, 'd'); if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) { - ctx->error(ctx, "can't link window: %s", cause); + cmdq_error(cmdq, "can't link window: %s", cause); free(cause); return (CMD_RETURN_ERROR); } diff --git a/cmd-list-buffers.c b/cmd-list-buffers.c index b1d59f2f..54284d55 100644 --- a/cmd-list-buffers.c +++ b/cmd-list-buffers.c @@ -27,7 +27,7 @@ * List paste buffers. */ -enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_list_buffers_entry = { "list-buffers", "lsb", @@ -40,7 +40,7 @@ const struct cmd_entry cmd_list_buffers_entry = { }; enum cmd_retval -cmd_list_buffers_exec(unused struct cmd *self, struct cmd_ctx *ctx) +cmd_list_buffers_exec(unused struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct paste_buffer *pb; @@ -59,7 +59,7 @@ cmd_list_buffers_exec(unused struct cmd *self, struct cmd_ctx *ctx) format_paste_buffer(ft, pb); line = format_expand(ft, template); - ctx->print(ctx, "%s", line); + cmdq_print(cmdq, "%s", line); free(line); format_free(ft); diff --git a/cmd-list-clients.c b/cmd-list-clients.c index 70f6c809..e0f8558e 100644 --- a/cmd-list-clients.c +++ b/cmd-list-clients.c @@ -28,7 +28,7 @@ * List all clients. */ -enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_list_clients_entry = { "list-clients", "lsc", @@ -41,7 +41,7 @@ const struct cmd_entry cmd_list_clients_entry = { }; enum cmd_retval -cmd_list_clients_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; @@ -52,7 +52,7 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_ctx *ctx) char *line; if (args_has(args, 't')) { - s = cmd_find_session(ctx, args_get(args, 't'), 0); + s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); } else @@ -75,7 +75,7 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_ctx *ctx) format_client(ft, c); line = format_expand(ft, template); - ctx->print(ctx, "%s", line); + cmdq_print(cmdq, "%s", line); free(line); format_free(ft); diff --git a/cmd-list-commands.c b/cmd-list-commands.c index 05a31ec5..7073d5f8 100644 --- a/cmd-list-commands.c +++ b/cmd-list-commands.c @@ -24,7 +24,7 @@ * List all commands with usages. */ -enum cmd_retval cmd_list_commands_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_list_commands_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_list_commands_entry = { "list-commands", "lscm", @@ -37,16 +37,16 @@ const struct cmd_entry cmd_list_commands_entry = { }; enum cmd_retval -cmd_list_commands_exec(unused struct cmd *self, struct cmd_ctx *ctx) +cmd_list_commands_exec(unused struct cmd *self, struct cmd_q *cmdq) { const struct cmd_entry **entryp; for (entryp = cmd_table; *entryp != NULL; entryp++) { if ((*entryp)->alias != NULL) { - ctx->print(ctx, "%s (%s) %s", (*entryp)->name, + cmdq_print(cmdq, "%s (%s) %s", (*entryp)->name, (*entryp)->alias, (*entryp)->usage); } else { - ctx->print(ctx, "%s %s", (*entryp)->name, + cmdq_print(cmdq, "%s %s", (*entryp)->name, (*entryp)->usage); } } diff --git a/cmd-list-keys.c b/cmd-list-keys.c index dab6d545..1f568909 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -26,8 +26,8 @@ * List key bindings. */ -enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_ctx *); -enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_q *); +enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_list_keys_entry = { "list-keys", "lsk", @@ -40,7 +40,7 @@ const struct cmd_entry cmd_list_keys_entry = { }; enum cmd_retval -cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct key_binding *bd; @@ -50,7 +50,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx) int width, keywidth; if (args_has(args, 't')) - return (cmd_list_keys_table(self, ctx)); + return (cmd_list_keys_table(self, cmdq)); width = 0; @@ -91,14 +91,14 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx) continue; cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used); - ctx->print(ctx, "bind-key %s", tmp); + cmdq_print(cmdq, "bind-key %s", tmp); } return (CMD_RETURN_NORMAL); } enum cmd_retval -cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx) +cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; const char *tablename; @@ -109,7 +109,7 @@ cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx) tablename = args_get(args, 't'); if ((mtab = mode_key_findtable(tablename)) == NULL) { - ctx->error(ctx, "unknown key table: %s", tablename); + cmdq_error(cmdq, "unknown key table: %s", tablename); return (CMD_RETURN_ERROR); } @@ -138,7 +138,7 @@ cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx) mode = "c"; cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd); if (cmdstr != NULL) { - ctx->print(ctx, "bind-key -%st %s%s %*s %s%s%s%s", + cmdq_print(cmdq, "bind-key -%st %s%s %*s %s%s%s%s", mode, any_mode && *mode == '\0' ? " " : "", mtab->name, (int) width, key, cmdstr, mbind->arg != NULL ? " \"" : "", diff --git a/cmd-list-panes.c b/cmd-list-panes.c index 717562a4..910c19bc 100644 --- a/cmd-list-panes.c +++ b/cmd-list-panes.c @@ -27,13 +27,13 @@ * List panes on given window. */ -enum cmd_retval cmd_list_panes_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_list_panes_exec(struct cmd *, struct cmd_q *); -void cmd_list_panes_server(struct cmd *, struct cmd_ctx *); +void cmd_list_panes_server(struct cmd *, struct cmd_q *); void cmd_list_panes_session( - struct cmd *, struct session *, struct cmd_ctx *, int); + struct cmd *, struct session *, struct cmd_q *, int); void cmd_list_panes_window(struct cmd *, - struct session *, struct winlink *, struct cmd_ctx *, int); + struct session *, struct winlink *, struct cmd_q *, int); const struct cmd_entry cmd_list_panes_entry = { "list-panes", "lsp", @@ -46,51 +46,51 @@ const struct cmd_entry cmd_list_panes_entry = { }; enum cmd_retval -cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_list_panes_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s; struct winlink *wl; if (args_has(args, 'a')) - cmd_list_panes_server(self, ctx); + cmd_list_panes_server(self, cmdq); else if (args_has(args, 's')) { - s = cmd_find_session(ctx, args_get(args, 't'), 0); + s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); - cmd_list_panes_session(self, s, ctx, 1); + cmd_list_panes_session(self, s, cmdq, 1); } else { - wl = cmd_find_window(ctx, args_get(args, 't'), &s); + wl = cmd_find_window(cmdq, args_get(args, 't'), &s); if (wl == NULL) return (CMD_RETURN_ERROR); - cmd_list_panes_window(self, s, wl, ctx, 0); + cmd_list_panes_window(self, s, wl, cmdq, 0); } return (CMD_RETURN_NORMAL); } void -cmd_list_panes_server(struct cmd *self, struct cmd_ctx *ctx) +cmd_list_panes_server(struct cmd *self, struct cmd_q *cmdq) { struct session *s; RB_FOREACH(s, sessions, &sessions) - cmd_list_panes_session(self, s, ctx, 2); + cmd_list_panes_session(self, s, cmdq, 2); } void cmd_list_panes_session( - struct cmd *self, struct session *s, struct cmd_ctx *ctx, int type) + struct cmd *self, struct session *s, struct cmd_q *cmdq, int type) { struct winlink *wl; RB_FOREACH(wl, winlinks, &s->windows) - cmd_list_panes_window(self, s, wl, ctx, type); + cmd_list_panes_window(self, s, wl, cmdq, type); } void cmd_list_panes_window(struct cmd *self, - struct session *s, struct winlink *wl, struct cmd_ctx *ctx, int type) + struct session *s, struct winlink *wl, struct cmd_q *cmdq, int type) { struct args *args = self->args; struct window_pane *wp; @@ -135,7 +135,7 @@ cmd_list_panes_window(struct cmd *self, format_window_pane(ft, wp); line = format_expand(ft, template); - ctx->print(ctx, "%s", line); + cmdq_print(cmdq, "%s", line); free(line); format_free(ft); diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c index 81cc51cc..14ac4808 100644 --- a/cmd-list-sessions.c +++ b/cmd-list-sessions.c @@ -28,7 +28,7 @@ * List all sessions. */ -enum cmd_retval cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_list_sessions_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_list_sessions_entry = { "list-sessions", "ls", @@ -41,7 +41,7 @@ const struct cmd_entry cmd_list_sessions_entry = { }; enum cmd_retval -cmd_list_sessions_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_list_sessions_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s; @@ -60,7 +60,7 @@ cmd_list_sessions_exec(struct cmd *self, struct cmd_ctx *ctx) format_session(ft, s); line = format_expand(ft, template); - ctx->print(ctx, "%s", line); + cmdq_print(cmdq, "%s", line); free(line); format_free(ft); diff --git a/cmd-list-windows.c b/cmd-list-windows.c index 0485e4a3..c709e471 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -27,11 +27,11 @@ * List windows on given session. */ -enum cmd_retval cmd_list_windows_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_list_windows_exec(struct cmd *, struct cmd_q *); -void cmd_list_windows_server(struct cmd *, struct cmd_ctx *); +void cmd_list_windows_server(struct cmd *, struct cmd_q *); void cmd_list_windows_session( - struct cmd *, struct session *, struct cmd_ctx *, int); + struct cmd *, struct session *, struct cmd_q *, int); const struct cmd_entry cmd_list_windows_entry = { "list-windows", "lsw", @@ -44,35 +44,35 @@ const struct cmd_entry cmd_list_windows_entry = { }; enum cmd_retval -cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_list_windows_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s; if (args_has(args, 'a')) - cmd_list_windows_server(self, ctx); + cmd_list_windows_server(self, cmdq); else { - s = cmd_find_session(ctx, args_get(args, 't'), 0); + s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); - cmd_list_windows_session(self, s, ctx, 0); + cmd_list_windows_session(self, s, cmdq, 0); } return (CMD_RETURN_NORMAL); } void -cmd_list_windows_server(struct cmd *self, struct cmd_ctx *ctx) +cmd_list_windows_server(struct cmd *self, struct cmd_q *cmdq) { struct session *s; RB_FOREACH(s, sessions, &sessions) - cmd_list_windows_session(self, s, ctx, 1); + cmd_list_windows_session(self, s, cmdq, 1); } void cmd_list_windows_session( - struct cmd *self, struct session *s, struct cmd_ctx *ctx, int type) + struct cmd *self, struct session *s, struct cmd_q *cmdq, int type) { struct args *args = self->args; struct winlink *wl; @@ -102,7 +102,7 @@ cmd_list_windows_session( format_window_pane(ft, wl->window->active); line = format_expand(ft, template); - ctx->print(ctx, "%s", line); + cmdq_print(cmdq, "%s", line); free(line); format_free(ft); diff --git a/cmd-list.c b/cmd-list.c index d1e72e93..82ae7480 100644 --- a/cmd-list.c +++ b/cmd-list.c @@ -24,7 +24,8 @@ #include "tmux.h" struct cmd_list * -cmd_list_parse(int argc, char **argv, char **cause) +cmd_list_parse(int argc, char **argv, const char* file, u_int line, + char **cause) { struct cmd_list *cmdlist; struct cmd *cmd; @@ -34,7 +35,7 @@ cmd_list_parse(int argc, char **argv, char **cause) copy_argv = cmd_copy_argv(argc, argv); - cmdlist = xmalloc(sizeof *cmdlist); + cmdlist = xcalloc(1, sizeof *cmdlist); cmdlist->references = 1; TAILQ_INIT(&cmdlist->list); @@ -55,7 +56,7 @@ cmd_list_parse(int argc, char **argv, char **cause) if (arglen != 1) new_argc++; - cmd = cmd_parse(new_argc, new_argv, cause); + cmd = cmd_parse(new_argc, new_argv, file, line, cause); if (cmd == NULL) goto bad; TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry); @@ -64,7 +65,8 @@ cmd_list_parse(int argc, char **argv, ch