mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Sync OpenBSD patchset 726:
Add a choose-buffer command for easier use of the paste buffer stack.
This commit is contained in:
		
							
								
								
									
										146
									
								
								cmd-choose-buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								cmd-choose-buffer.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | |||||||
|  | /* $Id: cmd-choose-buffer.c,v 1.1 2010-06-22 23:35:20 tcunha Exp $ */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
|  |  * | ||||||
|  |  * Permission to use, copy, modify, and distribute this software for any | ||||||
|  |  * purpose with or without fee is hereby granted, provided that the above | ||||||
|  |  * copyright notice and this permission notice appear in all copies. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||||
|  |  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||||
|  |  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||||
|  |  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER | ||||||
|  |  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | ||||||
|  |  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <sys/types.h> | ||||||
|  |  | ||||||
|  | #include <ctype.h> | ||||||
|  |  | ||||||
|  | #include "tmux.h" | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Enter choice mode to choose a buffer. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | int	cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *); | ||||||
|  |  | ||||||
|  | void	cmd_choose_buffer_callback(void *, int); | ||||||
|  | void	cmd_choose_buffer_free(void *); | ||||||
|  |  | ||||||
|  | const struct cmd_entry cmd_choose_buffer_entry = { | ||||||
|  | 	"choose-buffer", NULL, | ||||||
|  | 	CMD_TARGET_WINDOW_USAGE " [template]", | ||||||
|  | 	CMD_ARG01, "", | ||||||
|  | 	cmd_target_init, | ||||||
|  | 	cmd_target_parse, | ||||||
|  | 	cmd_choose_buffer_exec, | ||||||
|  | 	cmd_target_free, | ||||||
|  | 	cmd_target_print | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct cmd_choose_buffer_data { | ||||||
|  | 	struct client	*client; | ||||||
|  | 	char   		*template; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | int | ||||||
|  | cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||||
|  | { | ||||||
|  | 	struct cmd_target_data		*data = self->data; | ||||||
|  | 	struct cmd_choose_buffer_data	*cdata; | ||||||
|  | 	struct session			*s; | ||||||
|  | 	struct winlink			*wl; | ||||||
|  | 	struct paste_buffer		*pb; | ||||||
|  | 	u_int				 idx; | ||||||
|  | 	char				*tmp; | ||||||
|  |  | ||||||
|  | 	if (ctx->curclient == NULL) { | ||||||
|  | 		ctx->error(ctx, "must be run interactively"); | ||||||
|  | 		return (-1); | ||||||
|  | 	} | ||||||
|  | 	s = ctx->curclient->session; | ||||||
|  |  | ||||||
|  | 	if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) | ||||||
|  | 		return (-1); | ||||||
|  |  | ||||||
|  | 	if (paste_get_top(&s->buffers) == NULL) | ||||||
|  | 		return (0); | ||||||
|  |  | ||||||
|  | 	if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) | ||||||
|  | 		return (0); | ||||||
|  |  | ||||||
|  | 	idx = 0; | ||||||
|  | 	while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) { | ||||||
|  | 		tmp = paste_print(pb, 50); | ||||||
|  | 		window_choose_add(wl->window->active, idx - 1, | ||||||
|  | 		    "%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp); | ||||||
|  | 		xfree(tmp); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	cdata = xmalloc(sizeof *cdata); | ||||||
|  | 	if (data->arg != NULL) | ||||||
|  | 		cdata->template = xstrdup(data->arg); | ||||||
|  | 	else | ||||||
|  | 		cdata->template = xstrdup("paste-buffer -b '%%'"); | ||||||
|  | 	cdata->client = ctx->curclient; | ||||||
|  | 	cdata->client->references++; | ||||||
|  |  | ||||||
|  | 	window_choose_ready(wl->window->active, | ||||||
|  | 	    0, cmd_choose_buffer_callback, cmd_choose_buffer_free, cdata); | ||||||
|  |  | ||||||
|  | 	return (0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | cmd_choose_buffer_callback(void *data, int idx) | ||||||
|  | { | ||||||
|  | 	struct cmd_choose_buffer_data	*cdata = data; | ||||||
|  | 	struct cmd_list			*cmdlist; | ||||||
|  | 	struct cmd_ctx			 ctx; | ||||||
|  | 	char				*template, *cause, tmp[16]; | ||||||
|  |  | ||||||
|  | 	if (idx == -1) | ||||||
|  | 		return; | ||||||
|  | 	if (cdata->client->flags & CLIENT_DEAD) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	xsnprintf(tmp, sizeof tmp, "%u", idx); | ||||||
|  | 	template = cmd_template_replace(cdata->template, tmp, 1); | ||||||
|  |  | ||||||
|  | 	if (cmd_string_parse(template, &cmdlist, &cause) != 0) { | ||||||
|  | 		if (cause != NULL) { | ||||||
|  | 			*cause = toupper((u_char) *cause); | ||||||
|  | 			status_message_set(cdata->client, "%s", cause); | ||||||
|  | 			xfree(cause); | ||||||
|  | 		} | ||||||
|  | 		xfree(template); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 	xfree(template); | ||||||
|  |  | ||||||
|  | 	ctx.msgdata = NULL; | ||||||
|  | 	ctx.curclient = cdata->client; | ||||||
|  |  | ||||||
|  | 	ctx.error = key_bindings_error; | ||||||
|  | 	ctx.print = key_bindings_print; | ||||||
|  | 	ctx.info = key_bindings_info; | ||||||
|  |  | ||||||
|  | 	ctx.cmdclient = NULL; | ||||||
|  |  | ||||||
|  | 	cmd_list_exec(cmdlist, &ctx); | ||||||
|  | 	cmd_list_free(cmdlist); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | cmd_choose_buffer_free(void *data) | ||||||
|  | { | ||||||
|  | 	struct cmd_choose_buffer_data	*cdata = data; | ||||||
|  |  | ||||||
|  | 	cdata->client->references--; | ||||||
|  | 	xfree(cdata->template); | ||||||
|  | 	xfree(cdata); | ||||||
|  | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: cmd-list-buffers.c,v 1.15 2009-12-04 22:14:47 tcunha Exp $ */ | /* $Id: cmd-list-buffers.c,v 1.16 2010-06-22 23:35:20 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -46,32 +46,17 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx) | |||||||
| 	struct session		*s; | 	struct session		*s; | ||||||
| 	struct paste_buffer	*pb; | 	struct paste_buffer	*pb; | ||||||
| 	u_int			 idx; | 	u_int			 idx; | ||||||
| 	char			 tmp[51 * 4 + 1]; | 	char			*tmp; | ||||||
| 	size_t			 size, len; |  | ||||||
|  |  | ||||||
| 	if ((s = cmd_find_session(ctx, data->target)) == NULL) | 	if ((s = cmd_find_session(ctx, data->target)) == NULL) | ||||||
| 		return (-1); | 		return (-1); | ||||||
|  |  | ||||||
| 	idx = 0; | 	idx = 0; | ||||||
| 	while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) { | 	while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) { | ||||||
| 		size = pb->size; | 		tmp = paste_print(pb, 50); | ||||||
|  | 		ctx->print(ctx, | ||||||
| 		/* Translate the first 50 characters. */ | 		    "%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp); | ||||||
| 		len = size; | 		xfree(tmp); | ||||||
| 		if (len > 50) |  | ||||||
| 			len = 50; |  | ||||||
| 		strvisx(tmp, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL); |  | ||||||
|  |  | ||||||
| 		/* |  | ||||||
| 		 * If the first 50 characters were encoded as a longer string, |  | ||||||
| 		 * or there is definitely more data, add "...". |  | ||||||
| 		 */ |  | ||||||
| 		if (size > 50 || strlen(tmp) > 50) { |  | ||||||
| 			tmp[50 - 3] = '\0'; |  | ||||||
| 			strlcat(tmp, "...", sizeof tmp); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		ctx->print(ctx, "%u: %zu bytes: \"%s\"", idx - 1, size, tmp); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return (0); | 	return (0); | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								cmd.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: cmd.c,v 1.140 2010-06-22 23:29:05 tcunha Exp $ */ | /* $Id: cmd.c,v 1.141 2010-06-22 23:35:20 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -31,6 +31,7 @@ const struct cmd_entry *cmd_table[] = { | |||||||
| 	&cmd_bind_key_entry, | 	&cmd_bind_key_entry, | ||||||
| 	&cmd_break_pane_entry, | 	&cmd_break_pane_entry, | ||||||
| 	&cmd_capture_pane_entry, | 	&cmd_capture_pane_entry, | ||||||
|  | 	&cmd_choose_buffer_entry, | ||||||
| 	&cmd_choose_client_entry, | 	&cmd_choose_client_entry, | ||||||
| 	&cmd_choose_session_entry, | 	&cmd_choose_session_entry, | ||||||
| 	&cmd_choose_window_entry, | 	&cmd_choose_window_entry, | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: key-bindings.c,v 1.92 2010-05-14 14:33:39 tcunha Exp $ */ | /* $Id: key-bindings.c,v 1.93 2010-06-22 23:35:20 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -122,6 +122,7 @@ key_bindings_init(void) | |||||||
| 		{ '8', 			  0, &cmd_select_window_entry }, | 		{ '8', 			  0, &cmd_select_window_entry }, | ||||||
| 		{ '9', 			  0, &cmd_select_window_entry }, | 		{ '9', 			  0, &cmd_select_window_entry }, | ||||||
| 		{ ':', 			  0, &cmd_command_prompt_entry }, | 		{ ':', 			  0, &cmd_command_prompt_entry }, | ||||||
|  | 		{ '=', 			  0, &cmd_choose_buffer_entry }, | ||||||
| 		{ '?', 			  0, &cmd_list_keys_entry }, | 		{ '?', 			  0, &cmd_list_keys_entry }, | ||||||
| 		{ 'D',			  0, &cmd_choose_client_entry }, | 		{ 'D',			  0, &cmd_choose_client_entry }, | ||||||
| 		{ '[', 			  0, &cmd_copy_mode_entry }, | 		{ '[', 			  0, &cmd_copy_mode_entry }, | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								paste.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								paste.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: paste.c,v 1.13 2009-12-04 22:14:47 tcunha Exp $ */ | /* $Id: paste.c,v 1.14 2010-06-22 23:35:20 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -20,6 +20,7 @@ | |||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
|  |  | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <vis.h> | ||||||
|  |  | ||||||
| #include "tmux.h" | #include "tmux.h" | ||||||
|  |  | ||||||
| @@ -156,3 +157,27 @@ paste_replace(struct paste_stack *ps, u_int idx, char *data, size_t size) | |||||||
|  |  | ||||||
| 	return (0); | 	return (0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Convert a buffer into a visible string. */ | ||||||
|  | char * | ||||||
|  | paste_print(struct paste_buffer *pb, size_t width) | ||||||
|  | { | ||||||
|  | 	char	*buf; | ||||||
|  | 	size_t	 len, used; | ||||||
|  |  | ||||||
|  | 	if (width < 3) | ||||||
|  | 		width = 3; | ||||||
|  | 	buf = xmalloc(width * 4 + 1); | ||||||
|  |  | ||||||
|  | 	len = pb->size; | ||||||
|  | 	if (len > width) | ||||||
|  | 		len = width; | ||||||
|  |  | ||||||
|  | 	used = strvisx(buf, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL); | ||||||
|  | 	if (pb->size > width || used > width) { | ||||||
|  | 		buf[width - 3] = '\0'; | ||||||
|  | 		strlcat(buf, "...", width); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return (buf); | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| .\" $Id: tmux.1,v 1.259 2010-06-22 23:29:05 tcunha Exp $ | .\" $Id: tmux.1,v 1.260 2010-06-22 23:35:20 tcunha Exp $ | ||||||
| .\" | .\" | ||||||
| .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| .\" | .\" | ||||||
| @@ -248,6 +248,8 @@ Select windows 0 to 9. | |||||||
| Enter the | Enter the | ||||||
| .Nm | .Nm | ||||||
| command prompt. | command prompt. | ||||||
|  | .It = | ||||||
|  | Choose which buffer to paste interactively from a list. | ||||||
| .It \&? | .It \&? | ||||||
| List all key bindings. | List all key bindings. | ||||||
| .It D | .It D | ||||||
| @@ -2447,6 +2449,23 @@ command above). | |||||||
| .Pp | .Pp | ||||||
| The buffer commands are as follows: | The buffer commands are as follows: | ||||||
| .Bl -tag -width Ds | .Bl -tag -width Ds | ||||||
|  | .It Xo | ||||||
|  | .Ic choose-buffer | ||||||
|  | .Op Fl t Ar target-window | ||||||
|  | .Op Ar template | ||||||
|  | .Xc | ||||||
|  | Put a window into buffer choice mode, where a buffer may be chosen | ||||||
|  | interactively from a list. | ||||||
|  | After a buffer is selected, | ||||||
|  | .Ql %% | ||||||
|  | is replaced by the buffer index in | ||||||
|  | .Ar template | ||||||
|  | and the result executed as a command. | ||||||
|  | If | ||||||
|  | .Ar template | ||||||
|  | is not given, "paste-buffer -b '%%'" is used. | ||||||
|  | This command works only from inside | ||||||
|  | .Nm . | ||||||
| .It Ic clear-history Op Fl t Ar target-pane | .It Ic clear-history Op Fl t Ar target-pane | ||||||
| .D1 (alias: Ic clearhist ) | .D1 (alias: Ic clearhist ) | ||||||
| Remove and free the history for the specified pane. | Remove and free the history for the specified pane. | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: tmux.h,v 1.563 2010-06-22 23:29:05 tcunha Exp $ */ | /* $Id: tmux.h,v 1.564 2010-06-22 23:35:20 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -1405,6 +1405,7 @@ int		 paste_free_top(struct paste_stack *); | |||||||
| int		 paste_free_index(struct paste_stack *, u_int); | int		 paste_free_index(struct paste_stack *, u_int); | ||||||
| void		 paste_add(struct paste_stack *, char *, size_t, u_int); | void		 paste_add(struct paste_stack *, char *, size_t, u_int); | ||||||
| int		 paste_replace(struct paste_stack *, u_int, char *, size_t); | int		 paste_replace(struct paste_stack *, u_int, char *, size_t); | ||||||
|  | char		*paste_print(struct paste_buffer *, size_t); | ||||||
|  |  | ||||||
| /* clock.c */ | /* clock.c */ | ||||||
| extern const char clock_table[14][5][5]; | extern const char clock_table[14][5][5]; | ||||||
| @@ -1441,6 +1442,7 @@ extern const struct cmd_entry cmd_attach_session_entry; | |||||||
| extern const struct cmd_entry cmd_bind_key_entry; | extern const struct cmd_entry cmd_bind_key_entry; | ||||||
| extern const struct cmd_entry cmd_break_pane_entry; | extern const struct cmd_entry cmd_break_pane_entry; | ||||||
| extern const struct cmd_entry cmd_capture_pane_entry; | extern const struct cmd_entry cmd_capture_pane_entry; | ||||||
|  | extern const struct cmd_entry cmd_choose_buffer_entry; | ||||||
| extern const struct cmd_entry cmd_choose_client_entry; | extern const struct cmd_entry cmd_choose_client_entry; | ||||||
| extern const struct cmd_entry cmd_choose_session_entry; | extern const struct cmd_entry cmd_choose_session_entry; | ||||||
| extern const struct cmd_entry cmd_choose_window_entry; | extern const struct cmd_entry cmd_choose_window_entry; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Tiago Cunha
					Tiago Cunha