mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-23 08:33:17 +01: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:
parent
4b8bb7770f
commit
f4fdddc930
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user