mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Merge branch 'master' of github.com:tmux/tmux
This commit is contained in:
		@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
@@ -154,6 +160,15 @@ key_bindings_get(struct key_table *table, key_code key)
 | 
			
		||||
	return (RB_FIND(key_bindings, &table->key_bindings, &bd));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
@@ -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)
 | 
			
		||||
{
 | 
			
		||||
@@ -525,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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								mode-tree.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								mode-tree.c
									
									
									
									
									
								
							@@ -80,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;
 | 
			
		||||
@@ -248,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)
 | 
			
		||||
{
 | 
			
		||||
@@ -257,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)
 | 
			
		||||
{
 | 
			
		||||
@@ -512,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;
 | 
			
		||||
@@ -543,6 +559,12 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent,
 | 
			
		||||
	return (mti);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
@@ -683,6 +705,8 @@ 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);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								tmux.1
									
									
									
									
									
								
							@@ -1970,8 +1970,8 @@ This command works only if at least one client is attached.
 | 
			
		||||
.Op Fl t Ar target-pane
 | 
			
		||||
.Op Ar template
 | 
			
		||||
.Xc
 | 
			
		||||
Put a pane into customize mode, where options may be browsed and modified from a
 | 
			
		||||
list.
 | 
			
		||||
Put a pane into customize mode, where options and key bindings may be browsed
 | 
			
		||||
and modified from a list.
 | 
			
		||||
Option values in the list are shown for the active pane in the current window.
 | 
			
		||||
.Fl Z
 | 
			
		||||
zooms the pane.
 | 
			
		||||
@@ -1985,11 +1985,11 @@ The following keys may be used in customize mode:
 | 
			
		||||
.It Li "-" Ta "Collapse selected item"
 | 
			
		||||
.It Li "M-+" Ta "Expand all items"
 | 
			
		||||
.It Li "M--" Ta "Collapse all items"
 | 
			
		||||
.It Li "s" Ta "Set pane, window, session or global option value"
 | 
			
		||||
.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 "u" Ta "Unset an option (set to default value if global)"
 | 
			
		||||
.It Li "U" Ta "Unset tagged options"
 | 
			
		||||
.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"
 | 
			
		||||
.It Li "n" Ta "Repeat last search"
 | 
			
		||||
.It Li "t" Ta "Toggle if item is tagged"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1669,6 +1669,7 @@ RB_HEAD(key_bindings, key_binding);
 | 
			
		||||
struct key_table {
 | 
			
		||||
	const char		*name;
 | 
			
		||||
	struct key_bindings	 key_bindings;
 | 
			
		||||
	struct key_bindings	 default_key_bindings;
 | 
			
		||||
 | 
			
		||||
	u_int			 references;
 | 
			
		||||
 | 
			
		||||
@@ -2245,6 +2246,7 @@ struct key_table *key_bindings_first_table(void);
 | 
			
		||||
struct key_table *key_bindings_next_table(struct key_table *);
 | 
			
		||||
void	 key_bindings_unref_table(struct key_table *);
 | 
			
		||||
struct key_binding *key_bindings_get(struct key_table *, key_code);
 | 
			
		||||
struct key_binding *key_bindings_get_default(struct key_table *, key_code);
 | 
			
		||||
struct key_binding *key_bindings_first(struct key_table *);
 | 
			
		||||
struct key_binding *key_bindings_next(struct key_table *, struct key_binding *);
 | 
			
		||||
void	 key_bindings_add(const char *, key_code, const char *, int,
 | 
			
		||||
@@ -2698,7 +2700,9 @@ typedef u_int (*mode_tree_height_cb)(void *, u_int);
 | 
			
		||||
typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code);
 | 
			
		||||
u_int	 mode_tree_count_tagged(struct mode_tree_data *);
 | 
			
		||||
void	*mode_tree_get_current(struct mode_tree_data *);
 | 
			
		||||
const char *mode_tree_get_current_name(struct mode_tree_data *);
 | 
			
		||||
void	 mode_tree_expand_current(struct mode_tree_data *);
 | 
			
		||||
void	 mode_tree_collapse_current(struct mode_tree_data *);
 | 
			
		||||
void	 mode_tree_expand(struct mode_tree_data *, uint64_t);
 | 
			
		||||
int	 mode_tree_set_current(struct mode_tree_data *, uint64_t);
 | 
			
		||||
void	 mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb,
 | 
			
		||||
@@ -2716,6 +2720,7 @@ void	 mode_tree_resize(struct mode_tree_data *, u_int, u_int);
 | 
			
		||||
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_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 *,
 | 
			
		||||
 
 | 
			
		||||
@@ -34,9 +34,13 @@ static void		 window_customize_key(struct window_mode_entry *,
 | 
			
		||||
			     struct winlink *, key_code, struct mouse_event *);
 | 
			
		||||
 | 
			
		||||
#define WINDOW_CUSTOMIZE_DEFAULT_FORMAT \
 | 
			
		||||
	"#{?option_is_global,,#[reverse](#{option_scope})#[default] }" \
 | 
			
		||||
	"#[ignore]" \
 | 
			
		||||
	"#{option_value}#{?option_unit, #{option_unit},}"
 | 
			
		||||
	"#{?is_option," \
 | 
			
		||||
		"#{?option_is_global,,#[reverse](#{option_scope})#[default] }" \
 | 
			
		||||
		"#[ignore]" \
 | 
			
		||||
		"#{option_value}#{?option_unit, #{option_unit},}" \
 | 
			
		||||
	"," \
 | 
			
		||||
		"#{key}" \
 | 
			
		||||
	"}"
 | 
			
		||||
 | 
			
		||||
static const struct menu_item window_customize_menu_items[] = {
 | 
			
		||||
	{ "Select", '\r', NULL },
 | 
			
		||||
@@ -63,6 +67,7 @@ const struct window_mode window_customize_mode = {
 | 
			
		||||
 | 
			
		||||
enum window_customize_scope {
 | 
			
		||||
	WINDOW_CUSTOMIZE_NONE,
 | 
			
		||||
	WINDOW_CUSTOMIZE_KEY,
 | 
			
		||||
	WINDOW_CUSTOMIZE_SERVER,
 | 
			
		||||
	WINDOW_CUSTOMIZE_GLOBAL_SESSION,
 | 
			
		||||
	WINDOW_CUSTOMIZE_SESSION,
 | 
			
		||||
@@ -74,6 +79,10 @@ enum window_customize_scope {
 | 
			
		||||
struct window_customize_itemdata {
 | 
			
		||||
	struct window_customize_modedata	*data;
 | 
			
		||||
	enum window_customize_scope		 scope;
 | 
			
		||||
 | 
			
		||||
	char					*table;
 | 
			
		||||
	key_code				 key;
 | 
			
		||||
 | 
			
		||||
	struct options				*oo;
 | 
			
		||||
	char					*name;
 | 
			
		||||
	int					 idx;
 | 
			
		||||
@@ -82,7 +91,7 @@ struct window_customize_itemdata {
 | 
			
		||||
struct window_customize_modedata {
 | 
			
		||||
	struct window_pane			 *wp;
 | 
			
		||||
	int					  dead;
 | 
			
		||||
	int			 		  references;
 | 
			
		||||
	int					  references;
 | 
			
		||||
 | 
			
		||||
	struct mode_tree_data			 *data;
 | 
			
		||||
	char					 *format;
 | 
			
		||||
@@ -103,7 +112,7 @@ window_customize_get_tag(struct options_entry *o, int idx,
 | 
			
		||||
	if (oe == NULL)
 | 
			
		||||
		return ((uint64_t)o);
 | 
			
		||||
	offset = ((char *)oe - (char *)options_table) / sizeof *options_table;
 | 
			
		||||
	return ((offset << 32) | ((idx + 1) << 1) | 1);
 | 
			
		||||
	return ((2ULL << 62)|(offset << 32)|((idx + 1) << 1)|1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct options *
 | 
			
		||||
@@ -112,6 +121,7 @@ window_customize_get_tree(enum window_customize_scope scope,
 | 
			
		||||
{
 | 
			
		||||
	switch (scope) {
 | 
			
		||||
	case WINDOW_CUSTOMIZE_NONE:
 | 
			
		||||
	case WINDOW_CUSTOMIZE_KEY:
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	case WINDOW_CUSTOMIZE_SERVER:
 | 
			
		||||
		return (global_options);
 | 
			
		||||
@@ -145,6 +155,27 @@ window_customize_check_item(struct window_customize_modedata *data,
 | 
			
		||||
	return (item->oo == window_customize_get_tree(item->scope, fsp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
window_customize_get_key(struct window_customize_itemdata *item,
 | 
			
		||||
    struct key_table **ktp, struct key_binding **bdp)
 | 
			
		||||
{
 | 
			
		||||
	struct key_table	*kt;
 | 
			
		||||
	struct key_binding	*bd;
 | 
			
		||||
 | 
			
		||||
	kt = key_bindings_get_table(item->table, 0);
 | 
			
		||||
	if (kt == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	bd = key_bindings_get(kt, item->key);
 | 
			
		||||
	if (bd == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	if (ktp != NULL)
 | 
			
		||||
		*ktp = kt;
 | 
			
		||||
	if (bdp != NULL)
 | 
			
		||||
		*bdp = bd;
 | 
			
		||||
	return (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
window_customize_scope_text(enum window_customize_scope scope,
 | 
			
		||||
    struct cmd_find_state *fs)
 | 
			
		||||
@@ -154,6 +185,7 @@ window_customize_scope_text(enum window_customize_scope scope,
 | 
			
		||||
 | 
			
		||||
	switch (scope) {
 | 
			
		||||
	case WINDOW_CUSTOMIZE_NONE:
 | 
			
		||||
	case WINDOW_CUSTOMIZE_KEY:
 | 
			
		||||
	case WINDOW_CUSTOMIZE_SERVER:
 | 
			
		||||
	case WINDOW_CUSTOMIZE_GLOBAL_SESSION:
 | 
			
		||||
	case WINDOW_CUSTOMIZE_GLOBAL_WINDOW:
 | 
			
		||||
@@ -187,6 +219,7 @@ window_customize_add_item(struct window_customize_modedata *data)
 | 
			
		||||
static void
 | 
			
		||||
window_customize_free_item(struct window_customize_itemdata *item)
 | 
			
		||||
{
 | 
			
		||||
	free(item->table);
 | 
			
		||||
	free(item->name);
 | 
			
		||||
	free(item);
 | 
			
		||||
}
 | 
			
		||||
@@ -403,15 +436,93 @@ window_customize_build_options(struct window_customize_modedata *data,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_build_keys(struct window_customize_modedata *data,
 | 
			
		||||
    struct key_table *kt, struct format_tree *ft, const char *filter,
 | 
			
		||||
    struct cmd_find_state *fs, u_int number)
 | 
			
		||||
{
 | 
			
		||||
	struct mode_tree_item			*top, *child, *mti;
 | 
			
		||||
	struct window_customize_itemdata	*item;
 | 
			
		||||
	struct key_binding			*bd;
 | 
			
		||||
	char					*title, *text, *tmp, *expanded;
 | 
			
		||||
	const char				*flag;
 | 
			
		||||
	uint64_t				 tag;
 | 
			
		||||
 | 
			
		||||
	tag = (1ULL << 62)|((uint64_t)number << 54)|1;
 | 
			
		||||
 | 
			
		||||
	xasprintf(&title, "Key Table - %s", kt->name);
 | 
			
		||||
	top = mode_tree_add(data->data, NULL, NULL, tag, title, NULL, 0);
 | 
			
		||||
	free(title);
 | 
			
		||||
 | 
			
		||||
	ft = format_create_from_state(NULL, NULL, fs);
 | 
			
		||||
	format_add(ft, "is_option", "0");
 | 
			
		||||
	format_add(ft, "is_key", "1");
 | 
			
		||||
 | 
			
		||||
	bd = key_bindings_first(kt);
 | 
			
		||||
	while (bd != NULL) {
 | 
			
		||||
		format_add(ft, "key", "%s", key_string_lookup_key(bd->key));
 | 
			
		||||
		if (bd->note != NULL)
 | 
			
		||||
			format_add(ft, "key_note", "%s", bd->note);
 | 
			
		||||
		if (filter != NULL) {
 | 
			
		||||
			expanded = format_expand(ft, filter);
 | 
			
		||||
			if (!format_true(expanded)) {
 | 
			
		||||
				free(expanded);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			free(expanded);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		item = window_customize_add_item(data);
 | 
			
		||||
		item->scope = WINDOW_CUSTOMIZE_KEY;
 | 
			
		||||
		item->table = xstrdup(kt->name);
 | 
			
		||||
		item->key = bd->key;
 | 
			
		||||
 | 
			
		||||
		expanded = format_expand(ft, data->format);
 | 
			
		||||
		child = mode_tree_add(data->data, top, item, (uint64_t)bd,
 | 
			
		||||
		    expanded, NULL, 0);
 | 
			
		||||
		free(expanded);
 | 
			
		||||
 | 
			
		||||
		tmp = cmd_list_print(bd->cmdlist, 0);
 | 
			
		||||
		xasprintf(&text, "#[ignore]%s", tmp);
 | 
			
		||||
		free(tmp);
 | 
			
		||||
		mti = mode_tree_add(data->data, child, item,
 | 
			
		||||
		    tag|(bd->key << 3)|(0 << 1)|1, "Command", text, -1);
 | 
			
		||||
		mode_tree_draw_as_parent(mti);
 | 
			
		||||
		free(text);
 | 
			
		||||
 | 
			
		||||
		if (bd->note != NULL)
 | 
			
		||||
			xasprintf(&text, "#[ignore]%s", bd->note);
 | 
			
		||||
		else
 | 
			
		||||
			text = xstrdup("");
 | 
			
		||||
		mti = mode_tree_add(data->data, child, item,
 | 
			
		||||
		    tag|(bd->key << 3)|(1 << 1)|1, "Note", text, -1);
 | 
			
		||||
		mode_tree_draw_as_parent(mti);
 | 
			
		||||
		free(text);
 | 
			
		||||
 | 
			
		||||
		if (bd->flags & KEY_BINDING_REPEAT)
 | 
			
		||||
			flag = "on";
 | 
			
		||||
		else
 | 
			
		||||
			flag = "off";
 | 
			
		||||
		mti = mode_tree_add(data->data, child, item,
 | 
			
		||||
		    tag|(bd->key << 3)|(2 << 1)|1, "Repeat", flag, -1);
 | 
			
		||||
		mode_tree_draw_as_parent(mti);
 | 
			
		||||
 | 
			
		||||
		bd = key_bindings_next(kt, bd);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	format_free(ft);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_build(void *modedata,
 | 
			
		||||
    __unused struct mode_tree_sort_criteria *sort_crit, __unused uint64_t *tag,
 | 
			
		||||
    const char *filter)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_modedata	*data = modedata;
 | 
			
		||||
	struct cmd_find_state		 fs;
 | 
			
		||||
	struct format_tree		*ft;
 | 
			
		||||
	u_int				 i;
 | 
			
		||||
	struct cmd_find_state			 fs;
 | 
			
		||||
	struct format_tree			*ft;
 | 
			
		||||
	u_int					 i;
 | 
			
		||||
	struct key_table			*kt;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < data->item_size; i++)
 | 
			
		||||
		window_customize_free_item(data->item_list[i]);
 | 
			
		||||
@@ -425,35 +536,110 @@ window_customize_build(void *modedata,
 | 
			
		||||
		cmd_find_from_pane(&fs, data->wp, 0);
 | 
			
		||||
 | 
			
		||||
	ft = format_create_from_state(NULL, NULL, &fs);
 | 
			
		||||
	format_add(ft, "is_option", "1");
 | 
			
		||||
	format_add(ft, "is_key", "0");
 | 
			
		||||
 | 
			
		||||
	window_customize_build_options(data, "Server Options",
 | 
			
		||||
	    (1ULL << 63)|OPTIONS_TABLE_SERVER,
 | 
			
		||||
	    (3ULL << 62)|(OPTIONS_TABLE_SERVER << 1)|1,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_SERVER, global_options,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_NONE, NULL,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_NONE, NULL,
 | 
			
		||||
	    ft, filter, &fs);
 | 
			
		||||
	window_customize_build_options(data, "Session Options",
 | 
			
		||||
	    (1ULL << 63)|OPTIONS_TABLE_SESSION,
 | 
			
		||||
	    (3ULL << 62)|(OPTIONS_TABLE_SESSION << 1)|1,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_GLOBAL_SESSION, global_s_options,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_SESSION, fs.s->options,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_NONE, NULL,
 | 
			
		||||
	    ft, filter, &fs);
 | 
			
		||||
	window_customize_build_options(data, "Window & Pane Options",
 | 
			
		||||
	    (1ULL << 63)|OPTIONS_TABLE_WINDOW,
 | 
			
		||||
	    (3ULL << 62)|(OPTIONS_TABLE_WINDOW << 1)|1,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_GLOBAL_WINDOW, global_w_options,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_WINDOW, fs.w->options,
 | 
			
		||||
	    WINDOW_CUSTOMIZE_PANE, fs.wp->options,
 | 
			
		||||
	    ft, filter, &fs);
 | 
			
		||||
 | 
			
		||||
	format_free(ft);
 | 
			
		||||
	ft = format_create_from_state(NULL, NULL, &fs);
 | 
			
		||||
 | 
			
		||||
	i = 0;
 | 
			
		||||
	kt = key_bindings_first_table();
 | 
			
		||||
	while (kt != NULL) {
 | 
			
		||||
		if (!RB_EMPTY(&kt->key_bindings)) {
 | 
			
		||||
			window_customize_build_keys(data, kt, ft, filter, &fs,
 | 
			
		||||
			    i);
 | 
			
		||||
			if (++i == 256)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		kt = key_bindings_next_table(kt);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	format_free(ft);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_draw(void *modedata, void *itemdata,
 | 
			
		||||
    struct screen_write_ctx *ctx, u_int sx, u_int sy)
 | 
			
		||||
window_customize_draw_key(__unused struct window_customize_modedata *data,
 | 
			
		||||
    struct window_customize_itemdata *item, struct screen_write_ctx *ctx,
 | 
			
		||||
    u_int sx, u_int sy)
 | 
			
		||||
{
 | 
			
		||||
	struct screen		*s = ctx->s;
 | 
			
		||||
	u_int			 cx = s->cx, cy = s->cy;
 | 
			
		||||
	struct key_table	*kt;
 | 
			
		||||
	struct key_binding	*bd, *default_bd;
 | 
			
		||||
	const char		*note, *period = "";
 | 
			
		||||
	char			*cmd, *default_cmd;
 | 
			
		||||
 | 
			
		||||
	if (item == NULL || !window_customize_get_key(item, &kt, &bd))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	note = bd->note;
 | 
			
		||||
	if (note == NULL)
 | 
			
		||||
		note = "There is no note for this key.";
 | 
			
		||||
	if (*note != '\0' && note[strlen (note) - 1] != '.')
 | 
			
		||||
		period = ".";
 | 
			
		||||
	if (!screen_write_text(ctx, cx, sx, sy, 0, &grid_default_cell, "%s%s",
 | 
			
		||||
	    note, period))
 | 
			
		||||
		return;
 | 
			
		||||
	screen_write_cursormove(ctx, cx, s->cy + 1, 0); /* skip line */
 | 
			
		||||
	if (s->cy >= cy + sy - 1)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0,
 | 
			
		||||
	    &grid_default_cell, "This key is in the %s table.", kt->name))
 | 
			
		||||
		return;
 | 
			
		||||
	if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0,
 | 
			
		||||
	    &grid_default_cell, "This key %s repeat.",
 | 
			
		||||
	    (bd->flags & KEY_BINDING_REPEAT) ? "does" : "does not"))
 | 
			
		||||
		return;
 | 
			
		||||
	screen_write_cursormove(ctx, cx, s->cy + 1, 0); /* skip line */
 | 
			
		||||
	if (s->cy >= cy + sy - 1)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	cmd = cmd_list_print(bd->cmdlist, 0);
 | 
			
		||||
	if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0,
 | 
			
		||||
	    &grid_default_cell, "Command: %s", cmd)) {
 | 
			
		||||
		free(cmd);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	default_bd = key_bindings_get_default(kt, bd->key);
 | 
			
		||||
	if (default_bd != NULL) {
 | 
			
		||||
		default_cmd = cmd_list_print(default_bd->cmdlist, 0);
 | 
			
		||||
		if (strcmp(cmd, default_cmd) != 0 &&
 | 
			
		||||
		    !screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0,
 | 
			
		||||
		    &grid_default_cell, "The default is: %s", default_cmd)) {
 | 
			
		||||
			free(default_cmd);
 | 
			
		||||
			free(cmd);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		free(default_cmd);
 | 
			
		||||
	}
 | 
			
		||||
	free(cmd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_draw_option(struct window_customize_modedata *data,
 | 
			
		||||
    struct window_customize_itemdata *item, struct screen_write_ctx *ctx,
 | 
			
		||||
    u_int sx, u_int sy)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_modedata	 *data = modedata;
 | 
			
		||||
	struct window_customize_itemdata	 *item = itemdata;
 | 
			
		||||
	struct screen				 *s = ctx->s;
 | 
			
		||||
	u_int					  cx = s->cx, cy = s->cy;
 | 
			
		||||
	int					  idx;
 | 
			
		||||
@@ -469,7 +655,7 @@ window_customize_draw(void *modedata, void *itemdata,
 | 
			
		||||
	struct cmd_find_state			  fs;
 | 
			
		||||
	struct format_tree			 *ft;
 | 
			
		||||
 | 
			
		||||
	if (item == NULL || !window_customize_check_item(data, item, &fs))
 | 
			
		||||
	if (!window_customize_check_item(data, item, &fs))
 | 
			
		||||
		return;
 | 
			
		||||
	name = item->name;
 | 
			
		||||
	idx = item->idx;
 | 
			
		||||
@@ -622,7 +808,7 @@ window_customize_draw(void *modedata, void *itemdata,
 | 
			
		||||
				goto out;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 	if (go != NULL && options_owner(o) != go) {
 | 
			
		||||
	if (go != NULL && options_owner(o) != go) {
 | 
			
		||||
		parent = options_get_only(go, name);
 | 
			
		||||
		if (parent != NULL) {
 | 
			
		||||
			value = options_to_string(parent, -1 , 0);
 | 
			
		||||
@@ -639,6 +825,22 @@ out:
 | 
			
		||||
	format_free(ft);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_draw(void *modedata, void *itemdata,
 | 
			
		||||
    struct screen_write_ctx *ctx, u_int sx, u_int sy)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_modedata	*data = modedata;
 | 
			
		||||
	struct window_customize_itemdata	*item = itemdata;
 | 
			
		||||
 | 
			
		||||
	if (item == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (item->scope == WINDOW_CUSTOMIZE_KEY)
 | 
			
		||||
		window_customize_draw_key(data, item, ctx, sx, sy);
 | 
			
		||||
	else
 | 
			
		||||
		window_customize_draw_option(data, item, ctx, sx, sy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_menu(void *modedata, struct client *c, key_code key)
 | 
			
		||||
{
 | 
			
		||||
@@ -727,14 +929,30 @@ window_customize_resize(struct window_mode_entry *wme, u_int sx, u_int sy)
 | 
			
		||||
	mode_tree_resize(data->data, sx, sy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_free_callback(void *modedata)
 | 
			
		||||
{
 | 
			
		||||
	window_customize_destroy(modedata);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_free_item_callback(void *itemdata)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_itemdata	*item = itemdata;
 | 
			
		||||
	struct window_customize_modedata	*data = item->data;
 | 
			
		||||
 | 
			
		||||
	window_customize_free_item(item);
 | 
			
		||||
	window_customize_destroy(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
window_customize_set_callback(struct client *c, void *itemdata, const char *s,
 | 
			
		||||
    __unused int done)
 | 
			
		||||
window_customize_set_option_callback(struct client *c, void *itemdata,
 | 
			
		||||
    const char *s, __unused int done)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_itemdata	*item = itemdata;
 | 
			
		||||
	struct window_customize_modedata	*data = item->data;
 | 
			
		||||
	struct options_entry			*o;
 | 
			
		||||
 	const struct options_table_entry	*oe;
 | 
			
		||||
	const struct options_table_entry	*oe;
 | 
			
		||||
	struct options				*oo = item->oo;
 | 
			
		||||
	const char				*name = item->name;
 | 
			
		||||
	char					*cause;
 | 
			
		||||
@@ -778,17 +996,8 @@ fail:
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_set_free(void *itemdata)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_itemdata	*item = itemdata;
 | 
			
		||||
	struct window_customize_modedata	*data = item->data;
 | 
			
		||||
 | 
			
		||||
	window_customize_free_item(item);
 | 
			
		||||
	window_customize_destroy(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_set_option(struct client *c, struct window_customize_modedata *data,
 | 
			
		||||
window_customize_set_option(struct client *c,
 | 
			
		||||
    struct window_customize_modedata *data,
 | 
			
		||||
    struct window_customize_itemdata *item, int global, int pane)
 | 
			
		||||
{
 | 
			
		||||
	struct options_entry			*o;
 | 
			
		||||
@@ -807,7 +1016,6 @@ window_customize_set_option(struct client *c, struct window_customize_modedata *
 | 
			
		||||
	o = options_get(item->oo, name);
 | 
			
		||||
	if (o == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	value = options_to_string(o, idx, 0);
 | 
			
		||||
 | 
			
		||||
	oe = options_table_entry(o);
 | 
			
		||||
	if (~oe->scope & OPTIONS_TABLE_PANE)
 | 
			
		||||
@@ -819,6 +1027,7 @@ window_customize_set_option(struct client *c, struct window_customize_modedata *
 | 
			
		||||
		if (global) {
 | 
			
		||||
			switch (item->scope) {
 | 
			
		||||
			case WINDOW_CUSTOMIZE_NONE:
 | 
			
		||||
			case WINDOW_CUSTOMIZE_KEY:
 | 
			
		||||
			case WINDOW_CUSTOMIZE_SERVER:
 | 
			
		||||
			case WINDOW_CUSTOMIZE_GLOBAL_SESSION:
 | 
			
		||||
			case WINDOW_CUSTOMIZE_GLOBAL_WINDOW:
 | 
			
		||||
@@ -835,6 +1044,7 @@ window_customize_set_option(struct client *c, struct window_customize_modedata *
 | 
			
		||||
		} else {
 | 
			
		||||
			switch (item->scope) {
 | 
			
		||||
			case WINDOW_CUSTOMIZE_NONE:
 | 
			
		||||
			case WINDOW_CUSTOMIZE_KEY:
 | 
			
		||||
			case WINDOW_CUSTOMIZE_SERVER:
 | 
			
		||||
			case WINDOW_CUSTOMIZE_SESSION:
 | 
			
		||||
				scope = item->scope;
 | 
			
		||||
@@ -863,7 +1073,7 @@ window_customize_set_option(struct client *c, struct window_customize_modedata *
 | 
			
		||||
			oo = window_customize_get_tree(scope, &fs);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	    if (oe != NULL && oe->type == OPTIONS_TABLE_FLAG) {
 | 
			
		||||
	if (oe != NULL && oe->type == OPTIONS_TABLE_FLAG) {
 | 
			
		||||
		flag = options_get_number(oo, name);
 | 
			
		||||
		options_set_number(oo, name, !flag);
 | 
			
		||||
	} else if (oe != NULL && oe->type == OPTIONS_TABLE_CHOICE) {
 | 
			
		||||
@@ -891,7 +1101,9 @@ window_customize_set_option(struct client *c, struct window_customize_modedata *
 | 
			
		||||
			xasprintf(&prompt, "(%s%s%s) ", name, space, text);
 | 
			
		||||
		free(text);
 | 
			
		||||
 | 
			
		||||
		new_item = xmalloc(sizeof *new_item);
 | 
			
		||||
		value = options_to_string(o, idx, 0);
 | 
			
		||||
 | 
			
		||||
		new_item = xcalloc(1, sizeof *new_item);
 | 
			
		||||
		new_item->data = data;
 | 
			
		||||
		new_item->scope = scope;
 | 
			
		||||
		new_item->oo = oo;
 | 
			
		||||
@@ -899,10 +1111,14 @@ window_customize_set_option(struct client *c, struct window_customize_modedata *
 | 
			
		||||
		new_item->idx = idx;
 | 
			
		||||
 | 
			
		||||
		data->references++;
 | 
			
		||||
		status_prompt_set(c, prompt, value, window_customize_set_callback,
 | 
			
		||||
		    window_customize_set_free, new_item, PROMPT_NOFORMAT);
 | 
			
		||||
		status_prompt_set(c, prompt, value,
 | 
			
		||||
		    window_customize_set_option_callback,
 | 
			
		||||
		    window_customize_free_item_callback, new_item,
 | 
			
		||||
		    PROMPT_NOFORMAT);
 | 
			
		||||
 | 
			
		||||
		free(prompt);
 | 
			
		||||
		free(value);
 | 
			
		||||
	}
 | 
			
		||||
	free(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -915,11 +1131,12 @@ window_customize_unset_option(struct window_customize_modedata *data,
 | 
			
		||||
	if (item == NULL || !window_customize_check_item(data, item, NULL))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
 	o = options_get(item->oo, item->name);
 | 
			
		||||
	o = options_get(item->oo, item->name);
 | 
			
		||||
	if (o == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	if (item->idx != -1) {
 | 
			
		||||
		mode_tree_up(data->data, 0);
 | 
			
		||||
		if (item == mode_tree_get_current(data->data))
 | 
			
		||||
			mode_tree_up(data->data, 0);
 | 
			
		||||
		options_array_set(o, item->idx, NULL, 0, NULL);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -933,11 +1150,198 @@ window_customize_unset_option(struct window_customize_modedata *data,
 | 
			
		||||
		options_default(options_owner(o), oe);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
window_customize_set_command_callback(struct client *c, void *itemdata,
 | 
			
		||||
    const char *s, __unused int done)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_itemdata	*item = itemdata;
 | 
			
		||||
	struct window_customize_modedata	*data = item->data;
 | 
			
		||||
	struct key_binding			*bd;
 | 
			
		||||
	struct cmd_parse_result			*pr;
 | 
			
		||||
	char					*error;
 | 
			
		||||
 | 
			
		||||
	if (s == NULL || *s == '\0' || data->dead)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (item == NULL || !window_customize_get_key(item, NULL, &bd))
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	pr = cmd_parse_from_string(s, NULL);
 | 
			
		||||
	switch (pr->status) {
 | 
			
		||||
	case CMD_PARSE_EMPTY:
 | 
			
		||||
		error = xstrdup("empty command");
 | 
			
		||||
		goto fail;
 | 
			
		||||
	case CMD_PARSE_ERROR:
 | 
			
		||||
		error = pr->error;
 | 
			
		||||
		goto fail;
 | 
			
		||||
	case CMD_PARSE_SUCCESS:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	cmd_list_free(bd->cmdlist);
 | 
			
		||||
	bd->cmdlist = pr->cmdlist;
 | 
			
		||||
 | 
			
		||||
	mode_tree_build(data->data);
 | 
			
		||||
	mode_tree_draw(data->data);
 | 
			
		||||
	data->wp->flags |= PANE_REDRAW;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
	*error = toupper((u_char)*error);
 | 
			
		||||
	status_message_set(c, 1, "%s", error);
 | 
			
		||||
	free(error);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
window_customize_set_note_callback(__unused struct client *c, void *itemdata,
 | 
			
		||||
    const char *s, __unused int done)
 | 
			
		||||
{
 | 
			
		||||
	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);
 | 
			
		||||
	if (item == NULL || !window_customize_get_key(item, NULL, &bd))
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	free((void *)bd->note);
 | 
			
		||||
	bd->note = xstrdup(s);
 | 
			
		||||
 | 
			
		||||
	mode_tree_build(data->data);
 | 
			
		||||
	mode_tree_draw(data->data);
 | 
			
		||||
	data->wp->flags |= PANE_REDRAW;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_set_key(struct client *c,
 | 
			
		||||
    struct window_customize_modedata *data,
 | 
			
		||||
    struct window_customize_itemdata *item)
 | 
			
		||||
{
 | 
			
		||||
	key_code				 key = item->key;
 | 
			
		||||
	struct key_binding			*bd;
 | 
			
		||||
	const char				*s;
 | 
			
		||||
	char					*prompt, *value;
 | 
			
		||||
	struct window_customize_itemdata	*new_item;
 | 
			
		||||
 | 
			
		||||
	if (item == NULL || !window_customize_get_key(item, NULL, &bd))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	s = mode_tree_get_current_name(data->data);
 | 
			
		||||
	if (strcmp(s, "Repeat") == 0)
 | 
			
		||||
		bd->flags ^= KEY_BINDING_REPEAT;
 | 
			
		||||
	else if (strcmp(s, "Command") == 0) {
 | 
			
		||||
		xasprintf(&prompt, "(%s) ", key_string_lookup_key(key));
 | 
			
		||||
		value = cmd_list_print(bd->cmdlist, 0);
 | 
			
		||||
 | 
			
		||||
		new_item = xcalloc(1, sizeof *new_item);
 | 
			
		||||
		new_item->data = data;
 | 
			
		||||
		new_item->scope = item->scope;
 | 
			
		||||
		new_item->table = xstrdup(item->table);
 | 
			
		||||
		new_item->key = key;
 | 
			
		||||
 | 
			
		||||
		data->references++;
 | 
			
		||||
		status_prompt_set(c, prompt, value,
 | 
			
		||||
		    window_customize_set_command_callback,
 | 
			
		||||
		    window_customize_free_item_callback, new_item,
 | 
			
		||||
		    PROMPT_NOFORMAT);
 | 
			
		||||
		free(prompt);
 | 
			
		||||
		free(value);
 | 
			
		||||
	} else if (strcmp(s, "Note") == 0) {
 | 
			
		||||
		xasprintf(&prompt, "(%s) ", key_string_lookup_key(key));
 | 
			
		||||
 | 
			
		||||
		new_item = xcalloc(1, sizeof *new_item);
 | 
			
		||||
		new_item->data = data;
 | 
			
		||||
		new_item->scope = item->scope;
 | 
			
		||||
		new_item->table = xstrdup(item->table);
 | 
			
		||||
		new_item->key = key;
 | 
			
		||||
 | 
			
		||||
		data->references++;
 | 
			
		||||
		status_prompt_set(c, prompt, (bd->note == NULL ? "" : bd->note),
 | 
			
		||||
		    window_customize_set_note_callback,
 | 
			
		||||
		    window_customize_free_item_callback, new_item,
 | 
			
		||||
		    PROMPT_NOFORMAT);
 | 
			
		||||
		free(prompt);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_unset_key(struct window_customize_modedata *data,
 | 
			
		||||
    struct window_customize_itemdata *item)
 | 
			
		||||
{
 | 
			
		||||
	struct key_table	*kt;
 | 
			
		||||
	struct key_binding	*bd;
 | 
			
		||||
 | 
			
		||||
	if (item == NULL || !window_customize_get_key(item, &kt, &bd))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (item == mode_tree_get_current(data->data)) {
 | 
			
		||||
		mode_tree_collapse_current(data->data);
 | 
			
		||||
		mode_tree_up(data->data, 0);
 | 
			
		||||
	}
 | 
			
		||||
	key_bindings_remove(kt->name, bd->key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
window_customize_unset_each(void *modedata, void *itemdata,
 | 
			
		||||
    __unused struct client *c, __unused key_code key)
 | 
			
		||||
{
 | 
			
		||||
	window_customize_unset_option(modedata, itemdata);
 | 
			
		||||
	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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
window_customize_unset_current_callback(__unused struct client *c,
 | 
			
		||||
    void *modedata, const char *s, __unused int done)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_modedata	*data = modedata;
 | 
			
		||||
	struct window_customize_itemdata	*item;
 | 
			
		||||
 | 
			
		||||
	if (s == NULL || *s == '\0' || data->dead)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
 | 
			
		||||
		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);
 | 
			
		||||
	}
 | 
			
		||||
	mode_tree_build(data->data);
 | 
			
		||||
	mode_tree_draw(data->data);
 | 
			
		||||
	data->wp->flags |= PANE_REDRAW;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
window_customize_unset_tagged_callback(struct client *c, void *modedata,
 | 
			
		||||
    const char *s, __unused int done)
 | 
			
		||||
{
 | 
			
		||||
	struct window_customize_modedata	*data = modedata;
 | 
			
		||||
 | 
			
		||||
	if (s == NULL || *s == '\0' || data->dead)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	mode_tree_each_tagged(data->data, window_customize_unset_each, c,
 | 
			
		||||
	    KEYC_NONE, 0);
 | 
			
		||||
	mode_tree_build(data->data);
 | 
			
		||||
	mode_tree_draw(data->data);
 | 
			
		||||
	data->wp->flags |= PANE_REDRAW;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -949,6 +1353,8 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
 | 
			
		||||
	struct window_customize_modedata	*data = wme->data;
 | 
			
		||||
	struct window_customize_itemdata	*item, *new_item;
 | 
			
		||||
	int					 finished;
 | 
			
		||||
	char					*prompt;
 | 
			
		||||
	u_int					 tagged;
 | 
			
		||||
 | 
			
		||||
	item = mode_tree_get_current(data->data);
 | 
			
		||||
	finished = mode_tree_key(data->data, c, &key, m, NULL, NULL);
 | 
			
		||||
@@ -960,12 +1366,16 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
 | 
			
		||||
	case 's':
 | 
			
		||||
		if (item == NULL)
 | 
			
		||||
			break;
 | 
			
		||||
		window_customize_set_option(c, data, item, 0, 1);
 | 
			
		||||
		options_push_changes(item->name);
 | 
			
		||||
		if (item->scope == WINDOW_CUSTOMIZE_KEY)
 | 
			
		||||
			window_customize_set_key(c, data, item);
 | 
			
		||||
		else {
 | 
			
		||||
			window_customize_set_option(c, data, item, 0, 1);
 | 
			
		||||
			options_push_changes(item->name);
 | 
			
		||||
		}
 | 
			
		||||
		mode_tree_build(data->data);
 | 
			
		||||
		break;
 | 
			
		||||
	case 'w':
 | 
			
		||||
		if (item == NULL)
 | 
			
		||||
		if (item == NULL || item->scope == WINDOW_CUSTOMIZE_KEY)
 | 
			
		||||
			break;
 | 
			
		||||
		window_customize_set_option(c, data, item, 0, 0);
 | 
			
		||||
		options_push_changes(item->name);
 | 
			
		||||
@@ -973,7 +1383,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
 | 
			
		||||
		break;
 | 
			
		||||
	case 'S':
 | 
			
		||||
	case 'W':
 | 
			
		||||
		if (item == NULL)
 | 
			
		||||
		if (item == NULL || item->scope == WINDOW_CUSTOMIZE_KEY)
 | 
			
		||||
			break;
 | 
			
		||||
		window_customize_set_option(c, data, item, 1, 0);
 | 
			
		||||
		options_push_changes(item->name);
 | 
			
		||||
@@ -982,15 +1392,29 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
 | 
			
		||||
	case 'u':
 | 
			
		||||
		if (item == NULL)
 | 
			
		||||
			break;
 | 
			
		||||
		window_customize_unset_option(data, item);
 | 
			
		||||
		options_push_changes(item->name);
 | 
			
		||||
		mode_tree_build(data->data);
 | 
			
		||||
		if (item->scope == WINDOW_CUSTOMIZE_KEY) {
 | 
			
		||||
			xasprintf(&prompt, "Unbind key %s? ",
 | 
			
		||||
			    key_string_lookup_key(item->key));
 | 
			
		||||
		} else
 | 
			
		||||
			xasprintf(&prompt, "Unset option %s? ", item->name);
 | 
			
		||||
		data->references++;
 | 
			
		||||
		status_prompt_set(c, prompt, "",
 | 
			
		||||
		    window_customize_unset_current_callback,
 | 
			
		||||
		    window_customize_free_callback, data,
 | 
			
		||||
		    PROMPT_SINGLE|PROMPT_NOFORMAT);
 | 
			
		||||
		free(prompt);
 | 
			
		||||
		break;
 | 
			
		||||
	case 'U':
 | 
			
		||||
		mode_tree_each_tagged(data->data, window_customize_unset_each,
 | 
			
		||||
		    c, KEYC_NONE, 1);
 | 
			
		||||
		options_push_changes(item->name);
 | 
			
		||||
		mode_tree_build(data->data);
 | 
			
		||||
		tagged = mode_tree_count_tagged(data->data);
 | 
			
		||||
		if (tagged == 0)
 | 
			
		||||
			break;
 | 
			
		||||
		xasprintf(&prompt, "Unset or unbind %u tagged? ", tagged);
 | 
			
		||||
		data->references++;
 | 
			
		||||
		status_prompt_set(c, prompt, "",
 | 
			
		||||
		    window_customize_unset_tagged_callback,
 | 
			
		||||
		    window_customize_free_callback, data,
 | 
			
		||||
		    PROMPT_SINGLE|PROMPT_NOFORMAT);
 | 
			
		||||
		free(prompt);
 | 
			
		||||
		break;
 | 
			
		||||
	case 'H':
 | 
			
		||||
		data->hide_global = !data->hide_global;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user