mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Support "bracketed paste" mode. This adds a -p flag to paste-buffer - if
this is used and the application has requested bracketed pastes, then tmux surrounds the pasted text by \033[200~ and \033[201~. Applications like vim can (apparently) use this to avoid, for example, indenting the text. From Ailin Nemui.
This commit is contained in:
		@@ -30,13 +30,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int	cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
					int	cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void	cmd_paste_buffer_filter(
 | 
					void	cmd_paste_buffer_filter(struct window_pane *,
 | 
				
			||||||
	    struct window_pane *, const char *, size_t, const char *);
 | 
						    const char *, size_t, const char *, int bracket);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct cmd_entry cmd_paste_buffer_entry = {
 | 
					const struct cmd_entry cmd_paste_buffer_entry = {
 | 
				
			||||||
	"paste-buffer", "pasteb",
 | 
						"paste-buffer", "pasteb",
 | 
				
			||||||
	"db:rs:t:", 0, 0,
 | 
						"db:prs:t:", 0, 0,
 | 
				
			||||||
	"[-dr] [-s separator] [-b buffer-index] [-t target-pane]",
 | 
						"[-dpr] [-s separator] [-b buffer-index] [-t target-pane]",
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
@@ -53,6 +53,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
	const char		*sepstr;
 | 
						const char		*sepstr;
 | 
				
			||||||
	char			*cause;
 | 
						char			*cause;
 | 
				
			||||||
	int			 buffer;
 | 
						int			 buffer;
 | 
				
			||||||
 | 
						int			 pflag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL)
 | 
						if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL)
 | 
				
			||||||
		return (-1);
 | 
							return (-1);
 | 
				
			||||||
@@ -86,7 +87,9 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
			else
 | 
								else
 | 
				
			||||||
				sepstr = "\r";
 | 
									sepstr = "\r";
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		cmd_paste_buffer_filter(wp, pb->data, pb->size, sepstr);
 | 
							pflag = args_has(args, 'p') &&
 | 
				
			||||||
 | 
							    (wp->screen->mode & MODE_BRACKETPASTE);
 | 
				
			||||||
 | 
							cmd_paste_buffer_filter(wp, pb->data, pb->size, sepstr, pflag);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Delete the buffer if -d. */
 | 
						/* Delete the buffer if -d. */
 | 
				
			||||||
@@ -102,13 +105,16 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Add bytes to a buffer and filter '\n' according to separator. */
 | 
					/* Add bytes to a buffer and filter '\n' according to separator. */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cmd_paste_buffer_filter(
 | 
					cmd_paste_buffer_filter(struct window_pane *wp,
 | 
				
			||||||
    struct window_pane *wp, const char *data, size_t size, const char *sep)
 | 
					    const char *data, size_t size, const char *sep, int bracket)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char	*end = data + size;
 | 
						const char	*end = data + size;
 | 
				
			||||||
	const char	*lf;
 | 
						const char	*lf;
 | 
				
			||||||
	size_t		 seplen;
 | 
						size_t		 seplen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bracket)
 | 
				
			||||||
 | 
							bufferevent_write(wp->event, "\033[200~", 6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	seplen = strlen(sep);
 | 
						seplen = strlen(sep);
 | 
				
			||||||
	while ((lf = memchr(data, '\n', end - data)) != NULL) {
 | 
						while ((lf = memchr(data, '\n', end - data)) != NULL) {
 | 
				
			||||||
		if (lf != data)
 | 
							if (lf != data)
 | 
				
			||||||
@@ -119,4 +125,7 @@ cmd_paste_buffer_filter(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (end != data)
 | 
						if (end != data)
 | 
				
			||||||
		bufferevent_write(wp->event, data, end - data);
 | 
							bufferevent_write(wp->event, data, end - data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bracket)
 | 
				
			||||||
 | 
							bufferevent_write(wp->event, "\033[201~", 6);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								input.c
									
									
									
									
									
								
							@@ -1212,6 +1212,9 @@ input_csi_dispatch(struct input_ctx *ictx)
 | 
				
			|||||||
		case 1049:
 | 
							case 1049:
 | 
				
			||||||
			window_pane_alternate_off(wp, &ictx->cell);
 | 
								window_pane_alternate_off(wp, &ictx->cell);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case 2004:
 | 
				
			||||||
 | 
								screen_write_bracketpaste(&ictx->ctx, 0);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
 | 
								log_debug("%s: unknown '%c'", __func__, ictx->ch);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -1264,6 +1267,9 @@ input_csi_dispatch(struct input_ctx *ictx)
 | 
				
			|||||||
		case 1049:
 | 
							case 1049:
 | 
				
			||||||
			window_pane_alternate_on(wp, &ictx->cell);
 | 
								window_pane_alternate_on(wp, &ictx->cell);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case 2004:
 | 
				
			||||||
 | 
								screen_write_bracketpaste(&ictx->ctx, 1);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			log_debug("%s: unknown '%c'", __func__, ictx->ch);
 | 
								log_debug("%s: unknown '%c'", __func__, ictx->ch);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -878,6 +878,18 @@ screen_write_mousemode_on(struct screen_write_ctx *ctx, int mode)
 | 
				
			|||||||
	s->mode |= mode;
 | 
						s->mode |= mode;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set bracketed paste mode. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					screen_write_bracketpaste(struct screen_write_ctx *ctx, int state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct screen	*s = ctx->s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (state)
 | 
				
			||||||
 | 
							s->mode |= MODE_BRACKETPASTE;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							s->mode &= ~MODE_BRACKETPASTE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Line feed. */
 | 
					/* Line feed. */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
 | 
					screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tmux.1
									
									
									
									
									
								
							@@ -3084,7 +3084,7 @@ List the global buffers.
 | 
				
			|||||||
Load the contents of the specified paste buffer from
 | 
					Load the contents of the specified paste buffer from
 | 
				
			||||||
.Ar path .
 | 
					.Ar path .
 | 
				
			||||||
.It Xo Ic paste-buffer
 | 
					.It Xo Ic paste-buffer
 | 
				
			||||||
.Op Fl dr
 | 
					.Op Fl dpr
 | 
				
			||||||
.Op Fl b Ar buffer-index
 | 
					.Op Fl b Ar buffer-index
 | 
				
			||||||
.Op Fl s Ar separator
 | 
					.Op Fl s Ar separator
 | 
				
			||||||
.Op Fl t Ar target-pane
 | 
					.Op Fl t Ar target-pane
 | 
				
			||||||
@@ -3103,6 +3103,10 @@ flag.
 | 
				
			|||||||
The
 | 
					The
 | 
				
			||||||
.Fl r
 | 
					.Fl r
 | 
				
			||||||
flag means to do no replacement (equivalent to a separator of LF).
 | 
					flag means to do no replacement (equivalent to a separator of LF).
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl p
 | 
				
			||||||
 | 
					is specified, paste bracket control codes are inserted around the
 | 
				
			||||||
 | 
					buffer if the application has requested bracketed paste mode.
 | 
				
			||||||
.It Xo Ic save-buffer
 | 
					.It Xo Ic save-buffer
 | 
				
			||||||
.Op Fl a
 | 
					.Op Fl a
 | 
				
			||||||
.Op Fl b Ar buffer-index
 | 
					.Op Fl b Ar buffer-index
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							@@ -573,6 +573,7 @@ struct mode_key_table {
 | 
				
			|||||||
#define MODE_MOUSE_BUTTON 0x40
 | 
					#define MODE_MOUSE_BUTTON 0x40
 | 
				
			||||||
#define MODE_MOUSE_ANY 0x80
 | 
					#define MODE_MOUSE_ANY 0x80
 | 
				
			||||||
#define MODE_MOUSE_UTF8 0x100
 | 
					#define MODE_MOUSE_UTF8 0x100
 | 
				
			||||||
 | 
					#define MODE_BRACKETPASTE 0x200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)
 | 
					#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1883,6 +1884,7 @@ void	 screen_write_cell(struct screen_write_ctx *,
 | 
				
			|||||||
	     const struct grid_cell *, const struct utf8_data *);
 | 
						     const struct grid_cell *, const struct utf8_data *);
 | 
				
			||||||
void	 screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
 | 
					void	 screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
 | 
				
			||||||
void	 screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
 | 
					void	 screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
 | 
				
			||||||
 | 
					void	 screen_write_bracketpaste(struct screen_write_ctx *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* screen-redraw.c */
 | 
					/* screen-redraw.c */
 | 
				
			||||||
void	 screen_redraw_screen(struct client *, int, int);
 | 
					void	 screen_redraw_screen(struct client *, int, int);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tty.c
									
									
									
									
									
								
							@@ -480,6 +480,12 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s)
 | 
				
			|||||||
		else
 | 
							else
 | 
				
			||||||
			tty_putcode(tty, TTYC_RMKX);
 | 
								tty_putcode(tty, TTYC_RMKX);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (changed & MODE_BRACKETPASTE) {
 | 
				
			||||||
 | 
							if (mode & MODE_BRACKETPASTE)
 | 
				
			||||||
 | 
								tty_puts(tty, "\033[?2004h");
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								tty_puts(tty, "\033[?2004l");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	tty->mode = mode;
 | 
						tty->mode = mode;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user