diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index 24affdfeb..5d5e122fd 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -34,8 +34,8 @@ static enum args_parse_type cmd_command_prompt_args_parse(struct args *, static enum cmd_retval cmd_command_prompt_exec(struct cmd *, struct cmdq_item *); -static int cmd_command_prompt_callback(struct client *, void *, - const char *, int); +static enum prompt_result cmd_command_prompt_callback(struct client *, void *, + const char *, enum prompt_key_result); static void cmd_command_prompt_free(void *); const struct cmd_entry cmd_command_prompt_entry = { @@ -176,9 +176,9 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_WAIT); } -static int +static enum prompt_result cmd_command_prompt_callback(struct client *c, void *data, const char *s, - int flags) + enum prompt_key_result key) { struct cmd_command_prompt_cdata *cdata = data; char *error; @@ -188,23 +188,23 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s, int argc = 0; char **argv = NULL; - if (s == NULL || (flags & PROMPT_INPUT_MOVE)) + if (s == NULL || key == PROMPT_KEY_MOVE) goto out; - if (flags & PROMPT_INPUT_DONE) { + if (key == PROMPT_KEY_CLOSE) { if (cdata->flags & PROMPT_INCREMENTAL) goto out; cmd_append_argv(&cdata->argc, &cdata->argv, s); if (++cdata->current != cdata->count) { prompt = &cdata->prompts[cdata->current]; status_prompt_update(c, prompt->prompt, prompt->input); - return (1); + return (PROMPT_CONTINUE); } } argc = cdata->argc; argv = cmd_copy_argv(cdata->argc, cdata->argv); - if (~flags & PROMPT_INPUT_DONE) + if (key != PROMPT_KEY_CLOSE) cmd_append_argv(&argc, &argv, s); else { cmd_free_argv(cdata->argc, cdata->argv); @@ -226,12 +226,12 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s, cmd_free_argv(argc, argv); if (c->prompt_inputcb != cmd_command_prompt_callback) - return (1); + return (PROMPT_CONTINUE); out: if (item != NULL) cmdq_continue(item); - return (0); + return (PROMPT_CLOSE); } static void diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c index bd9489c94..54bc9a2a1 100644 --- a/cmd-confirm-before.c +++ b/cmd-confirm-before.c @@ -33,8 +33,8 @@ static enum args_parse_type cmd_confirm_before_args_parse(struct args *, static enum cmd_retval cmd_confirm_before_exec(struct cmd *, struct cmdq_item *); -static int cmd_confirm_before_callback(struct client *, void *, - const char *, int); +static enum prompt_result cmd_confirm_before_callback(struct client *, void *, + const char *, enum prompt_key_result); static void cmd_confirm_before_free(void *); const struct cmd_entry cmd_confirm_before_entry = { @@ -118,9 +118,9 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_WAIT); } -static int +static enum prompt_result cmd_confirm_before_callback(struct client *c, void *data, const char *s, - __unused int flags) + __unused enum prompt_key_result key) { struct cmd_confirm_before_data *cdata = data; struct cmdq_item *item = cdata->item, *new_item; @@ -151,7 +151,7 @@ out: cmdq_get_client(item)->retval = retcode; cmdq_continue(item); } - return (0); + return (PROMPT_CLOSE); } static void diff --git a/mode-tree.c b/mode-tree.c index d91653805..917f0bbe5 100644 --- a/mode-tree.c +++ b/mode-tree.c @@ -1066,25 +1066,27 @@ mode_tree_search_set(struct mode_tree_data *mtd) mtd->wp->flags |= PANE_REDRAW; } -static int +static enum prompt_result mode_tree_search_callback(__unused struct client *c, void *data, const char *s, - __unused int flags) + enum prompt_key_result key) { struct mode_tree_data *mtd = data; if (mtd->dead) - return (0); + return (PROMPT_CLOSE); free(mtd->search); - if (s == NULL || *s == '\0') { + if (s == NULL || *s == '\0') mtd->search = NULL; - return (0); + else { + mtd->search = xstrdup(s); + mtd->search_icase = mode_tree_is_lowercase(s); + mode_tree_search_set(mtd); } - mtd->search = xstrdup(s); - mtd->search_icase = mode_tree_is_lowercase(s); - mode_tree_search_set(mtd); - return (0); + if (key == PROMPT_KEY_HANDLED) + return (PROMPT_CONTINUE); + return (PROMPT_CLOSE); } static void @@ -1093,14 +1095,14 @@ mode_tree_search_free(void *data) mode_tree_remove_ref(data); } -static int +static enum prompt_result mode_tree_filter_callback(__unused struct client *c, void *data, const char *s, - __unused int flags) + enum prompt_key_result key) { struct mode_tree_data *mtd = data; if (mtd->dead) - return (0); + return (PROMPT_CLOSE); if (mtd->filter != NULL) free(mtd->filter); @@ -1113,7 +1115,9 @@ mode_tree_filter_callback(__unused struct client *c, void *data, const char *s, mode_tree_draw(mtd); mtd->wp->flags |= PANE_REDRAW; - return (0); + if (key == PROMPT_KEY_HANDLED) + return (PROMPT_CONTINUE); + return (PROMPT_CLOSE); } static void diff --git a/server-client.c b/server-client.c index ecd94e3db..a0ffcc215 100644 --- a/server-client.c +++ b/server-client.c @@ -1504,8 +1504,14 @@ server_client_handle_key0(struct client *c, struct key_event *event, } server_client_clear_overlay(c); if (c->prompt_string != NULL) { - if (status_prompt_key(c, event->key) == 0) + switch (status_prompt_key(c, event->key)) { + case PROMPT_KEY_HANDLED: + case PROMPT_KEY_CLOSE: return (0); + case PROMPT_KEY_NOT_HANDLED: + case PROMPT_KEY_MOVE: + break; + } } } diff --git a/status.c b/status.c index d5b10ac7b..28f2de7f3 100644 --- a/status.c +++ b/status.c @@ -670,7 +670,7 @@ status_prompt_accept(__unused struct cmdq_item *item, void *data) void *pd = c->prompt_data; if (c->prompt_string != NULL) { - c->prompt_inputcb(c, pd, "y", PROMPT_INPUT_DONE); + c->prompt_inputcb(c, pd, "y", PROMPT_KEY_CLOSE); status_prompt_clear(c); } return (CMD_RETURN_NORMAL); @@ -735,7 +735,7 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs, if (flags & PROMPT_INCREMENTAL) { tmp = utf8_tocstr(c->prompt_buffer); xasprintf(&cp, "=%s", tmp); - c->prompt_inputcb(c, c->prompt_data, cp, 0); + c->prompt_inputcb(c, c->prompt_data, cp, PROMPT_KEY_HANDLED); free(cp); free(tmp); } @@ -1428,24 +1428,28 @@ status_prompt_backward_word(struct client *c, const char *separators) } /* Fire input callback when done. */ -static void +static enum prompt_key_result status_prompt_done(struct client *c, const char *s) { struct prompt_data *pd = c->prompt_data; - if (c->prompt_inputcb(c, pd, s, PROMPT_INPUT_DONE) == 0) + if (c->prompt_inputcb(c, pd, s, PROMPT_KEY_CLOSE) == PROMPT_CLOSE) { status_prompt_clear(c); + return (PROMPT_KEY_CLOSE); + } + c->flags |= CLIENT_REDRAWSTATUS; + return (PROMPT_KEY_HANDLED); } /* Check for a movement key. */ -static int +static enum prompt_key_result status_prompt_check_move(struct client *c, key_code key) { struct prompt_data *pd = c->prompt_data; char *s; if (~c->prompt_flags & PROMPT_INCREMENTAL) - return (0); + return (PROMPT_KEY_NOT_HANDLED); switch (key) { case KEYC_UP: case KEYC_DOWN: @@ -1455,17 +1459,20 @@ status_prompt_check_move(struct client *c, key_code key) case KEYC_NPAGE: break; default: - return (0); + return (PROMPT_KEY_NOT_HANDLED); } s = utf8_tocstr(c->prompt_buffer); - if (c->prompt_inputcb(c, pd, s, PROMPT_INPUT_MOVE) == 0) + if (c->prompt_inputcb(c, pd, s, PROMPT_KEY_MOVE) == PROMPT_CLOSE) { status_prompt_clear(c); + free(s); + return (PROMPT_KEY_CLOSE); + } free(s); - return (1); + return (PROMPT_KEY_MOVE); } /* Handle keys in prompt. */ -int +enum prompt_key_result status_prompt_key(struct client *c, key_code key) { struct prompt_data *pd = c->prompt_data; @@ -1474,13 +1481,14 @@ status_prompt_key(struct client *c, key_code key) const char *histstr, *separators = NULL, *ks; size_t size, idx; struct utf8_data tmp; + enum prompt_key_result result = PROMPT_KEY_HANDLED; int keys, word_is_separators; if (c->prompt_flags & PROMPT_KEY) { ks = key_string_lookup_key(key, 0); - c->prompt_inputcb(c, pd, ks, PROMPT_INPUT_DONE); + c->prompt_inputcb(c, pd, ks, PROMPT_KEY_CLOSE); status_prompt_clear(c); - return (0); + return (PROMPT_KEY_CLOSE); } size = utf8_strlen(c->prompt_buffer); @@ -1491,10 +1499,10 @@ status_prompt_key(struct client *c, key_code key) if (key >= '0' && key <= '9') goto append_key; s = utf8_tocstr(c->prompt_buffer); - c->prompt_inputcb(c, pd, s, PROMPT_INPUT_DONE); + c->prompt_inputcb(c, pd, s, PROMPT_KEY_CLOSE); status_prompt_clear(c); free(s); - return (1); + return (PROMPT_KEY_NOT_HANDLED); } if (c->prompt_flags & (PROMPT_SINGLE|PROMPT_QUOTENEXT)) { @@ -1502,7 +1510,7 @@ status_prompt_key(struct client *c, key_code key) key = 0x7f; else if ((key & KEYC_MASK_KEY) > 0x7f) { if (!KEYC_IS_UNICODE(key)) - return (0); + return (PROMPT_KEY_HANDLED); key &= KEYC_MASK_KEY; } else key &= (key & KEYC_CTRL) ? 0x1f : KEYC_MASK_KEY; @@ -1518,13 +1526,14 @@ status_prompt_key(struct client *c, key_code key) case 2: goto append_key; default: - return (0); + return (PROMPT_KEY_HANDLED); } } process_key: - if (status_prompt_check_move(c, key)) - return (1); + result = status_prompt_check_move(c, key); + if (result != PROMPT_KEY_NOT_HANDLED) + return (result); switch (key) { case KEYC_LEFT: case 'b'|KEYC_CTRL: @@ -1560,10 +1569,8 @@ process_key: break; case KEYC_BSPACE: case 'h'|KEYC_CTRL: - if (c->prompt_flags & PROMPT_BSPACE_EXIT && size == 0) { - status_prompt_done(c, NULL); - break; - } + if (c->prompt_flags & PROMPT_BSPACE_EXIT && size == 0) + return (status_prompt_done(c, NULL)); if (c->prompt_index != 0) { if (c->prompt_index == size) c->prompt_buffer[--c->prompt_index].size = 0; @@ -1706,15 +1713,14 @@ process_key: s = utf8_tocstr(c->prompt_buffer); if (*s != '\0') status_prompt_add_history(s, c->prompt_type); - status_prompt_done(c, s); + result = status_prompt_done(c, s); free(s); - break; + return (result); case '\033': /* Escape */ case '['|KEYC_CTRL: case 'c'|KEYC_CTRL: case 'g'|KEYC_CTRL: - status_prompt_done(c, NULL); - break; + return (status_prompt_done(c, NULL)); case 'r'|KEYC_CTRL: if (~c->prompt_flags & PROMPT_INCREMENTAL) break; @@ -1745,7 +1751,7 @@ process_key: } c->flags |= CLIENT_REDRAWSTATUS; - return (0); + return (PROMPT_KEY_HANDLED); append_key: if (key <= 0x7f) { @@ -1755,7 +1761,7 @@ append_key: } else if (KEYC_IS_UNICODE(key)) utf8_to_data(key, &tmp); else - return (0); + return (PROMPT_KEY_HANDLED); c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 2, sizeof *c->prompt_buffer); @@ -1774,11 +1780,12 @@ append_key: } if (c->prompt_flags & PROMPT_SINGLE) { - if (utf8_strlen(c->prompt_buffer) != 1) + if (utf8_strlen(c->prompt_buffer) != 1) { status_prompt_clear(c); - else { + result = PROMPT_KEY_CLOSE; + } else { s = utf8_tocstr(c->prompt_buffer); - status_prompt_done(c, s); + result = status_prompt_done(c, s); free(s); } } @@ -1788,11 +1795,11 @@ changed: if (c->prompt_flags & PROMPT_INCREMENTAL) { s = utf8_tocstr(c->prompt_buffer); xasprintf(&cp, "%c%s", prefix, s); - c->prompt_inputcb(c, pd, cp, 0); + c->prompt_inputcb(c, pd, cp, PROMPT_KEY_HANDLED); free(cp); free(s); } - return (0); + return (result); } /* Get previous line from the history. */ diff --git a/tmux.h b/tmux.h index ed39eec9f..035844e98 100644 --- a/tmux.h +++ b/tmux.h @@ -1990,11 +1990,26 @@ RB_HEAD(client_windows, client_window); /* Maximum time to be pasting. */ #define CLIENT_PASTE_TIME_LIMIT 5 -/* Client connection. */ -#define PROMPT_INPUT_DONE 0x1 -#define PROMPT_INPUT_MOVE 0x2 -typedef int (*prompt_input_cb)(struct client *, void *, const char *, int); +/* Prompt result. */ +enum prompt_result { + PROMPT_CONTINUE, + PROMPT_CLOSE +}; + +/* Prompt key result. */ +enum prompt_key_result { + PROMPT_KEY_NOT_HANDLED, + PROMPT_KEY_HANDLED, + PROMPT_KEY_CLOSE, + PROMPT_KEY_MOVE +}; + +/* Prompt callbacks. */ +typedef enum prompt_result (*prompt_input_cb)(struct client *, void *, + const char *, enum prompt_key_result); typedef void (*prompt_free_cb)(void *); + +/* Overlay callbacks. */ typedef struct visible_ranges *(*overlay_check_cb)(struct client *, void *, u_int, u_int, u_int); typedef struct screen *(*overlay_mode_cb)(struct client *, void *, u_int *, @@ -2003,6 +2018,8 @@ typedef void (*overlay_draw_cb)(struct client *, void *); typedef int (*overlay_key_cb)(struct client *, void *, struct key_event *); typedef void (*overlay_free_cb)(struct client *, void *); typedef void (*overlay_resize_cb)(struct client *, void *); + +/* Client connection. */ struct client { const char *name; struct tmuxpeer *peer; @@ -3107,7 +3124,7 @@ void status_prompt_set(struct client *, struct cmd_find_state *, void *, int, enum prompt_type); void status_prompt_clear(struct client *); int status_prompt_redraw(struct client *); -int status_prompt_key(struct client *, key_code); +enum prompt_key_result status_prompt_key(struct client *, key_code); void status_prompt_update(struct client *, const char *, const char *); void status_prompt_load_history(void); void status_prompt_save_history(void); diff --git a/window-customize.c b/window-customize.c index da676bd34..1e954fca9 100644 --- a/window-customize.c +++ b/window-customize.c @@ -979,9 +979,9 @@ window_customize_free_item_callback(void *itemdata) window_customize_destroy(data); } -static int +static enum prompt_result window_customize_set_option_callback(struct client *c, void *itemdata, - const char *s, __unused int flags) + const char *s, __unused enum prompt_key_result key) { struct window_customize_itemdata *item = itemdata; struct window_customize_modedata *data = item->data; @@ -993,12 +993,12 @@ window_customize_set_option_callback(struct client *c, void *itemdata, int idx = item->idx; if (s == NULL || *s == '\0' || data->dead) - return (0); + return (PROMPT_CLOSE); if (item == NULL || !window_customize_check_item(data, item, NULL)) - return (0); + return (PROMPT_CLOSE); o = options_get(oo, name); if (o == NULL) - return (0); + return (PROMPT_CLOSE); oe = options_table_entry(o); if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_ARRAY)) { @@ -1020,13 +1020,13 @@ window_customize_set_option_callback(struct client *c, void *itemdata, mode_tree_draw(data->data); data->wp->flags |= PANE_REDRAW; - return (0); + return (PROMPT_CLOSE); fail: *cause = toupper((u_char)*cause); status_message_set(c, -1, 1, 0, 0, "%s", cause); free(cause); - return (0); + return (PROMPT_CLOSE); } static void @@ -1193,9 +1193,9 @@ window_customize_reset_option(struct window_customize_modedata *data, } } -static int +static enum prompt_result window_customize_set_command_callback(struct client *c, void *itemdata, - const char *s, __unused int flags) + const char *s, __unused enum prompt_key_result key) { struct window_customize_itemdata *item = itemdata; struct window_customize_modedata *data = item->data; @@ -1204,9 +1204,9 @@ window_customize_set_command_callback(struct client *c, void *itemdata, char *error; if (s == NULL || *s == '\0' || data->dead) - return (0); + return (PROMPT_CLOSE); if (item == NULL || !window_customize_get_key(item, NULL, &bd)) - return (0); + return (PROMPT_CLOSE); pr = cmd_parse_from_string(s, NULL); switch (pr->status) { @@ -1223,27 +1223,27 @@ window_customize_set_command_callback(struct client *c, void *itemdata, mode_tree_draw(data->data); data->wp->flags |= PANE_REDRAW; - return (0); + return (PROMPT_CLOSE); fail: *error = toupper((u_char)*error); status_message_set(c, -1, 1, 0, 0, "%s", error); free(error); - return (0); + return (PROMPT_CLOSE); } -static int +static enum prompt_result window_customize_set_note_callback(__unused struct client *c, void *itemdata, - const char *s, __unused int flags) + const char *s, __unused enum prompt_key_result key) { struct window_customize_itemdata *item = itemdata; struct window_customize_modedata *data = item->data; struct key_binding *bd; if (s == NULL || *s == '\0' || data->dead) - return (0); + return (PROMPT_CLOSE); if (item == NULL || !window_customize_get_key(item, NULL, &bd)) - return (0); + return (PROMPT_CLOSE); free((void *)bd->note); bd->note = xstrdup(s); @@ -1252,7 +1252,7 @@ window_customize_set_note_callback(__unused struct client *c, void *itemdata, mode_tree_draw(data->data); data->wp->flags |= PANE_REDRAW; - return (0); + return (PROMPT_CLOSE); } static void @@ -1370,17 +1370,17 @@ window_customize_change_each(void *modedata, void *itemdata, options_push_changes(item->name); } -static int +static enum prompt_result window_customize_change_current_callback(__unused struct client *c, - void *modedata, const char *s, __unused int flags) + void *modedata, const char *s, __unused enum prompt_key_result key) { struct window_customize_modedata *data = modedata; struct window_customize_itemdata *item; if (s == NULL || *s == '\0' || data->dead) - return (0); + return (PROMPT_CLOSE); if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') - return (0); + return (PROMPT_CLOSE); item = mode_tree_get_current(data->data); switch (data->change) { @@ -1403,19 +1403,19 @@ window_customize_change_current_callback(__unused struct client *c, mode_tree_draw(data->data); data->wp->flags |= PANE_REDRAW; - return (0); + return (PROMPT_CLOSE); } -static int +static enum prompt_result window_customize_change_tagged_callback(struct client *c, void *modedata, - const char *s, __unused int flags) + const char *s, __unused enum prompt_key_result key) { struct window_customize_modedata *data = modedata; if (s == NULL || *s == '\0' || data->dead) - return (0); + return (PROMPT_CLOSE); if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') - return (0); + return (PROMPT_CLOSE); mode_tree_each_tagged(data->data, window_customize_change_each, c, KEYC_NONE, 0); @@ -1423,7 +1423,7 @@ window_customize_change_tagged_callback(struct client *c, void *modedata, mode_tree_draw(data->data); data->wp->flags |= PANE_REDRAW; - return (0); + return (PROMPT_CLOSE); } static void diff --git a/window-tree.c b/window-tree.c index 6e4b626c6..30c564dfd 100644 --- a/window-tree.c +++ b/window-tree.c @@ -1080,14 +1080,14 @@ window_tree_command_done(__unused struct cmdq_item *item, void *modedata) return (CMD_RETURN_NORMAL); } -static int +static enum prompt_result window_tree_command_callback(struct client *c, void *modedata, const char *s, - __unused int flags) + __unused enum prompt_key_result key) { struct window_tree_modedata *data = modedata; if (s == NULL || *s == '\0' || data->dead) - return (0); + return (PROMPT_CLOSE); data->entered = s; mode_tree_each_tagged(data->data, window_tree_command_each, c, @@ -1097,7 +1097,7 @@ window_tree_command_callback(struct client *c, void *modedata, const char *s, data->references++; cmdq_append(c, cmdq_get_callback(window_tree_command_done, data)); - return (0); + return (PROMPT_CLOSE); } static void @@ -1139,17 +1139,17 @@ window_tree_kill_each(__unused void *modedata, void *itemdata, } } -static int +static enum prompt_result window_tree_kill_current_callback(struct client *c, void *modedata, - const char *s, __unused int flags) + const char *s, __unused enum prompt_key_result key) { struct window_tree_modedata *data = modedata; struct mode_tree_data *mtd = data->data; if (s == NULL || *s == '\0' || data->dead) - return (0); + return (PROMPT_CLOSE); if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') - return (0); + return (PROMPT_CLOSE); window_tree_kill_each(data, mode_tree_get_current(mtd), c, KEYC_NONE); server_renumber_all(); @@ -1157,20 +1157,20 @@ window_tree_kill_current_callback(struct client *c, void *modedata, data->references++; cmdq_append(c, cmdq_get_callback(window_tree_command_done, data)); - return (0); + return (PROMPT_CLOSE); } -static int +static enum prompt_result window_tree_kill_tagged_callback(struct client *c, void *modedata, - const char *s, __unused int flags) + const char *s, __unused enum prompt_key_result key) { struct window_tree_modedata *data = modedata; struct mode_tree_data *mtd = data->data; if (s == NULL || *s == '\0' || data->dead) - return (0); + return (PROMPT_CLOSE); if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') - return (0); + return (PROMPT_CLOSE); mode_tree_each_tagged(mtd, window_tree_kill_each, c, KEYC_NONE, 1); server_renumber_all(); @@ -1178,7 +1178,7 @@ window_tree_kill_tagged_callback(struct client *c, void *modedata, data->references++; cmdq_append(c, cmdq_get_callback(window_tree_command_done, data)); - return (0); + return (PROMPT_CLOSE); } static key_code