diff --git a/cmd-display-message.c b/cmd-display-message.c index 201f8b75..ddc55846 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]", - CMD_CLIENT_C|CMD_PANE_T, + CMD_CLIENT_C|CMD_PANE_T|CMD_CLIENT_CANFAIL, cmd_display_message_exec }; diff --git a/cmd-find.c b/cmd-find.c index 30c433b6..4c08147d 100644 --- a/cmd-find.c +++ b/cmd-find.c @@ -466,11 +466,10 @@ cmd_find_get_window(struct cmd_find_state *fs, const char *window) /* Otherwise try as a session itself. */ if (cmd_find_get_session(fs, window) == 0) { - if (~fs->flags & CMD_FIND_WINDOW_INDEX) { - fs->wl = fs->s->curw; - fs->w = fs->wl->window; + fs->wl = fs->s->curw; + fs->w = fs->wl->window; + if (~fs->flags & CMD_FIND_WINDOW_INDEX) fs->idx = fs->wl->idx; - } return (0); } @@ -492,6 +491,13 @@ cmd_find_get_window_with_session(struct cmd_find_state *fs, const char *window) log_debug("%s: %s", __func__, window); exact = (fs->flags & CMD_FIND_EXACT_WINDOW); + /* + * Start with the current window as the default. So if only an index is + * found, the window will be the current. + */ + fs->wl = fs->s->curw; + fs->w = fs->wl->window; + /* Check for window ids starting with @. */ if (*window == '@') { fs->w = window_find_by_id_str(window); @@ -975,8 +981,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_q *cmdq, /* This will fill in winlink and window. */ if (cmd_find_get_window_with_session(fs, window) != 0) goto no_window; - if (~flags & CMD_FIND_WINDOW_INDEX) - fs->wp = fs->wl->window->active; + fs->wp = fs->wl->window->active; goto found; } @@ -1016,8 +1021,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_q *cmdq, /* This will fill in session, winlink and window. */ if (cmd_find_get_window(fs, window) != 0) goto no_window; - if (~flags & CMD_FIND_WINDOW_INDEX) - fs->wp = fs->wl->window->active; + fs->wp = fs->wl->window->active; goto found; } diff --git a/cmd-new-window.c b/cmd-new-window.c index 8154bdfb..18d2952b 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -39,12 +39,7 @@ 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]", - /* - * 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_INDEX_T, cmd_new_window_exec }; diff --git a/cmd-show-environment.c b/cmd-show-environment.c index 8feb2e22..723d3039 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]", - CMD_SESSION_T, + CMD_SESSION_T|CMD_CANFAIL, cmd_show_environment_exec }; diff --git a/cmd-show-options.c b/cmd-show-options.c index 5437ec73..3b39a532 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]", - CMD_WINDOW_T, + CMD_WINDOW_T|CMD_CANFAIL, cmd_show_options_exec }; @@ -46,7 +46,7 @@ const struct cmd_entry cmd_show_window_options_entry = { "show-window-options", "showw", "gvt:", 0, 1, "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]", - CMD_WINDOW_T, + CMD_WINDOW_T|CMD_CANFAIL, cmd_show_options_exec }; diff --git a/cmd.c b/cmd.c index 6aaddcf0..39834c5a 100644 --- a/cmd.c +++ b/cmd.c @@ -206,9 +206,8 @@ 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); +static void cmd_clear_state(struct cmd_state *); +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) @@ -407,29 +406,11 @@ cmd_clear_state(struct cmd_state *state) 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; + struct cmd_find_state *fsf = NULL; const char *flag; int flags = cmd->entry->flags, everything = 0; int allflags = 0, targetflags, error; @@ -437,14 +418,13 @@ cmd_set_state_flag(struct cmd *cmd, struct cmd_q *cmdq, char c) struct window *w; struct winlink *wl; struct window_pane *wp; - struct cmd_find_state fs; /* Set up state for either -t or -s. */ if (c == 't') { - statef = &cmdq->state.tflag; + fsf = &cmdq->state.tflag; allflags = CMD_ALL_T; } else if (c == 's') { - statef = &cmdq->state.sflag; + fsf = &cmdq->state.sflag; allflags = CMD_ALL_S; } @@ -479,25 +459,21 @@ cmd_set_state_flag(struct cmd *cmd, struct cmd_q *cmdq, char c) case CMD_SESSION_T|CMD_PANE_T: case CMD_SESSION_S|CMD_PANE_S: if (flag != NULL && flag[strcspn(flag, ":.")] != '\0') { - error = cmd_find_target(&fs, cmdq, flag, CMD_FIND_PANE, + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_PANE, targetflags); if (error != 0) return (-1); - statef->s = fs.s; - statef->wl = fs.wl; - statef->wp = fs.wp; } else { - error = cmd_find_target(&fs, cmdq, flag, + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_SESSION, targetflags); if (error != 0) return (-1); - statef->s = fs.s; if (flag == NULL) { - statef->wl = statef->s->curw; - statef->wp = statef->s->curw->window->active; + fsf->wl = fsf->s->curw; + fsf->wp = fsf->s->curw->window->active; } else { - s = statef->s; + s = fsf->s; if ((w = window_find_by_id_str(flag)) != NULL) wp = w->active; else { @@ -507,34 +483,29 @@ cmd_set_state_flag(struct cmd *cmd, struct cmd_q *cmdq, char c) } wl = winlink_find_by_window(&s->windows, w); if (wl != NULL) { - statef->wl = wl; - statef->wp = wp; + fsf->wl = wl; + fsf->wp = wp; } } } break; case CMD_MOVEW_R|CMD_INDEX_T: case CMD_MOVEW_R|CMD_INDEX_S: - error = cmd_find_target(&fs, cmdq, flag, CMD_FIND_SESSION, - targetflags); - if (error == 0) - statef->s = fs.s; - else { - error = cmd_find_target(&fs, cmdq, flag, + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_SESSION, + targetflags|CMD_FIND_QUIET); + if (error != 0) { + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX); if (error != 0) return (-1); - statef->s = fs.s; - statef->idx = fs.idx; } break; case CMD_SESSION_T: case CMD_SESSION_S: - error = cmd_find_target(&fs, cmdq, flag, CMD_FIND_SESSION, + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_SESSION, targetflags); if (error != 0) return (-1); - statef->s = fs.s; break; case CMD_WINDOW_MARKED_T: case CMD_WINDOW_MARKED_S: @@ -542,12 +513,10 @@ cmd_set_state_flag(struct cmd *cmd, struct cmd_q *cmdq, char c) /* FALLTHROUGH */ case CMD_WINDOW_T: case CMD_WINDOW_S: - error = cmd_find_target(&fs, cmdq, flag, CMD_FIND_WINDOW, + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_WINDOW, targetflags); if (error != 0) return (-1); - statef->s = fs.s; - statef->wl = fs.wl; break; case CMD_PANE_MARKED_T: case CMD_PANE_MARKED_S: @@ -555,22 +524,17 @@ cmd_set_state_flag(struct cmd *cmd, struct cmd_q *cmdq, char c) /* FALLTHROUGH */ case CMD_PANE_T: case CMD_PANE_S: - error = cmd_find_target(&fs, cmdq, flag, CMD_FIND_PANE, + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_PANE, targetflags); if (error != 0) return (-1); - statef->s = fs.s; - statef->wl = fs.wl; - statef->wp = fs.wp; break; case CMD_INDEX_T: case CMD_INDEX_S: - error = cmd_find_target(&fs, cmdq, flag, CMD_FIND_WINDOW, + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX); if (error != 0) return (-1); - statef->s = fs.s; - statef->idx = fs.idx; break; default: fatalx("too many -%c for %s", c, cmd->entry->name); @@ -585,36 +549,31 @@ cmd_set_state_flag(struct cmd *cmd, struct cmd_q *cmdq, char c) return (0); complete_everything: - if (statef->s == NULL) { + if (fsf->s == NULL) { if (state->c != NULL) - statef->s = state->c->session; - if (statef->s == NULL) { - error = cmd_find_target(&fs, cmdq, NULL, + fsf->s = state->c->session; + if (fsf->s == NULL) { + error = cmd_find_target(fsf, cmdq, NULL, CMD_FIND_SESSION, CMD_FIND_QUIET); - if (error == 0) - statef->s = fs.s; + if (error != 0) + fsf->s = NULL; } - if (statef->s == NULL) { + if (fsf->s == NULL) { if (flags & CMD_CANFAIL) return (0); cmdq_error(cmdq, "no current session"); return (-1); } } - if (statef->wl == NULL) { - error = cmd_find_target(&fs, cmdq, flag, CMD_FIND_WINDOW, 0); - if (error != 0) { - statef->s = fs.s; - statef->wl = fs.wl; - } + if (fsf->wl == NULL) { + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_WINDOW, 0); + if (error != 0) + return (-1); } - if (statef->wp == NULL) { - error = cmd_find_target(&fs, cmdq, flag, CMD_FIND_PANE, 0); - if (error != 0) { - statef->s = fs.s; - statef->wl = fs.wl; - statef->wp = fs.wp; - } + if (fsf->wp == NULL) { + error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_PANE, 0); + if (error != 0) + return (-1); } return (0); } @@ -624,9 +583,8 @@ 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; + int error, quiet; tmp = cmd_print(cmd); log_debug("preparing state for: %s (client %p)", tmp, cmdq->client); @@ -635,6 +593,11 @@ cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq) /* Start with an empty state. */ cmd_clear_state(state); + /* No error messages if can fail. */ + quiet = 0; + if (cmd->entry->flags & CMD_CLIENT_CANFAIL) + quiet = 1; + /* * 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 @@ -642,24 +605,16 @@ cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq) */ switch (cmd->entry->flags & (CMD_CLIENT_C|CMD_CLIENT_T)) { case 0: - state->c = cmd_get_state_client(cmdq, 1); + state->c = cmd_find_client(cmdq, NULL, 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) + state->c = cmd_find_client(cmdq, args_get(args, 'c'), quiet); + if (!quiet && 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) + state->c = cmd_find_client(cmdq, args_get(args, 't'), quiet); + if (!quiet && state->c == NULL) return (-1); break; default: diff --git a/tmux.h b/tmux.h index 113a53b8..cda3da2a 100644 --- a/tmux.h +++ b/tmux.h @@ -1295,18 +1295,37 @@ 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; - +/* Command find structures. */ +enum cmd_find_type { + CMD_FIND_PANE, + CMD_FIND_WINDOW, + CMD_FIND_SESSION, }; +struct cmd_find_state { + struct cmd_q *cmdq; + int flags; + struct cmd_find_state *current; + + struct session *s; + struct winlink *wl; + struct window *w; + struct window_pane *wp; + int idx; +}; + +/* Command find flags. */ +#define CMD_FIND_PREFER_UNATTACHED 0x1 +#define CMD_FIND_QUIET 0x2 +#define CMD_FIND_WINDOW_INDEX 0x4 +#define CMD_FIND_DEFAULT_MARKED 0x8 +#define CMD_FIND_EXACT_SESSION 0x10 +#define CMD_FIND_EXACT_WINDOW 0x20 + +/* Context for command being executed. */ struct cmd_state { struct client *c; - struct cmd_state_flag tflag; - struct cmd_state_flag sflag; + struct cmd_find_state tflag; + struct cmd_find_state sflag; }; /* Command and list of commands. */ @@ -1400,6 +1419,7 @@ struct cmd_entry { #define CMD_PANE_MARKED_T 0x10000 #define CMD_WINDOW_MARKED_T 0x20000 #define CMD_WINDOW_MARKED_S 0x40000 +#define CMD_CLIENT_CANFAIL 0x80000 int flags; enum cmd_retval (*exec)(struct cmd *, struct cmd_q *); @@ -1409,32 +1429,6 @@ struct cmd_entry { #define CMD_ALL_S (CMD_SESSION_S|CMD_WINDOW_S|CMD_PANE_S|CMD_INDEX_S| \ CMD_PANE_MARKED_S|CMD_WINDOW_MARKED_S) -/* Command find structures. */ -enum cmd_find_type { - CMD_FIND_PANE, - CMD_FIND_WINDOW, - CMD_FIND_SESSION, -}; -struct cmd_find_state { - struct cmd_q *cmdq; - int flags; - struct cmd_find_state *current; - - struct session *s; - struct winlink *wl; - struct window *w; - struct window_pane *wp; - int idx; -}; - -/* Command fine flags. */ -#define CMD_FIND_PREFER_UNATTACHED 0x1 -#define CMD_FIND_QUIET 0x2 -#define CMD_FIND_WINDOW_INDEX 0x4 -#define CMD_FIND_DEFAULT_MARKED 0x8 -#define CMD_FIND_EXACT_SESSION 0x10 -#define CMD_FIND_EXACT_WINDOW 0x20 - /* Key binding and key table. */ struct key_binding { key_code key;