mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Incremental search in copy mode (on for emacs keys by default) - much
the same as normal searching but updates the cursor position and marked search terms as you type. C-r and C-s in the prompt repeat the search, once finished searching (with Enter), N and n work as before.
This commit is contained in:
		| @@ -32,15 +32,15 @@ | ||||
| static enum cmd_retval	cmd_command_prompt_exec(struct cmd *, | ||||
| 			    struct cmdq_item *); | ||||
|  | ||||
| static int	cmd_command_prompt_callback(void *, const char *); | ||||
| static int	cmd_command_prompt_callback(void *, const char *, int); | ||||
| static void	cmd_command_prompt_free(void *); | ||||
|  | ||||
| const struct cmd_entry cmd_command_prompt_entry = { | ||||
| 	.name = "command-prompt", | ||||
| 	.alias = NULL, | ||||
|  | ||||
| 	.args = { "1I:Np:t:", 0, 1 }, | ||||
| 	.usage = "[-1N] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " " | ||||
| 	.args = { "1iI:Np:t:", 0, 1 }, | ||||
| 	.usage = "[-1Ni] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " " | ||||
| 		 "[template]", | ||||
|  | ||||
| 	.tflag = CMD_CLIENT, | ||||
| @@ -51,10 +51,14 @@ const struct cmd_entry cmd_command_prompt_entry = { | ||||
|  | ||||
| struct cmd_command_prompt_cdata { | ||||
| 	struct client	*c; | ||||
| 	int		 flags; | ||||
|  | ||||
| 	char		*inputs; | ||||
| 	char		*next_input; | ||||
| 	char		*next_prompt; | ||||
|  | ||||
| 	char		*prompts; | ||||
| 	char		*next_prompt; | ||||
|  | ||||
| 	char		*template; | ||||
| 	int		 idx; | ||||
| }; | ||||
| @@ -73,14 +77,17 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 	if (c->prompt_string != NULL) | ||||
| 		return (CMD_RETURN_NORMAL); | ||||
|  | ||||
| 	cdata = xmalloc(sizeof *cdata); | ||||
| 	cdata = xcalloc(1, sizeof *cdata); | ||||
| 	cdata->c = c; | ||||
| 	cdata->idx = 1; | ||||
|  | ||||
| 	cdata->inputs = NULL; | ||||
| 	cdata->next_input = NULL; | ||||
| 	cdata->next_prompt = NULL; | ||||
|  | ||||
| 	cdata->prompts = NULL; | ||||
| 	cdata->next_prompt = NULL; | ||||
|  | ||||
| 	cdata->template = NULL; | ||||
| 	cdata->idx = 1; | ||||
|  | ||||
| 	if (args->argc != 0) | ||||
| 		cdata->template = xstrdup(args->argv[0]); | ||||
| @@ -112,11 +119,13 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) | ||||
|  | ||||
| 	flags = 0; | ||||
| 	if (args_has(args, '1')) | ||||
| 		flags |= PROMPT_SINGLE; | ||||
| 		cdata->flags |= PROMPT_SINGLE; | ||||
| 	else if (args_has(args, 'N')) | ||||
| 		flags |= PROMPT_NUMERIC; | ||||
| 		cdata->flags |= PROMPT_NUMERIC; | ||||
| 	else if (args_has(args, 'i')) | ||||
| 		cdata->flags |= PROMPT_INCREMENTAL; | ||||
| 	status_prompt_set(c, prompt, input, cmd_command_prompt_callback, | ||||
| 	    cmd_command_prompt_free, cdata, flags); | ||||
| 	    cmd_command_prompt_free, cdata, cdata->flags); | ||||
| 	free(prompt); | ||||
|  | ||||
| 	return (CMD_RETURN_NORMAL); | ||||
| @@ -134,7 +143,7 @@ cmd_command_prompt_error(struct cmdq_item *item, void *data) | ||||
| } | ||||
|  | ||||
| static int | ||||
| cmd_command_prompt_callback(void *data, const char *s) | ||||
| cmd_command_prompt_callback(void *data, const char *s, int done) | ||||
| { | ||||
| 	struct cmd_command_prompt_cdata	*cdata = data; | ||||
| 	struct client			*c = cdata->c; | ||||
| @@ -145,16 +154,20 @@ cmd_command_prompt_callback(void *data, const char *s) | ||||
|  | ||||
| 	if (s == NULL) | ||||
| 		return (0); | ||||
| 	if (done && (cdata->flags & PROMPT_INCREMENTAL)) | ||||
| 		return (0); | ||||
|  | ||||
| 	new_template = cmd_template_replace(cdata->template, s, cdata->idx); | ||||
| 	if (done) { | ||||
| 		free(cdata->template); | ||||
| 		cdata->template = new_template; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * Check if there are more prompts; if so, get its respective input | ||||
| 	 * and update the prompt data. | ||||
| 	 */ | ||||
| 	if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) { | ||||
| 	if (done && (ptr = strsep(&cdata->next_prompt, ",")) != NULL) { | ||||
| 		xasprintf(&prompt, "%s ", ptr); | ||||
| 		input = strsep(&cdata->next_input, ","); | ||||
| 		status_prompt_update(c, prompt, input); | ||||
| @@ -178,6 +191,8 @@ cmd_command_prompt_callback(void *data, const char *s) | ||||
| 	if (new_item != NULL) | ||||
| 		cmdq_append(c, new_item); | ||||
|  | ||||
| 	if (!done) | ||||
| 		free(new_template); | ||||
| 	if (c->prompt_callbackfn != (void *)&cmd_command_prompt_callback) | ||||
| 		return (1); | ||||
| 	return (0); | ||||
|   | ||||
| @@ -31,7 +31,7 @@ | ||||
| static enum cmd_retval	cmd_confirm_before_exec(struct cmd *, | ||||
| 			    struct cmdq_item *); | ||||
|  | ||||
| static int	cmd_confirm_before_callback(void *, const char *); | ||||
| static int	cmd_confirm_before_callback(void *, const char *, int); | ||||
| static void	cmd_confirm_before_free(void *); | ||||
|  | ||||
| const struct cmd_entry cmd_confirm_before_entry = { | ||||
| @@ -96,7 +96,7 @@ cmd_confirm_before_error(struct cmdq_item *item, void *data) | ||||
| } | ||||
|  | ||||
| static int | ||||
| cmd_confirm_before_callback(void *data, const char *s) | ||||
| cmd_confirm_before_callback(void *data, const char *s, __unused int done) | ||||
| { | ||||
| 	struct cmd_confirm_before_data	*cdata = data; | ||||
| 	struct client			*c = cdata->client; | ||||
|   | ||||
							
								
								
									
										2
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								cmd.c
									
									
									
									
									
								
							| @@ -692,7 +692,7 @@ cmd_template_replace(const char *template, const char *s, int idx) | ||||
|  | ||||
| 			buf = xrealloc(buf, len + (strlen(s) * 2) + 1); | ||||
| 			for (cp = s; *cp != '\0'; cp++) { | ||||
| 				if (quoted && *cp == '"') | ||||
| 				if (quoted && (*cp == '"' || *cp == '$')) | ||||
| 					buf[len++] = '\\'; | ||||
| 				buf[len++] = *cp; | ||||
| 			} | ||||
|   | ||||
| @@ -243,23 +243,23 @@ key_bindings_init(void) | ||||
| 		"bind -Tcopy-mode C-k send -X copy-end-of-line", | ||||
| 		"bind -Tcopy-mode C-n send -X cursor-down", | ||||
| 		"bind -Tcopy-mode C-p send -X cursor-up", | ||||
| 		"bind -Tcopy-mode C-r command-prompt -p'search up' \"send -X search-backward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode C-s command-prompt -p'search down' \"send -X search-forward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode C-r command-prompt -ip'search up' 'send -X search-backward-incremental \"%%%\"'", | ||||
| 		"bind -Tcopy-mode C-s command-prompt -ip'search down' 'send -X search-forward-incremental \"%%%\"'", | ||||
| 		"bind -Tcopy-mode C-v send -X page-down", | ||||
| 		"bind -Tcopy-mode C-w send -X copy-selection-and-cancel", | ||||
| 		"bind -Tcopy-mode Escape send -X cancel", | ||||
| 		"bind -Tcopy-mode Space send -X page-down", | ||||
| 		"bind -Tcopy-mode , send -X jump-reverse", | ||||
| 		"bind -Tcopy-mode \\; send -X jump-again", | ||||
| 		"bind -Tcopy-mode F command-prompt -1p'jump backward' \"send -X jump-backward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode F command-prompt -1p'jump backward' 'send -X jump-backward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode N send -X search-reverse", | ||||
| 		"bind -Tcopy-mode R send -X rectangle-toggle", | ||||
| 		"bind -Tcopy-mode T command-prompt -1p'jump to backward' \"send -X jump-to-backward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode f command-prompt -1p'jump forward' \"send -X jump-forward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode g command-prompt -p'goto line' \"send -X goto-line '%%'\"", | ||||
| 		"bind -Tcopy-mode T command-prompt -1p'jump to backward' 'send -X jump-to-backward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode f command-prompt -1p'jump forward' 'send -X jump-forward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode g command-prompt -p'goto line' 'send -X goto-line \"%%%\"'", | ||||
| 		"bind -Tcopy-mode n send -X search-again", | ||||
| 		"bind -Tcopy-mode q send -X cancel", | ||||
| 		"bind -Tcopy-mode t command-prompt -1p'jump to forward' \"send -X jump-to-forward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode t command-prompt -1p'jump to forward' 'send -X jump-to-forward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode MouseDown1Pane select-pane", | ||||
| 		"bind -Tcopy-mode MouseDrag1Pane select-pane\\; send -X begin-selection", | ||||
| 		"bind -Tcopy-mode MouseDragEnd1Pane send -X copy-selection-and-cancel", | ||||
| @@ -273,15 +273,15 @@ key_bindings_init(void) | ||||
| 		"bind -Tcopy-mode Down send -X cursor-down", | ||||
| 		"bind -Tcopy-mode Left send -X cursor-left", | ||||
| 		"bind -Tcopy-mode Right send -X cursor-right", | ||||
| 		"bind -Tcopy-mode M-1 command-prompt -Np'repeat' -I1 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-2 command-prompt -Np'repeat' -I2 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-3 command-prompt -Np'repeat' -I3 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-4 command-prompt -Np'repeat' -I4 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-5 command-prompt -Np'repeat' -I5 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-6 command-prompt -Np'repeat' -I6 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-7 command-prompt -Np'repeat' -I7 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-8 command-prompt -Np'repeat' -I8 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-9 command-prompt -Np'repeat' -I9 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode M-1 command-prompt -Np'repeat' -I1 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-2 command-prompt -Np'repeat' -I2 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-3 command-prompt -Np'repeat' -I3 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-4 command-prompt -Np'repeat' -I4 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-5 command-prompt -Np'repeat' -I5 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-6 command-prompt -Np'repeat' -I6 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-7 command-prompt -Np'repeat' -I7 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-8 command-prompt -Np'repeat' -I8 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-9 command-prompt -Np'repeat' -I9 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode M-< send -X history-top", | ||||
| 		"bind -Tcopy-mode M-> send -X history-bottom", | ||||
| 		"bind -Tcopy-mode M-R send -X top-line", | ||||
| @@ -313,25 +313,25 @@ key_bindings_init(void) | ||||
| 		"bind -Tcopy-mode-vi Space send -X begin-selection", | ||||
| 		"bind -Tcopy-mode-vi '$' send -X end-of-line", | ||||
| 		"bind -Tcopy-mode-vi , send -X jump-reverse", | ||||
| 		"bind -Tcopy-mode-vi / command-prompt -p'search down' \"send -X search-forward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode-vi / command-prompt -p'search down' 'send -X search-forward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 0 send -X start-of-line", | ||||
| 		"bind -Tcopy-mode-vi 1 command-prompt -Np'repeat' -I1 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 2 command-prompt -Np'repeat' -I2 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 3 command-prompt -Np'repeat' -I3 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 4 command-prompt -Np'repeat' -I4 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 5 command-prompt -Np'repeat' -I5 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 6 command-prompt -Np'repeat' -I6 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 7 command-prompt -Np'repeat' -I7 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 8 command-prompt -Np'repeat' -I8 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 9 command-prompt -Np'repeat' -I9 \"send -N '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi : command-prompt -p'goto line' \"send -X goto-line '%%'\"", | ||||
| 		"bind -Tcopy-mode-vi 1 command-prompt -Np'repeat' -I1 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 2 command-prompt -Np'repeat' -I2 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 3 command-prompt -Np'repeat' -I3 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 4 command-prompt -Np'repeat' -I4 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 5 command-prompt -Np'repeat' -I5 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 6 command-prompt -Np'repeat' -I6 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 7 command-prompt -Np'repeat' -I7 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 8 command-prompt -Np'repeat' -I8 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi 9 command-prompt -Np'repeat' -I9 'send -N \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi : command-prompt -p'goto line' 'send -X goto-line \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi \\; send -X jump-again", | ||||
| 		"bind -Tcopy-mode-vi ? command-prompt -p'search up' \"send -X search-backward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode-vi ? command-prompt -p'search up' 'send -X search-backward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi A send -X append-selection-and-cancel", | ||||
| 		"bind -Tcopy-mode-vi B send -X previous-space", | ||||
| 		"bind -Tcopy-mode-vi D send -X copy-end-of-line", | ||||
| 		"bind -Tcopy-mode-vi E send -X next-space-end", | ||||
| 		"bind -Tcopy-mode-vi F command-prompt -1p'jump backward' \"send -X jump-backward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode-vi F command-prompt -1p'jump backward' 'send -X jump-backward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi G send -X history-bottom", | ||||
| 		"bind -Tcopy-mode-vi H send -X top-line", | ||||
| 		"bind -Tcopy-mode-vi J send -X scroll-down", | ||||
| @@ -339,13 +339,13 @@ key_bindings_init(void) | ||||
| 		"bind -Tcopy-mode-vi L send -X bottom-line", | ||||
| 		"bind -Tcopy-mode-vi M send -X middle-line", | ||||
| 		"bind -Tcopy-mode-vi N send -X search-reverse", | ||||
| 		"bind -Tcopy-mode-vi T command-prompt -1p'jump to backward' \"send -X jump-to-backward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode-vi T command-prompt -1p'jump to backward' 'send -X jump-to-backward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi V send -X select-line", | ||||
| 		"bind -Tcopy-mode-vi W send -X next-space", | ||||
| 		"bind -Tcopy-mode-vi ^ send -X back-to-indentation", | ||||
| 		"bind -Tcopy-mode-vi b send -X previous-word", | ||||
| 		"bind -Tcopy-mode-vi e send -X next-word-end", | ||||
| 		"bind -Tcopy-mode-vi f command-prompt -1p'jump forward' \"send -X jump-forward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode-vi f command-prompt -1p'jump forward' 'send -X jump-forward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi g send -X history-top", | ||||
| 		"bind -Tcopy-mode-vi h send -X cursor-left", | ||||
| 		"bind -Tcopy-mode-vi j send -X cursor-down", | ||||
| @@ -354,7 +354,7 @@ key_bindings_init(void) | ||||
| 		"bind -Tcopy-mode-vi n send -X search-again", | ||||
| 		"bind -Tcopy-mode-vi o send -X other-end", | ||||
| 		"bind -Tcopy-mode-vi q send -X cancel", | ||||
| 		"bind -Tcopy-mode-vi t command-prompt -1p'jump to forward' \"send -X jump-to-forward \\\"%%%\\\"\"", | ||||
| 		"bind -Tcopy-mode-vi t command-prompt -1p'jump to forward' 'send -X jump-to-forward \"%%%\"'", | ||||
| 		"bind -Tcopy-mode-vi v send -X rectangle-toggle", | ||||
| 		"bind -Tcopy-mode-vi w send -X next-word", | ||||
| 		"bind -Tcopy-mode-vi { send -X previous-paragraph", | ||||
|   | ||||
							
								
								
									
										80
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								status.c
									
									
									
									
									
								
							| @@ -657,7 +657,7 @@ status_message_redraw(struct client *c) | ||||
| /* Enable status line prompt. */ | ||||
| void | ||||
| status_prompt_set(struct client *c, const char *msg, const char *input, | ||||
|     int (*callbackfn)(void *, const char *), void (*freefn)(void *), | ||||
|     int (*callbackfn)(void *, const char *, int), void (*freefn)(void *), | ||||
|     void *data, int flags) | ||||
| { | ||||
| 	struct format_tree	*ft; | ||||
| @@ -687,6 +687,7 @@ status_prompt_set(struct client *c, const char *msg, const char *input, | ||||
| 	c->prompt_flags = flags; | ||||
| 	c->prompt_mode = PROMPT_ENTRY; | ||||
|  | ||||
| 	if (~flags & PROMPT_INCREMENTAL) | ||||
| 		c->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE); | ||||
| 	c->flags |= CLIENT_STATUS; | ||||
|  | ||||
| @@ -976,7 +977,7 @@ status_prompt_key(struct client *c, key_code key) | ||||
| { | ||||
| 	struct options		*oo = c->session->options; | ||||
| 	struct paste_buffer	*pb; | ||||
| 	char			*s, word[64]; | ||||
| 	char			*s, *cp, word[64], prefix = '='; | ||||
| 	const char		*histstr, *bufdata, *ws = NULL; | ||||
| 	u_char			 ch; | ||||
| 	size_t			 size, n, off, idx, bufsize, used; | ||||
| @@ -989,7 +990,7 @@ status_prompt_key(struct client *c, key_code key) | ||||
| 		if (key >= '0' && key <= '9') | ||||
| 			goto append_key; | ||||
| 		s = utf8_tocstr(c->prompt_buffer); | ||||
| 		c->prompt_callbackfn(c->prompt_data, s); | ||||
| 		c->prompt_callbackfn(c->prompt_data, s, 1); | ||||
| 		status_prompt_clear(c); | ||||
| 		free(s); | ||||
| 		return (1); | ||||
| @@ -1013,28 +1014,28 @@ process_key: | ||||
| 	case '\002': /* C-b */ | ||||
| 		if (c->prompt_index > 0) { | ||||
| 			c->prompt_index--; | ||||
| 			c->flags |= CLIENT_STATUS; | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case KEYC_RIGHT: | ||||
| 	case '\006': /* C-f */ | ||||
| 		if (c->prompt_index < size) { | ||||
| 			c->prompt_index++; | ||||
| 			c->flags |= CLIENT_STATUS; | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case KEYC_HOME: | ||||
| 	case '\001': /* C-a */ | ||||
| 		if (c->prompt_index != 0) { | ||||
| 			c->prompt_index = 0; | ||||
| 			c->flags |= CLIENT_STATUS; | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case KEYC_END: | ||||
| 	case '\005': /* C-e */ | ||||
| 		if (c->prompt_index != size) { | ||||
| 			c->prompt_index = size; | ||||
| 			c->flags |= CLIENT_STATUS; | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case '\011': /* Tab */ | ||||
| @@ -1094,8 +1095,7 @@ process_key: | ||||
| 		c->prompt_index = (first - c->prompt_buffer) + strlen(s); | ||||
| 		free(s); | ||||
|  | ||||
| 		c->flags |= CLIENT_STATUS; | ||||
| 		break; | ||||
| 		goto changed; | ||||
| 	case KEYC_BSPACE: | ||||
| 	case '\010': /* C-h */ | ||||
| 		if (c->prompt_index != 0) { | ||||
| @@ -1108,7 +1108,7 @@ process_key: | ||||
| 				    sizeof *c->prompt_buffer); | ||||
| 				c->prompt_index--; | ||||
| 			} | ||||
| 			c->flags |= CLIENT_STATUS; | ||||
| 			goto changed; | ||||
| 		} | ||||
| 		break; | ||||
| 	case KEYC_DC: | ||||
| @@ -1118,18 +1118,17 @@ process_key: | ||||
| 			    c->prompt_buffer + c->prompt_index + 1, | ||||
| 			    (size + 1 - c->prompt_index) * | ||||
| 			    sizeof *c->prompt_buffer); | ||||
| 			c->flags |= CLIENT_STATUS; | ||||
| 			goto changed; | ||||
| 		} | ||||
| 		break; | ||||
| 	case '\025': /* C-u */ | ||||
| 		c->prompt_buffer[0].size = 0; | ||||
| 		c->prompt_index = 0; | ||||
| 		c->flags |= CLIENT_STATUS; | ||||
| 		break; | ||||
| 		goto changed; | ||||
| 	case '\013': /* C-k */ | ||||
| 		if (c->prompt_index < size) { | ||||
| 			c->prompt_buffer[c->prompt_index].size = 0; | ||||
| 			c->flags |= CLIENT_STATUS; | ||||
| 			goto changed; | ||||
| 		} | ||||
| 		break; | ||||
| 	case '\027': /* C-w */ | ||||
| @@ -1161,8 +1160,7 @@ process_key: | ||||
| 		    '\0', (c->prompt_index - idx) * sizeof *c->prompt_buffer); | ||||
| 		c->prompt_index = idx; | ||||
|  | ||||
| 		c->flags |= CLIENT_STATUS; | ||||
| 		break; | ||||
| 		goto changed; | ||||
| 	case 'f'|KEYC_ESCAPE: | ||||
| 		ws = options_get_string(oo, "word-separators"); | ||||
|  | ||||
| @@ -1185,8 +1183,7 @@ process_key: | ||||
| 		    c->prompt_index != 0) | ||||
| 			c->prompt_index--; | ||||
|  | ||||
| 		c->flags |= CLIENT_STATUS; | ||||
| 		break; | ||||
| 		goto changed; | ||||
| 	case 'b'|KEYC_ESCAPE: | ||||
| 		ws = options_get_string(oo, "word-separators"); | ||||
|  | ||||
| @@ -1206,9 +1203,7 @@ process_key: | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		c->flags |= CLIENT_STATUS; | ||||
| 		break; | ||||
| 		goto changed; | ||||
| 	case KEYC_UP: | ||||
| 	case '\020': /* C-p */ | ||||
| 		histstr = status_prompt_up_history(&c->prompt_hindex); | ||||
| @@ -1217,8 +1212,7 @@ process_key: | ||||
| 		free(c->prompt_buffer); | ||||
| 		c->prompt_buffer = utf8_fromcstr(histstr); | ||||
| 		c->prompt_index = utf8_strlen(c->prompt_buffer); | ||||
| 		c->flags |= CLIENT_STATUS; | ||||
| 		break; | ||||
| 		goto changed; | ||||
| 	case KEYC_DOWN: | ||||
| 	case '\016': /* C-n */ | ||||
| 		histstr = status_prompt_down_history(&c->prompt_hindex); | ||||
| @@ -1227,8 +1221,7 @@ process_key: | ||||
| 		free(c->prompt_buffer); | ||||
| 		c->prompt_buffer = utf8_fromcstr(histstr); | ||||
| 		c->prompt_index = utf8_strlen(c->prompt_buffer); | ||||
| 		c->flags |= CLIENT_STATUS; | ||||
| 		break; | ||||
| 		goto changed; | ||||
| 	case '\031': /* C-y */ | ||||
| 		if ((pb = paste_get_top(NULL)) == NULL) | ||||
| 			break; | ||||
| @@ -1259,9 +1252,7 @@ process_key: | ||||
| 			} | ||||
| 			c->prompt_index += n; | ||||
| 		} | ||||
|  | ||||
| 		c->flags |= CLIENT_STATUS; | ||||
| 		break; | ||||
| 		goto changed; | ||||
| 	case '\024': /* C-t */ | ||||
| 		idx = c->prompt_index; | ||||
| 		if (idx < size) | ||||
| @@ -1272,7 +1263,7 @@ process_key: | ||||
| 			    &c->prompt_buffer[idx - 1]); | ||||
| 			utf8_copy(&c->prompt_buffer[idx - 1], &tmp); | ||||
| 			c->prompt_index = idx; | ||||
| 			c->flags |= CLIENT_STATUS; | ||||
| 			goto changed; | ||||
| 		} | ||||
| 		break; | ||||
| 	case '\r': | ||||
| @@ -1280,16 +1271,33 @@ process_key: | ||||
| 		s = utf8_tocstr(c->prompt_buffer); | ||||
| 		if (*s != '\0') | ||||
| 			status_prompt_add_history(s); | ||||
| 		if (c->prompt_callbackfn(c->prompt_data, s) == 0) | ||||
| 		if (c->prompt_callbackfn(c->prompt_data, s, 1) == 0) | ||||
| 			status_prompt_clear(c); | ||||
| 		free(s); | ||||
| 		break; | ||||
| 	case '\033': /* Escape */ | ||||
| 	case '\003': /* C-c */ | ||||
| 		if (c->prompt_callbackfn(c->prompt_data, NULL) == 0) | ||||
| 		if (c->prompt_callbackfn(c->prompt_data, NULL, 1) == 0) | ||||
| 			status_prompt_clear(c); | ||||
| 		break; | ||||
| 	case '\022': /* C-r */ | ||||
| 		if (c->prompt_flags & PROMPT_INCREMENTAL) { | ||||
| 			prefix = '-'; | ||||
| 			goto changed; | ||||
| 		} | ||||
| 		break; | ||||
| 	case '\023': /* C-s */ | ||||
| 		if (c->prompt_flags & PROMPT_INCREMENTAL) { | ||||
| 			prefix = '+'; | ||||
| 			goto changed; | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		goto append_key; | ||||
| 	} | ||||
|  | ||||
| 	c->flags |= CLIENT_STATUS; | ||||
| 	return (0); | ||||
|  | ||||
| append_key: | ||||
| 	if (key <= 0x1f || key >= KEYC_BASE) | ||||
| @@ -1317,12 +1325,20 @@ append_key: | ||||
| 		s = utf8_tocstr(c->prompt_buffer); | ||||
| 		if (strlen(s) != 1) | ||||
| 			status_prompt_clear(c); | ||||
| 		else if (c->prompt_callbackfn(c->prompt_data, s) == 0) | ||||
| 		else if (c->prompt_callbackfn(c->prompt_data, s, 1) == 0) | ||||
| 			status_prompt_clear(c); | ||||
| 		free(s); | ||||
| 	} | ||||
|  | ||||
| changed: | ||||
| 	c->flags |= CLIENT_STATUS; | ||||
| 	if (c->prompt_flags & PROMPT_INCREMENTAL) { | ||||
| 		s = utf8_tocstr(c->prompt_buffer); | ||||
| 		xasprintf(&cp, "%c%s", prefix, s); | ||||
| 		c->prompt_callbackfn(c->prompt_data, cp, 0); | ||||
| 		free(cp); | ||||
| 		free(s); | ||||
| 	} | ||||
| 	return (0); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										13
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -1020,7 +1020,7 @@ Key tables may be viewed with the | ||||
| command. | ||||
| .Pp | ||||
| The following commands are supported in copy mode: | ||||
| .Bl -column "CommandXXXXXXXXXXXXXXXXX" "viXXXXXXXXXX" "emacs" -offset indent | ||||
| .Bl -column "CommandXXXXXXXXXXXXXXXXXXXXXXXXXX" "viXXXXXXXXXX" "emacs" -offset indent | ||||
| .It Sy "Command" Ta Sy "vi" Ta Sy "emacs" | ||||
| .It Li "append-selection" Ta "" Ta "" | ||||
| .It Li "append-selection-and-cancel" Ta "A" Ta "" | ||||
| @@ -1067,8 +1067,10 @@ The following commands are supported in copy mode: | ||||
| .It Li "scroll-down" Ta "C-e" Ta "C-Down" | ||||
| .It Li "scroll-up" Ta "C-y" Ta "C-Up" | ||||
| .It Li "search-again" Ta "n" Ta "n" | ||||
| .It Li "search-backward <for>" Ta "?" Ta "C-r" | ||||
| .It Li "search-forward <for>" Ta "/" Ta "C-s" | ||||
| .It Li "search-backward <for>" Ta "?" Ta "" | ||||
| .It Li "search-forward <for>" Ta "/" Ta "" | ||||
| .It Li "search-backward-incremental <for>" Ta "" Ta "C-r" | ||||
| .It Li "search-forward-incremental <for>" Ta "" Ta "C-s" | ||||
| .It Li "search-reverse" Ta "N" Ta "N" | ||||
| .It Li "select-line" Ta "V" Ta "" | ||||
| .It Li "start-of-line" Ta "0" Ta "C-a" | ||||
| @@ -3730,7 +3732,7 @@ session option. | ||||
| Commands related to the status line are as follows: | ||||
| .Bl -tag -width Ds | ||||
| .It Xo Ic command-prompt | ||||
| .Op Fl 1 | ||||
| .Op Fl 1i | ||||
| .Op Fl I Ar inputs | ||||
| .Op Fl p Ar prompts | ||||
| .Op Fl t Ar target-client | ||||
| @@ -3780,6 +3782,9 @@ but any quotation marks are escaped. | ||||
| .Fl 1 | ||||
| makes the prompt only accept one key press, in this case the resulting input | ||||
| is a single character. | ||||
| .Fl i | ||||
| executes the command every time the prompt input changes instead of when the | ||||
| user exits the command prompt. | ||||
| .Pp | ||||
| The following keys have a special meaning in the command prompt, depending | ||||
| on the value of the | ||||
|   | ||||
							
								
								
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -1417,7 +1417,7 @@ struct client { | ||||
| 	char		*prompt_string; | ||||
| 	struct utf8_data *prompt_buffer; | ||||
| 	size_t		 prompt_index; | ||||
| 	int		 (*prompt_callbackfn)(void *, const char *); | ||||
| 	int		 (*prompt_callbackfn)(void *, const char *, int); | ||||
| 	void		 (*prompt_freefn)(void *); | ||||
| 	void		*prompt_data; | ||||
| 	u_int		 prompt_hindex; | ||||
| @@ -1425,6 +1425,7 @@ struct client { | ||||
|  | ||||
| #define PROMPT_SINGLE 0x1 | ||||
| #define PROMPT_NUMERIC 0x2 | ||||
| #define PROMPT_INCREMENTAL 0x4 | ||||
| 	int		 prompt_flags; | ||||
|  | ||||
| 	struct session	*session; | ||||
| @@ -1915,7 +1916,7 @@ void printflike(2, 3) status_message_set(struct client *, const char *, ...); | ||||
| void	 status_message_clear(struct client *); | ||||
| int	 status_message_redraw(struct client *); | ||||
| void	 status_prompt_set(struct client *, const char *, const char *, | ||||
| 	     int (*)(void *, const char *), void (*)(void *), void *, int); | ||||
| 	     int (*)(void *, const char *, int), void (*)(void *), void *, int); | ||||
| void	 status_prompt_clear(struct client *); | ||||
| int	 status_prompt_redraw(struct client *); | ||||
| int	 status_prompt_key(struct client *, key_code); | ||||
|   | ||||
							
								
								
									
										167
									
								
								window-copy.c
									
									
									
									
									
								
							
							
						
						
									
										167
									
								
								window-copy.c
									
									
									
									
									
								
							| @@ -50,14 +50,15 @@ static int	window_copy_search_lr(struct grid *, struct grid *, u_int *, | ||||
| static int	window_copy_search_rl(struct grid *, struct grid *, u_int *, | ||||
| 		    u_int, u_int, u_int, int); | ||||
| static int	window_copy_search_marks(struct window_pane *, struct screen *); | ||||
| static void	window_copy_clear_marks(struct window_pane *); | ||||
| static void	window_copy_move_left(struct screen *, u_int *, u_int *); | ||||
| static void	window_copy_move_right(struct screen *, u_int *, u_int *); | ||||
| static int	window_copy_is_lowercase(const char *); | ||||
| static void	window_copy_search_jump(struct window_pane *, struct grid *, | ||||
| static int	window_copy_search_jump(struct window_pane *, struct grid *, | ||||
| 		    struct grid *, u_int, u_int, u_int, int, int, int); | ||||
| static void	window_copy_search(struct window_pane *, int, int); | ||||
| static void	window_copy_search_up(struct window_pane *, int); | ||||
| static void	window_copy_search_down(struct window_pane *, int); | ||||
| static int	window_copy_search(struct window_pane *, int, int); | ||||
| static int	window_copy_search_up(struct window_pane *, int); | ||||
| static int	window_copy_search_down(struct window_pane *, int); | ||||
| static void	window_copy_goto_line(struct window_pane *, const char *); | ||||
| static void	window_copy_update_cursor(struct window_pane *, u_int, u_int); | ||||
| static void	window_copy_start_selection(struct window_pane *); | ||||
| @@ -173,6 +174,9 @@ struct window_copy_mode_data { | ||||
| 	int		 searchtype; | ||||
| 	char		*searchstr; | ||||
| 	bitstr_t        *searchmark; | ||||
| 	int		 searchx; | ||||
| 	int		 searchy; | ||||
| 	int		 searcho; | ||||
|  | ||||
| 	int		 jumptype; | ||||
| 	char		 jumpchar; | ||||
| @@ -203,6 +207,7 @@ window_copy_init(struct window_pane *wp) | ||||
| 	data->searchtype = WINDOW_COPY_OFF; | ||||
| 	data->searchstr = NULL; | ||||
| 	data->searchmark = NULL; | ||||
| 	data->searchx = data->searchy = data->searcho = -1; | ||||
|  | ||||
| 	if (wp->fd != -1) | ||||
| 		bufferevent_disable(wp->event, EV_READ|EV_WRITE); | ||||
| @@ -487,6 +492,9 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy) | ||||
|  | ||||
| 	if (data->searchmark != NULL) | ||||
| 		window_copy_search_marks(wp, NULL); | ||||
| 	data->searchx = data->cx; | ||||
| 	data->searchy = data->cy; | ||||
| 	data->searcho = data->oy; | ||||
|  | ||||
| 	window_copy_redraw_screen(wp); | ||||
| } | ||||
| @@ -507,7 +515,8 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 	struct screen			*sn = &data->screen; | ||||
| 	const char			*command, *argument, *ws; | ||||
| 	u_int				 np = wp->modeprefix; | ||||
| 	int				 cancel = 0; | ||||
| 	int				 cancel = 0, redraw = 0; | ||||
| 	char				 prefix; | ||||
|  | ||||
| 	if (args->argc == 0) | ||||
| 		return; | ||||
| @@ -521,13 +530,13 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			if (s != NULL) | ||||
| 				window_copy_append_selection(wp, NULL); | ||||
| 			window_copy_clear_selection(wp); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "append-selection-and-cancel") == 0) { | ||||
| 			if (s != NULL) | ||||
| 				window_copy_append_selection(wp, NULL); | ||||
| 			window_copy_clear_selection(wp); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 			cancel = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "back-to-indentation") == 0) | ||||
| @@ -538,7 +547,7 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			else { | ||||
| 				sn->sel.lineflag = LINE_SEL_NONE; | ||||
| 				window_copy_start_selection(wp); | ||||
| 				window_copy_redraw_screen(wp); | ||||
| 				redraw = 1; | ||||
| 			} | ||||
| 		} | ||||
| 		if (strcmp(command, "stop-selection") == 0) | ||||
| @@ -547,20 +556,20 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			data->cx = 0; | ||||
| 			data->cy = screen_size_y(sn) - 1; | ||||
| 			window_copy_update_selection(wp, 1); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "cancel") == 0) | ||||
| 			cancel = 1; | ||||
| 		if (strcmp(command, "clear-selection") == 0) { | ||||
| 			window_copy_clear_selection(wp); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "copy-end-of-line") == 0) { | ||||
| 			window_copy_start_selection(wp); | ||||
| 			for (; np > 1; np--) | ||||
| 				window_copy_cursor_down(wp, 0); | ||||
| 			window_copy_cursor_end_of_line(wp); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
|  | ||||
| 			if (s != NULL) { | ||||
| 				window_copy_copy_selection(wp, NULL); | ||||
| @@ -573,7 +582,7 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			for (; np > 1; np--) | ||||
| 				window_copy_cursor_down(wp, 0); | ||||
| 			window_copy_cursor_end_of_line(wp); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
|  | ||||
| 			if (s != NULL) { | ||||
| 				window_copy_copy_selection(wp, NULL); | ||||
| @@ -584,13 +593,13 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			if (s != NULL) | ||||
| 				window_copy_copy_selection(wp, NULL); | ||||
| 			window_copy_clear_selection(wp); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "copy-selection-and-cancel") == 0) { | ||||
| 			if (s != NULL) | ||||
| 				window_copy_copy_selection(wp, NULL); | ||||
| 			window_copy_clear_selection(wp); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 			cancel = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "cursor-down") == 0) { | ||||
| @@ -624,14 +633,14 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			data->cy = screen_size_y(sn) - 1; | ||||
| 			data->oy = 0; | ||||
| 			window_copy_update_selection(wp, 1); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "history-top") == 0) { | ||||
| 			data->cx = 0; | ||||
| 			data->cy = 0; | ||||
| 			data->oy = screen_hsize(data->backing); | ||||
| 			window_copy_update_selection(wp, 1); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "jump-again") == 0) { | ||||
| 			switch (data->jumptype) { | ||||
| @@ -677,7 +686,7 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			data->cx = 0; | ||||
| 			data->cy = (screen_size_y(sn) - 1) / 2; | ||||
| 			window_copy_update_selection(wp, 1); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "next-paragraph") == 0) { | ||||
| 			for (; np != 0; np--) | ||||
| @@ -766,7 +775,7 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			for (; np > 1; np--) | ||||
| 				window_copy_cursor_down(wp, 0); | ||||
| 			window_copy_cursor_end_of_line(wp); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "select-word") == 0) { | ||||
| 			sn->sel.lineflag = LINE_SEL_LEFT_RIGHT; | ||||
| @@ -775,7 +784,7 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			window_copy_cursor_previous_word(wp, ws); | ||||
| 			window_copy_start_selection(wp); | ||||
| 			window_copy_cursor_next_word_end(wp, ws); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 		if (strcmp(command, "start-of-line") == 0) | ||||
| 			window_copy_cursor_start_of_line(wp); | ||||
| @@ -783,7 +792,7 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 			data->cx = 0; | ||||
| 			data->cy = 0; | ||||
| 			window_copy_update_selection(wp, 1); | ||||
| 			window_copy_redraw_screen(wp); | ||||
| 			redraw = 1; | ||||
| 		} | ||||
| 	} else if (args->argc == 2 && *args->argv[1] != '\0') { | ||||
| 		argument = args->argv[1]; | ||||
| @@ -825,26 +834,98 @@ window_copy_command(struct window_pane *wp, struct client *c, struct session *s, | ||||
| 		} | ||||
| 		if (strcmp(command, "search-backward") == 0) { | ||||
| 			data->searchtype = WINDOW_COPY_SEARCHUP; | ||||
| 			free(data->searchstr); | ||||
| 			data->searchstr = xstrdup(argument); | ||||
| 			for (; np != 0; np--) | ||||
| 				window_copy_search_up(wp, 1); | ||||
| 		} | ||||
| 		if (strcmp(command, "search-forward") == 0) { | ||||
| 			data->searchtype = WINDOW_COPY_SEARCHDOWN; | ||||
| 			free(data->searchstr); | ||||
| 			data->searchstr = xstrdup(argument); | ||||
| 			for (; np != 0; np--) | ||||
| 				window_copy_search_down(wp, 1); | ||||
| 		} | ||||
| 		if (strcmp(command, "search-backward-incremental") == 0) { | ||||
| 			prefix = *argument++; | ||||
| 			if (data->searchx == -1 || data->searchy == -1) { | ||||
| 				data->searchx = data->cx; | ||||
| 				data->searchy = data->cy; | ||||
| 				data->searcho = data->oy; | ||||
| 			} else if (data->searchstr != NULL && | ||||
| 			    strcmp(argument, data->searchstr) != 0) { | ||||
| 				data->cx = data->searchx; | ||||
| 				data->cy = data->searchy; | ||||
| 				data->oy = data->searcho; | ||||
| 				redraw = 1; | ||||
| 			} | ||||
| 			if (*argument == '\0') { | ||||
| 				window_copy_clear_marks(wp); | ||||
| 				redraw = 1; | ||||
| 			} else if (prefix == '=' || prefix == '-') { | ||||
| 				data->searchtype = WINDOW_COPY_SEARCHUP; | ||||
| 				free(data->searchstr); | ||||
| 				data->searchstr = xstrdup(argument); | ||||
| 				if (!window_copy_search_up(wp, 1)) { | ||||
| 					window_copy_clear_marks(wp); | ||||
| 					redraw = 1; | ||||
| 				} | ||||
| 			} else if (prefix == '+') { | ||||
| 				data->searchtype = WINDOW_COPY_SEARCHDOWN; | ||||
| 				free(data->searchstr); | ||||
| 				data->searchstr = xstrdup(argument); | ||||
| 				if (!window_copy_search_down(wp, 1)) { | ||||
| 					window_copy_clear_marks(wp); | ||||
| 					redraw = 1; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if (strcmp(command, "search-forward-incremental") == 0) { | ||||
| 			prefix = *argument++; | ||||
| 			if (data->searchx == -1 || data->searchy == -1) { | ||||
| 				data->searchx = data->cx; | ||||
| 				data->searchy = data->cy; | ||||
| 				data->searcho = data->oy; | ||||
| 			} else if (data->searchstr != NULL && | ||||
| 			    strcmp(argument, data->searchstr) != 0) { | ||||
| 				data->cx = data->searchx; | ||||
| 				data->cy = data->searchy; | ||||
| 				data->oy = data->searcho; | ||||
| 				redraw = 1; | ||||
| 			} | ||||
| 			if (*argument == '\0') { | ||||
| 				window_copy_clear_marks(wp); | ||||
| 				redraw = 1; | ||||
| 			} else if (prefix == '=' || prefix == '+') { | ||||
| 				data->searchtype = WINDOW_COPY_SEARCHDOWN; | ||||
| 				free(data->searchstr); | ||||
| 				data->searchstr = xstrdup(argument); | ||||
| 				if (!window_copy_search_down(wp, 1)) { | ||||
| 					window_copy_clear_marks(wp); | ||||
| 					redraw = 1; | ||||
| 				} | ||||
| 			} else if (prefix == '-') { | ||||
| 				data->searchtype = WINDOW_COPY_SEARCHUP; | ||||
| 				free(data->searchstr); | ||||
| 				data->searchstr = xstrdup(argument); | ||||
| 				if (!window_copy_search_up(wp, 1)) { | ||||
| 					window_copy_clear_marks(wp); | ||||
| 					redraw = 1; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (strncmp(command, "search-", 7) != 0 && data->searchmark != NULL) { | ||||
| 		free(data->searchmark); | ||||
| 		data->searchmark = NULL; | ||||
| 		window_copy_redraw_screen(wp); | ||||
| 		window_copy_clear_marks(wp); | ||||
| 		redraw = 1; | ||||
| 		data->searchx = data->searchy = -1; | ||||
| 	} | ||||
|  | ||||
| 	if (cancel) | ||||
| 		window_pane_reset_mode(wp); | ||||
| 	else if (redraw) | ||||
| 		window_copy_redraw_screen(wp); | ||||
| 	wp->modeprefix = 1; | ||||
| } | ||||
|  | ||||
| @@ -986,7 +1067,7 @@ window_copy_is_lowercase(const char *ptr) | ||||
|  * up, down otherwise. If wrap then go to begin/end of grid and try again if | ||||
|  * not found. | ||||
|  */ | ||||
| static void | ||||
| static int | ||||
| window_copy_search_jump(struct window_pane *wp, struct grid *gd, | ||||
|     struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap, | ||||
|     int direction) | ||||
| @@ -1015,13 +1096,17 @@ window_copy_search_jump(struct window_pane *wp, struct grid *gd, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (found) | ||||
| 	if (found) { | ||||
| 		window_copy_scroll_to(wp, px, i); | ||||
| 	else if (wrap) { | ||||
| 		window_copy_search_jump(wp, gd, sgd, direction ? 0 : gd->sx - 1, | ||||
| 		    direction ? 0 : gd->hsize + gd->sy - 1, fy, cis, 0, | ||||
| 		    direction); | ||||
| 		return (1); | ||||
| 	} | ||||
| 	if (wrap) { | ||||
| 		return (window_copy_search_jump(wp, gd, sgd, | ||||
| 		    direction ? 0 : gd->sx - 1, | ||||
| 		    direction ? 0 : gd->hsize + gd->sy - 1, fy, cis, 0, | ||||
| 		    direction)); | ||||
| 	} | ||||
| 	return (0); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -1029,7 +1114,7 @@ window_copy_search_jump(struct window_pane *wp, struct grid *gd, | ||||
|  * down. If moveflag is 0 then look for string at the current cursor position | ||||
|  * as well. | ||||
|  */ | ||||
| static void | ||||
| static int | ||||
| window_copy_search(struct window_pane *wp, int direction, int moveflag) | ||||
| { | ||||
| 	struct window_copy_mode_data	*data = wp->modedata; | ||||
| @@ -1037,7 +1122,7 @@ window_copy_search(struct window_pane *wp, int direction, int moveflag) | ||||
| 	struct screen_write_ctx		 ctx; | ||||
| 	struct grid			*gd = s->grid; | ||||
| 	u_int				 fx, fy, endline; | ||||
| 	int				 wrapflag, cis; | ||||
| 	int				 wrapflag, cis, found; | ||||
|  | ||||
| 	fx = data->cx; | ||||
| 	fy = screen_hsize(data->backing) - data->oy + data->cy; | ||||
| @@ -1062,13 +1147,14 @@ window_copy_search(struct window_pane *wp, int direction, int moveflag) | ||||
| 		endline = gd->hsize + gd->sy - 1; | ||||
| 	else | ||||
| 		endline = 0; | ||||
| 	window_copy_search_jump(wp, gd, ss.grid, fx, fy, endline, cis, | ||||
| 	found = window_copy_search_jump(wp, gd, ss.grid, fx, fy, endline, cis, | ||||
| 	    wrapflag, direction); | ||||
|  | ||||
| 	if (window_copy_search_marks(wp, &ss)) | ||||
| 		window_copy_redraw_screen(wp); | ||||
|  | ||||
| 	screen_free(&ss); | ||||
| 	return (found); | ||||
| } | ||||
|  | ||||
| static int | ||||
| @@ -1119,15 +1205,24 @@ window_copy_search_marks(struct window_pane *wp, struct screen *ssp) | ||||
| } | ||||
|  | ||||
| static void | ||||
| window_copy_search_up(struct window_pane *wp, int moveflag) | ||||
| window_copy_clear_marks(struct window_pane *wp) | ||||
| { | ||||
| 	window_copy_search(wp, 0, moveflag); | ||||
| 	struct window_copy_mode_data	*data = wp->modedata; | ||||
|  | ||||
| 	free(data->searchmark); | ||||
| 	data->searchmark = NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| static int | ||||
| window_copy_search_up(struct window_pane *wp, int moveflag) | ||||
| { | ||||
| 	return (window_copy_search(wp, 0, moveflag)); | ||||
| } | ||||
|  | ||||
| static int | ||||
| window_copy_search_down(struct window_pane *wp, int moveflag) | ||||
| { | ||||
| 	window_copy_search(wp, 1, moveflag); | ||||
| 	return (window_copy_search(wp, 1, moveflag)); | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 nicm
					nicm