mirror of
https://github.com/tmux/tmux.git
synced 2026-10-13 14:24:28 +00:00
Add a key to change an array key in customize mode.
This commit is contained in:
@@ -82,15 +82,15 @@ enum window_customize_change {
|
||||
};
|
||||
|
||||
struct window_customize_itemdata {
|
||||
struct window_customize_modedata *data;
|
||||
enum window_customize_scope scope;
|
||||
struct window_customize_modedata *data;
|
||||
enum window_customize_scope scope;
|
||||
|
||||
char *table;
|
||||
key_code key;
|
||||
char *table;
|
||||
key_code key;
|
||||
|
||||
struct options *oo;
|
||||
char *name;
|
||||
int idx;
|
||||
struct options *oo;
|
||||
char *name;
|
||||
char *array_key;
|
||||
};
|
||||
|
||||
struct window_customize_modedata {
|
||||
@@ -111,15 +111,17 @@ struct window_customize_modedata {
|
||||
};
|
||||
|
||||
static uint64_t
|
||||
window_customize_get_tag(struct options_entry *o, int idx,
|
||||
window_customize_get_tag(struct options_entry *o, struct options_array_item *a,
|
||||
const struct options_table_entry *oe)
|
||||
{
|
||||
uint64_t offset;
|
||||
|
||||
if (a != NULL)
|
||||
return ((uint64_t)(uintptr_t)a);
|
||||
if (oe == NULL)
|
||||
return ((uint64_t)o);
|
||||
offset = ((char *)oe - (char *)options_table) / sizeof *options_table;
|
||||
return ((2ULL << 62)|(offset << 32)|((idx + 1) << 1)|1);
|
||||
return ((2ULL << 62)|(offset << 32)|1);
|
||||
}
|
||||
|
||||
static struct options *
|
||||
@@ -224,6 +226,7 @@ window_customize_free_item(struct window_customize_itemdata *item)
|
||||
{
|
||||
free(item->table);
|
||||
free(item->name);
|
||||
free(item->array_key);
|
||||
free(item);
|
||||
}
|
||||
|
||||
@@ -237,26 +240,26 @@ window_customize_build_array(struct window_customize_modedata *data,
|
||||
struct window_customize_itemdata *item;
|
||||
struct options_array_item *ai;
|
||||
char *name, *value, *text;
|
||||
u_int idx;
|
||||
uint64_t tag;
|
||||
const char *array_key;
|
||||
|
||||
ai = options_array_first(o);
|
||||
while (ai != NULL) {
|
||||
idx = options_array_item_index(ai);
|
||||
array_key = options_array_item_key(ai);
|
||||
|
||||
xasprintf(&name, "%s[%u]", options_name(o), idx);
|
||||
xasprintf(&name, "%s[%s]", options_name(o), array_key);
|
||||
format_add(ft, "option_name", "%s", name);
|
||||
value = options_to_string(o, idx, 0);
|
||||
value = options_to_string(o, array_key, 0);
|
||||
format_add(ft, "option_value", "%s", value);
|
||||
|
||||
item = window_customize_add_item(data);
|
||||
item->scope = scope;
|
||||
item->oo = oo;
|
||||
item->name = xstrdup(options_name(o));
|
||||
item->idx = idx;
|
||||
item->array_key = xstrdup(array_key);
|
||||
|
||||
text = format_expand(ft, data->format);
|
||||
tag = window_customize_get_tag(o, idx, oe);
|
||||
tag = window_customize_get_tag(o, ai, oe);
|
||||
mode_tree_add(data->data, top, item, tag, name, text, -1);
|
||||
free(text);
|
||||
|
||||
@@ -307,7 +310,7 @@ window_customize_build_option(struct window_customize_modedata *data,
|
||||
format_add(ft, "option_unit", "%s", "");
|
||||
|
||||
if (!array) {
|
||||
value = options_to_string(o, -1, 0);
|
||||
value = options_to_string(o, NULL, 0);
|
||||
format_add(ft, "option_value", "%s", value);
|
||||
free(value);
|
||||
}
|
||||
@@ -324,13 +327,12 @@ window_customize_build_option(struct window_customize_modedata *data,
|
||||
item->oo = oo;
|
||||
item->scope = scope;
|
||||
item->name = xstrdup(name);
|
||||
item->idx = -1;
|
||||
|
||||
if (array)
|
||||
text = NULL;
|
||||
else
|
||||
text = format_expand(ft, data->format);
|
||||
tag = window_customize_get_tag(o, -1, oe);
|
||||
tag = window_customize_get_tag(o, NULL, oe);
|
||||
top = mode_tree_add(data->data, top, item, tag, name, text, 0);
|
||||
free(text);
|
||||
|
||||
@@ -483,7 +485,6 @@ window_customize_build_keys(struct window_customize_modedata *data,
|
||||
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,
|
||||
@@ -653,12 +654,12 @@ window_customize_draw_option(struct window_customize_modedata *data,
|
||||
{
|
||||
struct screen *s = ctx->s;
|
||||
u_int cx = s->cx, cy = s->cy;
|
||||
int idx;
|
||||
struct options_entry *o, *parent;
|
||||
struct options *go, *wo;
|
||||
const struct options_table_entry *oe;
|
||||
struct grid_cell gc;
|
||||
const char **choice, *text, *name;
|
||||
const char *array_key;
|
||||
const char *space = "", *unit = "";
|
||||
char *value = NULL, *expanded;
|
||||
char *default_value = NULL;
|
||||
@@ -669,7 +670,7 @@ window_customize_draw_option(struct window_customize_modedata *data,
|
||||
if (!window_customize_check_item(data, item, &fs))
|
||||
return;
|
||||
name = item->name;
|
||||
idx = item->idx;
|
||||
array_key = item->array_key;
|
||||
|
||||
o = options_get(item->oo, name);
|
||||
if (o == NULL)
|
||||
@@ -708,25 +709,25 @@ window_customize_draw_option(struct window_customize_modedata *data,
|
||||
&grid_default_cell, "This is a %s option.", text))
|
||||
goto out;
|
||||
if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_ARRAY)) {
|
||||
if (idx != -1) {
|
||||
if (array_key != NULL) {
|
||||
if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy),
|
||||
0, &grid_default_cell,
|
||||
"This is an array option, index %u.", idx))
|
||||
"This is an array option, key %s.", array_key))
|
||||
goto out;
|
||||
} else {
|
||||
if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy),
|
||||
0, &grid_default_cell, "This is an array option."))
|
||||
goto out;
|
||||
}
|
||||
if (idx == -1)
|
||||
if (array_key == NULL)
|
||||
goto out;
|
||||
}
|
||||
screen_write_cursormove(ctx, cx, s->cy + 1, 0); /* skip line */
|
||||
if (s->cy >= cy + sy - 1)
|
||||
goto out;
|
||||
|
||||
value = options_to_string(o, idx, 0);
|
||||
if (oe != NULL && idx == -1) {
|
||||
value = options_to_string(o, array_key, 0);
|
||||
if (oe != NULL && array_key == NULL) {
|
||||
default_value = options_default_to_string(oe);
|
||||
if (strcmp(default_value, value) == 0) {
|
||||
free(default_value);
|
||||
@@ -820,7 +821,7 @@ window_customize_draw_option(struct window_customize_modedata *data,
|
||||
if (wo != NULL && options_owner(o) != wo) {
|
||||
parent = options_get_only(wo, name);
|
||||
if (parent != NULL) {
|
||||
value = options_to_string(parent, -1 , 0);
|
||||
value = options_to_string(parent, NULL, 0);
|
||||
if (!screen_write_text(ctx, s->cx, sx,
|
||||
sy - (s->cy - cy), 0, &grid_default_cell,
|
||||
"Window value (from window %u): %s%s%s", fs.wl->idx,
|
||||
@@ -831,7 +832,7 @@ window_customize_draw_option(struct window_customize_modedata *data,
|
||||
if (go != NULL && options_owner(o) != go) {
|
||||
parent = options_get_only(go, name);
|
||||
if (parent != NULL) {
|
||||
value = options_to_string(parent, -1 , 0);
|
||||
value = options_to_string(parent, NULL, 0);
|
||||
if (!screen_write_text(ctx, s->cx, sx,
|
||||
sy - (s->cy - cy), 0, &grid_default_cell,
|
||||
"Global value: %s%s%s", value, space, unit))
|
||||
@@ -896,6 +897,8 @@ static const char* window_customize_help_lines[] = {
|
||||
"#[fg=themelightgrey]"
|
||||
" U #[#{E:tree-mode-border-style},acs]x#[default] Unset tagged %1s",
|
||||
"#[fg=themelightgrey]"
|
||||
" a #[#{E:tree-mode-border-style},acs]x#[default] Change array key",
|
||||
"#[fg=themelightgrey]"
|
||||
" f #[#{E:tree-mode-border-style},acs]x#[default] Enter a filter",
|
||||
"#[fg=themelightgrey]"
|
||||
" v #[#{E:tree-mode-border-style},acs]x#[default] Toggle information",
|
||||
@@ -1007,8 +1010,10 @@ window_customize_set_option_callback(struct client *c, void *itemdata,
|
||||
const struct options_table_entry *oe;
|
||||
struct options *oo = item->oo;
|
||||
const char *name = item->name;
|
||||
const char *array_key = item->array_key;
|
||||
char *cause;
|
||||
int idx = item->idx;
|
||||
u_int idx;
|
||||
char keybuf[32];
|
||||
|
||||
if (s == NULL || *s == '\0' || data->dead)
|
||||
return (PROMPT_CLOSE);
|
||||
@@ -1020,13 +1025,15 @@ window_customize_set_option_callback(struct client *c, void *itemdata,
|
||||
oe = options_table_entry(o);
|
||||
|
||||
if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_ARRAY)) {
|
||||
if (idx == -1) {
|
||||
if (array_key == NULL) {
|
||||
for (idx = 0; idx < INT_MAX; idx++) {
|
||||
if (options_array_get(o, idx) == NULL)
|
||||
if (options_array_getv(o, "%u", idx) == NULL)
|
||||
break;
|
||||
}
|
||||
xsnprintf(keybuf, sizeof keybuf, "%u", idx);
|
||||
array_key = keybuf;
|
||||
}
|
||||
if (options_array_set(o, idx, s, 0, &cause) != 0)
|
||||
if (options_array_set(o, array_key, s, 0, &cause) != 0)
|
||||
goto fail;
|
||||
} else {
|
||||
if (options_from_string(oo, oe, name, s, 0, &cause) != 0)
|
||||
@@ -1056,10 +1063,11 @@ window_customize_set_option(struct client *c,
|
||||
const struct options_table_entry *oe;
|
||||
struct options *oo;
|
||||
struct window_customize_itemdata *new_item;
|
||||
int flag, idx = item->idx;
|
||||
int flag;
|
||||
enum window_customize_scope scope = WINDOW_CUSTOMIZE_NONE;
|
||||
u_int choice;
|
||||
const char *name = item->name, *space = "";
|
||||
const char *array_key = item->array_key;
|
||||
char *prompt, *value, *text;
|
||||
struct cmd_find_state fs;
|
||||
|
||||
@@ -1142,25 +1150,26 @@ window_customize_set_option(struct client *c,
|
||||
else if (scope != WINDOW_CUSTOMIZE_SERVER)
|
||||
space = ", global";
|
||||
if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_ARRAY)) {
|
||||
if (idx == -1) {
|
||||
if (array_key == NULL) {
|
||||
xasprintf(&prompt, "(%s[+]%s%s) ", name, space,
|
||||
text);
|
||||
} else {
|
||||
xasprintf(&prompt, "(%s[%d]%s%s) ", name, idx,
|
||||
space, text);
|
||||
xasprintf(&prompt, "(%s[%s]%s%s) ", name,
|
||||
array_key, space, text);
|
||||
}
|
||||
} else
|
||||
xasprintf(&prompt, "(%s%s%s) ", name, space, text);
|
||||
free(text);
|
||||
|
||||
value = options_to_string(o, idx, 0);
|
||||
value = options_to_string(o, array_key, 0);
|
||||
|
||||
new_item = xcalloc(1, sizeof *new_item);
|
||||
new_item->data = data;
|
||||
new_item->scope = scope;
|
||||
new_item->oo = oo;
|
||||
new_item->name = xstrdup(name);
|
||||
new_item->idx = idx;
|
||||
if (array_key != NULL)
|
||||
new_item->array_key = xstrdup(array_key);
|
||||
|
||||
data->references++;
|
||||
mode_tree_set_prompt(data->data, c, prompt, value,
|
||||
@@ -1173,6 +1182,84 @@ window_customize_set_option(struct client *c,
|
||||
}
|
||||
}
|
||||
|
||||
static enum prompt_result
|
||||
window_customize_set_array_key_callback(struct client *c, void *itemdata,
|
||||
const char *s, __unused enum prompt_key_result key)
|
||||
{
|
||||
struct window_customize_itemdata *item = itemdata;
|
||||
struct window_customize_modedata *data;
|
||||
struct options_entry *o;
|
||||
const char *name, *array_key;
|
||||
char *value, *cause;
|
||||
|
||||
if (item == NULL)
|
||||
return (PROMPT_CLOSE);
|
||||
data = item->data;
|
||||
if (s == NULL || *s == '\0' || data->dead)
|
||||
return (PROMPT_CLOSE);
|
||||
name = item->name;
|
||||
array_key = item->array_key;
|
||||
if (array_key == NULL || !window_customize_check_item(data, item, NULL))
|
||||
return (PROMPT_CLOSE);
|
||||
|
||||
o = options_get(item->oo, name);
|
||||
if (o == NULL)
|
||||
return (PROMPT_CLOSE);
|
||||
if (options_array_get(o, s) != NULL)
|
||||
return (PROMPT_CLOSE);
|
||||
|
||||
value = options_to_string(o, array_key, 0);
|
||||
if (options_array_set(o, s, value, 0, &cause) != 0)
|
||||
goto fail;
|
||||
free(value);
|
||||
|
||||
options_array_set(o, array_key, NULL, 0, NULL);
|
||||
options_push_changes(item->name);
|
||||
mode_tree_build(data->data);
|
||||
mode_tree_draw(data->data);
|
||||
data->wp->flags |= PANE_REDRAW;
|
||||
|
||||
return (PROMPT_CLOSE);
|
||||
|
||||
fail:
|
||||
free(value);
|
||||
*cause = toupper((u_char)*cause);
|
||||
status_message_set(c, -1, 1, 0, 0, "%s", cause);
|
||||
free(cause);
|
||||
return (PROMPT_CLOSE);
|
||||
}
|
||||
|
||||
static void
|
||||
window_customize_set_array_key(struct client *c,
|
||||
struct window_customize_modedata *data,
|
||||
struct window_customize_itemdata *item)
|
||||
{
|
||||
struct window_customize_itemdata *new_item;
|
||||
char *prompt;
|
||||
|
||||
if (item == NULL ||
|
||||
item->array_key == NULL ||
|
||||
!window_customize_check_item(data, item, NULL))
|
||||
return;
|
||||
|
||||
xasprintf(&prompt, "(%s[%s]) ", item->name, item->array_key);
|
||||
|
||||
new_item = xcalloc(1, sizeof *new_item);
|
||||
new_item->data = data;
|
||||
new_item->scope = item->scope;
|
||||
new_item->oo = item->oo;
|
||||
new_item->name = xstrdup(item->name);
|
||||
new_item->array_key = xstrdup(item->array_key);
|
||||
|
||||
data->references++;
|
||||
mode_tree_set_prompt(data->data, c, prompt, item->array_key,
|
||||
PROMPT_TYPE_COMMAND, PROMPT_NOFORMAT,
|
||||
window_customize_set_array_key_callback,
|
||||
window_customize_free_item_callback, new_item);
|
||||
|
||||
free(prompt);
|
||||
}
|
||||
|
||||
static void
|
||||
window_customize_unset_option(struct window_customize_modedata *data,
|
||||
struct window_customize_itemdata *item)
|
||||
@@ -1185,9 +1272,10 @@ window_customize_unset_option(struct window_customize_modedata *data,
|
||||
o = options_get(item->oo, item->name);
|
||||
if (o == NULL)
|
||||
return;
|
||||
if (item->idx != -1 && item == mode_tree_get_current(data->data))
|
||||
if (item->array_key != NULL &&
|
||||
item == mode_tree_get_current(data->data))
|
||||
mode_tree_up(data->data, 0);
|
||||
options_remove_or_default(o, item->idx, NULL);
|
||||
options_remove_or_default(o, item->array_key, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1199,14 +1287,14 @@ window_customize_reset_option(struct window_customize_modedata *data,
|
||||
|
||||
if (item == NULL || !window_customize_check_item(data, item, NULL))
|
||||
return;
|
||||
if (item->idx != -1)
|
||||
if (item->array_key != NULL)
|
||||
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);
|
||||
options_remove_or_default(o, NULL, NULL);
|
||||
oo = options_get_parent(oo);
|
||||
}
|
||||
}
|
||||
@@ -1452,7 +1540,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, idx;
|
||||
int finished;
|
||||
char *prompt;
|
||||
u_int tagged;
|
||||
|
||||
@@ -1462,6 +1550,11 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
||||
item = new_item;
|
||||
|
||||
switch (key) {
|
||||
case 'a':
|
||||
if (item == NULL || item->scope == WINDOW_CUSTOMIZE_KEY)
|
||||
break;
|
||||
window_customize_set_array_key(c, data, item);
|
||||
break;
|
||||
case '\r':
|
||||
case 's':
|
||||
if (item == NULL)
|
||||
@@ -1490,7 +1583,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
||||
mode_tree_build(data->data);
|
||||
break;
|
||||
case 'd':
|
||||
if (item == NULL || item->idx != -1)
|
||||
if (item == NULL || item->array_key != NULL)
|
||||
break;
|
||||
xasprintf(&prompt, "Reset %s to default? ", item->name);
|
||||
data->references++;
|
||||
@@ -1519,10 +1612,10 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
||||
case 'u':
|
||||
if (item == NULL)
|
||||
break;
|
||||
idx = item->idx;
|
||||
if (idx != -1)
|
||||
xasprintf(&prompt, "Unset %s[%d]? ", item->name, idx);
|
||||
else
|
||||
if (item->array_key != NULL) {
|
||||
xasprintf(&prompt, "Unset %s[%s]? ", item->name,
|
||||
item->array_key);
|
||||
} else
|
||||
xasprintf(&prompt, "Unset %s? ", item->name);
|
||||
data->references++;
|
||||
data->change = WINDOW_CUSTOMIZE_UNSET;
|
||||
|
||||
Reference in New Issue
Block a user