mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +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
	 nicm
					nicm