mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 01:34:18 +00:00 
			
		
		
		
	Add formats for word and line under the mouse and use them to add some
items to the pane menu.
This commit is contained in:
		@@ -79,7 +79,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
		title = format_single(NULL, args_get(args, 'T'), c, s, wl, wp);
 | 
							title = format_single(NULL, args_get(args, 'T'), c, s, wl, wp);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		title = xstrdup("");
 | 
							title = xstrdup("");
 | 
				
			||||||
	menu = menu_create(string, c, fs, title);
 | 
						menu = menu_create(string, item, c, fs, title);
 | 
				
			||||||
	free(title);
 | 
						free(title);
 | 
				
			||||||
	if (menu == NULL) {
 | 
						if (menu == NULL) {
 | 
				
			||||||
		cmdq_error(item, "invalid menu %s", string);
 | 
							cmdq_error(item, "invalid menu %s", string);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										144
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										144
									
								
								format.c
									
									
									
									
									
								
							@@ -84,6 +84,12 @@ static void	 format_defaults_winlink(struct format_tree *, struct winlink *);
 | 
				
			|||||||
	"New After,w,new-window -a|" \
 | 
						"New After,w,new-window -a|" \
 | 
				
			||||||
	"New At End,W,new-window"
 | 
						"New At End,W,new-window"
 | 
				
			||||||
#define DEFAULT_PANE_MENU \
 | 
					#define DEFAULT_PANE_MENU \
 | 
				
			||||||
 | 
						"#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},},,copy-mode -t=; send -Xt= search-backward \"#{q:mouse_word}\"|" \
 | 
				
			||||||
 | 
						"#{?mouse_word,Type #[underscore]#{=/9/...:mouse_word},},,send-keys -l \"#{q:mouse_word}\"|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
 | 
						"#{?mouse_word,Copy #[underscore]#{=/9/...:mouse_word},},c,set-buffer \"#{q:mouse_word}\"|" \
 | 
				
			||||||
 | 
						"#{?mouse_line,Copy Line,},l,set-buffer \"#{q:mouse_line}\"|" \
 | 
				
			||||||
 | 
						"|" \
 | 
				
			||||||
	"Horizontal Split,h,split-window -h|" \
 | 
						"Horizontal Split,h,split-window -h|" \
 | 
				
			||||||
	"Vertical Split,v,split-window -v|" \
 | 
						"Vertical Split,v,split-window -v|" \
 | 
				
			||||||
	"|" \
 | 
						"|" \
 | 
				
			||||||
@@ -170,6 +176,8 @@ struct format_tree {
 | 
				
			|||||||
	time_t			 time;
 | 
						time_t			 time;
 | 
				
			||||||
	u_int			 loop;
 | 
						u_int			 loop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct mouse_event	 m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RB_HEAD(format_entry_tree, format_entry) tree;
 | 
						RB_HEAD(format_entry_tree, format_entry) tree;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static int format_entry_cmp(struct format_entry *, struct format_entry *);
 | 
					static int format_entry_cmp(struct format_entry *, struct format_entry *);
 | 
				
			||||||
@@ -743,6 +751,121 @@ format_cb_cursor_character(struct format_tree *ft, struct format_entry *fe)
 | 
				
			|||||||
		xasprintf(&fe->value, "%.*s", (int)gc.data.size, gc.data.data);
 | 
							xasprintf(&fe->value, "%.*s", (int)gc.data.size, gc.data.data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Callback for mouse_word. */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 x, y, end;
 | 
				
			||||||
 | 
						struct grid		*gd;
 | 
				
			||||||
 | 
						struct grid_line	*gl;
 | 
				
			||||||
 | 
						struct grid_cell	 gc;
 | 
				
			||||||
 | 
						const char		*ws;
 | 
				
			||||||
 | 
						struct utf8_data	*ud = NULL;
 | 
				
			||||||
 | 
						size_t			 size = 0;
 | 
				
			||||||
 | 
						int			 found = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ft->m.valid)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						wp = cmd_mouse_pane(&ft->m, NULL, NULL);
 | 
				
			||||||
 | 
						if (wp == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						gd = wp->base.grid;
 | 
				
			||||||
 | 
						ws = options_get_string(global_s_options, "word-separators");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						y = gd->hsize + y;
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							grid_get_cell(gd, x, y, &gc);
 | 
				
			||||||
 | 
							if (gc.flags & GRID_FLAG_PADDING)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (utf8_cstrhas(ws, &gc.data)) {
 | 
				
			||||||
 | 
								found = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (x == 0) {
 | 
				
			||||||
 | 
								if (y == 0)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								gl = &gd->linedata[y - 1];
 | 
				
			||||||
 | 
								if (~gl->flags & GRID_LINE_WRAPPED)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								y--;
 | 
				
			||||||
 | 
								x = grid_line_length(gd, y);
 | 
				
			||||||
 | 
								if (x == 0)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							x--;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							if (found) {
 | 
				
			||||||
 | 
								end = grid_line_length(gd, y);
 | 
				
			||||||
 | 
								if (end == 0 || x == end - 1) {
 | 
				
			||||||
 | 
									if (y == gd->hsize + gd->sy - 1)
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									gl = &gd->linedata[y];
 | 
				
			||||||
 | 
									if (~gl->flags & GRID_LINE_WRAPPED)
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									y++;
 | 
				
			||||||
 | 
									x = 0;
 | 
				
			||||||
 | 
								} else
 | 
				
			||||||
 | 
									x++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							found = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							grid_get_cell(gd, x, y, &gc);
 | 
				
			||||||
 | 
							if (gc.flags & GRID_FLAG_PADDING)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (utf8_cstrhas(ws, &gc.data))
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ud = xreallocarray(ud, size + 2, sizeof *ud);
 | 
				
			||||||
 | 
							memcpy(&ud[size++], &gc.data, sizeof *ud);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (size != 0) {
 | 
				
			||||||
 | 
							ud[size].size = 0;
 | 
				
			||||||
 | 
							fe->value = utf8_tocstr(ud);
 | 
				
			||||||
 | 
							free(ud);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Callback for mouse_line. */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 x, y;
 | 
				
			||||||
 | 
						struct grid		*gd;
 | 
				
			||||||
 | 
						struct grid_cell	 gc;
 | 
				
			||||||
 | 
						struct utf8_data	*ud = NULL;
 | 
				
			||||||
 | 
						size_t			 size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ft->m.valid)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						wp = cmd_mouse_pane(&ft->m, NULL, NULL);
 | 
				
			||||||
 | 
						if (wp == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						gd = wp->base.grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						y = gd->hsize + y;
 | 
				
			||||||
 | 
						for (x = 0; x < grid_line_length(gd, y); x++) {
 | 
				
			||||||
 | 
							grid_get_cell(gd, x, y, &gc);
 | 
				
			||||||
 | 
							if (gc.flags & GRID_FLAG_PADDING)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ud = xreallocarray(ud, size + 2, sizeof *ud);
 | 
				
			||||||
 | 
							memcpy(&ud[size++], &gc.data, sizeof *ud);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (size != 0) {
 | 
				
			||||||
 | 
							ud[size].size = 0;
 | 
				
			||||||
 | 
							fe->value = utf8_tocstr(ud);
 | 
				
			||||||
 | 
							free(ud);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Merge a format tree. */
 | 
					/* Merge a format tree. */
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
format_merge(struct format_tree *ft, struct format_tree *from)
 | 
					format_merge(struct format_tree *ft, struct format_tree *from)
 | 
				
			||||||
@@ -759,10 +882,29 @@ format_merge(struct format_tree *ft, struct format_tree *from)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
format_create_add_item(struct format_tree *ft, struct cmdq_item *item)
 | 
					format_create_add_item(struct format_tree *ft, struct cmdq_item *item)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct mouse_event	*m;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 x, y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (item->cmd != NULL)
 | 
						if (item->cmd != NULL)
 | 
				
			||||||
		format_add(ft, "command", "%s", item->cmd->entry->name);
 | 
							format_add(ft, "command", "%s", item->cmd->entry->name);
 | 
				
			||||||
	if (item->shared != NULL && item->shared->formats != NULL)
 | 
					
 | 
				
			||||||
 | 
						if (item->shared == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (item->shared->formats != NULL)
 | 
				
			||||||
		format_merge(ft, item->shared->formats);
 | 
							format_merge(ft, item->shared->formats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m = &item->shared->mouse;
 | 
				
			||||||
 | 
						if (m->valid && ((wp = cmd_mouse_pane(m, NULL, NULL)) != NULL)) {
 | 
				
			||||||
 | 
							format_add(ft, "mouse_pane", "%%%u", wp->id);
 | 
				
			||||||
 | 
							if (cmd_mouse_at(wp, m, &x, &y, 0) == 0) {
 | 
				
			||||||
 | 
								format_add(ft, "mouse_x", "%u", x);
 | 
				
			||||||
 | 
								format_add(ft, "mouse_y", "%u", y);
 | 
				
			||||||
 | 
								format_add_cb(ft, "mouse_word", format_cb_mouse_word);
 | 
				
			||||||
 | 
								format_add_cb(ft, "mouse_line", format_cb_mouse_line);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						memcpy(&ft->m, m, sizeof ft->m);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Create a new tree. */
 | 
					/* Create a new tree. */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								grid.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								grid.c
									
									
									
									
									
								
							@@ -1350,3 +1350,22 @@ grid_unwrap_position(struct grid *gd, u_int *px, u_int *py, u_int wx, u_int wy)
 | 
				
			|||||||
	*px = wx;
 | 
						*px = wx;
 | 
				
			||||||
	*py = yy;
 | 
						*py = yy;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get length of line. */
 | 
				
			||||||
 | 
					u_int
 | 
				
			||||||
 | 
					grid_line_length(struct grid *gd, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct grid_cell	gc;
 | 
				
			||||||
 | 
						u_int			px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						px = grid_get_line(gd, py)->cellsize;
 | 
				
			||||||
 | 
						if (px > gd->sx)
 | 
				
			||||||
 | 
							px = gd->sx;
 | 
				
			||||||
 | 
						while (px > 0) {
 | 
				
			||||||
 | 
							grid_get_cell(gd, px - 1, py, &gc);
 | 
				
			||||||
 | 
							if (gc.data.size != 1 || *gc.data.data != ' ')
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							px--;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (px);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										48
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								menu.c
									
									
									
									
									
								
							@@ -41,8 +41,8 @@ struct menu_data {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
menu_add_item(struct menu *menu, struct menu_item *item, struct client *c,
 | 
					menu_add_item(struct menu *menu, struct menu_item *item,
 | 
				
			||||||
    struct cmd_find_state *fs)
 | 
					    struct cmdq_item *qitem, struct client *c, struct cmd_find_state *fs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct menu_item	*new_item;
 | 
						struct menu_item	*new_item;
 | 
				
			||||||
	const char		*key;
 | 
						const char		*key;
 | 
				
			||||||
@@ -57,24 +57,31 @@ 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;
 | 
				
			||||||
	if (fs != NULL) {
 | 
						if (fs != NULL) {
 | 
				
			||||||
		name = format_single(NULL, item->name, c, fs->s, fs->wl,
 | 
							name = format_single(qitem, item->name, c, fs->s, fs->wl,
 | 
				
			||||||
		    fs->wp);
 | 
							    fs->wp);
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		name = xstrdup(item->name);
 | 
							name = format_single(qitem, item->name, c, NULL, NULL, NULL);
 | 
				
			||||||
	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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (item->key != KEYC_UNKNOWN) {
 | 
						if (item->key != KEYC_UNKNOWN) {
 | 
				
			||||||
		key = key_string_lookup_key(item->key);
 | 
							key = key_string_lookup_key(item->key);
 | 
				
			||||||
		xasprintf(&new_item->name, "%s #[align=right](%s)", name, key);
 | 
							xasprintf(&new_item->name, "%s#[default] #[align=right](%s)",
 | 
				
			||||||
 | 
							    name, key);
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		xasprintf(&new_item->name, "%s", name);
 | 
							xasprintf(&new_item->name, "%s", name);
 | 
				
			||||||
	free(name);
 | 
						free(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (item->command != NULL)
 | 
						if (item->command != NULL) {
 | 
				
			||||||
		new_item->command = xstrdup(item->command);
 | 
							if (fs != NULL) {
 | 
				
			||||||
	else
 | 
								new_item->command = format_single(qitem, item->command,
 | 
				
			||||||
 | 
								    c, fs->s, fs->wl, fs->wp);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								new_item->command = format_single(qitem, item->command,
 | 
				
			||||||
 | 
								    c, NULL, NULL, NULL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
		new_item->command = NULL;
 | 
							new_item->command = NULL;
 | 
				
			||||||
	new_item->key = item->key;
 | 
						new_item->key = item->key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,8 +91,8 @@ menu_add_item(struct menu *menu, struct menu_item *item, struct client *c,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
menu_parse_item(struct menu *menu, const char *s, struct client *c,
 | 
					menu_parse_item(struct menu *menu, const char *s, struct cmdq_item *qitem,
 | 
				
			||||||
    struct cmd_find_state *fs)
 | 
					    struct client *c, struct cmd_find_state *fs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char			*copy, *first;
 | 
						char			*copy, *first;
 | 
				
			||||||
	const char		*second, *third;
 | 
						const char		*second, *third;
 | 
				
			||||||
@@ -100,15 +107,15 @@ menu_parse_item(struct menu *menu, const char *s, struct client *c,
 | 
				
			|||||||
			item.name = first;
 | 
								item.name = first;
 | 
				
			||||||
			item.command = (char *)third;
 | 
								item.command = (char *)third;
 | 
				
			||||||
			item.key = key_string_lookup_string(second);
 | 
								item.key = key_string_lookup_string(second);
 | 
				
			||||||
			menu_add_item(menu, &item, c, fs);
 | 
								menu_add_item(menu, &item, qitem, c, fs);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(copy);
 | 
						free(copy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct menu *
 | 
					struct menu *
 | 
				
			||||||
menu_create(const char *s, struct client *c, struct cmd_find_state *fs,
 | 
					menu_create(const char *s, struct cmdq_item *qitem, struct client *c,
 | 
				
			||||||
    const char *title)
 | 
					    struct cmd_find_state *fs, const char *title)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct menu	*menu;
 | 
						struct menu	*menu;
 | 
				
			||||||
	char		*copy, *string, *next;
 | 
						char		*copy, *string, *next;
 | 
				
			||||||
@@ -124,10 +131,11 @@ menu_create(const char *s, struct client *c, struct cmd_find_state *fs,
 | 
				
			|||||||
		next = (char *)format_skip(string, "|");
 | 
							next = (char *)format_skip(string, "|");
 | 
				
			||||||
		if (next != NULL)
 | 
							if (next != NULL)
 | 
				
			||||||
			*next++ = '\0';
 | 
								*next++ = '\0';
 | 
				
			||||||
		if (*string == '\0')
 | 
							if (*string == '\0') {
 | 
				
			||||||
			menu_add_item(menu, NULL, c, fs);
 | 
								if (menu->count != 0)
 | 
				
			||||||
		else
 | 
									menu_add_item(menu, NULL, qitem, c, fs);
 | 
				
			||||||
			menu_parse_item(menu, string, c, fs);
 | 
							} else
 | 
				
			||||||
 | 
								menu_parse_item(menu, string, qitem, c, fs);
 | 
				
			||||||
		string = next;
 | 
							string = next;
 | 
				
			||||||
	} while (next != NULL);
 | 
						} while (next != NULL);
 | 
				
			||||||
	free(copy);
 | 
						free(copy);
 | 
				
			||||||
@@ -283,7 +291,11 @@ chosen:
 | 
				
			|||||||
		cmdq_append(c, new_item);
 | 
							cmdq_append(c, new_item);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case CMD_PARSE_SUCCESS:
 | 
						case CMD_PARSE_SUCCESS:
 | 
				
			||||||
		new_item = cmdq_get_command(pr->cmdlist, NULL, NULL, 0);
 | 
							if (md->item != NULL)
 | 
				
			||||||
 | 
								m = &md->item->shared->mouse;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								m = NULL;
 | 
				
			||||||
 | 
							new_item = cmdq_get_command(pr->cmdlist, &md->fs, m, 0);
 | 
				
			||||||
		cmd_list_free(pr->cmdlist);
 | 
							cmd_list_free(pr->cmdlist);
 | 
				
			||||||
		cmdq_append(c, new_item);
 | 
							cmdq_append(c, new_item);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -828,7 +828,7 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
 | 
				
			|||||||
		s = MODE_TREE_MENU;
 | 
							s = MODE_TREE_MENU;
 | 
				
			||||||
		title = xstrdup("");
 | 
							title = xstrdup("");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	menu = menu_create(s, c, NULL, title);
 | 
						menu = menu_create(s, NULL, c, NULL, title);
 | 
				
			||||||
	free(title);
 | 
						free(title);
 | 
				
			||||||
	if (menu == NULL)
 | 
						if (menu == NULL)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -551,7 +551,7 @@ const struct options_table_entry options_table[] = {
 | 
				
			|||||||
	{ .name = "word-separators",
 | 
						{ .name = "word-separators",
 | 
				
			||||||
	  .type = OPTIONS_TABLE_STRING,
 | 
						  .type = OPTIONS_TABLE_STRING,
 | 
				
			||||||
	  .scope = OPTIONS_TABLE_SESSION,
 | 
						  .scope = OPTIONS_TABLE_SESSION,
 | 
				
			||||||
	  .default_str = " -_@"
 | 
						  .default_str = " "
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Window options. */
 | 
						/* Window options. */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.1
									
									
									
									
									
								
							@@ -4129,6 +4129,10 @@ The following variables are available, where appropriate:
 | 
				
			|||||||
.It Li "mouse_any_flag" Ta "" Ta "Pane mouse any flag"
 | 
					.It Li "mouse_any_flag" Ta "" Ta "Pane mouse any flag"
 | 
				
			||||||
.It Li "mouse_button_flag" Ta "" Ta "Pane mouse button flag"
 | 
					.It Li "mouse_button_flag" Ta "" Ta "Pane mouse button flag"
 | 
				
			||||||
.It Li "mouse_standard_flag" Ta "" Ta "Pane mouse standard flag"
 | 
					.It Li "mouse_standard_flag" Ta "" Ta "Pane mouse standard flag"
 | 
				
			||||||
 | 
					.It Li "mouse_x" Ta "" Ta "Mouse X position, if any"
 | 
				
			||||||
 | 
					.It Li "mouse_y" Ta "" Ta "Mouse Y position, if any"
 | 
				
			||||||
 | 
					.It Li "mouse_word" Ta "" Ta "Word under mouse, if any"
 | 
				
			||||||
 | 
					.It Li "mouse_line" Ta "" Ta "Line under mouse, if any"
 | 
				
			||||||
.It Li "pane_active" Ta "" Ta "1 if active pane"
 | 
					.It Li "pane_active" Ta "" Ta "1 if active pane"
 | 
				
			||||||
.It Li "pane_at_bottom" Ta "" Ta "1 if pane is at the bottom of window"
 | 
					.It Li "pane_at_bottom" Ta "" Ta "1 if pane is at the bottom of window"
 | 
				
			||||||
.It Li "pane_at_left" Ta "" Ta "1 if pane is at the left of window"
 | 
					.It Li "pane_at_left" Ta "" Ta "1 if pane is at the left of window"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							@@ -2219,6 +2219,7 @@ void	 grid_duplicate_lines(struct grid *, u_int, struct grid *, u_int,
 | 
				
			|||||||
void	 grid_reflow(struct grid *, u_int);
 | 
					void	 grid_reflow(struct grid *, u_int);
 | 
				
			||||||
void	 grid_wrap_position(struct grid *, u_int, u_int, u_int *, u_int *);
 | 
					void	 grid_wrap_position(struct grid *, u_int, u_int, u_int *, u_int *);
 | 
				
			||||||
void	 grid_unwrap_position(struct grid *, u_int *, u_int *, u_int, u_int);
 | 
					void	 grid_unwrap_position(struct grid *, u_int *, u_int *, u_int, u_int);
 | 
				
			||||||
 | 
					u_int	 grid_line_length(struct grid *, u_int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* grid-view.c */
 | 
					/* grid-view.c */
 | 
				
			||||||
void	 grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
 | 
					void	 grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *);
 | 
				
			||||||
@@ -2583,6 +2584,7 @@ struct utf8_data *utf8_fromcstr(const char *);
 | 
				
			|||||||
char		*utf8_tocstr(struct utf8_data *);
 | 
					char		*utf8_tocstr(struct utf8_data *);
 | 
				
			||||||
u_int		 utf8_cstrwidth(const char *);
 | 
					u_int		 utf8_cstrwidth(const char *);
 | 
				
			||||||
char		*utf8_padcstr(const char *, u_int);
 | 
					char		*utf8_padcstr(const char *, u_int);
 | 
				
			||||||
 | 
					int		 utf8_cstrhas(const char *, const struct utf8_data *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* procname.c */
 | 
					/* procname.c */
 | 
				
			||||||
char   *get_proc_name(int, char *);
 | 
					char   *get_proc_name(int, char *);
 | 
				
			||||||
@@ -2598,7 +2600,7 @@ __dead void printflike(1, 2) fatal(const char *, ...);
 | 
				
			|||||||
__dead void printflike(1, 2) fatalx(const char *, ...);
 | 
					__dead void printflike(1, 2) fatalx(const char *, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* menu.c */
 | 
					/* menu.c */
 | 
				
			||||||
struct menu	*menu_create(const char *, struct client *,
 | 
					struct menu	*menu_create(const char *, struct cmdq_item *, struct client *,
 | 
				
			||||||
		    struct cmd_find_state *, const char *);
 | 
							    struct cmd_find_state *, const char *);
 | 
				
			||||||
void		 menu_free(struct menu *);
 | 
					void		 menu_free(struct menu *);
 | 
				
			||||||
int		 menu_display(struct menu *, int, struct cmdq_item *, u_int,
 | 
					int		 menu_display(struct menu *, int, struct cmdq_item *, u_int,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								utf8.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								utf8.c
									
									
									
									
									
								
							@@ -410,3 +410,23 @@ utf8_padcstr(const char *s, u_int width)
 | 
				
			|||||||
	out[slen] = '\0';
 | 
						out[slen] = '\0';
 | 
				
			||||||
	return (out);
 | 
						return (out);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					utf8_cstrhas(const char *s, const struct utf8_data *ud)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct utf8_data	*copy, *loop;
 | 
				
			||||||
 | 
						int			 found = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						copy = utf8_fromcstr(s);
 | 
				
			||||||
 | 
						for (loop = copy; loop->size != 0; loop++) {
 | 
				
			||||||
 | 
							if (loop->size != ud->size)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (memcmp(loop->data, ud->data, loop->size) == 0) {
 | 
				
			||||||
 | 
								found = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						free(copy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (found);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2810,54 +2810,19 @@ window_copy_in_set(struct window_mode_entry *wme, u_int px, u_int py,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	struct window_copy_mode_data	*data = wme->data;
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
	struct grid_cell		 gc;
 | 
						struct grid_cell		 gc;
 | 
				
			||||||
	const struct utf8_data		*ud;
 | 
					 | 
				
			||||||
	struct utf8_data		*copy;
 | 
					 | 
				
			||||||
	struct utf8_data		*loop;
 | 
					 | 
				
			||||||
	int				 found = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	grid_get_cell(data->backing->grid, px, py, &gc);
 | 
						grid_get_cell(data->backing->grid, px, py, &gc);
 | 
				
			||||||
	if (gc.flags & GRID_FLAG_PADDING)
 | 
						if (gc.flags & GRID_FLAG_PADDING)
 | 
				
			||||||
		return (0);
 | 
							return (0);
 | 
				
			||||||
	ud = &gc.data;
 | 
						return (utf8_cstrhas(set, &gc.data));
 | 
				
			||||||
 | 
					 | 
				
			||||||
	copy = utf8_fromcstr(set);
 | 
					 | 
				
			||||||
	for (loop = copy; loop->size != 0; loop++) {
 | 
					 | 
				
			||||||
		if (loop->size != ud->size)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		if (memcmp(loop->data, ud->data, loop->size) == 0) {
 | 
					 | 
				
			||||||
			found = 1;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	free(copy);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return (found);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u_int
 | 
					static u_int
 | 
				
			||||||
window_copy_find_length(struct window_mode_entry *wme, u_int py)
 | 
					window_copy_find_length(struct window_mode_entry *wme, u_int py)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct window_copy_mode_data	*data = wme->data;
 | 
						struct window_copy_mode_data	*data = wme->data;
 | 
				
			||||||
	struct screen			*s = data->backing;
 | 
					 | 
				
			||||||
	struct grid_cell		 gc;
 | 
					 | 
				
			||||||
	u_int				 px;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						return (grid_line_length(data->backing->grid, py));
 | 
				
			||||||
	 * If the pane has been resized, its grid can contain old overlong
 | 
					 | 
				
			||||||
	 * lines. grid_peek_cell does not allow accessing cells beyond the
 | 
					 | 
				
			||||||
	 * width of the grid, and screen_write_copy treats them as spaces, so
 | 
					 | 
				
			||||||
	 * ignore them here too.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	px = grid_get_line(s->grid, py)->cellsize;
 | 
					 | 
				
			||||||
	if (px > screen_size_x(s))
 | 
					 | 
				
			||||||
		px = screen_size_x(s);
 | 
					 | 
				
			||||||
	while (px > 0) {
 | 
					 | 
				
			||||||
		grid_get_cell(s->grid, px - 1, py, &gc);
 | 
					 | 
				
			||||||
		if (gc.data.size != 1 || *gc.data.data != ' ')
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		px--;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return (px);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user