mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add simple menus to tree, client, buffer modes.
This commit is contained in:
		@@ -67,7 +67,7 @@ cmd_send_keys_inject(struct client *c, struct cmd_find_state *fs,
 | 
				
			|||||||
	if (wme == NULL || wme->mode->key_table == NULL) {
 | 
						if (wme == NULL || wme->mode->key_table == NULL) {
 | 
				
			||||||
		if (options_get_number(fs->wp->window->options, "xterm-keys"))
 | 
							if (options_get_number(fs->wp->window->options, "xterm-keys"))
 | 
				
			||||||
			key |= KEYC_XTERM;
 | 
								key |= KEYC_XTERM;
 | 
				
			||||||
		window_pane_key(fs->wp, NULL, fs->s, fs->wl, key, NULL);
 | 
							window_pane_key(fs->wp, item->client, fs->s, fs->wl, key, NULL);
 | 
				
			||||||
		return (item);
 | 
							return (item);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	table = key_bindings_get_table(wme->mode->key_table(wme), 1);
 | 
						table = key_bindings_get_table(wme->mode->key_table(wme), 1);
 | 
				
			||||||
@@ -132,7 +132,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
			cmdq_error(item, "no mouse target");
 | 
								cmdq_error(item, "no mouse target");
 | 
				
			||||||
			return (CMD_RETURN_ERROR);
 | 
								return (CMD_RETURN_ERROR);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		window_pane_key(wp, NULL, s, wl, m->key, m);
 | 
							window_pane_key(wp, item->client, s, wl, m->key, m);
 | 
				
			||||||
		return (CMD_RETURN_NORMAL);
 | 
							return (CMD_RETURN_NORMAL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -278,8 +278,8 @@ key_bindings_init(void)
 | 
				
			|||||||
		"bind -n WheelDownStatus next-window",
 | 
							"bind -n WheelDownStatus next-window",
 | 
				
			||||||
		"bind -n WheelUpStatus previous-window",
 | 
							"bind -n WheelUpStatus previous-window",
 | 
				
			||||||
		"bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'",
 | 
							"bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'",
 | 
				
			||||||
		"bind -n MouseDown3Pane if-shell -Ft= '#{mouse_any_flag}' 'select-pane -t=; send-keys -M' 'select-pane -mt='",
 | 
							"bind -n MouseDown3Pane if -Ft= '#{||:mouse_any_flag,pane_in_mode}' 'select-pane -t=; send-keys -M' 'select-pane -mt='",
 | 
				
			||||||
		"bind -n WheelUpPane if-shell -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'",
 | 
							"bind -n WheelUpPane if -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'",
 | 
				
			||||||
		"bind -n MouseDown3StatusRight display-menu -t= -xM -yS -F -M \"#{client_menu}\" -T \"#[align=centre]#{client_name}\"",
 | 
							"bind -n MouseDown3StatusRight display-menu -t= -xM -yS -F -M \"#{client_menu}\" -T \"#[align=centre]#{client_name}\"",
 | 
				
			||||||
		"bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -F -M \"#{session_menu}\" -T \"#[align=centre]#{session_name}\"",
 | 
							"bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -F -M \"#{session_menu}\" -T \"#[align=centre]#{session_name}\"",
 | 
				
			||||||
		"bind -n MouseDown3Status display-menu -t= -xW -yS -F -M \"#{window_menu}\" -T \"#[align=centre]#{window_index}:#{window_name}\"",
 | 
							"bind -n MouseDown3Status display-menu -t= -xW -yS -F -M \"#{window_menu}\" -T \"#[align=centre]#{window_index}:#{window_name}\"",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								menu.c
									
									
									
									
									
								
							@@ -56,7 +56,11 @@ menu_add_item(struct menu *menu, struct menu_item *item, struct client *c,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (item == NULL || *item->name == '\0') /* horizontal line */
 | 
						if (item == NULL || *item->name == '\0') /* horizontal line */
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	name = format_single(NULL, item->name, c, fs->s, fs->wl, fs->wp);
 | 
						if (fs != NULL) {
 | 
				
			||||||
 | 
							name = format_single(NULL, item->name, c, fs->s, fs->wl,
 | 
				
			||||||
 | 
							    fs->wp);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							name = xstrdup(item->name);
 | 
				
			||||||
	if (*name == '\0') { /* no item if empty after format expanded */
 | 
						if (*name == '\0') { /* no item if empty after format expanded */
 | 
				
			||||||
		menu->count--;
 | 
							menu->count--;
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
@@ -118,7 +122,6 @@ menu_create(const char *s, struct client *c, struct cmd_find_state *fs,
 | 
				
			|||||||
	copy = string = xstrdup(s);
 | 
						copy = string = xstrdup(s);
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		next = (char *)format_skip(string, "|");
 | 
							next = (char *)format_skip(string, "|");
 | 
				
			||||||
		log_debug("XXX %s -- %s", next, string);
 | 
					 | 
				
			||||||
		if (next != NULL)
 | 
							if (next != NULL)
 | 
				
			||||||
			*next++ = '\0';
 | 
								*next++ = '\0';
 | 
				
			||||||
		if (*string == '\0')
 | 
							if (*string == '\0')
 | 
				
			||||||
@@ -180,6 +183,9 @@ menu_free_cb(struct client *c)
 | 
				
			|||||||
	if (md->item != NULL)
 | 
						if (md->item != NULL)
 | 
				
			||||||
		md->item->flags &= ~CMDQ_WAITING;
 | 
							md->item->flags &= ~CMDQ_WAITING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (md->cb != NULL)
 | 
				
			||||||
 | 
							md->cb(md->menu, UINT_MAX, KEYC_NONE, md->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	screen_free(&md->s);
 | 
						screen_free(&md->s);
 | 
				
			||||||
	menu_free(md->menu);
 | 
						menu_free(md->menu);
 | 
				
			||||||
	free(md);
 | 
						free(md);
 | 
				
			||||||
@@ -274,6 +280,7 @@ chosen:
 | 
				
			|||||||
		return (1);
 | 
							return (1);
 | 
				
			||||||
	if (md->cb != NULL) {
 | 
						if (md->cb != NULL) {
 | 
				
			||||||
	    md->cb(md->menu, md->choice, item->key, md->data);
 | 
						    md->cb(md->menu, md->choice, item->key, md->data);
 | 
				
			||||||
 | 
						    md->cb = NULL;
 | 
				
			||||||
	    return (1);
 | 
						    return (1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cmdlist = cmd_string_parse(item->command, NULL, 0, &cause);
 | 
						cmdlist = cmd_string_parse(item->command, NULL, 0, &cause);
 | 
				
			||||||
@@ -308,7 +315,8 @@ menu_display(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
 | 
				
			|||||||
	md->item = item;
 | 
						md->item = item;
 | 
				
			||||||
	md->flags = flags;
 | 
						md->flags = flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd_find_copy_state(&md->fs, fs);
 | 
						if (fs != NULL)
 | 
				
			||||||
 | 
							cmd_find_copy_state(&md->fs, fs);
 | 
				
			||||||
	screen_init(&md->s, menu->width + 4, menu->count + 2, 0);
 | 
						screen_init(&md->s, menu->width + 4, menu->count + 2, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	md->px = px;
 | 
						md->px = px;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										105
									
								
								mode-tree.c
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								mode-tree.c
									
									
									
									
									
								
							@@ -35,6 +35,7 @@ struct mode_tree_data {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	struct window_pane	 *wp;
 | 
						struct window_pane	 *wp;
 | 
				
			||||||
	void			 *modedata;
 | 
						void			 *modedata;
 | 
				
			||||||
 | 
						const char		 *menu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char		**sort_list;
 | 
						const char		**sort_list;
 | 
				
			||||||
	u_int			  sort_size;
 | 
						u_int			  sort_size;
 | 
				
			||||||
@@ -43,6 +44,7 @@ struct mode_tree_data {
 | 
				
			|||||||
	mode_tree_build_cb        buildcb;
 | 
						mode_tree_build_cb        buildcb;
 | 
				
			||||||
	mode_tree_draw_cb         drawcb;
 | 
						mode_tree_draw_cb         drawcb;
 | 
				
			||||||
	mode_tree_search_cb       searchcb;
 | 
						mode_tree_search_cb       searchcb;
 | 
				
			||||||
 | 
						mode_tree_menu_cb         menucb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct mode_tree_list	  children;
 | 
						struct mode_tree_list	  children;
 | 
				
			||||||
	struct mode_tree_list	  saved;
 | 
						struct mode_tree_list	  saved;
 | 
				
			||||||
@@ -89,8 +91,21 @@ struct mode_tree_line {
 | 
				
			|||||||
	int				 flat;
 | 
						int				 flat;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mode_tree_menu {
 | 
				
			||||||
 | 
						struct mode_tree_data		*data;
 | 
				
			||||||
 | 
						struct client			*c;
 | 
				
			||||||
 | 
						u_int				 line;
 | 
				
			||||||
 | 
						void				*itemdata;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void mode_tree_free_items(struct mode_tree_list *);
 | 
					static void mode_tree_free_items(struct mode_tree_list *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MODE_TREE_MENU \
 | 
				
			||||||
 | 
						"Scroll Left,<,|" \
 | 
				
			||||||
 | 
						"Scroll Right,>,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Cancel,q,"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct mode_tree_item *
 | 
					static struct mode_tree_item *
 | 
				
			||||||
mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag)
 | 
					mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -299,8 +314,9 @@ mode_tree_each_tagged(struct mode_tree_data *mtd, mode_tree_each_cb cb,
 | 
				
			|||||||
struct mode_tree_data *
 | 
					struct mode_tree_data *
 | 
				
			||||||
mode_tree_start(struct window_pane *wp, struct args *args,
 | 
					mode_tree_start(struct window_pane *wp, struct args *args,
 | 
				
			||||||
    mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb,
 | 
					    mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb,
 | 
				
			||||||
    mode_tree_search_cb searchcb, void *modedata, const char **sort_list,
 | 
					    mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, void *modedata,
 | 
				
			||||||
    u_int sort_size, struct screen **s)
 | 
					    const char *menu, const char **sort_list, u_int sort_size,
 | 
				
			||||||
 | 
					    struct screen **s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mode_tree_data	*mtd;
 | 
						struct mode_tree_data	*mtd;
 | 
				
			||||||
	const char		*sort;
 | 
						const char		*sort;
 | 
				
			||||||
@@ -311,6 +327,7 @@ mode_tree_start(struct window_pane *wp, struct args *args,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	mtd->wp = wp;
 | 
						mtd->wp = wp;
 | 
				
			||||||
	mtd->modedata = modedata;
 | 
						mtd->modedata = modedata;
 | 
				
			||||||
 | 
						mtd->menu = menu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mtd->sort_list = sort_list;
 | 
						mtd->sort_list = sort_list;
 | 
				
			||||||
	mtd->sort_size = sort_size;
 | 
						mtd->sort_size = sort_size;
 | 
				
			||||||
@@ -334,6 +351,7 @@ mode_tree_start(struct window_pane *wp, struct args *args,
 | 
				
			|||||||
	mtd->buildcb = buildcb;
 | 
						mtd->buildcb = buildcb;
 | 
				
			||||||
	mtd->drawcb = drawcb;
 | 
						mtd->drawcb = drawcb;
 | 
				
			||||||
	mtd->searchcb = searchcb;
 | 
						mtd->searchcb = searchcb;
 | 
				
			||||||
 | 
						mtd->menucb = menucb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TAILQ_INIT(&mtd->children);
 | 
						TAILQ_INIT(&mtd->children);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -762,6 +780,71 @@ mode_tree_filter_free(void *data)
 | 
				
			|||||||
	mode_tree_remove_ref(data);
 | 
						mode_tree_remove_ref(data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					mode_tree_menu_callback(__unused struct menu *menu, __unused u_int idx,
 | 
				
			||||||
 | 
					    key_code key, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mode_tree_menu		*mtm = data;
 | 
				
			||||||
 | 
						struct mode_tree_data		*mtd = mtm->data;
 | 
				
			||||||
 | 
						struct mode_tree_item		*mti;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mtd->dead || key == KEYC_NONE)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mtm->line >= mtd->line_size)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						mti = mtd->line_list[mtm->line].item;
 | 
				
			||||||
 | 
						if (mti->itemdata != mtm->itemdata)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						mtd->current = mtm->line;
 | 
				
			||||||
 | 
						mtd->menucb (mtd->modedata, mtm->c, key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						mode_tree_remove_ref(mtd);
 | 
				
			||||||
 | 
						free(mtm);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
 | 
				
			||||||
 | 
					    u_int y, int outside)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mode_tree_item	*mti;
 | 
				
			||||||
 | 
						struct menu		*menu;
 | 
				
			||||||
 | 
						struct mode_tree_menu	*mtm;
 | 
				
			||||||
 | 
						const char		*s;
 | 
				
			||||||
 | 
						char			*title;
 | 
				
			||||||
 | 
						u_int			 line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mtd->offset + y > mtd->line_size - 1)
 | 
				
			||||||
 | 
							line = mtd->current;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							line = mtd->offset + y;
 | 
				
			||||||
 | 
							mti = mtd->line_list[line].item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!outside) {
 | 
				
			||||||
 | 
							s = mtd->menu;
 | 
				
			||||||
 | 
							xasprintf(&title, "#[align=centre]%s", mti->name);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							s = MODE_TREE_MENU;
 | 
				
			||||||
 | 
							title = xstrdup("");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						menu = menu_create(s, c, NULL, title);
 | 
				
			||||||
 | 
						free(title);
 | 
				
			||||||
 | 
						if (menu == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mtm = xmalloc(sizeof *mtm);
 | 
				
			||||||
 | 
						mtm->data = mtd;
 | 
				
			||||||
 | 
						mtm->c = c;
 | 
				
			||||||
 | 
						mtm->line = line;
 | 
				
			||||||
 | 
						mtm->itemdata = mti->itemdata;
 | 
				
			||||||
 | 
						mtd->references++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (menu_display(menu, 0, NULL, x, y, c, NULL, mode_tree_menu_callback,
 | 
				
			||||||
 | 
						    mtm) != 0)
 | 
				
			||||||
 | 
							menu_free(menu);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
 | 
					mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
 | 
				
			||||||
    struct mouse_event *m, u_int *xp, u_int *yp)
 | 
					    struct mouse_event *m, u_int *xp, u_int *yp)
 | 
				
			||||||
@@ -772,7 +855,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
 | 
				
			|||||||
	int			 choice;
 | 
						int			 choice;
 | 
				
			||||||
	key_code		 tmp;
 | 
						key_code		 tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (KEYC_IS_MOUSE(*key)) {
 | 
						if (KEYC_IS_MOUSE(*key) && m != NULL) {
 | 
				
			||||||
		if (cmd_mouse_at(mtd->wp, m, &x, &y, 0) != 0) {
 | 
							if (cmd_mouse_at(mtd->wp, m, &x, &y, 0) != 0) {
 | 
				
			||||||
			*key = KEYC_NONE;
 | 
								*key = KEYC_NONE;
 | 
				
			||||||
			return (0);
 | 
								return (0);
 | 
				
			||||||
@@ -782,20 +865,29 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
 | 
				
			|||||||
		if (yp != NULL)
 | 
							if (yp != NULL)
 | 
				
			||||||
			*yp = y;
 | 
								*yp = y;
 | 
				
			||||||
		if (x > mtd->width || y > mtd->height) {
 | 
							if (x > mtd->width || y > mtd->height) {
 | 
				
			||||||
 | 
								if (*key == KEYC_MOUSEDOWN3_PANE)
 | 
				
			||||||
 | 
									mode_tree_display_menu(mtd, c, x, y, 1);
 | 
				
			||||||
			if (!mtd->preview)
 | 
								if (!mtd->preview)
 | 
				
			||||||
				*key = KEYC_NONE;
 | 
									*key = KEYC_NONE;
 | 
				
			||||||
			return (0);
 | 
								return (0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (mtd->offset + y < mtd->line_size) {
 | 
							if (mtd->offset + y < mtd->line_size) {
 | 
				
			||||||
			if (*key == KEYC_MOUSEDOWN1_PANE ||
 | 
								if (*key == KEYC_MOUSEDOWN1_PANE ||
 | 
				
			||||||
 | 
								    *key == KEYC_MOUSEDOWN3_PANE ||
 | 
				
			||||||
			    *key == KEYC_DOUBLECLICK1_PANE)
 | 
								    *key == KEYC_DOUBLECLICK1_PANE)
 | 
				
			||||||
				mtd->current = mtd->offset + y;
 | 
									mtd->current = mtd->offset + y;
 | 
				
			||||||
			if (*key == KEYC_DOUBLECLICK1_PANE)
 | 
								if (*key == KEYC_DOUBLECLICK1_PANE)
 | 
				
			||||||
				*key = '\r';
 | 
									*key = '\r';
 | 
				
			||||||
			else
 | 
								else {
 | 
				
			||||||
 | 
									if (*key == KEYC_MOUSEDOWN3_PANE)
 | 
				
			||||||
 | 
										mode_tree_display_menu(mtd, c, x, y, 0);
 | 
				
			||||||
				*key = KEYC_NONE;
 | 
									*key = KEYC_NONE;
 | 
				
			||||||
		} else
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (*key == KEYC_MOUSEDOWN3_PANE)
 | 
				
			||||||
 | 
									mode_tree_display_menu(mtd, c, x, y, 0);
 | 
				
			||||||
			*key = KEYC_NONE;
 | 
								*key = KEYC_NONE;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return (0);
 | 
							return (0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -879,7 +971,8 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
 | 
				
			|||||||
			current->tagged = 1;
 | 
								current->tagged = 1;
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			current->tagged = 0;
 | 
								current->tagged = 0;
 | 
				
			||||||
		mode_tree_down(mtd, 0);
 | 
							if (m != NULL)
 | 
				
			||||||
 | 
								mode_tree_down(mtd, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'T':
 | 
						case 'T':
 | 
				
			||||||
		for (i = 0; i < mtd->line_size; i++)
 | 
							for (i = 0; i < mtd->line_size; i++)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tmux.h
									
									
									
									
									
								
							@@ -2408,8 +2408,9 @@ u_int		 layout_set_previous(struct window *);
 | 
				
			|||||||
/* mode-tree.c */
 | 
					/* mode-tree.c */
 | 
				
			||||||
typedef void (*mode_tree_build_cb)(void *, u_int, uint64_t *, const char *);
 | 
					typedef void (*mode_tree_build_cb)(void *, u_int, uint64_t *, const char *);
 | 
				
			||||||
typedef void (*mode_tree_draw_cb)(void *, void *, struct screen_write_ctx *,
 | 
					typedef void (*mode_tree_draw_cb)(void *, void *, struct screen_write_ctx *,
 | 
				
			||||||
    u_int, u_int);
 | 
						     u_int, u_int);
 | 
				
			||||||
typedef int (*mode_tree_search_cb)(void *, void *, const char *);
 | 
					typedef int (*mode_tree_search_cb)(void *, void *, const char *);
 | 
				
			||||||
 | 
					typedef void (*mode_tree_menu_cb)(void *, struct client *, key_code);
 | 
				
			||||||
typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code);
 | 
					typedef void (*mode_tree_each_cb)(void *, void *, struct client *, key_code);
 | 
				
			||||||
u_int	 mode_tree_count_tagged(struct mode_tree_data *);
 | 
					u_int	 mode_tree_count_tagged(struct mode_tree_data *);
 | 
				
			||||||
void	*mode_tree_get_current(struct mode_tree_data *);
 | 
					void	*mode_tree_get_current(struct mode_tree_data *);
 | 
				
			||||||
@@ -2420,7 +2421,8 @@ void	 mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb,
 | 
				
			|||||||
void	 mode_tree_down(struct mode_tree_data *, int);
 | 
					void	 mode_tree_down(struct mode_tree_data *, int);
 | 
				
			||||||
struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
 | 
					struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
 | 
				
			||||||
	     mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb,
 | 
						     mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb,
 | 
				
			||||||
	     void *, const char **, u_int, struct screen **);
 | 
						     mode_tree_menu_cb, void *, const char *, const char **, u_int,
 | 
				
			||||||
 | 
						     struct screen **);
 | 
				
			||||||
void	 mode_tree_zoom(struct mode_tree_data *, struct args *);
 | 
					void	 mode_tree_zoom(struct mode_tree_data *, struct args *);
 | 
				
			||||||
void	 mode_tree_build(struct mode_tree_data *);
 | 
					void	 mode_tree_build(struct mode_tree_data *);
 | 
				
			||||||
void	 mode_tree_free(struct mode_tree_data *);
 | 
					void	 mode_tree_free(struct mode_tree_data *);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,6 +39,19 @@ static void		 window_buffer_key(struct window_mode_entry *,
 | 
				
			|||||||
#define WINDOW_BUFFER_DEFAULT_FORMAT \
 | 
					#define WINDOW_BUFFER_DEFAULT_FORMAT \
 | 
				
			||||||
	"#{buffer_size} bytes (#{t:buffer_created})"
 | 
						"#{buffer_size} bytes (#{t:buffer_created})"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WINDOW_BUFFER_MENU \
 | 
				
			||||||
 | 
						"Paste,p,|" \
 | 
				
			||||||
 | 
						"Paste Tagged,P,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Tag,t,|" \
 | 
				
			||||||
 | 
						"Tag All,C-t,|" \
 | 
				
			||||||
 | 
						"Tag None,T,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Delete,d,|" \
 | 
				
			||||||
 | 
						"Delete Tagged,D,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Cancel,q,"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct window_mode window_buffer_mode = {
 | 
					const struct window_mode window_buffer_mode = {
 | 
				
			||||||
	.name = "buffer-mode",
 | 
						.name = "buffer-mode",
 | 
				
			||||||
	.default_format = WINDOW_BUFFER_DEFAULT_FORMAT,
 | 
						.default_format = WINDOW_BUFFER_DEFAULT_FORMAT,
 | 
				
			||||||
@@ -67,7 +80,9 @@ struct window_buffer_itemdata {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct window_buffer_modedata {
 | 
					struct window_buffer_modedata {
 | 
				
			||||||
 | 
						struct window_pane		 *wp;
 | 
				
			||||||
	struct cmd_find_state		  fs;
 | 
						struct cmd_find_state		  fs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct mode_tree_data		 *data;
 | 
						struct mode_tree_data		 *data;
 | 
				
			||||||
	char				 *command;
 | 
						char				 *command;
 | 
				
			||||||
	char				 *format;
 | 
						char				 *format;
 | 
				
			||||||
@@ -264,6 +279,19 @@ window_buffer_search(__unused void *modedata, void *itemdata, const char *ss)
 | 
				
			|||||||
	return (memmem(bufdata, bufsize, ss, strlen(ss)) != NULL);
 | 
						return (memmem(bufdata, bufsize, ss, strlen(ss)) != NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					window_buffer_menu(void *modedata, struct client *c, key_code key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_buffer_modedata	*data = modedata;
 | 
				
			||||||
 | 
						struct window_pane		*wp = data->wp;
 | 
				
			||||||
 | 
						struct window_mode_entry	*wme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wme = TAILQ_FIRST(&wp->modes);
 | 
				
			||||||
 | 
						if (wme == NULL || wme->data != modedata)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						window_buffer_key(wme, c, NULL, NULL, key, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct screen *
 | 
					static struct screen *
 | 
				
			||||||
window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
					window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
				
			||||||
    struct args *args)
 | 
					    struct args *args)
 | 
				
			||||||
@@ -273,6 +301,7 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
				
			|||||||
	struct screen			*s;
 | 
						struct screen			*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wme->data = data = xcalloc(1, sizeof *data);
 | 
						wme->data = data = xcalloc(1, sizeof *data);
 | 
				
			||||||
 | 
						data->wp = wp;
 | 
				
			||||||
	cmd_find_copy_state(&data->fs, fs);
 | 
						cmd_find_copy_state(&data->fs, fs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args == NULL || !args_has(args, 'F'))
 | 
						if (args == NULL || !args_has(args, 'F'))
 | 
				
			||||||
@@ -285,8 +314,9 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
				
			|||||||
		data->command = xstrdup(args->argv[0]);
 | 
							data->command = xstrdup(args->argv[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->data = mode_tree_start(wp, args, window_buffer_build,
 | 
						data->data = mode_tree_start(wp, args, window_buffer_build,
 | 
				
			||||||
	    window_buffer_draw, window_buffer_search, data,
 | 
						    window_buffer_draw, window_buffer_search, window_buffer_menu, data,
 | 
				
			||||||
	    window_buffer_sort_list, nitems(window_buffer_sort_list), &s);
 | 
						    WINDOW_BUFFER_MENU, window_buffer_sort_list,
 | 
				
			||||||
 | 
						    nitems(window_buffer_sort_list), &s);
 | 
				
			||||||
	mode_tree_zoom(data->data, args);
 | 
						mode_tree_zoom(data->data, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mode_tree_build(data->data);
 | 
						mode_tree_build(data->data);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,16 @@ static void		 window_client_key(struct window_mode_entry *,
 | 
				
			|||||||
	"session #{session_name} " \
 | 
						"session #{session_name} " \
 | 
				
			||||||
	"(#{client_width}x#{client_height}, #{t:client_activity})"
 | 
						"(#{client_width}x#{client_height}, #{t:client_activity})"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WINDOW_CLIENT_MENU \
 | 
				
			||||||
 | 
						"Detach,d,|" \
 | 
				
			||||||
 | 
						"Detach Tagged,D,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Tag,t,|" \
 | 
				
			||||||
 | 
						"Tag All,C-t,|" \
 | 
				
			||||||
 | 
						"Tag None,T,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Cancel,q,"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct window_mode window_client_mode = {
 | 
					const struct window_mode window_client_mode = {
 | 
				
			||||||
	.name = "client-mode",
 | 
						.name = "client-mode",
 | 
				
			||||||
	.default_format = WINDOW_CLIENT_DEFAULT_FORMAT,
 | 
						.default_format = WINDOW_CLIENT_DEFAULT_FORMAT,
 | 
				
			||||||
@@ -68,6 +78,8 @@ struct window_client_itemdata {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct window_client_modedata {
 | 
					struct window_client_modedata {
 | 
				
			||||||
 | 
						struct window_pane		 *wp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct mode_tree_data		 *data;
 | 
						struct mode_tree_data		 *data;
 | 
				
			||||||
	char				 *format;
 | 
						char				 *format;
 | 
				
			||||||
	char				 *command;
 | 
						char				 *command;
 | 
				
			||||||
@@ -249,6 +261,19 @@ window_client_draw(__unused void *modedata, void *itemdata,
 | 
				
			|||||||
	screen_write_fast_copy(ctx, &c->status.screen, 0, 0, sx, lines);
 | 
						screen_write_fast_copy(ctx, &c->status.screen, 0, 0, sx, lines);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					window_client_menu(void *modedata, struct client *c, key_code key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_client_modedata	*data = modedata;
 | 
				
			||||||
 | 
						struct window_pane		*wp = data->wp;
 | 
				
			||||||
 | 
						struct window_mode_entry	*wme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wme = TAILQ_FIRST(&wp->modes);
 | 
				
			||||||
 | 
						if (wme == NULL || wme->data != modedata)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						window_client_key(wme, c, NULL, NULL, key, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct screen *
 | 
					static struct screen *
 | 
				
			||||||
window_client_init(struct window_mode_entry *wme,
 | 
					window_client_init(struct window_mode_entry *wme,
 | 
				
			||||||
    __unused struct cmd_find_state *fs, struct args *args)
 | 
					    __unused struct cmd_find_state *fs, struct args *args)
 | 
				
			||||||
@@ -258,6 +283,7 @@ window_client_init(struct window_mode_entry *wme,
 | 
				
			|||||||
	struct screen			*s;
 | 
						struct screen			*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wme->data = data = xcalloc(1, sizeof *data);
 | 
						wme->data = data = xcalloc(1, sizeof *data);
 | 
				
			||||||
 | 
						data->wp = wp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args == NULL || !args_has(args, 'F'))
 | 
						if (args == NULL || !args_has(args, 'F'))
 | 
				
			||||||
		data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT);
 | 
							data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT);
 | 
				
			||||||
@@ -269,7 +295,8 @@ window_client_init(struct window_mode_entry *wme,
 | 
				
			|||||||
		data->command = xstrdup(args->argv[0]);
 | 
							data->command = xstrdup(args->argv[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->data = mode_tree_start(wp, args, window_client_build,
 | 
						data->data = mode_tree_start(wp, args, window_client_build,
 | 
				
			||||||
	    window_client_draw, NULL, data, window_client_sort_list,
 | 
						    window_client_draw, NULL, window_client_menu, data,
 | 
				
			||||||
 | 
						    WINDOW_CLIENT_MENU, window_client_sort_list,
 | 
				
			||||||
	    nitems(window_client_sort_list), &s);
 | 
						    nitems(window_client_sort_list), &s);
 | 
				
			||||||
	mode_tree_zoom(data->data, args);
 | 
						mode_tree_zoom(data->data, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,6 +53,19 @@ static void		 window_tree_key(struct window_mode_entry *,
 | 
				
			|||||||
		"}" \
 | 
							"}" \
 | 
				
			||||||
	"}"
 | 
						"}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WINDOW_TREE_MENU \
 | 
				
			||||||
 | 
						"Select,Enter,|" \
 | 
				
			||||||
 | 
						"Expand,Right,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Tag,t,|" \
 | 
				
			||||||
 | 
						"Tag All,C-t,|" \
 | 
				
			||||||
 | 
						"Tag None,T,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Kill,x,|" \
 | 
				
			||||||
 | 
						"Kill Tagged,X,|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"Cancel,q,"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct window_mode window_tree_mode = {
 | 
					const struct window_mode window_tree_mode = {
 | 
				
			||||||
	.name = "tree-mode",
 | 
						.name = "tree-mode",
 | 
				
			||||||
	.default_format = WINDOW_TREE_DEFAULT_FORMAT,
 | 
						.default_format = WINDOW_TREE_DEFAULT_FORMAT,
 | 
				
			||||||
@@ -814,6 +827,19 @@ window_tree_search(__unused void *modedata, void *itemdata, const char *ss)
 | 
				
			|||||||
	return (0);
 | 
						return (0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					window_tree_menu(void *modedata, struct client *c, key_code key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_tree_modedata	*data = modedata;
 | 
				
			||||||
 | 
						struct window_pane		*wp = data->wp;
 | 
				
			||||||
 | 
						struct window_mode_entry	*wme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wme = TAILQ_FIRST(&wp->modes);
 | 
				
			||||||
 | 
						if (wme == NULL || wme->data != modedata)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						window_tree_key(wme, c, NULL, NULL, key, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct screen *
 | 
					static struct screen *
 | 
				
			||||||
window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
					window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
				
			||||||
    struct args *args)
 | 
					    struct args *args)
 | 
				
			||||||
@@ -823,6 +849,8 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
				
			|||||||
	struct screen			*s;
 | 
						struct screen			*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wme->data = data = xcalloc(1, sizeof *data);
 | 
						wme->data = data = xcalloc(1, sizeof *data);
 | 
				
			||||||
 | 
						data->wp = wp;
 | 
				
			||||||
 | 
						data->references = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args_has(args, 's'))
 | 
						if (args_has(args, 's'))
 | 
				
			||||||
		data->type = WINDOW_TREE_SESSION;
 | 
							data->type = WINDOW_TREE_SESSION;
 | 
				
			||||||
@@ -832,9 +860,6 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
				
			|||||||
		data->type = WINDOW_TREE_PANE;
 | 
							data->type = WINDOW_TREE_PANE;
 | 
				
			||||||
	memcpy(&data->fs, fs, sizeof data->fs);
 | 
						memcpy(&data->fs, fs, sizeof data->fs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->wp = wp;
 | 
					 | 
				
			||||||
	data->references = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (args == NULL || !args_has(args, 'F'))
 | 
						if (args == NULL || !args_has(args, 'F'))
 | 
				
			||||||
		data->format = xstrdup(WINDOW_TREE_DEFAULT_FORMAT);
 | 
							data->format = xstrdup(WINDOW_TREE_DEFAULT_FORMAT);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
@@ -846,7 +871,8 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
 | 
				
			|||||||
	data->squash_groups = !args_has(args, 'G');
 | 
						data->squash_groups = !args_has(args, 'G');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->data = mode_tree_start(wp, args, window_tree_build,
 | 
						data->data = mode_tree_start(wp, args, window_tree_build,
 | 
				
			||||||
	    window_tree_draw, window_tree_search, data, window_tree_sort_list,
 | 
						    window_tree_draw, window_tree_search, window_tree_menu, data,
 | 
				
			||||||
 | 
						    WINDOW_TREE_MENU, window_tree_sort_list,
 | 
				
			||||||
	    nitems(window_tree_sort_list), &s);
 | 
						    nitems(window_tree_sort_list), &s);
 | 
				
			||||||
	mode_tree_zoom(data->data, args);
 | 
						mode_tree_zoom(data->data, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1146,7 +1172,7 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
 | 
				
			|||||||
		item = new_item;
 | 
							item = new_item;
 | 
				
			||||||
		data->offset = 0;
 | 
							data->offset = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (KEYC_IS_MOUSE(key))
 | 
						if (KEYC_IS_MOUSE(key) && m != NULL)
 | 
				
			||||||
		key = window_tree_mouse(data, key, x, item);
 | 
							key = window_tree_mouse(data, key, x, item);
 | 
				
			||||||
	switch (key) {
 | 
						switch (key) {
 | 
				
			||||||
	case '<':
 | 
						case '<':
 | 
				
			||||||
@@ -1207,7 +1233,6 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
 | 
				
			|||||||
		free(prompt);
 | 
							free(prompt);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '\r':
 | 
						case '\r':
 | 
				
			||||||
		item = mode_tree_get_current(data->data);
 | 
					 | 
				
			||||||
		name = window_tree_get_target(item, &fs);
 | 
							name = window_tree_get_target(item, &fs);
 | 
				
			||||||
		if (name != NULL)
 | 
							if (name != NULL)
 | 
				
			||||||
			mode_tree_run_command(c, NULL, data->command, name);
 | 
								mode_tree_run_command(c, NULL, data->command, name);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user