mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Merge branch 'obsd-master' into master
This commit is contained in:
		| @@ -30,9 +30,9 @@ const struct cmd_entry cmd_choose_tree_entry = { | ||||
| 	.name = "choose-tree", | ||||
| 	.alias = NULL, | ||||
|  | ||||
| 	.args = { "F:Gf:NO:rst:wZ", 0, 1 }, | ||||
| 	.usage = "[-GNrswZ] [-F format] [-f filter] [-O sort-order] " | ||||
| 	         CMD_TARGET_PANE_USAGE " [template]", | ||||
| 	.args = { "F:f:GK:NO:rst:wZ", 0, 1 }, | ||||
| 	.usage = "[-GNrswZ] [-F format] [-f filter] [-K key-format] " | ||||
| 		 "[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]", | ||||
|  | ||||
| 	.target = { 't', CMD_FIND_PANE, 0 }, | ||||
|  | ||||
| @@ -44,9 +44,9 @@ const struct cmd_entry cmd_choose_client_entry = { | ||||
| 	.name = "choose-client", | ||||
| 	.alias = NULL, | ||||
|  | ||||
| 	.args = { "F:f:NO:rt:Z", 0, 1 }, | ||||
| 	.usage = "[-NrZ] [-F format] [-f filter] [-O sort-order] " | ||||
| 	         CMD_TARGET_PANE_USAGE " [template]", | ||||
| 	.args = { "F:f:K:NO:rt:Z", 0, 1 }, | ||||
| 	.usage = "[-NrZ] [-F format] [-f filter] [-K key-format] " | ||||
| 		 "[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]", | ||||
|  | ||||
| 	.target = { 't', CMD_FIND_PANE, 0 }, | ||||
|  | ||||
| @@ -58,9 +58,9 @@ const struct cmd_entry cmd_choose_buffer_entry = { | ||||
| 	.name = "choose-buffer", | ||||
| 	.alias = NULL, | ||||
|  | ||||
| 	.args = { "F:f:NO:rt:Z", 0, 1 }, | ||||
| 	.usage = "[-NrZ] [-F format] [-f filter] [-O sort-order] " | ||||
| 	         CMD_TARGET_PANE_USAGE " [template]", | ||||
| 	.args = { "F:f:K:NO:rt:Z", 0, 1 }, | ||||
| 	.usage = "[-NrZ] [-F format] [-f filter] [-K key-format] " | ||||
| 		 "[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]", | ||||
|  | ||||
| 	.target = { 't', CMD_FIND_PANE, 0 }, | ||||
|  | ||||
|   | ||||
							
								
								
									
										32
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								format.c
									
									
									
									
									
								
							| @@ -100,6 +100,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) | ||||
| #define FORMAT_QUOTE_STYLE 0x2000 | ||||
| #define FORMAT_WINDOW_NAME 0x4000 | ||||
| #define FORMAT_SESSION_NAME 0x8000 | ||||
| #define FORMAT_CHARACTER 0x10000 | ||||
|  | ||||
| /* Limit on recursion. */ | ||||
| #define FORMAT_LOOP_LIMIT 10 | ||||
| @@ -3522,7 +3523,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s, | ||||
|  | ||||
| 	/* | ||||
| 	 * Modifiers are a ; separated list of the forms: | ||||
| 	 *      l,m,C,b,d,n,t,w,q,E,T,S,W,P,<,> | ||||
| 	 *      l,m,C,a,b,d,n,t,w,q,E,T,S,W,P,<,> | ||||
| 	 *	=a | ||||
| 	 *	=/a | ||||
| 	 *      =/a/ | ||||
| @@ -3539,7 +3540,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s, | ||||
| 			cp++; | ||||
|  | ||||
| 		/* Check single character modifiers with no arguments. */ | ||||
| 		if (strchr("lbdnwETSWP<>", cp[0]) != NULL && | ||||
| 		if (strchr("labdnwETSWP<>", cp[0]) != NULL && | ||||
| 		    format_is_end(cp[1])) { | ||||
| 			format_add_modifier(&list, count, cp, 1, NULL, 0); | ||||
| 			cp++; | ||||
| @@ -4016,10 +4017,10 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, | ||||
| { | ||||
| 	struct format_tree		 *ft = es->ft; | ||||
| 	struct window_pane		 *wp = ft->wp; | ||||
| 	const char			 *errptr, *copy, *cp, *marker = NULL; | ||||
| 	const char			 *errstr, *copy, *cp, *marker = NULL; | ||||
| 	const char			 *time_format = NULL; | ||||
| 	char				 *copy0, *condition, *found, *new; | ||||
| 	char				 *value, *left, *right; | ||||
| 	char				 *value, *left, *right, c; | ||||
| 	size_t				  valuelen; | ||||
| 	int				  modifiers = 0, limit = 0, width = 0; | ||||
| 	int				  j; | ||||
| @@ -4063,8 +4064,8 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, | ||||
| 				if (fm->argc < 1) | ||||
| 					break; | ||||
| 				limit = strtonum(fm->argv[0], INT_MIN, INT_MAX, | ||||
| 				    &errptr); | ||||
| 				if (errptr != NULL) | ||||
| 				    &errstr); | ||||
| 				if (errstr != NULL) | ||||
| 					limit = 0; | ||||
| 				if (fm->argc >= 2 && fm->argv[1] != NULL) | ||||
| 					marker = fm->argv[1]; | ||||
| @@ -4073,8 +4074,8 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, | ||||
| 				if (fm->argc < 1) | ||||
| 					break; | ||||
| 				width = strtonum(fm->argv[0], INT_MIN, INT_MAX, | ||||
| 				    &errptr); | ||||
| 				if (errptr != NULL) | ||||
| 				    &errstr); | ||||
| 				if (errstr != NULL) | ||||
| 					width = 0; | ||||
| 				break; | ||||
| 			case 'w': | ||||
| @@ -4088,6 +4089,9 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, | ||||
| 			case 'l': | ||||
| 				modifiers |= FORMAT_LITERAL; | ||||
| 				break; | ||||
| 			case 'a': | ||||
| 				modifiers |= FORMAT_CHARACTER; | ||||
| 				break; | ||||
| 			case 'b': | ||||
| 				modifiers |= FORMAT_BASENAME; | ||||
| 				break; | ||||
| @@ -4154,6 +4158,18 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen, | ||||
| 		goto done; | ||||
| 	} | ||||
|  | ||||
| 	/* Is this a character? */ | ||||
| 	if (modifiers & FORMAT_CHARACTER) { | ||||
| 		new = format_expand1(es, copy); | ||||
| 		c = strtonum(new, 32, 126, &errstr); | ||||
| 		if (errstr != NULL) | ||||
| 			value = xstrdup(""); | ||||
| 		else | ||||
| 			xasprintf(&value, "%c", c); | ||||
| 		free (new); | ||||
| 		goto done; | ||||
| 	} | ||||
|  | ||||
| 	/* Is this a loop, comparison or condition? */ | ||||
| 	if (modifiers & FORMAT_SESSIONS) { | ||||
| 		value = format_loop_sessions(es, copy); | ||||
|   | ||||
							
								
								
									
										68
									
								
								mode-tree.c
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								mode-tree.c
									
									
									
									
									
								
							| @@ -46,6 +46,7 @@ struct mode_tree_data { | ||||
| 	mode_tree_search_cb       searchcb; | ||||
| 	mode_tree_menu_cb         menucb; | ||||
| 	mode_tree_height_cb       heightcb; | ||||
| 	mode_tree_key_cb	  keycb; | ||||
|  | ||||
| 	struct mode_tree_list	  children; | ||||
| 	struct mode_tree_list	  saved; | ||||
| @@ -74,6 +75,10 @@ struct mode_tree_item { | ||||
| 	void				*itemdata; | ||||
| 	u_int				 line; | ||||
|  | ||||
| 	key_code			 key; | ||||
| 	const char			*keystr; | ||||
| 	size_t				 keylen; | ||||
|  | ||||
| 	uint64_t			 tag; | ||||
| 	const char			*name; | ||||
| 	const char			*text; | ||||
| @@ -135,6 +140,7 @@ mode_tree_free_item(struct mode_tree_item *mti) | ||||
|  | ||||
| 	free((void *)mti->name); | ||||
| 	free((void *)mti->text); | ||||
| 	free((void *)mti->keystr); | ||||
|  | ||||
| 	free(mti); | ||||
| } | ||||
| @@ -193,6 +199,26 @@ mode_tree_build_lines(struct mode_tree_data *mtd, | ||||
| 			flat = 0; | ||||
| 		if (mti->expanded) | ||||
| 			mode_tree_build_lines(mtd, &mti->children, depth + 1); | ||||
|  | ||||
| 		if (mtd->keycb != NULL) { | ||||
| 			mti->key = mtd->keycb(mtd->modedata, mti->itemdata, | ||||
| 			    mti->line); | ||||
| 			if (mti->key == KEYC_UNKNOWN) | ||||
| 				mti->key = KEYC_NONE; | ||||
| 		} else if (mti->line < 10) | ||||
| 			mti->key = '0' + mti->line; | ||||
| 		else if (mti->line < 36) | ||||
| 			mti->key = KEYC_META|('a' + mti->line - 10); | ||||
| 		else | ||||
| 			mti->key = KEYC_NONE; | ||||
| 		if (mti->key != KEYC_NONE) { | ||||
| 			mti->keystr = xstrdup(key_string_lookup_key(mti->key, | ||||
| 			    0)); | ||||
| 			mti->keylen = strlen(mti->keystr); | ||||
| 		} else { | ||||
| 			mti->keystr = NULL; | ||||
| 			mti->keylen = 0; | ||||
| 		} | ||||
| 	} | ||||
| 	TAILQ_FOREACH(mti, mtl, entry) { | ||||
| 		for (i = 0; i < mtd->line_size; i++) { | ||||
| @@ -363,7 +389,7 @@ struct mode_tree_data * | ||||
| mode_tree_start(struct window_pane *wp, struct args *args, | ||||
|     mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb, | ||||
|     mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, | ||||
|     mode_tree_height_cb heightcb, void *modedata, | ||||
|     mode_tree_height_cb heightcb, mode_tree_key_cb keycb, void *modedata, | ||||
|     const struct menu_item *menu, const char **sort_list, u_int sort_size, | ||||
|     struct screen **s) | ||||
| { | ||||
| @@ -402,6 +428,7 @@ mode_tree_start(struct window_pane *wp, struct args *args, | ||||
| 	mtd->searchcb = searchcb; | ||||
| 	mtd->menucb = menucb; | ||||
| 	mtd->heightcb = heightcb; | ||||
| 	mtd->keycb = keycb; | ||||
|  | ||||
| 	TAILQ_INIT(&mtd->children); | ||||
|  | ||||
| @@ -596,10 +623,10 @@ mode_tree_draw(struct mode_tree_data *mtd) | ||||
| 	struct screen_write_ctx	 ctx; | ||||
| 	struct grid_cell	 gc0, gc; | ||||
| 	u_int			 w, h, i, j, sy, box_x, box_y, width; | ||||
| 	char			*text, *start, key[7]; | ||||
| 	char			*text, *start, *key; | ||||
| 	const char		*tag, *symbol; | ||||
| 	size_t			 size, n; | ||||
| 	int			 keylen; | ||||
| 	int			 keylen, pad; | ||||
|  | ||||
| 	if (mtd->line_size == 0) | ||||
| 		return; | ||||
| @@ -614,28 +641,30 @@ mode_tree_draw(struct mode_tree_data *mtd) | ||||
| 	screen_write_start(&ctx, s); | ||||
| 	screen_write_clearscreen(&ctx, 8); | ||||
|  | ||||
| 	if (mtd->line_size > 10) | ||||
| 		keylen = 6; | ||||
| 	else | ||||
| 		keylen = 4; | ||||
| 	keylen = 0; | ||||
| 	for (i = 0; i < mtd->line_size; i++) { | ||||
| 		mti = mtd->line_list[i].item; | ||||
| 		if (mti->key == KEYC_NONE) | ||||
| 			continue; | ||||
| 		if ((int)mti->keylen + 3 > keylen) | ||||
| 			keylen = mti->keylen + 3; | ||||
| 	} | ||||
|  | ||||
| 	for (i = 0; i < mtd->line_size; i++) { | ||||
| 		if (i < mtd->offset) | ||||
| 			continue; | ||||
| 		if (i > mtd->offset + h - 1) | ||||
| 			break; | ||||
|  | ||||
| 		line = &mtd->line_list[i]; | ||||
| 		mti = line->item; | ||||
|  | ||||
| 		screen_write_cursormove(&ctx, 0, i - mtd->offset, 0); | ||||
|  | ||||
| 		if (i < 10) | ||||
| 			snprintf(key, sizeof key, "(%c)  ", '0' + i); | ||||
| 		else if (i < 36) | ||||
| 			snprintf(key, sizeof key, "(M-%c)", 'a' + (i - 10)); | ||||
| 		pad = keylen - 2 - mti->keylen; | ||||
| 		if (mti->key != KEYC_NONE) | ||||
| 			xasprintf(&key, "(%s)%*s", mti->keystr, pad, ""); | ||||
| 		else | ||||
| 			*key = '\0'; | ||||
| 			key = xstrdup(""); | ||||
|  | ||||
| 		if (line->flat) | ||||
| 			symbol = ""; | ||||
| @@ -698,6 +727,7 @@ mode_tree_draw(struct mode_tree_data *mtd) | ||||
| 			} | ||||
| 		} | ||||
| 		free(text); | ||||
| 		free(key); | ||||
|  | ||||
| 		if (mti->tagged) { | ||||
| 			gc.attr ^= GRID_ATTR_BRIGHT; | ||||
| @@ -951,7 +981,6 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, | ||||
| 	struct mode_tree_item	*current, *parent, *mti; | ||||
| 	u_int			 i, x, y; | ||||
| 	int			 choice; | ||||
| 	key_code		 tmp; | ||||
|  | ||||
| 	if (KEYC_IS_MOUSE(*key) && m != NULL) { | ||||
| 		if (cmd_mouse_at(mtd->wp, m, &x, &y, 0) != 0) { | ||||
| @@ -993,12 +1022,11 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, | ||||
| 	current = line->item; | ||||
|  | ||||
| 	choice = -1; | ||||
| 	if (*key >= '0' && *key <= '9') | ||||
| 		choice = (*key) - '0'; | ||||
| 	else if (((*key) & KEYC_MASK_MODIFIERS) == KEYC_META) { | ||||
| 		tmp = (*key) & KEYC_MASK_KEY; | ||||
| 		if (tmp >= 'a' && tmp <= 'z') | ||||
| 			choice = 10 + (tmp - 'a'); | ||||
| 	for (i = 0; i < mtd->line_size; i++) { | ||||
| 		if (*key == mtd->line_list[i].item->key) { | ||||
| 			choice = i; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (choice != -1) { | ||||
| 		if ((u_int)choice > mtd->line_size - 1) { | ||||
|   | ||||
							
								
								
									
										34
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -1985,12 +1985,17 @@ The default is to capture only the visible contents of the pane. | ||||
| .Op Fl NrZ | ||||
| .Op Fl F Ar format | ||||
| .Op Fl f Ar filter | ||||
| .Op Fl K Ar key-format | ||||
| .Op Fl O Ar sort-order | ||||
| .Op Fl t Ar target-pane | ||||
| .Op Ar template | ||||
| .Xc | ||||
| Put a pane into client mode, allowing a client to be selected interactively from | ||||
| a list. | ||||
| Each client is shown on one line. | ||||
| A shortcut key is shown on the left in brackets allowing for immediate choice, | ||||
| or the list may be navigated and an item chosen or otherwise manipulated using | ||||
| the keys below. | ||||
| .Fl Z | ||||
| zooms the pane. | ||||
| The following keys may be used in client mode: | ||||
| @@ -2040,7 +2045,9 @@ specifies an initial filter: the filter is a format - if it evaluates to zero, | ||||
| the item in the list is not shown, otherwise it is shown. | ||||
| If a filter would lead to an empty list, it is ignored. | ||||
| .Fl F | ||||
| specifies the format for each item in the list. | ||||
| specifies the format for each item in the list and | ||||
| .Fl K | ||||
| a format for each shortcut key; both are evaluated once for each line. | ||||
| .Fl N | ||||
| starts without the preview. | ||||
| This command works only if at least one client is attached. | ||||
| @@ -2049,12 +2056,17 @@ This command works only if at least one client is attached. | ||||
| .Op Fl GNrswZ | ||||
| .Op Fl F Ar format | ||||
| .Op Fl f Ar filter | ||||
| .Op Fl K Ar key-format | ||||
| .Op Fl O Ar sort-order | ||||
| .Op Fl t Ar target-pane | ||||
| .Op Ar template | ||||
| .Xc | ||||
| Put a pane into tree mode, where a session, window or pane may be chosen | ||||
| interactively from a list. | ||||
| interactively from a tree. | ||||
| Each session, window or pane is shown on one line. | ||||
| A shortcut key is shown on the left in brackets allowing for immediate choice, | ||||
| or the tree may be navigated and an item chosen or otherwise manipulated using | ||||
| the keys below. | ||||
| .Fl s | ||||
| starts with sessions collapsed and | ||||
| .Fl w | ||||
| @@ -2113,7 +2125,9 @@ specifies an initial filter: the filter is a format - if it evaluates to zero, | ||||
| the item in the list is not shown, otherwise it is shown. | ||||
| If a filter would lead to an empty list, it is ignored. | ||||
| .Fl F | ||||
| specifies the format for each item in the tree. | ||||
| specifies the format for each item in the tree and | ||||
| .Fl K | ||||
| a format for each shortcut key; both are evaluated once for each line. | ||||
| .Fl N | ||||
| starts without the preview. | ||||
| .Fl G | ||||
| @@ -4663,6 +4677,11 @@ For example, | ||||
| multiplies 5.5 by 3 for a result with four decimal places and | ||||
| .Ql #{e|%%:7,3} | ||||
| returns the modulus of 7 and 3. | ||||
| .Ql a | ||||
| replaces a numeric argument by its ASCII equivalent, so | ||||
| .Ql #{a:98} | ||||
| results in | ||||
| .Ql b . | ||||
| .Pp | ||||
| A limit may be placed on the length of the resultant string by prefixing it | ||||
| by an | ||||
| @@ -5681,12 +5700,17 @@ The buffer commands are as follows: | ||||
| .Op Fl NZr | ||||
| .Op Fl F Ar format | ||||
| .Op Fl f Ar filter | ||||
| .Op Fl K Ar key-format | ||||
| .Op Fl O Ar sort-order | ||||
| .Op Fl t Ar target-pane | ||||
| .Op Ar template | ||||
| .Xc | ||||
| Put a pane into buffer mode, where a buffer may be chosen interactively from | ||||
| a list. | ||||
| Each buffer is shown on one line. | ||||
| A shortcut key is shown on the left in brackets allowing for immediate choice, | ||||
| or the list may be navigated and an item chosen or otherwise manipulated using | ||||
| the keys below. | ||||
| .Fl Z | ||||
| zooms the pane. | ||||
| The following keys may be used in buffer mode: | ||||
| @@ -5734,7 +5758,9 @@ specifies an initial filter: the filter is a format - if it evaluates to zero, | ||||
| the item in the list is not shown, otherwise it is shown. | ||||
| If a filter would lead to an empty list, it is ignored. | ||||
| .Fl F | ||||
| specifies the format for each item in the list. | ||||
| specifies the format for each item in the list and | ||||
| .Fl K | ||||
| a format for each shortcut key; both are evaluated once for each line. | ||||
| .Fl N | ||||
| starts without the preview. | ||||
| This command works only if at least one client is attached. | ||||
|   | ||||
							
								
								
									
										3
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -2856,6 +2856,7 @@ typedef void (*mode_tree_draw_cb)(void *, void *, struct screen_write_ctx *, | ||||
| typedef int (*mode_tree_search_cb)(void *, void *, const char *); | ||||
| typedef void (*mode_tree_menu_cb)(void *, struct client *, key_code); | ||||
| typedef u_int (*mode_tree_height_cb)(void *, u_int); | ||||
| typedef key_code (*mode_tree_key_cb)(void *, 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 *); | ||||
| @@ -2870,7 +2871,7 @@ void	 mode_tree_up(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 *, | ||||
| 	     mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb, | ||||
| 	     mode_tree_menu_cb, mode_tree_height_cb, void *, | ||||
| 	     mode_tree_menu_cb, mode_tree_height_cb, mode_tree_key_cb, void *, | ||||
| 	     const struct menu_item *, const char **, u_int, struct screen **); | ||||
| void	 mode_tree_zoom(struct mode_tree_data *, struct args *); | ||||
| void	 mode_tree_build(struct mode_tree_data *); | ||||
|   | ||||
| @@ -41,6 +41,17 @@ static void		 window_buffer_key(struct window_mode_entry *, | ||||
| #define WINDOW_BUFFER_DEFAULT_FORMAT \ | ||||
| 	"#{t/p:buffer_created}: #{buffer_sample}" | ||||
|  | ||||
| #define WINDOW_BUFFER_DEFAULT_KEY_FORMAT \ | ||||
| 	"#{?#{e|<:#{line},10}," \ | ||||
| 		"#{line}" \ | ||||
| 	"," \ | ||||
| 		"#{?#{e|<:#{line},36},"	\ | ||||
| 	        	"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \ | ||||
| 		"," \ | ||||
| 	        	"" \ | ||||
| 		"}" \ | ||||
| 	"}" | ||||
|  | ||||
| static const struct menu_item window_buffer_menu_items[] = { | ||||
| 	{ "Paste", 'p', NULL }, | ||||
| 	{ "Paste Tagged", 'P', NULL }, | ||||
| @@ -93,6 +104,7 @@ struct window_buffer_modedata { | ||||
| 	struct mode_tree_data		 *data; | ||||
| 	char				 *command; | ||||
| 	char				 *format; | ||||
| 	char				 *key_format; | ||||
|  | ||||
| 	struct window_buffer_itemdata	**item_list; | ||||
| 	u_int				  item_size; | ||||
| @@ -232,7 +244,8 @@ window_buffer_draw(__unused void *modedata, void *itemdata, | ||||
| 		while (end != pdata + psize && *end != '\n') | ||||
| 			end++; | ||||
| 		buf = xreallocarray(buf, 4, end - start + 1); | ||||
| 		utf8_strvis(buf, start, end - start, VIS_OCTAL|VIS_CSTYLE|VIS_TAB); | ||||
| 		utf8_strvis(buf, start, end - start, | ||||
| 		    VIS_OCTAL|VIS_CSTYLE|VIS_TAB); | ||||
| 		if (*buf != '\0') { | ||||
| 			screen_write_cursormove(ctx, cx, cy + i, 0); | ||||
| 			screen_write_nputs(ctx, sx, &grid_default_cell, "%s", | ||||
| @@ -275,6 +288,41 @@ window_buffer_menu(void *modedata, struct client *c, key_code key) | ||||
| 	window_buffer_key(wme, c, NULL, NULL, key, NULL); | ||||
| } | ||||
|  | ||||
| static key_code | ||||
| window_buffer_get_key(void *modedata, void *itemdata, u_int line) | ||||
| { | ||||
| 	struct window_buffer_modedata	*data = modedata; | ||||
| 	struct window_buffer_itemdata	*item = itemdata; | ||||
| 	struct format_tree		*ft; | ||||
| 	struct session			*s; | ||||
| 	struct winlink			*wl; | ||||
| 	struct window_pane		*wp; | ||||
| 	struct paste_buffer		*pb; | ||||
| 	char				*expanded; | ||||
| 	key_code			 key; | ||||
|  | ||||
| 	if (cmd_find_valid_state(&data->fs)) { | ||||
| 		s = data->fs.s; | ||||
| 		wl = data->fs.wl; | ||||
| 		wp = data->fs.wp; | ||||
| 	} | ||||
| 	pb = paste_get_name(item->name); | ||||
| 	if (pb == NULL) | ||||
| 		return KEYC_NONE; | ||||
|  | ||||
| 	ft = format_create(NULL, NULL, FORMAT_NONE, 0); | ||||
| 	format_defaults(ft, NULL, NULL, 0, NULL); | ||||
| 	format_defaults(ft, NULL, s, wl, wp); | ||||
| 	format_defaults_paste_buffer(ft, pb); | ||||
| 	format_add(ft, "line", "%u", line); | ||||
|  | ||||
| 	expanded = format_expand(ft, data->key_format); | ||||
| 	key = key_string_lookup_string(expanded); | ||||
| 	free(expanded); | ||||
| 	format_free(ft); | ||||
| 	return key; | ||||
| } | ||||
|  | ||||
| static struct screen * | ||||
| window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs, | ||||
|     struct args *args) | ||||
| @@ -291,6 +339,10 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs, | ||||
| 		data->format = xstrdup(WINDOW_BUFFER_DEFAULT_FORMAT); | ||||
| 	else | ||||
| 		data->format = xstrdup(args_get(args, 'F')); | ||||
| 	if (args == NULL || !args_has(args, 'K')) | ||||
| 		data->key_format = xstrdup(WINDOW_BUFFER_DEFAULT_KEY_FORMAT); | ||||
| 	else | ||||
| 		data->key_format = xstrdup(args_get(args, 'K')); | ||||
| 	if (args == NULL || args->argc == 0) | ||||
| 		data->command = xstrdup(WINDOW_BUFFER_DEFAULT_COMMAND); | ||||
| 	else | ||||
| @@ -298,8 +350,8 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs, | ||||
|  | ||||
| 	data->data = mode_tree_start(wp, args, window_buffer_build, | ||||
| 	    window_buffer_draw, window_buffer_search, window_buffer_menu, NULL, | ||||
| 	    data, window_buffer_menu_items, window_buffer_sort_list, | ||||
| 	    nitems(window_buffer_sort_list), &s); | ||||
| 	    window_buffer_get_key, data, window_buffer_menu_items, | ||||
| 	    window_buffer_sort_list, nitems(window_buffer_sort_list), &s); | ||||
| 	mode_tree_zoom(data->data, args); | ||||
|  | ||||
| 	mode_tree_build(data->data); | ||||
| @@ -324,6 +376,7 @@ window_buffer_free(struct window_mode_entry *wme) | ||||
| 	free(data->item_list); | ||||
|  | ||||
| 	free(data->format); | ||||
| 	free(data->key_format); | ||||
| 	free(data->command); | ||||
|  | ||||
| 	free(data); | ||||
|   | ||||
| @@ -40,6 +40,17 @@ static void		 window_client_key(struct window_mode_entry *, | ||||
| #define WINDOW_CLIENT_DEFAULT_FORMAT \ | ||||
| 	"#{t/p:client_activity}: session #{session_name}" | ||||
|  | ||||
| #define WINDOW_CLIENT_DEFAULT_KEY_FORMAT \ | ||||
| 	"#{?#{e|<:#{line},10}," \ | ||||
| 		"#{line}" \ | ||||
| 	"," \ | ||||
| 		"#{?#{e|<:#{line},36},"	\ | ||||
| 	        	"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \ | ||||
| 		"," \ | ||||
| 	        	"" \ | ||||
| 		"}" \ | ||||
| 	"}" | ||||
|  | ||||
| static const struct menu_item window_client_menu_items[] = { | ||||
| 	{ "Detach", 'd', NULL }, | ||||
| 	{ "Detach Tagged", 'D', NULL }, | ||||
| @@ -87,6 +98,7 @@ struct window_client_modedata { | ||||
|  | ||||
| 	struct mode_tree_data		 *data; | ||||
| 	char				 *format; | ||||
| 	char				 *key_format; | ||||
| 	char				 *command; | ||||
|  | ||||
| 	struct window_client_itemdata	**item_list; | ||||
| @@ -252,6 +264,26 @@ window_client_menu(void *modedata, struct client *c, key_code key) | ||||
| 	window_client_key(wme, c, NULL, NULL, key, NULL); | ||||
| } | ||||
|  | ||||
| static key_code | ||||
| window_client_get_key(void *modedata, void *itemdata, u_int line) | ||||
| { | ||||
| 	struct window_client_modedata	*data = modedata; | ||||
| 	struct window_client_itemdata	*item = itemdata; | ||||
| 	struct format_tree		*ft; | ||||
| 	char				*expanded; | ||||
| 	key_code			 key; | ||||
|  | ||||
| 	ft = format_create(NULL, NULL, FORMAT_NONE, 0); | ||||
| 	format_defaults(ft, item->c, NULL, 0, NULL); | ||||
| 	format_add(ft, "line", "%u", line); | ||||
|  | ||||
| 	expanded = format_expand(ft, data->key_format); | ||||
| 	key = key_string_lookup_string(expanded); | ||||
| 	free(expanded); | ||||
| 	format_free(ft); | ||||
| 	return key; | ||||
| } | ||||
|  | ||||
| static struct screen * | ||||
| window_client_init(struct window_mode_entry *wme, | ||||
|     __unused struct cmd_find_state *fs, struct args *args) | ||||
| @@ -267,15 +299,19 @@ window_client_init(struct window_mode_entry *wme, | ||||
| 		data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT); | ||||
| 	else | ||||
| 		data->format = xstrdup(args_get(args, 'F')); | ||||
| 	if (args == NULL || !args_has(args, 'K')) | ||||
| 		data->key_format = xstrdup(WINDOW_CLIENT_DEFAULT_KEY_FORMAT); | ||||
| 	else | ||||
| 		data->key_format = xstrdup(args_get(args, 'K')); | ||||
| 	if (args == NULL || args->argc == 0) | ||||
| 		data->command = xstrdup(WINDOW_CLIENT_DEFAULT_COMMAND); | ||||
| 	else | ||||
| 		data->command = xstrdup(args->argv[0]); | ||||
|  | ||||
| 	data->data = mode_tree_start(wp, args, window_client_build, | ||||
| 	    window_client_draw, NULL, window_client_menu, NULL, data, | ||||
| 	    window_client_menu_items, window_client_sort_list, | ||||
| 	    nitems(window_client_sort_list), &s); | ||||
| 	    window_client_draw, NULL, window_client_menu, NULL, | ||||
| 	    window_client_get_key, data, window_client_menu_items, | ||||
| 	    window_client_sort_list, nitems(window_client_sort_list), &s); | ||||
| 	mode_tree_zoom(data->data, args); | ||||
|  | ||||
| 	mode_tree_build(data->data); | ||||
| @@ -300,6 +336,7 @@ window_client_free(struct window_mode_entry *wme) | ||||
| 	free(data->item_list); | ||||
|  | ||||
| 	free(data->format); | ||||
| 	free(data->key_format); | ||||
| 	free(data->command); | ||||
|  | ||||
| 	free(data); | ||||
|   | ||||
| @@ -890,8 +890,8 @@ window_customize_init(struct window_mode_entry *wme, struct cmd_find_state *fs, | ||||
|  | ||||
| 	data->data = mode_tree_start(wp, args, window_customize_build, | ||||
| 	    window_customize_draw, NULL, window_customize_menu, | ||||
| 	    window_customize_height, data, window_customize_menu_items, NULL, 0, | ||||
| 	    &s); | ||||
| 	    window_customize_height, NULL, data, window_customize_menu_items, | ||||
| 	    NULL, 0, &s); | ||||
| 	mode_tree_zoom(data->data, args); | ||||
|  | ||||
| 	mode_tree_build(data->data); | ||||
|   | ||||
| @@ -56,6 +56,17 @@ static void		 window_tree_key(struct window_mode_entry *, | ||||
| 		"}" \ | ||||
| 	"}" | ||||
|  | ||||
| #define WINDOW_TREE_DEFAULT_KEY_FORMAT \ | ||||
| 	"#{?#{e|<:#{line},10}," \ | ||||
| 		"#{line}" \ | ||||
| 	"," \ | ||||
| 		"#{?#{e|<:#{line},36},"	\ | ||||
| 	        	"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \ | ||||
| 		"," \ | ||||
| 	        	"" \ | ||||
| 		"}" \ | ||||
| 	"}" | ||||
|  | ||||
| static const struct menu_item window_tree_menu_items[] = { | ||||
| 	{ "Select", '\r', NULL }, | ||||
| 	{ "Expand", KEYC_RIGHT, NULL }, | ||||
| @@ -117,6 +128,7 @@ struct window_tree_modedata { | ||||
|  | ||||
| 	struct mode_tree_data		 *data; | ||||
| 	char				 *format; | ||||
| 	char				 *key_format; | ||||
| 	char				 *command; | ||||
| 	int				  squash_groups; | ||||
|  | ||||
| @@ -856,6 +868,35 @@ window_tree_menu(void *modedata, struct client *c, key_code key) | ||||
| 	window_tree_key(wme, c, NULL, NULL, key, NULL); | ||||
| } | ||||
|  | ||||
| static key_code | ||||
| window_tree_get_key(void *modedata, void *itemdata, u_int line) | ||||
| { | ||||
| 	struct window_tree_modedata	*data = modedata; | ||||
| 	struct window_tree_itemdata	*item = itemdata; | ||||
| 	struct format_tree		*ft; | ||||
| 	struct session			*s; | ||||
| 	struct winlink			*wl; | ||||
| 	struct window_pane		*wp; | ||||
| 	char				*expanded; | ||||
| 	key_code			 key; | ||||
|  | ||||
| 	ft = format_create(NULL, NULL, FORMAT_NONE, 0); | ||||
| 	window_tree_pull_item(item, &s, &wl, &wp); | ||||
| 	if (item->type == WINDOW_TREE_SESSION) | ||||
| 		format_defaults(ft, NULL, s, NULL, NULL); | ||||
| 	else if (item->type == WINDOW_TREE_WINDOW) | ||||
| 		format_defaults(ft, NULL, s, wl, NULL); | ||||
| 	else | ||||
| 		format_defaults(ft, NULL, s, wl, wp); | ||||
| 	format_add(ft, "line", "%u", line); | ||||
|  | ||||
| 	expanded = format_expand(ft, data->key_format); | ||||
| 	key = key_string_lookup_string(expanded); | ||||
| 	free(expanded); | ||||
| 	format_free(ft); | ||||
| 	return key; | ||||
| } | ||||
|  | ||||
| static struct screen * | ||||
| window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs, | ||||
|     struct args *args) | ||||
| @@ -880,6 +921,10 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs, | ||||
| 		data->format = xstrdup(WINDOW_TREE_DEFAULT_FORMAT); | ||||
| 	else | ||||
| 		data->format = xstrdup(args_get(args, 'F')); | ||||
| 	if (args == NULL || !args_has(args, 'K')) | ||||
| 		data->key_format = xstrdup(WINDOW_TREE_DEFAULT_KEY_FORMAT); | ||||
| 	else | ||||
| 		data->key_format = xstrdup(args_get(args, 'K')); | ||||
| 	if (args == NULL || args->argc == 0) | ||||
| 		data->command = xstrdup(WINDOW_TREE_DEFAULT_COMMAND); | ||||
| 	else | ||||
| @@ -887,9 +932,9 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs, | ||||
| 	data->squash_groups = !args_has(args, 'G'); | ||||
|  | ||||
| 	data->data = mode_tree_start(wp, args, window_tree_build, | ||||
| 	    window_tree_draw, window_tree_search, window_tree_menu, NULL, data, | ||||
| 	    window_tree_menu_items, window_tree_sort_list, | ||||
| 	    nitems(window_tree_sort_list), &s); | ||||
| 	    window_tree_draw, window_tree_search, window_tree_menu, NULL, | ||||
| 	    window_tree_get_key, data, window_tree_menu_items, | ||||
| 	    window_tree_sort_list, nitems(window_tree_sort_list), &s); | ||||
| 	mode_tree_zoom(data->data, args); | ||||
|  | ||||
| 	mode_tree_build(data->data); | ||||
| @@ -913,6 +958,7 @@ window_tree_destroy(struct window_tree_modedata *data) | ||||
| 	free(data->item_list); | ||||
|  | ||||
| 	free(data->format); | ||||
| 	free(data->key_format); | ||||
| 	free(data->command); | ||||
|  | ||||
| 	free(data); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Thomas Adam
					Thomas Adam