diff options
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | cmd-choose-tree.c | 17 | ||||
| -rw-r--r-- | cmd-list-keys.c | 8 | ||||
| -rw-r--r-- | cmd-run-shell.c | 3 | ||||
| -rw-r--r-- | cmd-set-option.c | 216 | ||||
| -rw-r--r-- | cmd-show-messages.c | 4 | ||||
| -rw-r--r-- | cmd-show-options.c | 8 | ||||
| -rw-r--r-- | cmd.c | 2 | ||||
| -rw-r--r-- | format-draw.c | 2 | ||||
| -rw-r--r-- | format.c | 2 | ||||
| -rw-r--r-- | key-bindings.c | 60 | ||||
| -rw-r--r-- | mode-tree.c | 97 | ||||
| -rw-r--r-- | options-table.c | 358 | ||||
| -rw-r--r-- | options.c | 252 | ||||
| -rw-r--r-- | screen-write.c | 92 | ||||
| -rw-r--r-- | style.c | 7 | ||||
| -rw-r--r-- | tmux.1 | 47 | ||||
| -rw-r--r-- | tmux.h | 33 | ||||
| -rw-r--r-- | window-buffer.c | 4 | ||||
| -rw-r--r-- | window-client.c | 2 | ||||
| -rw-r--r-- | window-customize.c | 1430 | ||||
| -rw-r--r-- | window-tree.c | 2 |
22 files changed, 2284 insertions, 363 deletions
@@ -120,6 +120,7 @@ SRCS= alerts.c \ window-client.c \ window-clock.c \ window-copy.c \ + window-customize.c \ window-tree.c \ window.c \ xmalloc.c \ diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index 0ada8fd4..a58469ac 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -68,6 +68,19 @@ const struct cmd_entry cmd_choose_buffer_entry = { .exec = cmd_choose_tree_exec }; +const struct cmd_entry cmd_customize_mode_entry = { + .name = "customize-mode", + .alias = NULL, + + .args = { "F:f:Nt:Z", 0, 0 }, + .usage = "[-NZ] [-F format] [-f filter] " CMD_TARGET_PANE_USAGE, + + .target = { 't', CMD_FIND_PANE, 0 }, + + .flags = 0, + .exec = cmd_choose_tree_exec +}; + static enum cmd_retval cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item) { @@ -84,7 +97,9 @@ cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item) if (server_client_how_many() == 0) return (CMD_RETURN_NORMAL); mode = &window_client_mode; - } else + } else if (cmd_get_entry(self) == &cmd_customize_mode_entry) + mode = &window_customize_mode; + else mode = &window_tree_mode; window_pane_set_mode(wp, NULL, mode, target, args); diff --git a/cmd-list-keys.c b/cmd-list-keys.c index 4e7ba39c..60ef73af 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -68,7 +68,8 @@ cmd_list_keys_get_width(const char *tablename, key_code only) while (bd != NULL) { if ((only != KEYC_UNKNOWN && bd->key != only) || KEYC_IS_MOUSE(bd->key) || - bd->note == NULL) { + bd->note == NULL || + *bd->note == '\0') { bd = key_bindings_next(table, bd); continue; } @@ -99,14 +100,15 @@ cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args, while (bd != NULL) { if ((only != KEYC_UNKNOWN && bd->key != only) || KEYC_IS_MOUSE(bd->key) || - (bd->note == NULL && !args_has(args, 'a'))) { + ((bd->note == NULL || *bd->note == '\0') && + !args_has(args, 'a'))) { bd = key_bindings_next(table, bd); continue; } found = 1; key = key_string_lookup_key(bd->key); - if (bd->note == NULL) + if (bd->note == NULL || *bd->note == '\0') note = cmd_list_print(bd->cmdlist, 1); else note = xstrdup(bd->note); diff --git a/cmd-run-shell.c b/cmd-run-shell.c index 82d4a1a2..3792aaae 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -190,7 +190,8 @@ cmd_run_shell_callback(struct job *job) retcode = WTERMSIG(status); xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); retcode += 128; - } + } else + retcode = 0; if (msg != NULL) cmd_run_shell_print(job, msg); free(msg); diff --git a/cmd-set-option.c b/cmd-set-option.c index e04aa7ff..c6f83796 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -30,15 +30,6 @@ static enum cmd_retval cmd_set_option_exec(struct cmd *, struct cmdq_item *); -static int cmd_set_option_set(struct cmd *, struct cmdq_item *, - struct options *, struct options_entry *, const char *); -static int cmd_set_option_flag(struct cmdq_item *, - const struct options_table_entry *, struct options *, - const char *); -static int cmd_set_option_choice(struct cmdq_item *, - const struct options_table_entry *, struct options *, - const char *); - const struct cmd_entry cmd_set_option_entry = { .name = "set-option", .alias = "set", @@ -84,10 +75,6 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) struct args *args = cmd_get_args(self); int append = args_has(args, 'a'); struct cmd_find_state *target = cmdq_get_target(item); - struct client *loop; - struct session *s = target->s; - struct window *w; - struct window_pane *wp; struct options *oo; struct options_entry *parent, *o; char *name, *argument, *value = NULL, *cause; @@ -138,7 +125,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) parent = options_get(oo, name); /* Check that array options and indexes match up. */ - if (idx != -1 && (*name == '@' || !options_isarray(parent))) { + if (idx != -1 && (*name == '@' || !options_is_array(parent))) { cmdq_error(item, "not an array: %s", argument); goto fail; } @@ -185,10 +172,15 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) goto fail; } options_set_string(oo, name, append, "%s", value); - } else if (idx == -1 && !options_isarray(parent)) { - error = cmd_set_option_set(self, item, oo, parent, value); - if (error != 0) + } else if (idx == -1 && !options_is_array(parent)) { + error = options_from_string(oo, options_table_entry(parent), + options_table_entry(parent)->name, value, + args_has(args, 'a'), &cause); + if (error != 0) { + cmdq_error(item, "%s", cause); + free(cause); goto fail; + } } else { if (value == NULL) { cmdq_error(item, "empty value"); @@ -212,51 +204,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) } } - /* Update timers and so on for various options. */ - if (strcmp(name, "automatic-rename") == 0) { - RB_FOREACH(w, windows, &windows) { - if (w->active == NULL) - continue; - if (options_get_number(w->options, "automatic-rename")) - w->active->flags |= PANE_CHANGED; - } - } - if (strcmp(name, "key-table") == 0) { - TAILQ_FOREACH(loop, &clients, entry) - server_client_set_key_table(loop, NULL); - } - if (strcmp(name, "user-keys") == 0) { - TAILQ_FOREACH(loop, &clients, entry) { - if (loop->tty.flags & TTY_OPENED) - tty_keys_build(&loop->tty); - } - } - if (strcmp(name, "status") == 0 || - strcmp(name, "status-interval") == 0) - status_timer_start_all(); - if (strcmp(name, "monitor-silence") == 0) - alerts_reset_all(); - if (strcmp(name, "window-style") == 0 || - strcmp(name, "window-active-style") == 0) { - RB_FOREACH(wp, window_pane_tree, &all_window_panes) - wp->flags |= PANE_STYLECHANGED; - } - if (strcmp(name, "pane-border-status") == 0) { - RB_FOREACH(w, windows, &windows) - layout_fix_panes(w); - } - RB_FOREACH(s, sessions, &sessions) - status_update_cache(s); - - /* - * Update sizes and redraw. May not always be necessary but do it - * anyway. - */ - recalculate_sizes(); - TAILQ_FOREACH(loop, &clients, entry) { - if (loop->session != NULL) - server_redraw_client(loop); - } + options_push_changes(name); out: free(argument); @@ -270,147 +218,3 @@ fail: free(name); return (CMD_RETURN_ERROR); } - -static int -cmd_set_option_check_string(const struct options_table_entry *oe, - const char *value, char **cause) -{ - struct style sy; - - if (strcmp(oe->name, "default-shell") == 0 && !checkshell(value)) { - xasprintf(cause, "not a suitable shell: %s", value); - return (-1); - } - if (oe->pattern != NULL && fnmatch(oe->pattern, value, 0) != 0) { - xasprintf(cause, "value is invalid: %s", value); - return (-1); - } - if ((oe->flags & OPTIONS_TABLE_IS_STYLE) && - strstr(value, "#{") == NULL && - style_parse(&sy, &grid_default_cell, value) != 0) { - xasprintf(cause, "invalid style: %s", value); - return (-1); - } - return (0); -} - -static int -cmd_set_option_set(struct cmd *self, struct cmdq_item *item, struct options *oo, - struct options_entry *parent, const char *value) -{ - const struct options_table_entry *oe; - struct args *args = cmd_get_args(self); - int append = args_has(args, 'a'); - long long number; - const char *errstr, *new; - char *old, *cause; - key_code key; - - oe = options_table_entry(parent); - if (value == NULL && - oe->type != OPTIONS_TABLE_FLAG && - oe->type != OPTIONS_TABLE_CHOICE) { - cmdq_error(item, "empty value"); - return (-1); - } - - switch (oe->type) { - case OPTIONS_TABLE_STRING: - old = xstrdup(options_get_string(oo, oe->name)); - options_set_string(oo, oe->name, append, "%s", value); - new = options_get_string(oo, oe->name); - if (cmd_set_option_check_string(oe, new, &cause) != 0) { - cmdq_error(item, "%s", cause); - free(cause); - - options_set_string(oo, oe->name, 0, "%s", old); - free(old); - return (-1); - } - free(old); - return (0); - case OPTIONS_TABLE_NUMBER: - number = strtonum(value, oe->minimum, oe->maximum, &errstr); - if (errstr != NULL) { - cmdq_error(item, "value is %s: %s", errstr, value); - return (-1); - } - options_set_number(oo, oe->name, number); - return (0); - case OPTIONS_TABLE_KEY: - key = key_string_lookup_string(value); - if (key == KEYC_UNKNOWN) { - cmdq_error(item, "bad key: %s", value); - return (-1); - } - options_set_number(oo, oe->name, key); - return (0); - case OPTIONS_TABLE_COLOUR: - if ((number = colour_fromstring(value)) == -1) { - cmdq_error(item, "bad colour: %s", value); - return (-1); - } - options_set_number(oo, oe->name, number); - return (0); - case OPTIONS_TABLE_FLAG: - return (cmd_set_option_flag(item, oe, oo, value)); - case OPTIONS_TABLE_CHOICE: - return (cmd_set_option_choice(item, oe, oo, value)); - case OPTIONS_TABLE_COMMAND: - break; - } - return (-1); -} - -static int -cmd_set_option_flag(struct cmdq_item *item, - const struct options_table_entry *oe, struct options *oo, - const char *value) -{ - int flag; - - if (value == NULL || *value == '\0') - flag = !options_get_number(oo, oe->name); - else if (strcmp(value, "1") == 0 || - strcasecmp(value, "on") == 0 || - strcasecmp(value, "yes") == 0) - flag = 1; - else if (strcmp(value, "0") == 0 || - strcasecmp(value, "off") == 0 || - strcasecmp(value, "no") == 0) - flag = 0; - else { - cmdq_error(item, "bad value: %s", value); - return (-1); - } - options_set_number(oo, oe->name, flag); - return (0); -} - -static int -cmd_set_option_choice(struct cmdq_item *item, - const struct options_table_entry *oe, struct options *oo, - const char *value) -{ - const char **cp; - int n, choice = -1; - - if (value == NULL) { - choice = options_get_number(oo, oe->name); - if (choice < 2) - choice = !choice; - } else { - n = 0; - for (cp = oe->choices; *cp != NULL; cp++) { - if (strcmp(*cp, value) == 0) - choice = n; - n++; - } - if (choice == -1) { - cmdq_error(item, "unknown value: %s", value); - return (-1); - } - } - options_set_number(oo, oe->name, choice); - return (0); -} diff --git a/cmd-show-messages.c b/cmd-show-messages.c index 2fa68f2a..deb0487c 100644 --- a/cmd-show-messages.c +++ b/cmd-show-messages.c @@ -18,6 +18,7 @@ #include <sys/types.h> +#include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> @@ -29,6 +30,9 @@ * Show client message log. */ +#define SHOW_MESSAGES_TEMPLATE \ + "#{t/p:message_time}: #{message_text}" + static enum cmd_retval cmd_show_messages_exec(struct cmd *, struct cmdq_item *); diff --git a/cmd-show-options.c b/cmd-show-options.c index e2aec930..8e70eaa9 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -151,7 +151,7 @@ cmd_show_options_print(struct cmd *self, struct cmdq_item *item, xasprintf(&tmp, "%s[%d]", name, idx); name = tmp; } else { - if (options_isarray(o)) { + if (options_is_array(o)) { a = options_array_first(o); if (a == NULL) { if (!args_has(args, 'v')) @@ -168,10 +168,10 @@ cmd_show_options_print(struct cmd *self, struct cmdq_item *item, } } - value = options_tostring(o, idx, 0); + value = options_to_string(o, idx, 0); if (args_has(args, 'v')) cmdq_print(item, "%s", value); - else if (options_isstring(o)) { + else if (options_is_string(o)) { escaped = args_escape(value); if (parent) cmdq_print(item, "%s* %s", name, escaped); @@ -229,7 +229,7 @@ cmd_show_options_all(struct cmd *self, struct cmdq_item *item, int scope, } else parent = 0; - if (!options_isarray(o)) + if (!options_is_array(o)) cmd_show_options_print(self, item, o, -1, parent); else if ((a = options_array_first(o)) == NULL) { if (!args_has(args, 'v')) { @@ -40,6 +40,7 @@ extern const struct cmd_entry cmd_clock_mode_entry; extern const struct cmd_entry cmd_command_prompt_entry; extern const struct cmd_entry cmd_confirm_before_entry; extern const struct cmd_entry cmd_copy_mode_entry; +extern const struct cmd_entry cmd_customize_mode_entry; extern const struct cmd_entry cmd_delete_buffer_entry; extern const struct cmd_entry cmd_detach_client_entry; extern const struct cmd_entry cmd_display_menu_entry; @@ -130,6 +131,7 @@ const struct cmd_entry *cmd_table[] = { &cmd_command_prompt_entry, &cmd_confirm_before_entry, &cmd_copy_mode_entry, + &cmd_customize_mode_entry, &cmd_delete_buffer_entry, &cmd_detach_client_entry, &cmd_display_menu_entry, diff --git a/format-draw.c b/format-draw.c index 3751082e..bd32b2a8 100644 --- a/format-draw.c +++ b/format-draw.c @@ -547,7 +547,7 @@ format_draw(struct screen_write_ctx *octx, const struct grid_cell *base, */ cp = expanded; while (*cp != '\0') { - if (cp[0] != '#' || cp[1] != '[') { + if (cp[0] != '#' || cp[1] != '[' || sy.ignore) { /* See if this is a UTF-8 character. */ if ((more = utf8_open(ud, *cp)) == UTF8_MORE) { while (*++cp != '\0' && more == UTF8_MORE) @@ -1392,7 +1392,7 @@ format_find(struct format_tree *ft, const char *key, int modifiers, if (o == NULL) o = options_parse_get(global_s_options, key, &idx, 0); if (o != NULL) { - found = options_tostring(o, idx, 1); + found = options_to_string(o, idx, 1); goto found; } diff --git a/key-bindings.c b/key-bindings.c index 85bfb788..ecd2f7dc 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -89,9 +89,8 @@ key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2) } static void -key_bindings_free(struct key_table *table, struct key_binding *bd) +key_bindings_free(struct key_binding *bd) { - RB_REMOVE(key_bindings, &table->key_bindings, bd); cmd_list_free(bd->cmdlist); free((void *)bd->note); free(bd); @@ -110,6 +109,7 @@ key_bindings_get_table(const char *name, int create) table = xmalloc(sizeof *table); table->name = xstrdup(name); RB_INIT(&table->key_bindings); + RB_INIT(&table->default_key_bindings); table->references = 1; /* one reference in key_tables */ RB_INSERT(key_tables, &key_tables, table); @@ -138,8 +138,14 @@ key_bindings_unref_table(struct key_table *table) if (--table->references != 0) return; - RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1) - key_bindings_free(table, bd); + RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1) { + RB_REMOVE(key_bindings, &table->key_bindings, bd); + key_bindings_free(bd); + } + RB_FOREACH_SAFE(bd, key_bindings, &table->default_key_bindings, bd1) { + RB_REMOVE(key_bindings, &table->default_key_bindings, bd); + key_bindings_free(bd); + } free((void *)table->name); free(table); @@ -155,6 +161,15 @@ key_bindings_get(struct key_table *table, key_code key) } struct key_binding * +key_bindings_get_default(struct key_table *table, key_code key) +{ + struct key_binding bd; + + bd.key = key; + return (RB_FIND(key_bindings, &table->default_key_bindings, &bd)); +} + +struct key_binding * key_bindings_first(struct key_table *table) { return (RB_MIN(key_bindings, &table->key_bindings)); @@ -176,8 +191,10 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat, table = key_bindings_get_table(name, 1); bd = key_bindings_get(table, key & ~KEYC_XTERM); - if (bd != NULL) - key_bindings_free(table, bd); + if (bd != NULL) { + RB_REMOVE(key_bindings, &table->key_bindings, bd); + key_bindings_free(bd); + } bd = xcalloc(1, sizeof *bd); bd->key = key; @@ -203,9 +220,12 @@ key_bindings_remove(const char *name, key_code key) bd = key_bindings_get(table, key & ~KEYC_XTERM); if (bd == NULL) return; - key_bindings_free(table, bd); - if (RB_EMPTY(&table->key_bindings)) { + RB_REMOVE(key_bindings, &table->key_bindings, bd); + key_bindings_free(bd); + + if (RB_EMPTY(&table->key_bindings) && + RB_EMPTY(&table->default_key_bindings)) { RB_REMOVE(key_tables, &key_tables, table); key_bindings_unref_table(table); } @@ -228,6 +248,28 @@ key_bindings_remove_table(const char *name) } } +static enum cmd_retval +key_bindings_init_done(__unused struct cmdq_item *item, __unused void *data) +{ + struct key_table *table; + struct key_binding *bd, *new_bd; + + RB_FOREACH(table, key_tables, &key_tables) { + RB_FOREACH(bd, key_bindings, &table->key_bindings) { + new_bd = xcalloc(1, sizeof *bd); + new_bd->key = bd->key; + if (bd->note != NULL) + new_bd->note = xstrdup(bd->note); + new_bd->flags = bd->flags; + new_bd->cmdlist = bd->cmdlist; + new_bd->cmdlist->references++; + RB_INSERT(key_bindings, &table->default_key_bindings, + new_bd); + } + } + return (CMD_RETURN_NORMAL); +} + void key_bindings_init(void) { @@ -278,6 +320,7 @@ key_bindings_init(void) "bind -N 'Toggle the marked pane' m select-pane -m", "bind -N 'Select the next window' n next-window", "bind -N 'Select the next pane' o select-pane -t:.+", + "bind -N 'Customize options' C customize-mode -Z", "bind -N 'Select the previous pane' p previous-window", "bind -N 'Display pane numbers' q display-panes", "bind -N 'Redraw the current client' r refresh-client", @@ -524,6 +567,7 @@ key_bindings_init(void) cmdq_append(NULL, cmdq_get_command(pr->cmdlist, NULL)); cmd_list_free(pr->cmdlist); } + cmdq_append(NULL, cmdq_get_callback(key_bindings_init_done, NULL)); } static enum cmd_retval diff --git a/mode-tree.c b/mode-tree.c index b3b3f335..131830d6 100644 --- a/mode-tree.c +++ b/mode-tree.c @@ -45,6 +45,7 @@ struct mode_tree_data { mode_tree_draw_cb drawcb; mode_tree_search_cb searchcb; mode_tree_menu_cb menucb; + mode_tree_height_cb heightcb; struct mode_tree_list children; struct mode_tree_list saved; @@ -79,6 +80,7 @@ struct mode_tree_item { int expanded; int tagged; + int draw_as_parent; struct mode_tree_list children; TAILQ_ENTRY(mode_tree_item) entry; @@ -210,7 +212,7 @@ mode_tree_clear_tagged(struct mode_tree_list *mtl) } } -static void +void mode_tree_up(struct mode_tree_data *mtd, int wrap) { if (mtd->current == 0) { @@ -247,6 +249,12 @@ mode_tree_get_current(struct mode_tree_data *mtd) return (mtd->line_list[mtd->current].item->itemdata); } +const char * +mode_tree_get_current_name(struct mode_tree_data *mtd) +{ + return (mtd->line_list[mtd->current].item->name); +} + void mode_tree_expand_current(struct mode_tree_data *mtd) { @@ -256,6 +264,15 @@ mode_tree_expand_current(struct mode_tree_data *mtd) } } +void +mode_tree_collapse_current(struct mode_tree_data *mtd) +{ + if (mtd->line_list[mtd->current].item->expanded) { + mtd->line_list[mtd->current].item->expanded = 0; + mode_tree_build(mtd); + } +} + static int mode_tree_get_tag(struct mode_tree_data *mtd, uint64_t tag, u_int *found) { @@ -343,7 +360,8 @@ mode_tree_each_tagged(struct mode_tree_data *mtd, mode_tree_each_cb cb, struct mode_tree_data * mode_tree_start(struct window_pane *wp, struct args *args, mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb, - mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, void *modedata, + mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, + mode_tree_height_cb heightcb, void *modedata, const struct menu_item *menu, const char **sort_list, u_int sort_size, struct screen **s) { @@ -381,6 +399,7 @@ mode_tree_start(struct window_pane *wp, struct args *args, mtd->drawcb = drawcb; mtd->searchcb = searchcb; mtd->menucb = menucb; + mtd->heightcb = heightcb; TAILQ_INIT(&mtd->children); @@ -404,6 +423,27 @@ mode_tree_zoom(struct mode_tree_data *mtd, struct args *args) mtd->zoomed = -1; } +static void +mode_tree_set_height(struct mode_tree_data *mtd) +{ + struct screen *s = &mtd->screen; + u_int height; + + if (mtd->heightcb != NULL) { + height = mtd->heightcb(mtd, screen_size_y(s)); + if (height < screen_size_y(s)) + mtd->height = screen_size_y(s) - height; + } else { + mtd->height = (screen_size_y(s) / 3) * 2; + if (mtd->height > mtd->line_size) + mtd->height = screen_size_y(s) / 2; + } + if (mtd->height < 10) + mtd->height = screen_size_y(s); + if (screen_size_y(s) - mtd->height < 2) + mtd->height = screen_size_y(s); +} + void mode_tree_build(struct mode_tree_data *mtd) { @@ -434,15 +474,9 @@ mode_tree_build(struct mode_tree_data *mtd) mode_tree_set_current(mtd, tag); mtd->width = screen_size_x(s); - if (mtd->preview) { - mtd->height = (screen_size_y(s) / 3) * 2; - if (mtd->height > mtd->line_size) - mtd->height = screen_size_y(s) / 2; - if (mtd->height < 10) - mtd->height = screen_size_y(s); - if (screen_size_y(s) - mtd->height < 2) - mtd->height = screen_size_y(s); - } else + if (mtd->preview) + mode_tree_set_height(mtd); + else mtd->height = screen_size_y(s); mode_tree_check_selected(mtd); } @@ -494,7 +528,7 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent, struct mode_tree_item *mti, *saved; log_debug("%s: %llu, %s %s", __func__, (unsigned long long)tag, - name, text); + name, (text == NULL ? "" : text)); mti = xcalloc(1, sizeof *mti); mti->parent = parent; @@ -502,7 +536,8 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent, mti->tag = tag; mti->name = xstrdup(name); - mti->text = xstrdup(text); + if (text != NULL) + mti->text = xstrdup(text); saved = mode_tree_find_item(&mtd->saved, tag); if (saved != NULL) { @@ -525,6 +560,12 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent, } void +mode_tree_draw_as_parent(struct mode_tree_item *mti) +{ + mti->draw_as_parent = 1; +} + +void mode_tree_remove(struct mode_tree_data *mtd, struct mode_tree_item *mti) { struct mode_tree_item *parent = mti->parent; @@ -621,8 +662,8 @@ mode_tree_draw(struct mode_tree_data *mtd) tag = "*"; else tag = ""; - xasprintf(&text, "%-*s%s%s%s: ", keylen, key, start, mti->name, - tag); + xasprintf(&text, "%-*s%s%s%s%s", keylen, key, start, mti->name, + tag, (mti->text != NULL) ? ": " : "" ); width = utf8_cstrwidth(text); if (width > w) width = w; @@ -636,11 +677,17 @@ mode_tree_draw(struct mode_tree_data *mtd) if (i != mtd->current) { screen_write_clearendofline(&ctx, 8); screen_write_nputs(&ctx, w, &gc0, "%s", text); - format_draw(&ctx, &gc0, w - width, mti->text, NULL); + if (mti->text != NULL) { + format_draw(&ctx, &gc0, w - width, mti->text, + NULL); + } } else { screen_write_clearendofline(&ctx, gc.bg); screen_write_nputs(&ctx, w, &gc, "%s", text); - format_draw(&ctx, &gc, w - width, mti->text, NULL); + if (mti->text != NULL) { + format_draw(&ctx, &gc, w - width, mti->text, + NULL); + } } free(text); @@ -658,13 +705,18 @@ mode_tree_draw(struct mode_tree_data *mtd) line = &mtd->line_list[mtd->current]; mti = line->item; + if (mti->draw_as_parent) + mti = mti->parent; screen_write_cursormove(&ctx, 0, h, 0); screen_write_box(&ctx, w, sy - h); - xasprintf(&text, " %s (sort: %s%s)", mti->name, - mtd->sort_list[mtd->sort_crit.field], - mtd->sort_crit.reversed ? ", reversed" : ""); + if (mtd->sort_list != NULL) { + xasprintf(&text, " %s (sort: %s%s)", mti->name, + mtd->sort_list[mtd->sort_crit.field], + mtd->sort_crit.reversed ? ", reversed" : ""); + } else + xasprintf(&text, " %s", mti->name); if (w - 2 >= strlen(text)) { screen_write_cursormove(&ctx, 1, h, 0); screen_write_puts(&ctx, &gc0, "%s", text); @@ -680,7 +732,8 @@ mode_tree_draw(struct mode_tree_data *mtd) else screen_write_puts(&ctx, &gc0, "active"); screen_write_puts(&ctx, &gc0, ") "); - } + } else + screen_write_puts(&ctx, &gc0, " "); } free(text); @@ -1027,7 +1080,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, break; case 'O': mtd->sort_crit.field++; - if (mtd->sort_crit.field == mtd->sort_size) + if (mtd->sort_crit.field >= mtd->sort_size) mtd->sort_crit.field = 0; mode_tree_build(mtd); break; diff --git a/options-table.c b/options-table.c index 320a380f..55eb5b9f 100644 --- a/options-table.c +++ b/options-table.c @@ -103,9 +103,9 @@ static const char *options_table_window_size_list[] = { "," \ "#[range=window|#{window_index} list=focus " \ "#{?#{!=:#{window-status-current-style},default}," \ - "#{window-status-current-style}," \ - "#{window-status-style}" \ - "}" \ + "#{window-status-current-style}," \ + "#{window-status-style}" \ + "}" \ "#{?#{&&:#{window_last_flag}," \ "#{!=:#{window-status-last-style},default}}, " \ "#{window-status-last-style}," \ @@ -175,6 +175,7 @@ const struct options_table_entry options_table[] = { .type = OPTIONS_TABLE_KEY, .scope = OPTIONS_TABLE_SERVER, .default_num = '\177', + .text = "The key to send for backspace." }, { .name = "buffer-limit", @@ -182,7 +183,9 @@ const struct options_table_entry options_table[] = { .scope = OPTIONS_TABLE_SERVER, .minimum = 1, .maximum = INT_MAX, - .default_num = 50 + .default_num = 50, + .text = "The maximum number of automatic buffers. " + "When this is reached, the oldest buffer is deleted." }, { .name = "command-alias", @@ -195,25 +198,31 @@ const struct options_table_entry options_table[] = { "info=show-messages -JT," "choose-window=choose-tree -w," "choose-session=choose-tree -s", - .separator = "," + .separator = ",", + .text = "Array of command aliases. " + "Each entry is an alias and a command separated by '='." }, { .name = "copy-command", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SERVER, - .default_str = "" + .default_str = "", + .text = "Shell command run when text is copied. " + "If empty, no command is run." }, { .name = "default-terminal", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SERVER, - .default_str = "screen" + .default_str = "screen", + .text = "Default for the 'TERM' environment variable." }, { .name = "editor", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SERVER, - .default_str = _PATH_VI + .default_str = _PATH_VI, + .text = "Editor run to edit files." }, { .name = "escape-time", @@ -221,31 +230,38 @@ const struct options_table_entry options_table[] = { .scope = OPTIONS_TABLE_SERVER, .minimum = 0, .maximum = INT_MAX, - .default_num = 500 + .default_num = 500, + .text = "Time to wait before assuming a key is Escape." }, { .name = "exit-empty", .type = OPTIONS_TABLE_FLAG, .scope = OPTIONS_TABLE_SERVER, - .default_num = 1 + .default_num = 1, + .text = "Whether the server should exit if there are no sessions." }, { .name = "exit-unattached", .type = OPTIONS_TABLE_FLAG, .scope = OPTIONS_TABLE_SERVER, - .default_num = 0 + .default_num = 0, + .text = "Whether the server should exit if there are no attached " + "clients." }, { .name = "focus-events", .type = OPTIONS_TABLE_FLAG, .scope = OPTIONS_TABLE_SERVER, - .default_num = 0 + .default_num = 0, + .text = "Whether to send focus events to applications." }, { .name = "history-file", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SERVER, - .default_str = "" + .default_str = "", + .text = "Location of the command prompt history file. " + "Empty does not write a history file." }, { .name = "message-limit", @@ -253,14 +269,18 @@ const struct options_table_entry options_table[] = { .scope = OPTIONS_TABLE_SERVER, .minimum = 0, .maximum = INT_MAX, - .default_num = 1000 + .default_num = 1000, + .text = "Maximum number of server messages to keep." }, { .name = "set-clipboard", .type = OPTIONS_TABLE_CHOICE, .scope = OPTIONS_TABLE_SERVER, .choices = options_table_set_clipboard_list, - .default_num = 1 + .default_num = 1, + .text = "Whether to attempt to set the system clipboard ('on' or " + "'external') and whether to allow applications to create " + "paste buffers with an escape sequence ('on' only)." }, { .name = "terminal-overrides", @@ -268,7 +288,8 @@ const struct options_table_entry options_table[] = { .scope = OPTIONS_TABLE_SERVER, .flags = OPTIONS_TABLE_IS_ARRAY, .default_str = "", - .separator = "," + .separator = ",", + .text = "List of terminal capabilities overrides." }, { .name = "terminal-features", @@ -276,8 +297,10 @@ const struct options_table_entry options_table[] = { .scope = OPTIONS_TABLE_SERVER, .flags = OPTIONS_TABLE_IS_ARRAY, .default_str = "xterm*:clipboard:ccolour:cstyle:title," |