summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2020-06-16 08:18:34 +0000
committernicm <nicm>2020-06-16 08:18:34 +0000
commit1bf9555e4f1ad19e1e6f97ede6fb19808ff1c267 (patch)
tree517c3ac9fd211c1294523af5f9e11104ae41edaa
parentafe4ea4250073e482c6ec6accfc539f873df6977 (diff)
d and D keys to reset to default in customize mode.
-rw-r--r--cmd-set-option.c11
-rw-r--r--input.c8
-rw-r--r--key-bindings.c49
-rw-r--r--mode-tree.c15
-rw-r--r--options.c21
-rw-r--r--tmux.12
-rw-r--r--tmux.h6
-rw-r--r--window-customize.c164
8 files changed, 222 insertions, 54 deletions
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 36579f29..0df12aa0 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -151,16 +151,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'u')) {
if (o == NULL)
goto out;
- if (idx == -1) {
- if (*name == '@')
- options_remove(o);
- else if (oo == global_options ||
- oo == global_s_options ||
- oo == global_w_options)
- options_default(oo, options_table_entry(o));
- else
- options_remove(o);
- } else if (options_array_set(o, idx, NULL, 0, &cause) != 0) {
+ if (options_remove_or_default(o, idx, &cause) != 0) {
cmdq_error(item, "%s", cause);
free(cause);
goto fail;
diff --git a/input.c b/input.c
index 46d8734d..a3850371 100644
--- a/input.c
+++ b/input.c
@@ -2347,7 +2347,7 @@ static void
input_exit_rename(struct input_ctx *ictx)
{
struct window_pane *wp = ictx->wp;
- struct options_entry *oe;
+ struct options_entry *o;
if (wp == NULL)
return;
@@ -2361,9 +2361,9 @@ input_exit_rename(struct input_ctx *ictx)
return;
if (ictx->input_len == 0) {
- oe = options_get_only(wp->window->options, "automatic-rename");
- if (oe != NULL)
- options_remove(oe);
+ o = options_get_only(wp->window->options, "automatic-rename");
+ if (o != NULL)
+ options_remove_or_default(o, -1, NULL);
return;
}
window_set_name(wp->window, ictx->input_buf);
diff --git a/key-bindings.c b/key-bindings.c
index 9e198123..f11bb430 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -232,6 +232,38 @@ key_bindings_remove(const char *name, key_code key)
}
void
+key_bindings_reset(const char *name, key_code key)
+{
+ struct key_table *table;
+ struct key_binding *bd, *dd;
+
+ table = key_bindings_get_table(name, 0);
+ if (table == NULL)
+ return;
+
+ bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
+ if (bd == NULL)
+ return;
+
+ dd = key_bindings_get_default(table, bd->key);
+ if (dd == NULL) {
+ key_bindings_remove(name, bd->key);
+ return;
+ }
+
+ cmd_list_free(bd->cmdlist);
+ bd->cmdlist = dd->cmdlist;
+ bd->cmdlist->references++;
+
+ free((void *)bd->note);
+ if (dd->note != NULL)
+ bd->note = xstrdup(dd->note);
+ else
+ bd->note = NULL;
+ bd->flags = dd->flags;
+}
+
+void
key_bindings_remove_table(const char *name)
{
struct key_table *table;
@@ -248,6 +280,23 @@ key_bindings_remove_table(const char *name)
}
}
+void
+key_bindings_reset_table(const char *name)
+{
+ struct key_table *table;
+ struct key_binding *bd, *bd1;
+
+ table = key_bindings_get_table(name, 0);
+ if (table == NULL)
+ return;
+ if (RB_EMPTY(&table->default_key_bindings)) {
+ key_bindings_remove_table(name);
+ return;
+ }
+ RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1)
+ key_bindings_reset(name, bd->key);
+}
+
static enum cmd_retval
key_bindings_init_done(__unused struct cmdq_item *item, __unused void *data)
{
diff --git a/mode-tree.c b/mode-tree.c
index 993070ec..c4b776f9 100644
--- a/mode-tree.c
+++ b/mode-tree.c
@@ -80,7 +80,9 @@ struct mode_tree_item {
int expanded;
int tagged;
+
int draw_as_parent;
+ int no_tag;
struct mode_tree_list children;
TAILQ_ENTRY(mode_tree_item) entry;
@@ -566,6 +568,12 @@ mode_tree_draw_as_parent(struct mode_tree_item *mti)
}
void
+mode_tree_no_tag(struct mode_tree_item *mti)
+{
+ mti->no_tag = 1;
+}
+
+void
mode_tree_remove(struct mode_tree_data *mtd, struct mode_tree_item *mti)
{
struct mode_tree_item *parent = mti->parent;
@@ -1053,6 +1061,8 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
* Do not allow parents and children to both be tagged: untag
* all parents and children of current.
*/
+ if (current->no_tag)
+ break;
if (!current->tagged) {
parent = current->parent;
while (parent != NULL) {
@@ -1072,7 +1082,10 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
break;
case '\024': /* C-t */
for (i = 0; i < mtd->line_size; i++) {
- if (mtd->line_list[i].item->parent == NULL)
+ if ((mtd->line_list[i].item->parent == NULL &&
+ !mtd->line_list[i].item->no_tag) ||
+ (mtd->line_list[i].item->parent != NULL &&
+ mtd->line_list[i].item->parent->no_tag))
mtd->line_list[i].item->tagged = 1;
else
mtd->line_list[i].item->tagged = 0;
diff --git a/options.c b/options.c
index 6ed38bcd..336eb732 100644
--- a/options.c
+++ b/options.c
@@ -66,6 +66,7 @@ struct options {
};
static struct options_entry *options_add(struct options *, const char *);
+static void options_remove(struct options_entry *);
#define OPTIONS_IS_STRING(o) \
((o)->tableentry == NULL || \
@@ -315,7 +316,7 @@ options_add(struct options *oo, const char *name)
return (o);
}
-void
+static void
options_remove(struct options_entry *o)
{
struct options *oo = o->owner;
@@ -1106,3 +1107,21 @@ options_push_changes(const char *name)
server_redraw_client(loop);
}
}
+
+int
+options_remove_or_default(struct options_entry *o, int idx, char **cause)
+{
+ struct options *oo = o->owner;
+
+ if (idx == -1) {
+ if (o->tableentry != NULL &&
+ (oo == global_options ||
+ oo == global_s_options ||
+ oo == global_w_options))
+ options_default(oo, o->tableentry);
+ else
+ options_remove(o);
+ } else if (options_array_set(o, idx, NULL, 0, cause) != 0)
+ return (-1);
+ return (0);
+}
diff --git a/tmux.1 b/tmux.1
index d6fd1c85..3c017e64 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2031,6 +2031,8 @@ The following keys may be used in customize mode:
.It Li "s" Ta "Set option value or key attribute"
.It Li "S" Ta "Set global option value"
.It Li "w" Ta "Set window option value, if option is for pane and window"
+.It Li "d" Ta "Set an option or key to the default"
+.It Li "D" Ta "Set tagged options and tagged keys to the default"
.It Li "u" Ta "Unset an option (set to default value if global) or unbind a key"
.It Li "U" Ta "Unset tagged options and unbind tagged keys"
.It Li "C-s" Ta "Search by name"
diff --git a/tmux.h b/tmux.h
index 9bc89628..837566ca 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1988,7 +1988,6 @@ struct options *options_owner(struct options_entry *);
const struct options_table_entry *options_table_entry(struct options_entry *);
struct options_entry *options_get_only(struct options *, const char *);
struct options_entry *options_get(struct options *, const char *);
-void options_remove(struct options_entry *);
void options_array_clear(struct options_entry *);
union options_value *options_array_get(struct options_entry *, u_int);
int options_array_set(struct options_entry *, u_int, const char *,
@@ -2025,6 +2024,8 @@ int options_from_string(struct options *,
const struct options_table_entry *, const char *,
const char *, int, char **);
void options_push_changes(const char *);
+int options_remove_or_default(struct options_entry *, int,
+ char **);
/* options-table.c */
extern const struct options_table_entry options_table[];
@@ -2325,7 +2326,9 @@ struct key_binding *key_bindings_next(struct key_table *, struct key_binding *);
void key_bindings_add(const char *, key_code, const char *, int,
struct cmd_list *);
void key_bindings_remove(const char *, key_code);
+void key_bindings_reset(const char *, key_code);
void key_bindings_remove_table(const char *);
+void key_bindings_reset_table(const char *);
void key_bindings_init(void);
struct cmdq_item *key_bindings_dispatch(struct key_binding *,
struct cmdq_item *, struct client *, struct key_event *,
@@ -2802,6 +2805,7 @@ struct mode_tree_item *mode_tree_add(struct mode_tree_data *,
struct mode_tree_item *, void *, uint64_t, const char *,
const char *, int);
void mode_tree_draw_as_parent(struct mode_tree_item *);
+void mode_tree_no_tag(struct mode_tree_item *);
void mode_tree_remove(struct mode_tree_data *, struct mode_tree_item *);
void mode_tree_draw(struct mode_tree_data *);
int mode_tree_key(struct mode_tree_data *, struct client *, key_code *,
diff --git a/window-customize.c b/window-customize.c
index 093ebbe4..f60d2e6e 100644
--- a/window-customize.c
+++ b/window-customize.c
@@ -76,6 +76,11 @@ enum window_customize_scope {
WINDOW_CUSTOMIZE_PANE
};
+enum window_customize_change {
+ WINDOW_CUSTOMIZE_UNSET,
+ WINDOW_CUSTOMIZE_RESET,
+};
+
struct window_customize_itemdata {
struct window_customize_modedata *data;
enum window_customize_scope scope;
@@ -101,6 +106,7 @@ struct window_customize_modedata {
u_int item_size;
struct cmd_find_state fs;
+ enum window_customize_change change;
};
static uint64_t
@@ -380,6 +386,7 @@ window_customize_build_options(struct window_customize_modedata *data,
enum window_customize_scope scope;
top = mode_tree_add(data->data, NULL, NULL, tag, title, NULL, 0);
+ mode_tree_no_tag(top);
/*
* We get the options from the first tree, but build it using the
@@ -452,6 +459,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
xasprintf(&title, "Key Table - %s", kt->name);
top = mode_tree_add(data->data, NULL, NULL, tag, title, NULL, 0);
+ mode_tree_no_tag(top);
free(title);
ft = format_create_from_state(NULL, NULL, fs);
@@ -476,6 +484,8 @@ window_customize_build_keys(struct window_customize_modedata *data,
item->scope = WINDOW_CUSTOMIZE_KEY;
item->table = xstrdup(kt->name);
item->key = bd->key;
+ item->name = xstrdup(key_string_lookup_key(item->key, 0));
+ item->idx = -1;
expanded = format_expand(ft, data->format);
child = mode_tree_add(data->data, top, item, (uint64_t)bd,
@@ -488,6 +498,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
mti = mode_tree_add(data->data, child, item,
tag|(bd->key << 3)|(0 << 1)|1, "Command", text, -1);
mode_tree_draw_as_parent(mti);
+ mode_tree_no_tag(mti);
free(text);
if (bd->note != NULL)
@@ -497,6 +508,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
mti = mode_tree_add(data->data, child, item,
tag|(bd->key << 3)|(1 << 1)|1, "Note", text, -1);
mode_tree_draw_as_parent(mti);
+ mode_tree_no_tag(mti);
free(text);
if (bd->flags & KEY_BINDING_REPEAT)
@@ -506,6 +518,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
mti = mode_tree_add(data->data, child, item,
tag|(bd->key << 3)|(2 << 1)|1, "Repeat", flag, -1);
mode_tree_draw_as_parent(mti);
+ mode_tree_no_tag(mti);
bd = key_bindings_next(kt, bd);
}
@@ -1125,8 +1138,7 @@ static void
window_customize_unset_option(struct window_customize_modedata *data,
struct window_customize_itemdata *item)
{
- struct options_entry *o;
- const struct options_table_entry *oe;
+ struct options_entry *o;
if (item == NULL || !window_customize_check_item(data, item, NULL))
return;
@@ -1134,20 +1146,30 @@ window_customize_unset_option(struct window_customize_modedata *data,
o = options_get(item->oo, item->name);
if (o == NULL)
return;
- if (item->idx != -1) {
- if (item == mode_tree_get_current(data->data))
- mode_tree_up(data->data, 0);
- options_array_set(o, item->idx, NULL, 0, NULL);
+ if (item->idx != -1 && item == mode_tree_get_current(data->data))
+ mode_tree_up(data->data, 0);
+ options_remove_or_default(o, item->idx, NULL);
+}
+
+static void
+window_customize_reset_option(struct window_customize_modedata *data,
+ struct window_customize_itemdata *item)
+{
+ struct options *oo;
+ struct options_entry *o;
+
+ if (item == NULL || !window_customize_check_item(data, item, NULL))
+ return;
+ if (item->idx != -1)
return;
+
+ oo = item->oo;
+ while (oo != NULL) {
+ o = options_get_only(item->oo, item->name);
+ if (o != NULL)
+ options_remove_or_default(o, -1, NULL);
+ oo = options_get_parent(oo);
}
- oe = options_table_entry(o);
- if (oe != NULL &&
- options_owner(o) != global_options &&
- options_owner(o) != global_s_options &&
- options_owner(o) != global_w_options)
- options_remove(o);
- else
- options_default(options_owner(o), oe);
}
static int
@@ -1286,21 +1308,52 @@ window_customize_unset_key(struct window_customize_modedata *data,
}
static void
-window_customize_unset_each(void *modedata, void *itemdata,
+window_customize_reset_key(struct window_customize_modedata *data,
+ struct window_customize_itemdata *item)
+{
+ struct key_table *kt;
+ struct key_binding *dd, *bd;
+
+ if (item == NULL || !window_customize_get_key(item, &kt, &bd))
+ return;
+
+ dd = key_bindings_get_default(kt, bd->key);
+ if (dd != NULL && bd->cmdlist == dd->cmdlist)
+ return;
+ if (dd == NULL && item == mode_tree_get_current(data->data)) {
+ mode_tree_collapse_current(data->data);
+ mode_tree_up(data->data, 0);
+ }
+ key_bindings_reset(kt->name, bd->key);
+}
+
+static void
+window_customize_change_each(void *modedata, void *itemdata,
__unused struct client *c, __unused key_code key)
{
+ struct window_customize_modedata *data = modedata;
struct window_customize_itemdata *item = itemdata;
- if (item->scope == WINDOW_CUSTOMIZE_KEY)
- window_customize_unset_key(modedata, item);
- else {
- window_customize_unset_option(modedata, item);
- options_push_changes(item->name);
+ switch (data->change) {
+ case WINDOW_CUSTOMIZE_UNSET:
+ if (item->scope == WINDOW_CUSTOMIZE_KEY)
+ window_customize_unset_key(data, item);
+ else
+ window_customize_unset_option(data, item);
+ break;
+ case WINDOW_CUSTOMIZE_RESET:
+ if (item->scope == WINDOW_CUSTOMIZE_KEY)
+ window_customize_reset_key(data, item);
+ else
+ window_customize_reset_option(data, item);
+ break;
}
+ if (item->scope != WINDOW_CUSTOMIZE_KEY)
+ options_push_changes(item->name);
}
static int
-window_customize_unset_current_callback(__unused struct client *c,
+window_customize_change_current_callback(__unused struct client *c,
void *modedata, const char *s, __unused int done)
{
struct window_customize_modedata *data = modedata;
@@ -1312,12 +1365,22 @@ window_customize_unset_current_callback(__unused struct client *c,
return (0);
item = mode_tree_get_current(data->data);
- if (item->scope == WINDOW_CUSTOMIZE_KEY)
- window_customize_unset_key(data, item);
- else {
- window_customize_unset_option(data, item);
- options_push_changes(item->name);
+ switch (data->change) {
+ case WINDOW_CUSTOMIZE_UNSET:
+ if (item->scope == WINDOW_CUSTOMIZE_KEY)
+ window_customize_unset_key(data, item);
+ else
+ window_customize_unset_option(data, item);
+ break;
+ case WINDOW_CUSTOMIZE_RESET:
+ if (item->scope == WINDOW_CUSTOMIZE_KEY)
+ window_customize_reset_key(data, item);
+ else
+ window_customize_reset_option(data, item);
+ break;
}
+ if (item->scope != WINDOW_CUSTOMIZE_KEY)
+ options_push_changes(item->name);
mode_tree_build(data->data);
mode_tree_draw(data->data);
data->wp->flags |= PANE_REDRAW;
@@ -1326,7 +1389,7 @@ window_customize_unset_current_callback(__unused struct client *c,
}
static int
-window_customize_unset_tagged_callback(struct client *c, void *modedata,
+window_customize_change_tagged_callback(struct client *c, void *modedata,
const char *s, __unused int done)
{
struct window_customize_modedata *data = modedata;
@@ -1336,7 +1399,7 @@ window_customize_unset_tagged_callback(struct client *c, void *modedata,
if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
return (0);
- mode_tree_each_tagged(data->data, window_customize_unset_each, c,
+ mode_tree_each_tagged(data->data, window_customize_change_each, c,
KEYC_NONE, 0);
mode_tree_build(data->data);
mode_tree_draw(data->data);
@@ -1353,7 +1416,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
struct window_pane *wp = wme->wp;
struct window_customize_modedata *data = wme->data;
struct window_customize_itemdata *item, *new_item;
- int finished;
+ int finished, idx;
char *prompt;
u_int tagged;
@@ -1390,17 +1453,43 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
options_push_changes(item->name);
mode_tree_build(data->data);
break;
+ case 'd':
+ if (item == NULL || item->idx != -1)
+ break;
+ xasprintf(&prompt, "Reset %s to default? ", item->name);
+ data->references++;
+ data->change = WINDOW_CUSTOMIZE_RESET;
+ status_prompt_set(c, NULL, prompt, "",
+ window_customize_change_current_callback,
+ window_customize_free_callback, data,
+ PROMPT_SINGLE|PROMPT_NOFORMAT);
+ free(prompt);
+ break;
+ case 'D':
+ tagged = mode_tree_count_tagged(data->data);
+ if (tagged == 0)
+ break;
+ xasprintf(&prompt, "Reset %u tagged to default? ", tagged);
+ data->references++;
+ data->change = WINDOW_CUSTOMIZE_RESET;
+ status_prompt_set(c, NULL, prompt, "",
+ window_customize_change_tagged_callback,
+ window_customize_free_callback, data,
+ PROMPT_SINGLE|PROMPT_NOFORMAT);
+ free(prompt);
+ break;
case 'u':
if (item == NULL)
break;
- if (item->scope == WINDOW_CUSTOMIZE_KEY) {
- xasprintf(&prompt, "Unbind key %s? ",
- key_string_lookup_key(item->key, 0));
- } else
- xasprintf(&prompt, "Unset option %s? ", item->name);
+ idx = item->idx;
+ if (idx != -1)
+ xasprintf(&prompt, "Unset %s[%d]? ", item->name, idx);
+ else
+ xasprintf(&prompt, "Unset %s? ", item->name);
data->references++;
+ data->change = WINDOW_CUSTOMIZE_UNSET;
status_prompt_set(c, NULL, prompt, "",
- window_customize_unset_current_callback,
+ window_customize_change_current_callback,
window_customize_free_callback, data,
PROMPT_SINGLE|PROMPT_NOFORMAT);
free(prompt);
@@ -1409,10 +1498,11 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
tagged = mode_tree_count_tagged(data->data);
if (tagged == 0)
break;
- xasprintf(&prompt, "Unset or unbind %u tagged? ", tagged);
+ xasprintf(&prompt, "Unset %u tagged? ", tagged);
data->references++;
+ data->change = WINDOW_CUSTOMIZE_UNSET;
status_prompt_set(c, NULL, prompt, "",
- window_customize_unset_tagged_callback,
+ window_customize_change_tagged_callback,
window_customize_free_callback, data,
PROMPT_SINGLE|PROMPT_NOFORMAT);
free(prompt);