From 4a4daf13031673870341c68b990e20c314140118 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 13 Dec 2015 14:32:38 +0000 Subject: [PATCH] Instead of every command resolving the target (-t or -s) itself, prepare the state (client, session, winlink, pane) for it it before entering the command. Each command provides some flags that tell the prepare step what it is expecting. This is a requirement for having hooks on commands (for example, if you hook "select-window -t1:2", the hook command should to operate on window 1:2 not whatever it thinks is the current window), and should allow some other target improvements. The old cmd_find_* functions remain for the moment but that layer will be dropped later. Joint work with Thomas Adam. --- cmd-attach-session.c | 43 ++----- cmd-break-pane.c | 23 ++-- cmd-capture-pane.c | 7 +- cmd-choose-buffer.c | 11 +- cmd-choose-client.c | 11 +- cmd-choose-tree.c | 17 ++- cmd-clear-history.c | 11 +- cmd-command-prompt.c | 7 +- cmd-confirm-before.c | 7 +- cmd-copy-mode.c | 9 +- cmd-detach-client.c | 19 +--- cmd-display-message.c | 32 +----- cmd-display-panes.c | 12 +- cmd-find-window.c | 14 +-- cmd-if-shell.c | 33 ++---- cmd-join-pane.c | 15 ++- cmd-kill-pane.c | 9 +- cmd-kill-session.c | 5 +- cmd-kill-window.c | 16 +-- cmd-list-clients.c | 10 +- cmd-list-panes.c | 17 +-- cmd-list-windows.c | 11 +- cmd-load-buffer.c | 2 +- cmd-lock-server.c | 24 ++-- cmd-move-window.c | 30 ++--- cmd-new-session.c | 45 ++++---- cmd-new-window.c | 28 +++-- cmd-paste-buffer.c | 8 +- cmd-pipe-pane.c | 14 +-- cmd-queue.c | 25 ++-- cmd-refresh-client.c | 7 +- cmd-rename-session.c | 7 +- cmd-rename-window.c | 8 +- cmd-resize-pane.c | 16 +-- cmd-respawn-pane.c | 14 +-- cmd-respawn-window.c | 16 +-- cmd-rotate-window.c | 11 +- cmd-run-shell.c | 33 ++---- cmd-save-buffer.c | 2 +- cmd-select-layout.c | 11 +- cmd-select-pane.c | 24 ++-- cmd-select-window.c | 21 +--- cmd-send-keys.c | 13 +-- cmd-set-environment.c | 10 +- cmd-set-hook.c | 13 +-- cmd-set-option.c | 34 ++---- cmd-show-environment.c | 11 +- cmd-show-messages.c | 7 +- cmd-show-options.c | 28 ++--- cmd-source-file.c | 3 +- cmd-split-window.c | 19 ++-- cmd-swap-pane.c | 24 ++-- cmd-swap-window.c | 21 ++-- cmd-switch-client.c | 44 ++------ cmd.c | 251 +++++++++++++++++++++++++++++++++++++++++ tmux.h | 42 ++++++- 56 files changed, 606 insertions(+), 599 deletions(-) diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 00ced9df..c29e9d1a 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -36,48 +36,27 @@ const struct cmd_entry cmd_attach_session_entry = { "attach-session", "attach", "c:dErt:", 0, 0, "[-dEr] [-c working-directory] " CMD_TARGET_SESSION_USAGE, - CMD_STARTSERVER, + CMD_STARTSERVER|CMD_SESSION_T|CMD_PANE_T|CMD_PREFERUNATTACHED, cmd_attach_session_exec }; enum cmd_retval -cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag, - const char *cflag, int Eflag) +cmd_attach_session(struct cmd_q *cmdq, int dflag, int rflag, const char *cflag, + int Eflag) { - struct session *s; + struct session *s = cmdq->state.tflag.s; struct client *c = cmdq->client, *c_loop; - struct winlink *wl = NULL; - struct window *w = NULL; - struct window_pane *wp = NULL; + struct winlink *wl = cmdq->state.tflag.wl; + struct window_pane *wp = cmdq->state.tflag.wp; const char *update; - char *cause; + char *cause, *cwd; struct format_tree *ft; - char *cwd; if (RB_EMPTY(&sessions)) { cmdq_error(cmdq, "no sessions"); return (CMD_RETURN_ERROR); } - if (tflag == NULL) { - if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL) - return (CMD_RETURN_ERROR); - } else if (tflag[strcspn(tflag, ":.")] != '\0') { - if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL) - return (CMD_RETURN_ERROR); - } else { - if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL) - return (CMD_RETURN_ERROR); - w = window_find_by_id_str(tflag); - if (w == NULL) { - wp = window_pane_find_by_id_str(tflag); - if (wp != NULL) - w = wp->window; - } - if (w != NULL) - wl = winlink_find_by_window(&s->windows, w); - } - if (c == NULL) return (CMD_RETURN_NORMAL); if (server_client_check_nested(c)) { @@ -94,8 +73,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag, if (cflag != NULL) { ft = format_create(cmdq, 0); - format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, - NULL, NULL); + format_defaults(ft, c, s, wl, wp); cwd = format_expand(ft, cflag); format_free(ft); @@ -176,7 +154,6 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - return (cmd_attach_session(cmdq, args_get(args, 't'), - args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c'), - args_has(args, 'E'))); + return (cmd_attach_session(cmdq, args_has(args, 'd'), + args_has(args, 'r'), args_get(args, 'c'), args_has(args, 'E'))); } diff --git a/cmd-break-pane.c b/cmd-break-pane.c index 98d6ad3d..eb07fb87 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -34,7 +34,7 @@ const struct cmd_entry cmd_break_pane_entry = { "break-pane", "breakp", "dPF:s:t:", 0, 0, "[-dP] [-F format] " CMD_SRCDST_PANE_USAGE, - 0, + CMD_PANE_S|CMD_INDEX_T, cmd_break_pane_exec }; @@ -42,28 +42,22 @@ enum cmd_retval cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct winlink *wl; - struct session *src_s; - struct session *dst_s; - struct window_pane *wp; - struct window *w; + struct winlink *wl = cmdq->state.sflag.wl; + struct session *src_s = cmdq->state.sflag.s; + struct session *dst_s = cmdq->state.tflag.s; + struct window_pane *wp = cmdq->state.sflag.wp; + struct window *w = wl->window; char *name; char *cause; - int idx; + int idx = cmdq->state.tflag.idx; struct format_tree *ft; const char *template; char *cp; - wl = cmd_find_pane(cmdq, args_get(args, 's'), &src_s, &wp); - if (wl == NULL) - return (CMD_RETURN_ERROR); - if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst_s)) == -2) - return (CMD_RETURN_ERROR); if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) { cmdq_error(cmdq, "index %d already in use", idx); return (CMD_RETURN_ERROR); } - w = wl->window; if (window_count_panes(w) == 1) { cmdq_error(cmdq, "can't break with only one pane"); @@ -102,8 +96,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq) template = BREAK_PANE_TEMPLATE; ft = format_create(cmdq, 0); - format_defaults(ft, cmd_find_client(cmdq, NULL, 1), dst_s, wl, - wp); + format_defaults(ft, cmdq->state.c, dst_s, wl, wp); cp = format_expand(ft, template); cmdq_print(cmdq, "%s", cp); diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c index 6a7af47a..9d22a0f2 100644 --- a/cmd-capture-pane.c +++ b/cmd-capture-pane.c @@ -40,7 +40,7 @@ const struct cmd_entry cmd_capture_pane_entry = { "ab:CeE:JpPqS:t:", 0, 0, "[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] [-S start-line]" CMD_TARGET_PANE_USAGE, - 0, + CMD_PANE_T, cmd_capture_pane_exec }; @@ -175,14 +175,11 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; - struct window_pane *wp; + struct window_pane *wp = cmdq->state.tflag.wp; char *buf, *cause; const char *bufname; size_t len; - if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) - return (CMD_RETURN_ERROR); - len = 0; if (args_has(args, 'P')) buf = cmd_capture_pane_pending(args, wp, &len); diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c index dbb20fc4..4418d415 100644 --- a/cmd-choose-buffer.c +++ b/cmd-choose-buffer.c @@ -36,7 +36,7 @@ const struct cmd_entry cmd_choose_buffer_entry = { "choose-buffer", NULL, "F:t:", 0, 1, CMD_TARGET_WINDOW_USAGE " [-F format] [template]", - 0, + CMD_WINDOW_T, cmd_choose_buffer_exec }; @@ -44,15 +44,15 @@ enum cmd_retval cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c; + struct client *c = cmdq->state.c; + struct winlink *wl = cmdq->state.tflag.wl; struct window_choose_data *cdata; - struct winlink *wl; struct paste_buffer *pb; char *action, *action_data; const char *template; u_int idx; - if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) { + if (c == NULL) { cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } @@ -60,9 +60,6 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq) if ((template = args_get(args, 'F')) == NULL) template = CHOOSE_BUFFER_TEMPLATE; - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) - return (CMD_RETURN_ERROR); - if (paste_get_top(NULL) == NULL) return (CMD_RETURN_NORMAL); diff --git a/cmd-choose-client.c b/cmd-choose-client.c index 93a141ee..c58bc826 100644 --- a/cmd-choose-client.c +++ b/cmd-choose-client.c @@ -41,7 +41,7 @@ const struct cmd_entry cmd_choose_client_entry = { "choose-client", NULL, "F:t:", 0, 1, CMD_TARGET_WINDOW_USAGE " [-F format] [template]", - 0, + CMD_WINDOW_T, cmd_choose_client_exec }; @@ -53,22 +53,19 @@ enum cmd_retval cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c; + struct client *c = cmdq->state.c; struct client *c1; struct window_choose_data *cdata; - struct winlink *wl; + struct winlink *wl = cmdq->state.tflag.wl; const char *template; char *action; u_int idx, cur; - if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) { + if (c == NULL) { cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } - 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) return (CMD_RETURN_NORMAL); diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index 0b0fea6a..766978fe 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -48,7 +48,7 @@ const struct cmd_entry cmd_choose_tree_entry = { "S:W:swub:c:t:", 0, 1, "[-suw] [-b session-template] [-c window template] [-S format] " \ "[-W format] " CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_choose_tree_exec }; @@ -56,7 +56,7 @@ const struct cmd_entry cmd_choose_session_entry = { "choose-session", NULL, "F:t:", 0, 1, CMD_TARGET_WINDOW_USAGE " [-F format] [template]", - 0, + CMD_WINDOW_T, cmd_choose_tree_exec }; @@ -64,7 +64,7 @@ const struct cmd_entry cmd_choose_window_entry = { "choose-window", NULL, "F:t:", 0, 1, CMD_TARGET_WINDOW_USAGE "[-F format] [template]", - 0, + CMD_WINDOW_T, cmd_choose_tree_exec }; @@ -72,9 +72,9 @@ enum cmd_retval cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct winlink *wl, *wm; - struct session *s, *s2; - struct client *c; + struct client *c = cmdq->state.c; + struct winlink *wl = cmdq->state.tflag.wl, *wm; + struct session *s = cmdq->state.tflag.s, *s2; struct window_choose_data *wcd = NULL; const char *ses_template, *win_template; char *final_win_action, *cur_win_template; @@ -87,14 +87,11 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq) ses_template = win_template = NULL; ses_action = win_action = NULL; - if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) { + if (c == NULL) { cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) - return (CMD_RETURN_ERROR); - if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) return (CMD_RETURN_NORMAL); diff --git a/cmd-clear-history.c b/cmd-clear-history.c index 63e9d548..a76cab80 100644 --- a/cmd-clear-history.c +++ b/cmd-clear-history.c @@ -30,20 +30,17 @@ const struct cmd_entry cmd_clear_history_entry = { "clear-history", "clearhist", "t:", 0, 0, CMD_TARGET_PANE_USAGE, - 0, + CMD_PANE_T, cmd_clear_history_exec }; enum cmd_retval -cmd_clear_history_exec(struct cmd *self, struct cmd_q *cmdq) +cmd_clear_history_exec(__unused struct cmd *self, struct cmd_q *cmdq) { - struct args *args = self->args; - struct window_pane *wp; + struct window_pane *wp = cmdq->state.tflag.wp; struct grid *gd; - if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) - return (CMD_RETURN_ERROR); - gd = wp->base.grid; + gd = cmdq->state.tflag.wp->base.grid; if (wp->mode == &window_copy_mode) window_pane_reset_mode(wp); diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index 1622e0b7..900fceb9 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -38,7 +38,7 @@ const struct cmd_entry cmd_command_prompt_entry = { "command-prompt", NULL, "I:p:t:", 0, 1, "[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]", - 0, + CMD_CLIENT_T, cmd_command_prompt_exec }; @@ -58,13 +58,10 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq) struct args *args = self->args; const char *inputs, *prompts; struct cmd_command_prompt_cdata *cdata; - struct client *c; + struct client *c = cmdq->state.c; char *prompt, *ptr, *input = NULL; size_t n; - if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); - if (c->prompt_string != NULL) return (CMD_RETURN_NORMAL); diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c index 248515cd..17a575a2 100644 --- a/cmd-confirm-before.c +++ b/cmd-confirm-before.c @@ -37,7 +37,7 @@ const struct cmd_entry cmd_confirm_before_entry = { "confirm-before", "confirm", "p:t:", 1, 1, "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command", - 0, + CMD_CLIENT_T, cmd_confirm_before_exec }; @@ -51,13 +51,10 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct cmd_confirm_before_data *cdata; - struct client *c; + struct client *c = cmdq->state.c; char *cmd, *copy, *new_prompt, *ptr; const char *prompt; - if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); - if ((prompt = args_get(args, 'p')) != NULL) xasprintf(&new_prompt, "%s ", prompt); else { diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index e04b561b..79d06cee 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -29,8 +29,8 @@ enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_copy_mode_entry = { "copy-mode", NULL, "Met:u", 0, 0, - "[-Meu] " CMD_TARGET_PANE_USAGE, - 0, + "[-Mu] " CMD_TARGET_PANE_USAGE, + CMD_PANE_T, cmd_copy_mode_exec }; @@ -48,15 +48,14 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq) struct args *args = self->args; struct client *c = cmdq->client; struct session *s; - struct window_pane *wp; + struct window_pane *wp = cmdq->state.tflag.wp; if (args_has(args, 'M')) { if ((wp = cmd_mouse_pane(&cmdq->item->mouse, &s, NULL)) == NULL) return (CMD_RETURN_NORMAL); if (c == NULL || c->session != s) return (CMD_RETURN_NORMAL); - } else if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) - return (CMD_RETURN_ERROR); + } if (self->entry == &cmd_clock_mode_entry) { window_pane_set_mode(wp, &window_clock_mode); diff --git a/cmd-detach-client.c b/cmd-detach-client.c index d8128eae..86f8063c 100644 --- a/cmd-detach-client.c +++ b/cmd-detach-client.c @@ -31,8 +31,8 @@ enum cmd_retval cmd_detach_client_exec(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_detach_client_entry = { "detach-client", "detach", "as:t:P", 0, 0, - "[-aP] [-s target-session] " CMD_TARGET_CLIENT_USAGE, - CMD_READONLY, + "[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE, + CMD_READONLY|CMD_CLIENT_T|CMD_SESSION_S, cmd_detach_client_exec }; @@ -40,7 +40,7 @@ const struct cmd_entry cmd_suspend_client_entry = { "suspend-client", "suspendc", "t:", 0, 0, CMD_TARGET_CLIENT_USAGE, - 0, + CMD_CLIENT_T, cmd_detach_client_exec }; @@ -48,13 +48,11 @@ enum cmd_retval cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c, *cloop; + struct client *c = cmdq->state.c, *cloop; struct session *s; enum msgtype msgtype; if (self->entry == &cmd_suspend_client_entry) { - if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); tty_stop_tty(&c->tty); c->flags |= CLIENT_SUSPENDED; proc_send(c->peer, MSG_SUSPEND, -1, NULL, 0); @@ -67,10 +65,7 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq) msgtype = MSG_DETACH; if (args_has(args, 's')) { - s = cmd_find_session(cmdq, args_get(args, 's'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - + s = cmdq->state.sflag.s; TAILQ_FOREACH(cloop, &clients, entry) { if (cloop->session == s) server_client_detach(cloop, msgtype); @@ -78,10 +73,6 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_STOP); } - c = cmd_find_client(cmdq, args_get(args, 't'), 0); - if (c == NULL) - return (CMD_RETURN_ERROR); - if (args_has(args, 'a')) { TAILQ_FOREACH(cloop, &clients, entry) { if (cloop->session != NULL && cloop != c) diff --git a/cmd-display-message.c b/cmd-display-message.c index 7ca8e9c4..201f8b75 100644 --- a/cmd-display-message.c +++ b/cmd-display-message.c @@ -39,7 +39,7 @@ const struct cmd_entry cmd_display_message_entry = { "c:pt:F:", 0, 1, "[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE " [message]", - 0, + CMD_CLIENT_C|CMD_PANE_T, cmd_display_message_exec }; @@ -47,41 +47,19 @@ enum cmd_retval cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c; - struct session *s; - struct winlink *wl; - struct window_pane *wp; + struct client *c = cmdq->state.c; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; + struct window_pane *wp = cmdq->state.tflag.wp; const char *template; char *msg; struct format_tree *ft; - if (args_has(args, 't')) { - wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); - if (wl == NULL) - return (CMD_RETURN_ERROR); - } else { - wl = cmd_find_pane(cmdq, NULL, &s, &wp); - if (wl == NULL) - return (CMD_RETURN_ERROR); - } - if (args_has(args, 'F') && args->argc != 0) { cmdq_error(cmdq, "only one of -F or argument must be given"); return (CMD_RETURN_ERROR); } - if (args_has(args, 'c')) { - c = cmd_find_client(cmdq, args_get(args, 'c'), 0); - if (c == NULL) - return (CMD_RETURN_ERROR); - } else { - c = cmd_find_client(cmdq, NULL, 1); - if (c == NULL && !args_has(self->args, 'p')) { - cmdq_error(cmdq, "no client available"); - return (CMD_RETURN_ERROR); - } - } - template = args_get(args, 'F'); if (args->argc != 0) template = args->argv[0]; diff --git a/cmd-display-panes.c b/cmd-display-panes.c index 9ce89712..714ee19e 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -30,20 +30,14 @@ const struct cmd_entry cmd_display_panes_entry = { "display-panes", "displayp", "t:", 0, 0, CMD_TARGET_CLIENT_USAGE, - 0, + CMD_CLIENT_T, cmd_display_panes_exec }; enum cmd_retval -cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq) +cmd_display_panes_exec(__unused struct cmd *self, struct cmd_q *cmdq) { - struct args *args = self->args; - struct client *c; - - if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); - - server_set_identify(c); + server_set_identify(cmdq->state.c); return (CMD_RETURN_NORMAL); } diff --git a/cmd-find-window.c b/cmd-find-window.c index e92ae60f..1733b717 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -51,7 +51,7 @@ const struct cmd_entry cmd_find_window_entry = { "find-window", "findw", "F:CNt:T", 1, 4, "[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string", - 0, + CMD_WINDOW_T, cmd_find_window_exec }; @@ -137,10 +137,10 @@ enum cmd_retval cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c; + struct client *c = cmdq->state.c; struct window_choose_data *cdata; - struct session *s; - struct winlink *wl, *wm; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl, *wm; struct cmd_find_window_list find_list; struct cmd_find_window_data *find_data; struct cmd_find_window_data *find_data1; @@ -148,14 +148,10 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq) const char *template; u_int i, match_flags; - if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) { + if (c == NULL) { cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } - s = c->session; - - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) - return (CMD_RETURN_ERROR); if ((template = args_get(args, 'F')) == NULL) template = FIND_WINDOW_TEMPLATE; diff --git a/cmd-if-shell.c b/cmd-if-shell.c index 3345e8ce..404f4671 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -39,7 +39,7 @@ const struct cmd_entry cmd_if_shell_entry = { "if-shell", "if", "bFt:", 2, 3, "[-bF] " CMD_TARGET_PANE_USAGE " shell-command command [command]", - 0, + CMD_PANE_T|CMD_CANFAIL, cmd_if_shell_exec }; @@ -61,31 +61,20 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq) struct cmd_if_shell_data *cdata; char *shellcmd, *cmd, *cause; struct cmd_list *cmdlist; - struct client *c; - struct session *s = NULL; - struct winlink *wl = NULL; - struct window_pane *wp = NULL; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; + struct window_pane *wp = cmdq->state.tflag.wp; struct format_tree *ft; const char *cwd; - if (args_has(args, 't')) { - wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); - cwd = wp->cwd; - } else { - c = cmd_find_client(cmdq, NULL, 1); - if (c != NULL && c->session != NULL) { - s = c->session; - wl = s->curw; - wp = wl->window->active; - } - if (cmdq->client != NULL && cmdq->client->session == NULL) - cwd = cmdq->client->cwd; - else if (s != NULL) - cwd = s->cwd; - else - cwd = NULL; - } + cwd = wp->cwd; + if (cmdq->client != NULL && cmdq->client->session == NULL) + cwd = cmdq->client->cwd; + else if (s != NULL) + cwd = s->cwd; + else + cwd = NULL; ft = format_create(cmdq, 0); format_defaults(ft, NULL, s, wl, wp); shellcmd = format_expand(ft, args->argv[0]); diff --git a/cmd-join-pane.c b/cmd-join-pane.c index cc6432a4..6fc5b977 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -37,7 +37,7 @@ const struct cmd_entry cmd_join_pane_entry = { "join-pane", "joinp", "bdhvp:l:s:t:", 0, 0, "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE, - 0, + CMD_PANE_MARKED_S|CMD_PANE_T, cmd_join_pane_exec }; @@ -45,7 +45,7 @@ const struct cmd_entry cmd_move_pane_entry = { "move-pane", "movep", "bdhvp:l:s:t:", 0, 0, "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE, - 0, + CMD_PANE_S|CMD_PANE_T, cmd_join_pane_exec }; @@ -68,16 +68,15 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window) enum layout_type type; struct layout_cell *lc; - dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), &dst_s, &dst_wp); - if (dst_wl == NULL) - return (CMD_RETURN_ERROR); + dst_s = cmdq->state.tflag.s; + dst_wl = cmdq->state.tflag.wl; + dst_wp = cmdq->state.tflag.wp; dst_w = dst_wl->window; dst_idx = dst_wl->idx; server_unzoom_window(dst_w); - src_wl = cmd_find_pane_marked(cmdq, args_get(args, 's'), NULL, &src_wp); - if (src_wl == NULL) - return (CMD_RETURN_ERROR); + src_wl = cmdq->state.sflag.wl; + src_wp = cmdq->state.sflag.wp; src_w = src_wl->window; server_unzoom_window(src_w); diff --git a/cmd-kill-pane.c b/cmd-kill-pane.c index f4735fd2..d5f69ea9 100644 --- a/cmd-kill-pane.c +++ b/cmd-kill-pane.c @@ -32,19 +32,16 @@ const struct cmd_entry cmd_kill_pane_entry = { "kill-pane", "killp", "at:", 0, 0, "[-a] " CMD_TARGET_PANE_USAGE, - 0, + CMD_PANE_T, cmd_kill_pane_exec }; enum cmd_retval 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; + struct winlink *wl = cmdq->state.tflag.wl; + struct window_pane *loopwp, *tmpwp, *wp = cmdq->state.tflag.wp; - if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL) - return (CMD_RETURN_ERROR); server_unzoom_window(wl->window); if (window_count_panes(wl->window) == 1) { diff --git a/cmd-kill-session.c b/cmd-kill-session.c index 3f39c241..a4b0d5d2 100644 --- a/cmd-kill-session.c +++ b/cmd-kill-session.c @@ -33,7 +33,7 @@ const struct cmd_entry cmd_kill_session_entry = { "kill-session", NULL, "aCt:", 0, 0, "[-aC] " CMD_TARGET_SESSION_USAGE, - 0, + CMD_SESSION_T, cmd_kill_session_exec }; @@ -44,8 +44,7 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_q *cmdq) struct session *s, *sloop, *stmp; struct winlink *wl; - if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); + s = cmdq->state.tflag.s; if (args_has(args, 'C')) { RB_FOREACH(wl, winlinks, &s->windows) { diff --git a/cmd-kill-window.c b/cmd-kill-window.c index 4d346a71..4ab17472 100644 --- a/cmd-kill-window.c +++ b/cmd-kill-window.c @@ -30,7 +30,7 @@ const struct cmd_entry cmd_kill_window_entry = { "kill-window", "killw", "at:", 0, 0, "[-a] " CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_kill_window_exec }; @@ -38,21 +38,17 @@ const struct cmd_entry cmd_unlink_window_entry = { "unlink-window", "unlinkw", "kt:", 0, 0, "[-k] " CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_kill_window_exec }; enum cmd_retval cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq) { - struct args *args = self->args; - struct winlink *wl, *wl2, *wl3; - struct window *w; - struct session *s; - - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) - return (CMD_RETURN_ERROR); - w = wl->window; + struct args *args = self->args; + struct winlink *wl = cmdq->state.tflag.wl, *wl2, *wl3; + struct window *w = wl->window; + struct session *s = cmdq->state.tflag.s; if (self->entry == &cmd_unlink_window_entry) { if (!args_has(self->args, 'k') && !session_is_linked(s, w)) { diff --git a/cmd-list-clients.c b/cmd-list-clients.c index 2c13d398..effd8275 100644 --- a/cmd-list-clients.c +++ b/cmd-list-clients.c @@ -39,7 +39,7 @@ const struct cmd_entry cmd_list_clients_entry = { "list-clients", "lsc", "F:t:", 0, 0, "[-F format] " CMD_TARGET_SESSION_USAGE, - CMD_READONLY, + CMD_READONLY|CMD_SESSION_T, cmd_list_clients_exec }; @@ -54,11 +54,9 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq) u_int idx; char *line; - if (args_has(args, 't')) { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - } else + if (args_has(args, 't')) + s = cmdq->state.tflag.s; + else s = NULL; if ((template = args_get(args, 'F')) == NULL) diff --git a/cmd-list-panes.c b/cmd-list-panes.c index 23e530e2..2c9fa623 100644 --- a/cmd-list-panes.c +++ b/cmd-list-panes.c @@ -38,7 +38,7 @@ const struct cmd_entry cmd_list_panes_entry = { "list-panes", "lsp", "asF:t:", 0, 0, "[-as] [-F format] " CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_list_panes_exec }; @@ -46,22 +46,15 @@ enum cmd_retval cmd_list_panes_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *s; - struct winlink *wl; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; if (args_has(args, 'a')) cmd_list_panes_server(self, cmdq); - else if (args_has(args, 's')) { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); + else if (args_has(args, 's')) cmd_list_panes_session(self, s, cmdq, 1); - } else { - wl = cmd_find_window(cmdq, args_get(args, 't'), &s); - if (wl == NULL) - return (CMD_RETURN_ERROR); + else cmd_list_panes_window(self, s, wl, cmdq, 0); - } return (CMD_RETURN_NORMAL); } diff --git a/cmd-list-windows.c b/cmd-list-windows.c index 1eaee2d7..992ba0de 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -49,7 +49,7 @@ const struct cmd_entry cmd_list_windows_entry = { "list-windows", "lsw", "F:at:", 0, 0, "[-a] [-F format] " CMD_TARGET_SESSION_USAGE, - 0, + CMD_SESSION_T, cmd_list_windows_exec }; @@ -57,16 +57,11 @@ enum cmd_retval 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, cmdq); - else { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - cmd_list_windows_session(self, s, cmdq, 0); - } + else + cmd_list_windows_session(self, cmdq->state.tflag.s, cmdq, 0); return (CMD_RETURN_NORMAL); } diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c index 5ac2edc3..929e3bf2 100644 --- a/cmd-load-buffer.c +++ b/cmd-load-buffer.c @@ -72,7 +72,7 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq) if (c != NULL && c->session == NULL) cwd = c->cwd; - else if ((s = cmd_find_current(cmdq)) != NULL) + else if ((s = c->session) != NULL) cwd = s->cwd; else cwd = "."; diff --git a/cmd-lock-server.c b/cmd-lock-server.c index a0204129..5d20ebd4 100644 --- a/cmd-lock-server.c +++ b/cmd-lock-server.c @@ -38,7 +38,7 @@ const struct cmd_entry cmd_lock_session_entry = { "lock-session", "locks", "t:", 0, 0, CMD_TARGET_SESSION_USAGE, - 0, + CMD_SESSION_T, cmd_lock_server_exec }; @@ -46,30 +46,20 @@ const struct cmd_entry cmd_lock_client_entry = { "lock-client", "lockc", "t:", 0, 0, CMD_TARGET_CLIENT_USAGE, - 0, + CMD_CLIENT_T, cmd_lock_server_exec }; enum cmd_retval cmd_lock_server_exec(struct cmd *self, __unused struct cmd_q *cmdq) { - struct args *args = self->args; - struct client *c; - struct session *s; - if (self->entry == &cmd_lock_server_entry) server_lock(); - else if (self->entry == &cmd_lock_session_entry) { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - server_lock_session(s); - } else { - c = cmd_find_client(cmdq, args_get(args, 't'), 0); - if (c == NULL) - return (CMD_RETURN_ERROR); - server_lock_client(c); - } + else if (self->entry == &cmd_lock_session_entry) + server_lock_session(cmdq->state.tflag.s); + else + server_lock_client(cmdq->state.c); + recalculate_sizes(); return (CMD_RETURN_NORMAL); diff --git a/cmd-move-window.c b/cmd-move-window.c index 1bd46ab2..9e3a1c09 100644 --- a/cmd-move-window.c +++ b/cmd-move-window.c @@ -32,7 +32,7 @@ const struct cmd_entry cmd_move_window_entry = { "move-window", "movew", "adkrs:t:", 0, 0, "[-dkr] " CMD_SRCDST_WINDOW_USAGE, - 0, + CMD_WINDOW_S|CMD_MOVEW_R|CMD_INDEX_T, cmd_move_window_exec }; @@ -40,7 +40,7 @@ const struct cmd_entry cmd_link_window_entry = { "link-window", "linkw", "adks:t:", 0, 0, "[-dk] " CMD_SRCDST_WINDOW_USAGE, - 0, + CMD_WINDOW_S|CMD_INDEX_T, cmd_move_window_exec }; @@ -48,36 +48,28 @@ enum cmd_retval cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *src, *dst, *s; - struct winlink *wl; + struct session *src = cmdq->state.sflag.s; + struct session *dst = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.sflag.wl; char *cause; - int idx, kflag, dflag, sflag; + int idx = cmdq->state.tflag.idx, kflag, dflag, sflag; + + kflag = args_has(self->args, 'k'); + dflag = args_has(self->args, 'd'); if (args_has(args, 'r')) { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - - session_renumber_windows(s); + session_renumber_windows(dst); recalculate_sizes(); return (CMD_RETURN_NORMAL); } - if ((wl = cmd_find_window(cmdq, args_get(args, 's'), &src)) == NULL) - return (CMD_RETURN_ERROR); - 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'); sflag = args_has(self->args, 's'); if (args_has(self->args, 'a')) { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - if ((idx = winlink_shuffle_up(s, s->curw)) == -1) + if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1) return (CMD_RETURN_ERROR); } diff --git a/cmd-new-session.c b/cmd-new-session.c index 341399be..e589a361 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -41,7 +41,7 @@ const struct cmd_entry cmd_new_session_entry = { "[-AdDEP] [-c start-directory] [-F format] [-n window-name] " "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] " "[-y height] [command]", - CMD_STARTSERVER, + CMD_STARTSERVER|CMD_CANFAIL|CMD_SESSION_T, cmd_new_session_exec }; @@ -49,7 +49,7 @@ const struct cmd_entry cmd_has_session_entry = { "has-session", "has", "t:", 0, 0, CMD_TARGET_SESSION_USAGE, - 0, + CMD_SESSION_T, cmd_new_session_exec }; @@ -57,8 +57,9 @@ enum cmd_retval cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c = cmdq->client, *c0; - struct session *s, *groupwith; + struct client *c = cmdq->client; + struct session *s, *attach_sess; + struct session *groupwith = cmdq->state.tflag.s; struct window *w; struct environ *env; struct termios tio, *tiop; @@ -71,8 +72,10 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) struct environ_entry *envent; if (self->entry == &cmd_has_session_entry) { - if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL) - return (CMD_RETURN_ERROR); + /* + * cmd_prepare() will fail if the session cannot be found, + * hence always return success here. + */ return (CMD_RETURN_NORMAL); } @@ -87,9 +90,16 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) cmdq_error(cmdq, "bad session name: %s", newname); return (CMD_RETURN_ERROR); } - if (session_find(newname) != NULL) { + if ((attach_sess = session_find(newname)) != NULL) { if (args_has(args, 'A')) { - return (cmd_attach_session(cmdq, newname, + /* + * This cmdq is now destined for + * attach-session. Because attach-session + * will have already been prepared, copy this + * session into its tflag so it can be used. + */ + cmdq->state.tflag.s = attach_sess; + return (cmd_attach_session(cmdq, args_has(args, 'D'), 0, NULL, args_has(args, 'E'))); } @@ -98,12 +108,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) } } - target = args_get(args, 't'); - if (target != NULL) { - groupwith = cmd_find_session(cmdq, target, 0); - if (groupwith == NULL) - return (CMD_RETURN_ERROR); - } else + if ((target = args_get(args, 't')) == NULL) groupwith = NULL; /* Set -d if no client. */ @@ -120,14 +125,11 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) to_free = NULL; if (args_has(args, 'c')) { ft = format_create(cmdq, 0); - format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL, - NULL); + format_defaults(ft, c, NULL, NULL, NULL); to_free = cwd = format_expand(ft, args_get(args, 'c')); format_free(ft); } else if (c != NULL && c->session == NULL) cwd = c->cwd; - else if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL) - cwd = c0->session->cwd; else cwd = "."; @@ -193,7 +195,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) /* Figure out the command for the new window. */ argc = -1; argv = NULL; - if (target == NULL && args->argc != 0) { + if (!args_has(args, 't') && args->argc != 0) { argc = args->argc; argv = args->argv; } else if (target == NULL) { @@ -245,7 +247,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) * If a target session is given, this is to be part of a session group, * so add it to the group and synchronize. */ - if (groupwith != NULL) { + if (args_has(args, 't')) { session_group_add(groupwith, s); session_group_synchronize_to(s); session_select(s, RB_MIN(winlinks, &s->windows)->idx); @@ -285,8 +287,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) template = NEW_SESSION_TEMPLATE; ft = format_create(cmdq, 0); - format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL, - NULL); + format_defaults(ft, c, s, NULL, NULL); cp = format_expand(ft, template); cmdq_print(cmdq, "%s", cp); diff --git a/cmd-new-window.c b/cmd-new-window.c index ddfd6a20..8154bdfb 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -39,7 +39,12 @@ const struct cmd_entry cmd_new_window_entry = { "ac:dF:kn:Pt:", 0, -1, "[-adkP] [-c start-directory] [-F format] [-n window-name] " CMD_TARGET_WINDOW_USAGE " [command]", - 0, + /* + * Using PREP_CANFAIL here ensures that the wl is filled in + * regardless; making PREP_INDEX the thing we want -t to be used for + * in the specific case. + */ + CMD_INDEX_T|CMD_CANFAIL, cmd_new_window_exec }; @@ -47,26 +52,21 @@ enum cmd_retval cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *s; - struct winlink *wl; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; + struct client *c = cmdq->state.c; + int idx = cmdq->state.tflag.idx; const char *cmd, *path, *template, *cwd, *to_free; char **argv, *cause, *cp; - int argc, idx, detached; + int argc, detached; struct format_tree *ft; struct environ_entry *envent; if (args_has(args, 'a')) { - wl = cmd_find_window(cmdq, args_get(args, 't'), &s); - if (wl == NULL) - return (CMD_RETURN_ERROR); if ((idx = winlink_shuffle_up(s, wl)) == -1) { cmdq_error(cmdq, "no free window indexes"); return (CMD_RETURN_ERROR); } - } else { - idx = cmd_find_index(cmdq, args_get(args, 't'), &s); - if (idx == -2) - return (CMD_RETURN_ERROR); } detached = args_has(args, 'd'); @@ -95,8 +95,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) to_free = NULL; if (args_has(args, 'c')) { ft = format_create(cmdq, 0); - format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL, - NULL); + format_defaults(ft, c, s, NULL, NULL); cwd = to_free = format_expand(ft, args_get(args, 'c')); format_free(ft); } else if (cmdq->client != NULL && cmdq->client->session == NULL) @@ -144,8 +143,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) template = NEW_WINDOW_TEMPLATE; ft = format_create(cmdq, 0); - format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl, - NULL); + format_defaults(ft, c, s, wl, NULL); cp = format_expand(ft, template); cmdq_print(cmdq, "%s", cp); diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c index 87f09ee6..92a31c53 100644 --- a/cmd-paste-buffer.c +++ b/cmd-paste-buffer.c @@ -37,7 +37,7 @@ const struct cmd_entry cmd_paste_buffer_entry = { "paste-buffer", "pasteb", "db:prs:t:", 0, 0, "[-dpr] [-s separator] " CMD_BUFFER_USAGE " " CMD_TARGET_PANE_USAGE, - 0, + CMD_PANE_T, cmd_paste_buffer_exec }; @@ -45,16 +45,12 @@ enum cmd_retval cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct window_pane *wp; - struct session *s; + struct window_pane *wp = cmdq->state.tflag.wp; struct paste_buffer *pb; const char *sepstr, *bufname, *bufdata, *bufend, *line; size_t seplen, bufsize; int bracket = args_has(args, 'p'); - if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) - return (CMD_RETURN_ERROR); - bufname = NULL; if (args_has(args, 'b')) bufname = args_get(args, 'b'); diff --git a/cmd-pipe-pane.c b/cmd-pipe-pane.c index 79ef7818..ad4b02e0 100644 --- a/cmd-pipe-pane.c +++ b/cmd-pipe-pane.c @@ -41,7 +41,7 @@ const struct cmd_entry cmd_pipe_pane_entry = { "pipe-pane", "pipep", "ot:", 0, 1, "[-o] " CMD_TARGET_PANE_USAGE " [command]", - 0, + CMD_PANE_T, cmd_pipe_pane_exec }; @@ -49,18 +49,14 @@ enum cmd_retval cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c; - struct session *s; - struct winlink *wl; - struct window_pane *wp; + struct client *c = cmdq->state.c; + struct window_pane *wp = cmdq->state.tflag.wp; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; char *cmd; int old_fd, pipe_fd[2], null_fd; struct format_tree *ft; - if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) - return (CMD_RETURN_ERROR); - c = cmd_find_client(cmdq, NULL, 1); - /* Destroy the old pipe. */ old_fd = wp->pipe_fd; if (wp->pipe_fd != -1) { diff --git a/cmd-queue.c b/cmd-queue.c index c85fb048..7b2675fa 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -25,7 +25,7 @@ #include "tmux.h" -enum cmd_retval cmdq_continue_one(struct cmd_q *); +static enum cmd_retval cmdq_continue_one(struct cmd_q *); /* Create new command queue. */ struct cmd_q * @@ -179,37 +179,40 @@ cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m) } /* Process one command. */ -enum cmd_retval +static enum cmd_retval cmdq_continue_one(struct cmd_q *cmdq) { struct cmd *cmd = cmdq->cmd; enum cmd_retval retval; - char *s; + char *tmp; int flags = !!(cmd->flags & CMD_CONTROL); - s = cmd_print(cmd); - log_debug("cmdq %p: %s", cmdq, s); - free(s); + tmp = cmd_print(cmd); + log_debug("cmdq %p: %s", cmdq, tmp); + free(tmp); cmdq->time = time(NULL); cmdq->number++; cmdq_guard(cmdq, "begin", flags); + if (cmd_prepare_state(cmd, cmdq) != 0) + goto error; retval = cmd->entry->exec(cmd, cmdq); - if (retval == CMD_RETURN_ERROR) - cmdq_guard(cmdq, "error", flags); - else - cmdq_guard(cmdq, "end", flags); + cmdq_guard(cmdq, "end", flags); return (retval); + +error: + cmdq_guard(cmdq, "error", flags); + return (CMD_RETURN_ERROR); } /* Continue processing command queue. Returns 1 if finishes empty. */ int cmdq_continue(struct cmd_q *cmdq) { - struct client *c = cmdq->client; + struct client *c = cmdq->client; struct cmd_q_item *next; enum cmd_retval retval; int empty; diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c index 5a45ec25..9d1d0fce 100644 --- a/cmd-refresh-client.c +++ b/cmd-refresh-client.c @@ -30,7 +30,7 @@ const struct cmd_entry cmd_refresh_client_entry = { "refresh-client", "refresh", "C:St:", 0, 0, "[-S] [-C size] " CMD_TARGET_CLIENT_USAGE, - 0, + CMD_CLIENT_T, cmd_refresh_client_exec }; @@ -38,13 +38,10 @@ enum cmd_retval cmd_refresh_client_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c; + struct client *c = cmdq->state.c; const char *size; u_int w, h; - if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); - if (args_has(args, 'C')) { if ((size = args_get(args, 'C')) == NULL) { cmdq_error(cmdq, "missing size"); diff --git a/cmd-rename-session.c b/cmd-rename-session.c index 481154ce..0c1a7e8c 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -32,7 +32,7 @@ const struct cmd_entry cmd_rename_session_entry = { "rename-session", "rename", "t:", 1, 1, CMD_TARGET_SESSION_USAGE " new-name", - 0, + CMD_SESSION_T, cmd_rename_session_exec }; @@ -40,7 +40,7 @@ enum cmd_retval cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *s; + struct session *s = cmdq->state.tflag.s; const char *newname; newname = args->argv[0]; @@ -53,9 +53,6 @@ cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } - if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); - RB_REMOVE(sessions, &sessions, s); free(s->name); s->name = xstrdup(newname); diff --git a/cmd-rename-window.c b/cmd-rename-window.c index bc85d96b..6609ebab 100644 --- a/cmd-rename-window.c +++ b/cmd-rename-window.c @@ -32,7 +32,7 @@ const struct cmd_entry cmd_rename_window_entry = { "rename-window", "renamew", "t:", 1, 1, CMD_TARGET_WINDOW_USAGE " new-name", - 0, + CMD_WINDOW_T, cmd_rename_window_exec }; @@ -40,11 +40,7 @@ enum cmd_retval cmd_rename_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *s; - struct winlink *wl; - - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) - return (CMD_RETURN_ERROR); + struct winlink *wl = cmdq->state.tflag.wl; window_set_name(wl->window, args->argv[0]); options_set_number(wl->window->options, "automatic-rename", 0); diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index b342307d..a4de32df 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -33,9 +33,8 @@ void cmd_resize_pane_mouse_update(struct client *, struct mouse_event *); const struct cmd_entry cmd_resize_pane_entry = { "resize-pane", "resizep", "DLMRt:Ux:y:Z", 0, 1, - "[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE - " [adjustment]", - 0, + "[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " [adjustment]", + CMD_PANE_T, cmd_resize_pane_exec }; @@ -43,13 +42,13 @@ enum cmd_retval cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; + struct window_pane *wp = cmdq->state.tflag.wp; + struct winlink *wl = cmdq->state.tflag.wl; + struct window *w = wl->window; struct client *c = cmdq->client; - struct session *s; - struct winlink *wl; - struct window *w; + struct session *s = cmdq->state.tflag.s; const char *errstr; char *cause; - struct window_pane *wp; u_int adjust; int x, y; @@ -63,10 +62,7 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); } - if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL) - return (CMD_RETURN_ERROR); w = wl->window; - if (args_has(args, 'Z')) { if (w->flags & WINDOW_ZOOMED) window_unzoom(w); diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c index a50b9d06..45098d80 100644 --- a/cmd-respawn-pane.c +++ b/cmd-respawn-pane.c @@ -34,7 +34,7 @@ const struct cmd_entry cmd_respawn_pane_entry = { "respawn-pane", "respawnp", "kt:", 0, -1, "[-k] " CMD_TARGET_PANE_USAGE " [command]", - 0, + CMD_PANE_T, cmd_respawn_pane_exec }; @@ -42,20 +42,16 @@ enum cmd_retval cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct winlink *wl; - struct window *w; - struct window_pane *wp; - struct session *s; + struct winlink *wl = cmdq->state.tflag.wl; + struct window *w = wl->window; + struct window_pane *wp = cmdq->state.tflag.wp; + struct session *s = cmdq->state.tflag.s; struct environ *env; const char *path; char *cause; u_int idx; struct environ_entry *envent; - if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) - return (CMD_RETURN_ERROR); - w = wl->window; - if (!args_has(self->args, 'k') && wp->fd != -1) { if (window_pane_index(wp, &idx) != 0) fatalx("index not found"); diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c index 93af1b68..f6550dee 100644 --- a/cmd-respawn-window.c +++ b/cmd-respawn-window.c @@ -33,7 +33,7 @@ const struct cmd_entry cmd_respawn_window_entry = { "respawn-window", "respawnw", "kt:", 0, -1, "[-k] " CMD_TARGET_WINDOW_USAGE " [command]", - 0, + CMD_WINDOW_T, cmd_respawn_window_exec }; @@ -41,25 +41,21 @@ enum cmd_retval cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct winlink *wl; - struct window *w; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; + struct window *w = wl->window; struct window_pane *wp; - struct session *s; struct environ *env; const char *path; char *cause; struct environ_entry *envent; - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) - return (CMD_RETURN_ERROR); - w = wl->window; - if (!args_has(self->args, 'k')) { TAILQ_FOREACH(wp, &w->panes, entry) { if (wp->fd == -1) continue; - cmdq_error(cmdq, - "window still active: %s:%d", s->name, wl->idx); + cmdq_error(cmdq, "window still active: %s:%d", s->name, + wl->idx); return (CMD_RETURN_ERROR); } } diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c index 859ff04a..4122886a 100644 --- a/cmd-rotate-window.c +++ b/cmd-rotate-window.c @@ -30,24 +30,19 @@ const struct cmd_entry cmd_rotate_window_entry = { "rotate-window", "rotatew", "Dt:U", 0, 0, "[-DU] " CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_rotate_window_exec }; enum cmd_retval cmd_rotate_window_exec(struct cmd *self, struct cmd_q *cmdq) { - struct args *args = self->args; - struct winlink *wl; - struct window *w; + struct winlink *wl = cmdq->state.tflag.wl; + struct window *w = wl->window; struct window_pane *wp, *wp2; struct layout_cell *lc; u_int sx, sy, xoff, yoff; - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) - return (CMD_RETURN_ERROR); - w = wl->window; - if (args_has(self->args, 'D')) { wp = TAILQ_LAST(&w->panes, window_panes); TAILQ_REMOVE(&w->panes, wp, entry); diff --git a/cmd-run-shell.c b/cmd-run-shell.c index fd5d84d4..0dae39ac 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -39,7 +39,7 @@ const struct cmd_entry cmd_run_shell_entry = { "run-shell", "run", "bt:", 1, 1, "[-b] " CMD_TARGET_PANE_USAGE " shell-command", - 0, + CMD_PANE_T|CMD_CANFAIL, cmd_run_shell_exec }; @@ -75,31 +75,18 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq) struct args *args = self->args; struct cmd_run_shell_data *cdata; char *shellcmd; - struct client *c; - struct session *s = NULL; - struct winlink *wl = NULL; - struct window_pane *wp = NULL; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; + struct window_pane *wp = cmdq->state.tflag.wp; struct format_tree *ft; const char *cwd; - if (args_has(args, 't')) { - wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); - cwd = wp->cwd; - } else { - c = cmd_find_client(cmdq, NULL, 1); - if (c != NULL && c->session != NULL) { - s = c->session; - wl = s->curw; - wp = wl->window->active; - } - if (cmdq->client != NULL && cmdq->client->session == NULL) - cwd = cmdq->client->cwd; - else if (s != NULL) - cwd = s->cwd; - else - cwd = NULL; - } - + if (cmdq->client != NULL && cmdq->client->session == NULL) + cwd = cmdq->client->cwd; + else if (s != NULL) + cwd = s->cwd; + else + cwd = NULL; ft = format_create(cmdq, 0); format_defaults(ft, NULL, s, wl, wp); shellcmd = format_expand(ft, args->argv[0]); diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c index daef88a8..fc8d7bee 100644 --- a/cmd-save-buffer.c +++ b/cmd-save-buffer.c @@ -94,7 +94,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) if (c != NULL && c->session == NULL) cwd = c->cwd; - else if ((s = cmd_find_current(cmdq)) != NULL) + else if ((s = c->session) != NULL) cwd = s->cwd; else cwd = "."; diff --git a/cmd-select-layout.c b/cmd-select-layout.c index 14737dc8..aac60083 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -32,7 +32,7 @@ const struct cmd_entry cmd_select_layout_entry = { "select-layout", "selectl", "nopt:", 0, 1, "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]", - 0, + CMD_WINDOW_T, cmd_select_layout_exec }; @@ -40,7 +40,7 @@ const struct cmd_entry cmd_next_layout_entry = { "next-layout", "nextl", "t:", 0, 0, CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_select_layout_exec }; @@ -48,7 +48,7 @@ const struct cmd_entry cmd_previous_layout_entry = { "previous-layout", "prevl", "t:", 0, 0, CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_select_layout_exec }; @@ -56,16 +56,13 @@ enum cmd_retval cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct winlink *wl; + struct winlink *wl = cmdq->state.tflag.wl; struct window *w; const char *layoutname; char *oldlayout; int next, previous, layout; - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) - return (CMD_RETURN_ERROR); w = wl->window; - server_unzoom_window(w); next = self->entry == &cmd_next_layout_entry; diff --git a/cmd-select-pane.c b/cmd-select-pane.c index 7986e98c..e83dc609 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -30,7 +30,7 @@ const struct cmd_entry cmd_select_pane_entry = { "select-pane", "selectp", "DdegLlMmP:Rt:U", 0, 0, "[-DdegLlMmRU] [-P style] " CMD_TARGET_PANE_USAGE, - 0, + CMD_PANE_T, cmd_select_pane_exec }; @@ -38,7 +38,7 @@ const struct cmd_entry cmd_last_pane_entry = { "last-pane", "lastp", "det:", 0, 0, "[-de] " CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_select_pane_exec }; @@ -46,19 +46,15 @@ enum cmd_retval cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct winlink *wl; - struct window *w; - struct session *s; - struct window_pane *wp, *lastwp, *markedwp; + struct winlink *wl = cmdq->state.tflag.wl; + struct window *w = wl->window; + struct session *s = cmdq->state.tflag.s; + struct window_pane *wp = cmdq->state.tflag.wp, *lastwp, *markedwp; const char *style; if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) { - wl = cmd_find_window(cmdq, args_get(args, 't'), NULL); - if (wl == NULL) - return (CMD_RETURN_ERROR); - w = wl->window; - if (w->last == NULL) { + if (wl->window->last == NULL) { cmdq_error(cmdq, "no last pane"); return (CMD_RETURN_ERROR); } @@ -79,9 +75,11 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); } - if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) + server_unzoom_window(wp->window); + if (!window_pane_visible(wp)) { + cmdq_error(cmdq, "pane not visible"); return (CMD_RETURN_ERROR); - w = wl->window; + } if (args_has(args, 'm') || args_has(args, 'M')) { if (args_has(args, 'm') && !window_pane_visible(wp)) diff --git a/cmd-select-window.c b/cmd-select-window.c index f530f1fe..ede60dae 100644 --- a/cmd-select-window.c +++ b/cmd-select-window.c @@ -32,7 +32,7 @@ const struct cmd_entry cmd_select_window_entry = { "select-window", "selectw", "lnpTt:", 0, 0, "[-lnpT] " CMD_TARGET_WINDOW_USAGE, - 0, + CMD_WINDOW_T, cmd_select_window_exec }; @@ -40,7 +40,7 @@ const struct cmd_entry cmd_next_window_entry = { "next-window", "next", "at:", 0, 0, "[-a] " CMD_TARGET_SESSION_USAGE, - 0, + CMD_SESSION_T, cmd_select_window_exec }; @@ -48,7 +48,7 @@ const struct cmd_entry cmd_previous_window_entry = { "previous-window", "prev", "at:", 0, 0, "[-a] " CMD_TARGET_SESSION_USAGE, - 0, + CMD_SESSION_T, cmd_select_window_exec }; @@ -56,16 +56,15 @@ const struct cmd_entry cmd_last_window_entry = { "last-window", "last", "t:", 0, 0, CMD_TARGET_SESSION_USAGE, - 0, + CMD_SESSION_T, cmd_select_window_exec }; enum cmd_retval cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq) { - struct args *args = self->args; - struct winlink *wl; - struct session *s; + struct winlink *wl = cmdq->state.tflag.wl; + struct session *s = cmdq->state.tflag.s; int next, previous, last, activity; next = self->entry == &cmd_next_window_entry; @@ -79,10 +78,6 @@ cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq) last = 1; if (next || previous || last) { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - activity = args_has(self->args, 'a'); if (next) { if (session_next(s, activity) != 0) { @@ -103,10 +98,6 @@ cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq) server_redraw_session(s); } else { - wl = cmd_find_window(cmdq, args_get(args, 't'), &s); - if (wl == NULL) - return (CMD_RETURN_ERROR); - /* * If -T and select-window is invoked on same window as * current, switch to previous window. diff --git a/cmd-send-keys.c b/cmd-send-keys.c index 1461baa9..8f9b4ddf 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -33,7 +33,7 @@ const struct cmd_entry cmd_send_keys_entry = { "send-keys", "send", "lRMt:", 0, -1, "[-lRM] " CMD_TARGET_PANE_USAGE " key ...", - 0, + CMD_PANE_T, cmd_send_keys_exec }; @@ -41,7 +41,7 @@ const struct cmd_entry cmd_send_prefix_entry = { "send-prefix", NULL, "2t:", 0, 0, "[-2] " CMD_TARGET_PANE_USAGE, - 0, + CMD_PANE_T, cmd_send_keys_exec }; @@ -49,11 +49,11 @@ enum cmd_retval cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; + struct window_pane *wp = cmdq->state.tflag.wp; + struct session *s = cmdq->state.tflag.s; struct mouse_event *m = &cmdq->item->mouse; - struct window_pane *wp; - struct session *s; - int i, literal; const u_char *keystr; + int i, literal; key_code key; if (args_has(args, 'M')) { @@ -66,9 +66,6 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); } - if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) - return (CMD_RETURN_ERROR); - if (self->entry == &cmd_send_prefix_entry) { if (args_has(args, '2')) key = options_get_number(s->options, "prefix2"); diff --git a/cmd-set-environment.c b/cmd-set-environment.c index 2c0010af..4be967b7 100644 --- a/cmd-set-environment.c +++ b/cmd-set-environment.c @@ -33,7 +33,7 @@ const struct cmd_entry cmd_set_environment_entry = { "set-environment", "setenv", "grt:u", 1, 2, "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]", - 0, + CMD_SESSION_T, cmd_set_environment_exec }; @@ -41,7 +41,6 @@ enum cmd_retval cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *s; struct environ *env; const char *name, *value; @@ -62,11 +61,8 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq) if (args_has(self->args, 'g')) env = global_environ; - else { - if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); - env = s->environ; - } + else + env = cmdq->state.tflag.s->environ; if (args_has(self->args, 'u')) { if (value != NULL) { diff --git a/cmd-set-hook.c b/cmd-set-hook.c index ec58418e..d75b0ba1 100644 --- a/cmd-set-hook.c +++ b/cmd-set-hook.c @@ -33,7 +33,7 @@ const struct cmd_entry cmd_set_hook_entry = { "set-hook", NULL, "gt:u", 1, 2, "[-gu] " CMD_TARGET_SESSION_USAGE " hook-name [command]", - 0, + CMD_SESSION_T, cmd_set_hook_exec }; @@ -41,7 +41,7 @@ const struct cmd_entry cmd_show_hooks_entry = { "show-hooks", NULL, "gt:", 0, 1, "[-g] " CMD_TARGET_SESSION_USAGE, - 0, + CMD_SESSION_T, cmd_set_hook_exec }; @@ -49,7 +49,6 @@ enum cmd_retval cmd_set_hook_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *s; struct cmd_list *cmdlist; struct hooks *hooks; struct hook *hook; @@ -58,12 +57,8 @@ cmd_set_hook_exec(struct cmd *self, struct cmd_q *cmdq) if (args_has(args, 'g')) hooks = global_hooks; - else { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - hooks = s->hooks; - } + else + hooks = cmdq->state.tflag.s->hooks; if (self->entry == &cmd_show_hooks_entry) { hook = hooks_first(hooks); diff --git a/cmd-set-option.c b/cmd-set-option.c index daee62ac..86856fbb 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -67,8 +67,8 @@ struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *, const struct cmd_entry cmd_set_option_entry = { "set-option", "set", "agoqst:uw", 1, 2, - "[-agosquw] [-t target-session|target-window] option [value]", - 0, + "[-agosquw] [-t target-window] option [value]", + CMD_WINDOW_T|CMD_CANFAIL, cmd_set_option_exec }; @@ -76,7 +76,7 @@ const struct cmd_entry cmd_set_window_option_entry = { "set-window-option", "setw", "agoqt:u", 1, 2, "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]", - 0, + CMD_WINDOW_T|CMD_CANFAIL, cmd_set_option_exec }; @@ -84,12 +84,12 @@ enum cmd_retval cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - const struct options_table_entry *oe; - struct session *s; - struct winlink *wl; - struct client *c; - struct options *oo; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; struct window *w; + struct client *c; + const struct options_table_entry *oe; + struct options *oo; const char *optstr, *valstr; /* Get the option name and value. */ @@ -131,7 +131,6 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) if (args_has(self->args, 'g')) oo = global_w_options; else { - wl = cmd_find_window(cmdq, args_get(args, 't'), NULL); if (wl == NULL) { cmdq_error(cmdq, "couldn't set '%s'%s", optstr, @@ -145,7 +144,6 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) if (args_has(self->args, 'g')) oo = global_s_options; else { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) { cmdq_error(cmdq, "couldn't set '%s'%s", optstr, @@ -209,8 +207,8 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char *optstr, const char *valstr) { struct args *args = self->args; - struct session *s; - struct winlink *wl; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; struct options *oo; if (args_has(args, 's')) @@ -219,21 +217,13 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char *optstr, self->entry == &cmd_set_window_option_entry) { if (args_has(self->args, 'g')) oo = global_w_options; - else { - wl = cmd_find_window(cmdq, args_get(args, 't'), NULL); - if (wl == NULL) - return (CMD_RETURN_ERROR); + else oo = wl->window->options; - } } else { if (args_has(self->args, 'g')) oo = global_s_options; - else { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); + else oo = s->options; - } } if (args_has(args, 'u')) { diff --git a/cmd-show-environment.c b/cmd-show-environment.c index 96cfa289..8feb2e22 100644 --- a/cmd-show-environment.c +++ b/cmd-show-environment.c @@ -37,7 +37,7 @@ const struct cmd_entry cmd_show_environment_entry = { "show-environment", "showenv", "gst:", 0, 1, "[-gs] " CMD_TARGET_SESSION_USAGE " [name]", - 0, + CMD_SESSION_T, cmd_show_environment_exec }; @@ -86,18 +86,13 @@ enum cmd_retval cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *s; struct environ *env; struct environ_entry *envent; if (args_has(self->args, 'g')) env = global_environ; - else { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); - env = s->environ; - } + else + env = cmdq->state.tflag.s->environ; if (args->argc != 0) { envent = environ_find(env, args->argv[0]); diff --git a/cmd-show-messages.c b/cmd-show-messages.c index c98c2c91..b80b9fe7 100644 --- a/cmd-show-messages.c +++ b/cmd-show-messages.c @@ -35,7 +35,7 @@ const struct cmd_entry cmd_show_messages_entry = { "show-messages", "showmsgs", "JTt:", 0, 0, "[-JT] " CMD_TARGET_CLIENT_USAGE, - 0, + CMD_CLIENT_T, cmd_show_messages_exec }; @@ -94,7 +94,7 @@ enum cmd_retval cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c; + struct client *c = cmdq->state.c; struct message_entry *msg; char *tim; int done, blank; @@ -111,9 +111,6 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq) if (done) return (CMD_RETURN_NORMAL); - if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); - TAILQ_FOREACH(msg, &c->message_log, entry) { tim = ctime(&msg->msg_time); *strchr(tim, '\n') = '\0'; diff --git a/cmd-show-options.c b/cmd-show-options.c index fd96a0e2..5437ec73 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -38,7 +38,7 @@ const struct cmd_entry cmd_show_options_entry = { "show-options", "show", "gqst:vw", 0, 1, "[-gqsvw] [-t target-session|target-window] [option]", - 0, + CMD_WINDOW_T, cmd_show_options_exec }; @@ -46,19 +46,19 @@ const struct cmd_entry cmd_show_window_options_entry = { "show-window-options", "showw", "gvt:", 0, 1, "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]", - 0, + CMD_WINDOW_T, cmd_show_options_exec }; enum cmd_retval cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq) { - struct args *args = self->args; - struct session *s; - struct winlink *wl; - struct options *oo; - int quiet; - enum options_table_scope scope; + struct args *args = self->args; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; + struct options *oo; + enum options_table_scope scope; + int quiet; if (args_has(self->args, 's')) { oo = global_options; @@ -68,22 +68,14 @@ cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq) scope = OPTIONS_TABLE_WINDOW; if (args_has(self->args, 'g')) oo = global_w_options; - else { - wl = cmd_find_window(cmdq, args_get(args, 't'), NULL); - if (wl == NULL) - return (CMD_RETURN_ERROR); + else oo = wl->window->options; - } } else { scope = OPTIONS_TABLE_SESSION; if (args_has(self->args, 'g')) oo = global_s_options; - else { - s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) - return (CMD_RETURN_ERROR); + else oo = s->options; - } } quiet = args_has(self->args, 'q'); diff --git a/cmd-source-file.c b/cmd-source-file.c index e5710a0c..e776712c 100644 --- a/cmd-source-file.c +++ b/cmd-source-file.c @@ -45,8 +45,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq) struct cmd_q *cmdq1; char *cause; - cmdq1 = cmdq_new(NULL); - cmdq1->client = cmdq->client; + cmdq1 = cmdq_new(cmdq->client); cmdq1->emptyfn = cmd_source_file_done; cmdq1->data = cmdq; diff --git a/cmd-split-window.c b/cmd-split-window.c index 80d9e2b1..59efae35 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -40,7 +40,7 @@ const struct cmd_entry cmd_split_window_entry = { "bc:dF:l:hp:Pt:v", 0, -1, "[-bdhvP] [-c start-directory] [-F format] [-p percentage|-l size] " CMD_TARGET_PANE_USAGE " [command]", - 0, + CMD_PANE_T, cmd_split_window_exec }; @@ -48,10 +48,10 @@ enum cmd_retval cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct session *s; - struct winlink *wl; - struct window *w; - struct window_pane *wp, *new_wp = NULL; + struct session *s = cmdq->state.tflag.s; + struct winlink *wl = cmdq->state.tflag.wl; + struct window *w = wl->window; + struct window_pane *wp = cmdq->state.tflag.wp, *new_wp = NULL; struct environ *env; const char *cmd, *path, *shell, *template, *cwd, *to_free; char **argv, *cause, *new_cause, *cp; @@ -62,9 +62,6 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) struct format_tree *ft; struct environ_entry *envent; - if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) - return (CMD_RETURN_ERROR); - w = wl->window; server_unzoom_window(w); env = environ_create(); @@ -89,8 +86,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) to_free = NULL; if (args_has(args, 'c')) { ft = format_create(cmdq, 0); - format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL, - NULL); + format_defaults(ft, cmdq->state.c, s, NULL, NULL); to_free = cwd = format_expand(ft, args_get(args, 'c')); format_free(ft); } else if (cmdq->client != NULL && cmdq->client->session == NULL) @@ -166,8 +162,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) template = SPLIT_WINDOW_TEMPLATE; ft = format_create(cmdq, 0); - format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl, - new_wp); + format_defaults(ft, cmdq->state.c, s, wl, new_wp); cp = format_expand(ft, template); cmdq_print(cmdq, "%s", cp); diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c index dc2b7246..62d6bad3 100644 --- a/cmd-swap-pane.c +++ b/cmd-swap-pane.c @@ -32,7 +32,7 @@ const struct cmd_entry cmd_swap_pane_entry = { "swap-pane", "swapp", "dDs:t:U", 0, 0, "[-dDU] " CMD_SRCDST_PANE_USAGE, - 0, + CMD_PANE_MARKED_S|CMD_PANE_T, cmd_swap_pane_exec }; @@ -40,16 +40,18 @@ enum cmd_retval cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct winlink *src_wl, *dst_wl; + struct winlink *src_wl, *dst_wl; struct window *src_w, *dst_w; struct window_pane *tmp_wp, *src_wp, *dst_wp; struct layout_cell *src_lc, *dst_lc; u_int sx, sy, xoff, yoff; - dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &dst_wp); - if (dst_wl == NULL) - return (CMD_RETURN_ERROR); + dst_wl = cmdq->state.tflag.wl; dst_w = dst_wl->window; + dst_wp = cmdq->state.tflag.wp; + src_wp = cmdq->state.sflag.wp; + src_wl = cmdq->state.sflag.wl; + src_w = src_wl->window; server_unzoom_window(dst_w); if (!args_has(args, 's')) { @@ -62,19 +64,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq) src_wp = TAILQ_PREV(dst_wp, window_panes, entry); if (src_wp == NULL) src_wp = TAILQ_LAST(&dst_w->panes, window_panes); - } else { - src_wl = cmd_find_pane_marked(cmdq, NULL, NULL, - &src_wp); - if (src_wl == NULL) - return (CMD_RETURN_ERROR); - src_w = src_wl->window; } - } else { - src_wl = cmd_find_pane_marked(cmdq, args_get(args, 's'), NULL, - &src_wp); - if (src_wl == NULL) - return (CMD_RETURN_ERROR); - src_w = src_wl->window; } server_unzoom_window(src_w); diff --git a/cmd-swap-window.c b/cmd-swap-window.c index 51682e37..0ed3ca81 100644 --- a/cmd-swap-window.c +++ b/cmd-swap-window.c @@ -32,31 +32,28 @@ const struct cmd_entry cmd_swap_window_entry = { "swap-window", "swapw", "ds:t:", 0, 0, "[-d] " CMD_SRCDST_WINDOW_USAGE, - 0, + CMD_WINDOW_MARKED_S|CMD_WINDOW_MARKED_T, cmd_swap_window_exec }; enum cmd_retval cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq) { - struct args *args = self->args; - const char *target_src, *target_dst; struct session *src, *dst; struct session_group *sg_src, *sg_dst; struct winlink *wl_src, *wl_dst; struct window *w; - target_src = args_get(args, 's'); - if ((wl_src = cmd_find_window_marked(cmdq, target_src, &src)) == NULL) - return (CMD_RETURN_ERROR); - target_dst = args_get(args, 't'); - if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL) - return (CMD_RETURN_ERROR); - + wl_src = cmdq->state.sflag.wl; + src = cmdq->state.sflag.s; sg_src = session_group_find(src); + + wl_dst = cmdq->state.tflag.wl; + dst = cmdq->state.tflag.s; sg_dst = session_group_find(dst); - if (src != dst && - sg_src != NULL && sg_dst != NULL && sg_src == sg_dst) { + + if (src != dst && sg_src != NULL && sg_dst != NULL && + sg_src == sg_dst) { cmdq_error(cmdq, "can't move window, sessions are grouped"); return (CMD_RETURN_ERROR); } diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 4746b15a..919d0057 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -33,7 +33,7 @@ const struct cmd_entry cmd_switch_client_entry = { "switch-client", "switchc", "lc:Enpt:rT:", 0, 0, "[-Elnpr] [-c target-client] [-t target-session] [-T key-table]", - CMD_READONLY, + CMD_READONLY|CMD_CLIENT_C|CMD_PANE_T|CMD_SESSION_T|CMD_PREFERUNATTACHED, cmd_switch_client_exec }; @@ -41,16 +41,13 @@ enum cmd_retval cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; - struct client *c; - struct session *s = NULL; - struct winlink *wl = NULL; - struct window *w = NULL; - struct window_pane *wp = NULL; - const char *tflag, *tablename, *update; + struct cmd_state *state = &cmdq->state; + struct client *c = state->c; + struct session *s = cmdq->state.tflag.s; + struct window_pane *wp; + const char *tablename, *update; struct key_table *table; - if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL) - return (CMD_RETURN_ERROR); if (args_has(args, 'r')) c->flags ^= CLIENT_READONLY; @@ -68,7 +65,6 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); } - tflag = args_get(args, 't'); if (args_has(args, 'n')) { if ((s = session_next_session(c->session)) == NULL) { cmdq_error(cmdq, "can't find next session"); @@ -82,37 +78,21 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq) } else if (args_has(args, 'l')) { if (c->last_session != NULL && session_alive(c->last_session)) s = c->last_session; + else + s = NULL; if (s == NULL) { cmdq_error(cmdq, "can't find last session"); return (CMD_RETURN_ERROR); } - } else { - if (tflag == NULL) { - if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL) - return (CMD_RETURN_ERROR); - } else if (tflag[strcspn(tflag, ":.")] != '\0') { - if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL) - return (CMD_RETURN_ERROR); - } else { - if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL) - return (CMD_RETURN_ERROR); - w = window_find_by_id_str(tflag); - if (w == NULL) { - wp = window_pane_find_by_id_str(tflag); - if (wp != NULL) - w = wp->window; - } - if (w != NULL) - wl = winlink_find_by_window(&s->windows, w); - } - if (cmdq->client == NULL) return (CMD_RETURN_NORMAL); - if (wl != NULL) { + s = state->tflag.s; + if (state->tflag.wl != NULL) { + wp = state->tflag.wp; if (wp != NULL) window_set_active_pane(wp->window, wp); - session_set_current(s, wl); + session_set_current(s, state->tflag.wl); } } diff --git a/cmd.c b/cmd.c index a950a49a..eac3c199 100644 --- a/cmd.c +++ b/cmd.c @@ -207,6 +207,10 @@ const struct cmd_entry *cmd_table[] = { NULL }; +static void cmd_clear_state(struct cmd_state *); +static struct client *cmd_get_state_client(struct cmd_q *, int); +static int cmd_set_state_flag(struct cmd *, struct cmd_q *, char); + int cmd_pack_argv(int argc, char **argv, char *buf, size_t len) { @@ -388,6 +392,253 @@ usage: return (NULL); } +static void +cmd_clear_state(struct cmd_state *state) +{ + state->c = NULL; + + state->tflag.s = NULL; + state->tflag.wl = NULL; + state->tflag.wp = NULL; + state->tflag.idx = -1; + + state->sflag.s = NULL; + state->sflag.wl = NULL; + state->sflag.wp = NULL; + state->sflag.idx = -1; +} + +static struct client * +cmd_get_state_client(struct cmd_q *cmdq, int quiet) +{ + struct cmd *cmd = cmdq->cmd; + struct args *args = cmd->args; + + switch (cmd->entry->flags & (CMD_CLIENT_C|CMD_CLIENT_T)) { + case 0: + return (cmd_find_client(cmdq, NULL, 1)); + case CMD_CLIENT_C: + return (cmd_find_client(cmdq, args_get(args, 'c'), quiet)); + case CMD_CLIENT_T: + return (cmd_find_client(cmdq, args_get(args, 't'), quiet)); + default: + fatalx("both -t and -c for %s", cmd->entry->name); + } +} + +static int +cmd_set_state_flag(struct cmd *cmd, struct cmd_q *cmdq, char c) +{ + struct cmd_state *state = &cmdq->state; + struct cmd_state_flag *statef = NULL; + const char *flag; + int flags = cmd->entry->flags, everything = 0; + int allflags = 0; + int prefer = !!(flags & CMD_PREFERUNATTACHED); + struct session *s; + struct window *w; + struct winlink *wl; + struct window_pane *wp; + + if (c == 't') { + statef = &cmdq->state.tflag; + allflags = CMD_ALL_T; + } else if (c == 's') { + statef = &cmdq->state.sflag; + allflags = CMD_ALL_S; + } + + /* + * If the command wants something and no argument is present, use the + * base command instead. + */ + flag = args_get(cmd->args, c); + if (flag == NULL) { + if ((flags & allflags) == 0) + return (0); /* doesn't care about flag */ + cmd = cmdq->cmd; + everything = 1; + flag = args_get(cmd->args, c); + } + + /* + * If no flag and the current command is allowed to fail, just skip to + * fill in as much we can, otherwise continue and fail later if needed. + */ + if (flag == NULL && (flags & CMD_CANFAIL)) + goto complete_everything; + + /* Fill in state using command (current or base) flags. */ + switch (cmd->entry->flags & allflags) { + case 0: + break; + case CMD_SESSION_T|CMD_PANE_T: + case CMD_SESSION_S|CMD_PANE_S: + if (flag != NULL && flag[strcspn(flag, ":.")] != '\0') { + statef->wl = cmd_find_pane(cmdq, flag, &statef->s, + &statef->wp); + if (statef->wl == NULL) + return (-1); + } else { + statef->s = cmd_find_session(cmdq, flag, prefer); + if (statef->s == NULL) + return (-1); + + s = statef->s; + if (flag == NULL) { + statef->wl = s->curw; + statef->wp = s->curw->window->active; + } else { + if ((w = window_find_by_id_str(flag)) != NULL) + wp = w->active; + else { + wp = window_pane_find_by_id_str(flag); + if (wp != NULL) + w = wp->window; + } + wl = winlink_find_by_window(&s->windows, w); + if (wl != NULL) { + statef->wl = wl; + statef->wp = wp; + } + } + } + break; + case CMD_MOVEW_R|CMD_INDEX_T: + case CMD_MOVEW_R|CMD_INDEX_S: + statef->s = cmd_find_session(cmdq, flag, prefer); + if (statef->s == NULL) { + statef->idx = cmd_find_index(cmdq, flag, &statef->s); + if (statef->idx == -2) + return (-1); + } + break; + case CMD_SESSION_T: + case CMD_SESSION_S: + statef->s = cmd_find_session(cmdq, flag, prefer); + if (statef->s == NULL) + return (-1); + break; + case CMD_WINDOW_T: + case CMD_WINDOW_S: + statef->wl = cmd_find_window(cmdq, flag, &statef->s); + if (statef->wl == NULL) + return (-1); + break; + case CMD_WINDOW_MARKED_T: + case CMD_WINDOW_MARKED_S: + statef->wl = cmd_find_window_marked(cmdq, flag, &statef->s); + if (statef->wl == NULL) + return (-1); + break; + case CMD_PANE_T: + case CMD_PANE_S: + statef->wl = cmd_find_pane(cmdq, flag, &statef->s, + &statef->wp); + if (statef->wl == NULL) + return (-1); + break; + case CMD_PANE_MARKED_S: + case CMD_PANE_MARKED_T: + statef->wl = cmd_find_pane_marked(cmdq, flag, &statef->s, + &statef->wp); + if (statef->wl == NULL) + return (-1); + break; + case CMD_INDEX_T: + case CMD_INDEX_S: + statef->idx = cmd_find_index(cmdq, flag, &statef->s); + if (statef->idx == -2) + return (-1); + break; + default: + fatalx("too many -%c for %s", c, cmd->entry->name); + } + + /* + * If this is still the current command, it wants what it asked for and + * nothing more. If it's the base command, fill in as much as possible + * because the current command may have different flags. + */ + if (!everything) + return (0); + +complete_everything: + if (statef->s == NULL) { + if (state->c != NULL) + statef->s = state->c->session; + if (statef->s == NULL) + statef->s = cmd_find_current(cmdq); + if (statef->s == NULL) { + if (flags & CMD_CANFAIL) + return (0); + + cmdq_error(cmdq, "no current session"); + return (-1); + } + } + if (statef->wl == NULL) + statef->wl = cmd_find_window(cmdq, flag, &statef->s); + if (statef->wp == NULL) + statef->wl = cmd_find_pane(cmdq, flag, &statef->s, &statef->wp); + + return (0); +} + +int +cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq) +{ + struct cmd_state *state = &cmdq->state; + struct args *args = cmd->args; + const char *cflag, *tflag; + char *tmp; + int error; + + tmp = cmd_print(cmd); + log_debug("preparing state for: %s (client %d)", tmp, + cmdq->client != NULL ? cmdq->client->fd : -1); + free(tmp); + + /* Start with an empty state. */ + cmd_clear_state(state); + + /* + * If the command wants a client and provides -c or -t, use it. If not, + * try the base command instead via cmd_get_state_client. No client is + * allowed if no flags, otherwise it must be available. + */ + switch (cmd->entry->flags & (CMD_CLIENT_C|CMD_CLIENT_T)) { + case 0: + state->c = cmd_get_state_client(cmdq, 1); + break; + case CMD_CLIENT_C: + cflag = args_get(args, 'c'); + if (cflag == NULL) + state->c = cmd_get_state_client(cmdq, 0); + else + state->c = cmd_find_client(cmdq, cflag, 0); + if (state->c == NULL) + return (-1); + break; + case CMD_CLIENT_T: + tflag = args_get(args, 't'); + if (tflag == NULL) + state->c = cmd_get_state_client(cmdq, 0); + else + state->c = cmd_find_client(cmdq, tflag, 0); + if (state->c == NULL) + return (-1); + break; + default: + fatalx("both -c and -t for %s", cmd->entry->name); + } + + error = cmd_set_state_flag(cmd, cmdq, 't'); + if (error == 0) + error = cmd_set_state_flag(cmd, cmdq, 's'); + return (error); +} + char * cmd_print(struct cmd *cmd) { diff --git a/tmux.h b/tmux.h index e10fbcdf..5924470e 100644 --- a/tmux.h +++ b/tmux.h @@ -1293,6 +1293,20 @@ struct args { char **argv; }; +/* Context for a command about to be executed. */ +struct cmd_state_flag { + struct session *s; + struct winlink *wl; + struct window_pane *wp; + int idx; + +}; +struct cmd_state { + struct client *c; + struct cmd_state_flag tflag; + struct cmd_state_flag sflag; +}; + /* Command and list of commands. */ struct cmd { const struct cmd_entry *entry; @@ -1343,6 +1357,8 @@ struct cmd_q { struct cmd_q_item *item; struct cmd *cmd; + struct cmd_state state; + time_t time; u_int number; @@ -1365,10 +1381,31 @@ struct cmd_entry { #define CMD_STARTSERVER 0x1 #define CMD_READONLY 0x2 +#define CMD_SESSION_T 0x4 +#define CMD_SESSION_S 0x8 +#define CMD_WINDOW_T 0x10 +#define CMD_WINDOW_S 0x20 +#define CMD_PANE_T 0x40 +#define CMD_PANE_S 0x80 +#define CMD_CLIENT_T 0x100 +#define CMD_CLIENT_C 0x200 +#define CMD_INDEX_T 0x400 +#define CMD_INDEX_S 0x800 +#define CMD_CANFAIL 0x1000 +#define CMD_PREFERUNATTACHED 0x2000 +#define CMD_MOVEW_R 0x4000 /* for movew -r only */ +#define CMD_PANE_MARKED_S 0x8000 +#define CMD_PANE_MARKED_T 0x10000 +#define CMD_WINDOW_MARKED_T 0x20000 +#define CMD_WINDOW_MARKED_S 0x40000 int flags; enum cmd_retval (*exec)(struct cmd *, struct cmd_q *); }; +#define CMD_ALL_T (CMD_SESSION_T|CMD_WINDOW_T|CMD_PANE_T|CMD_INDEX_T| \ + CMD_MOVEW_R|CMD_PANE_MARKED_T|CMD_WINDOW_MARKED_T) +#define CMD_ALL_S (CMD_SESSION_S|CMD_WINDOW_S|CMD_PANE_S|CMD_INDEX_S| \ + CMD_PANE_MARKED_S|CMD_WINDOW_MARKED_S) /* Key binding and key table. */ struct key_binding { @@ -1718,6 +1755,7 @@ char **cmd_copy_argv(int, char **); void cmd_free_argv(int, char **); char *cmd_stringify_argv(int, char **); struct cmd *cmd_parse(int, char **, const char *, u_int, char **); +int cmd_prepare_state(struct cmd *, struct cmd_q *); char *cmd_print(struct cmd *); int cmd_mouse_at(struct window_pane *, struct mouse_event *, u_int *, u_int *, int); @@ -1728,8 +1766,8 @@ char *cmd_template_replace(const char *, const char *, int); extern const struct cmd_entry *cmd_table[]; /* cmd-attach-session.c */ -enum cmd_retval cmd_attach_session(struct cmd_q *, const char *, int, int, - const char *, int); +enum cmd_retval cmd_attach_session(struct cmd_q *, int, int, const char *, + int); /* cmd-list.c */ struct cmd_list *cmd_list_parse(int, char **, const char *, u_int, char **);