mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Sync OpenBSD patchset 702:
Enhance paste-buffer to allow lines to be separated by any string, from Andrea Barisani.
This commit is contained in:
		| @@ -1,4 +1,4 @@ | ||||
| /* $Id: cmd-paste-buffer.c,v 1.26 2010-04-06 21:59:37 nicm Exp $ */ | ||||
| /* $Id: cmd-paste-buffer.c,v 1.27 2010-06-06 00:01:36 tcunha Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||
| @@ -18,7 +18,9 @@ | ||||
|  | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <vis.h> | ||||
|  | ||||
| #include "tmux.h" | ||||
|  | ||||
| @@ -26,24 +28,106 @@ | ||||
|  * Paste paste buffer if present. | ||||
|  */ | ||||
|  | ||||
| struct cmd_paste_buffer_data { | ||||
| 	char	*target; | ||||
| 	int	 buffer; | ||||
|  | ||||
| 	int	 flag_delete; | ||||
| 	char	*sepstr; | ||||
| }; | ||||
|  | ||||
| void	cmd_paste_buffer_init(struct cmd *, int); | ||||
| int	cmd_paste_buffer_parse(struct cmd *, int, char **, char **); | ||||
| int	cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *); | ||||
| void	cmd_paste_buffer_lf2cr(struct window_pane *, const char *, size_t); | ||||
| void	cmd_paste_buffer_filter( | ||||
| 	    struct window_pane *, const char *, size_t, char *); | ||||
| void	cmd_paste_buffer_free(struct cmd *); | ||||
| size_t	cmd_paste_buffer_print(struct cmd *, char *, size_t); | ||||
|  | ||||
| const struct cmd_entry cmd_paste_buffer_entry = { | ||||
| 	"paste-buffer", "pasteb", | ||||
| 	"[-dr] " CMD_BUFFER_PANE_USAGE, | ||||
| 	0, "dr", | ||||
| 	cmd_buffer_init, | ||||
| 	cmd_buffer_parse, | ||||
| 	"[-dr] [-s separator] [-b buffer-index] [-t target-window]", | ||||
| 	0, "", | ||||
| 	cmd_paste_buffer_init, | ||||
| 	cmd_paste_buffer_parse, | ||||
| 	cmd_paste_buffer_exec, | ||||
| 	cmd_buffer_free, | ||||
| 	cmd_buffer_print | ||||
| 	cmd_paste_buffer_free, | ||||
| 	cmd_paste_buffer_print | ||||
| }; | ||||
|  | ||||
| /* ARGSUSED */ | ||||
| void | ||||
| cmd_paste_buffer_init(struct cmd *self, unused int arg) | ||||
| { | ||||
| 	struct cmd_paste_buffer_data	*data; | ||||
|  | ||||
| 	self->data = data = xmalloc(sizeof *data); | ||||
| 	data->target = NULL; | ||||
| 	data->buffer = -1; | ||||
| 	data->flag_delete = 0; | ||||
| 	data->sepstr = xstrdup("\r"); | ||||
| } | ||||
|  | ||||
| int | ||||
| cmd_paste_buffer_parse(struct cmd *self, int argc, char **argv, char **cause) | ||||
| { | ||||
| 	struct cmd_paste_buffer_data	*data; | ||||
| 	int			 opt, n; | ||||
| 	const char		*errstr; | ||||
|  | ||||
| 	cmd_paste_buffer_init(self, 0); | ||||
| 	data = self->data; | ||||
|  | ||||
| 	while ((opt = getopt(argc, argv, "b:ds:t:r")) != -1) { | ||||
| 		switch (opt) { | ||||
| 		case 'b': | ||||
| 			if (data->buffer == -1) { | ||||
| 				n = strtonum(optarg, 0, INT_MAX, &errstr); | ||||
| 				if (errstr != NULL) { | ||||
| 					xasprintf(cause, "buffer %s", errstr); | ||||
| 					goto error; | ||||
| 				} | ||||
| 				data->buffer = n; | ||||
| 			} | ||||
| 			break; | ||||
| 		case 'd': | ||||
| 			data->flag_delete = 1; | ||||
| 			break; | ||||
| 		case 's': | ||||
| 			if (data->sepstr != NULL) | ||||
| 				xfree(data->sepstr); | ||||
| 			data->sepstr = xstrdup(optarg); | ||||
| 			break; | ||||
| 		case 't': | ||||
| 			if (data->target == NULL) | ||||
| 				data->target = xstrdup(optarg); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			if (data->sepstr != NULL) | ||||
| 				xfree(data->sepstr); | ||||
| 			data->sepstr = xstrdup("\n"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			goto usage; | ||||
| 		} | ||||
| 	} | ||||
| 	argc -= optind; | ||||
| 	argv += optind; | ||||
|  | ||||
| 	return (0); | ||||
|  | ||||
| usage: | ||||
| 	xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); | ||||
|  | ||||
| error: | ||||
| 	self->entry->free(self); | ||||
| 	return (-1); | ||||
| } | ||||
|  | ||||
| int | ||||
| cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| { | ||||
| 	struct cmd_buffer_data	*data = self->data; | ||||
| 	struct cmd_paste_buffer_data	*data = self->data; | ||||
| 	struct window_pane		*wp; | ||||
| 	struct session			*s; | ||||
| 	struct paste_buffer		*pb; | ||||
| @@ -60,16 +144,11 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (pb != NULL) { | ||||
| 		/* -r means raw data without LF->CR conversion. */ | ||||
| 		if (cmd_check_flag(data->chflags, 'r')) | ||||
| 			bufferevent_write(wp->event, pb->data, pb->size); | ||||
| 		else | ||||
| 			cmd_paste_buffer_lf2cr(wp, pb->data, pb->size); | ||||
| 	} | ||||
| 	if (pb != NULL) | ||||
| 		cmd_paste_buffer_filter(wp, pb->data, pb->size, data->sepstr); | ||||
|  | ||||
| 	/* Delete the buffer if -d. */ | ||||
| 	if (cmd_check_flag(data->chflags, 'd')) { | ||||
| 	if (data->flag_delete) { | ||||
| 		if (data->buffer == -1) | ||||
| 			paste_free_top(&s->buffers); | ||||
| 		else | ||||
| @@ -79,20 +158,66 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| 	return (0); | ||||
| } | ||||
|  | ||||
| /* Add bytes to a buffer but change every '\n' to '\r'. */ | ||||
| /* Add bytes to a buffer and filter '\n' according to separator. */ | ||||
| void | ||||
| cmd_paste_buffer_lf2cr(struct window_pane *wp, const char *data, size_t size) | ||||
| cmd_paste_buffer_filter( | ||||
|     struct window_pane *wp, const char *data, size_t size, char *sep) | ||||
| { | ||||
| 	const char	*end = data + size; | ||||
| 	const char	*lf; | ||||
| 	size_t		 seplen; | ||||
|  | ||||
| 	seplen = strlen(sep); | ||||
| 	while ((lf = memchr(data, '\n', end - data)) != NULL) { | ||||
| 		if (lf != data) | ||||
| 			bufferevent_write(wp->event, data, lf - data); | ||||
| 		bufferevent_write(wp->event, "\r", 1); | ||||
| 		bufferevent_write(wp->event, sep, seplen); | ||||
| 		data = lf + 1; | ||||
| 	} | ||||
|  | ||||
| 	if (end != data) | ||||
| 		bufferevent_write(wp->event, data, end - data); | ||||
| } | ||||
|  | ||||
| void | ||||
| cmd_paste_buffer_free(struct cmd *self) | ||||
| { | ||||
| 	struct cmd_paste_buffer_data	*data = self->data; | ||||
|  | ||||
| 	if (data->target != NULL) | ||||
| 		xfree(data->target); | ||||
| 	if (data->sepstr != NULL) | ||||
| 		xfree(data->sepstr); | ||||
| 	xfree(data); | ||||
| } | ||||
|  | ||||
| size_t | ||||
| cmd_paste_buffer_print(struct cmd *self, char *buf, size_t len) | ||||
| { | ||||
| 	struct cmd_paste_buffer_data	*data = self->data; | ||||
| 	size_t				 off = 0; | ||||
| 	char                             tmp[BUFSIZ]; | ||||
| 	int				 r_flag; | ||||
|  | ||||
| 	r_flag = 0; | ||||
| 	if (data->sepstr != NULL) | ||||
| 		r_flag = (data->sepstr[0] == '\n' && data->sepstr[1] == '\0'); | ||||
|  | ||||
| 	off += xsnprintf(buf, len, "%s", self->entry->name); | ||||
| 	if (data == NULL) | ||||
| 		return (off); | ||||
| 	if (off < len && data->flag_delete) | ||||
| 		off += xsnprintf(buf + off, len - off, " -d"); | ||||
| 	if (off < len && r_flag) | ||||
| 		off += xsnprintf(buf + off, len - off, " -r"); | ||||
| 	if (off < len && data->buffer != -1) | ||||
| 		off += xsnprintf(buf + off, len - off, " -b %d", data->buffer); | ||||
| 	if (off < len && data->sepstr != NULL && !r_flag) { | ||||
| 		strnvis( | ||||
| 		    tmp, data->sepstr, sizeof tmp, VIS_OCTAL|VIS_TAB|VIS_NL); | ||||
| 		off += cmd_prarg(buf + off, len - off, " -s ", tmp); | ||||
| 	} | ||||
| 	if (off < len && data->target != NULL) | ||||
| 		off += cmd_prarg(buf + off, len - off, " -t ", data->target); | ||||
| 	return (off); | ||||
| } | ||||
|   | ||||
							
								
								
									
										14
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| .\" $Id: tmux.1,v 1.251 2010-06-05 23:56:29 tcunha Exp $ | ||||
| .\" $Id: tmux.1,v 1.252 2010-06-06 00:01:36 tcunha Exp $ | ||||
| .\" | ||||
| .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||
| .\" | ||||
| @@ -14,7 +14,7 @@ | ||||
| .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | ||||
| .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
| .\" | ||||
| .Dd $Mdocdate: May 14 2010 $ | ||||
| .Dd $Mdocdate: May 19 2010 $ | ||||
| .Dt TMUX 1 | ||||
| .Os | ||||
| .Sh NAME | ||||
| @@ -2387,6 +2387,7 @@ Load the contents of the specified paste buffer from | ||||
| .It Xo Ic paste-buffer | ||||
| .Op Fl dr | ||||
| .Op Fl b Ar buffer-index | ||||
| .Op Fl s Ar separator | ||||
| .Op Fl t Ar target-pane | ||||
| .Xc | ||||
| .D1 (alias: Ic pasteb ) | ||||
| @@ -2396,10 +2397,13 @@ With | ||||
| .Fl d , | ||||
| also delete the paste buffer from the stack. | ||||
| When output, any linefeed (LF) characters in the paste buffer are replaced with | ||||
| carriage returns (CR). | ||||
| This translation may be disabled with the | ||||
| .Fl r | ||||
| a separator, by default carriage return (CR). | ||||
| A custom separator may be specified using the | ||||
| .Fl s | ||||
| flag. | ||||
| The | ||||
| .Fl r | ||||
| flag means to do no replacement (equivalent to a separator of LF). | ||||
| .It Xo Ic save-buffer | ||||
| .Op Fl a | ||||
| .Op Fl b Ar buffer-index | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tiago Cunha
					Tiago Cunha