Skip to content

Commit 33ed602

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents bf5edde + ec2da36 commit 33ed602

File tree

14 files changed

+191
-17
lines changed

14 files changed

+191
-17
lines changed

runtime/doc/term.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ an external command (e.g., "!!"), the terminal will be put into Normal mode
8989
for a moment. This means that you can stop the output to the screen by
9090
hitting a printing key. Output resumes when you hit <BS>.
9191

92+
*xterm-bracketed-paste*
93+
When the 't_BE' option is set then 't_BE' will be sent to the
94+
terminal when entering "raw" mode and 't_BD' when leaving "raw" mode. The
95+
terminal is then expected to put 't_PS' before pasted text and 't_PE' after
96+
pasted text. This way Vim can separate text that is pasted from characters
97+
that are typed. The pasted text is handled like when the middle mouse button
98+
is used.
99+
100+
Note that in some situations Vim will not recognize the bracketed paste and
101+
you will get the raw text. In other situations Vim will only get the first
102+
pasted character and drop the rest, e.g. when using the "r" command.
103+
92104
*cs7-problem*
93105
Note: If the terminal settings are changed after running Vim, you might have
94106
an illegal combination of settings. This has been reported on Solaris 2.5
@@ -306,6 +318,10 @@ Added by Vim (there are no standard codes for these):
306318
|xterm-true-color|
307319
t_8b set background color (R, G, B) *t_8b* *'t_8b'*
308320
|xterm-true-color|
321+
t_BE enable bracketed paste mode *t_BE* *'t_BE'*
322+
|xterm-bracketed-paste|
323+
t_BD disable bracketed paste mode *t_BD* *'t_BD'*
324+
|xterm-bracketed-paste|
309325

310326
KEY CODES
311327
Note: Use the <> form if possible
@@ -398,6 +414,8 @@ Note: Use the <> form if possible
398414
t_KK <k8> keypad 8 *<k8>* *t_KK* *'t_KK'*
399415
t_KL <k9> keypad 9 *<k9>* *t_KL* *'t_KL'*
400416
<Mouse> leader of mouse code *<Mouse>*
417+
t_PS start of brackted paste |xterm-bracketed-paste| *t_PS* 't_PS'
418+
t_PE end of bracketed paste |xterm-bracketed-paste| *t_PE* 't_PE'
401419

402420
Note about t_so and t_mr: When the termcap entry "so" is not present the
403421
entry for "mr" is used. And vice versa. The same is done for "se" and "me".

src/edit.c

Lines changed: 104 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ static int dont_sync_undo = FALSE; /* CTRL-G U prevents syncing undo for
309309
* "cmdchar" can be:
310310
* 'i' normal insert command
311311
* 'a' normal append command
312+
* K_PS bracketed paste
312313
* 'R' replace command
313314
* 'r' "r<CR>" command: insert one <CR>. Note: count can be > 1, for redo,
314315
* but still only one <CR> is inserted. The <Esc> is not used for redo.
@@ -782,10 +783,14 @@ edit(
782783
dont_sync_undo = TRUE;
783784
else
784785
dont_sync_undo = FALSE;
785-
do
786-
{
787-
c = safe_vgetc();
788-
} while (c == K_IGNORE);
786+
if (cmdchar == K_PS)
787+
/* Got here from normal mode when bracketed paste started. */
788+
c = K_PS;
789+
else
790+
do
791+
{
792+
c = safe_vgetc();
793+
} while (c == K_IGNORE);
789794

790795
#ifdef FEAT_AUTOCMD
791796
/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
@@ -1202,6 +1207,16 @@ edit(
12021207
break;
12031208
# endif
12041209
#endif
1210+
case K_PS:
1211+
bracketed_paste(PASTE_INSERT, FALSE, NULL);
1212+
if (cmdchar == K_PS)
1213+
/* invoked from normal mode, bail out */
1214+
goto doESCkey;
1215+
break;
1216+
case K_PE:
1217+
/* Got K_PE without K_PS, ignore. */
1218+
break;
1219+
12051220
#ifdef FEAT_GUI_TABLINE
12061221
case K_TABLINE:
12071222
case K_TABMENU:
@@ -9457,6 +9472,91 @@ ins_mousescroll(int dir)
94579472
}
94589473
#endif
94599474

9475+
/*
9476+
* Handle receiving P_PS: start paste mode. Inserts the following text up to
9477+
* P_PE literally.
9478+
* When "drop" is TRUE then consume the text and drop it.
9479+
*/
9480+
int
9481+
bracketed_paste(paste_mode_T mode, int drop, garray_T *gap)
9482+
{
9483+
int c;
9484+
char_u buf[NUMBUFLEN + MB_MAXBYTES];
9485+
int idx = 0;
9486+
char_u *end = find_termcode((char_u *)"PE");
9487+
int ret_char = -1;
9488+
int save_allow_keys = allow_keys;
9489+
9490+
/* If the end code is too long we can't detect it, read everything. */
9491+
if (STRLEN(end) >= NUMBUFLEN)
9492+
end = NULL;
9493+
++no_mapping;
9494+
allow_keys = 0;
9495+
for (;;)
9496+
{
9497+
/* When the end is not defined read everything. */
9498+
if (end == NULL && vpeekc() == NUL)
9499+
break;
9500+
c = plain_vgetc();
9501+
#ifdef FEAT_MBYTE
9502+
if (has_mbyte)
9503+
idx += (*mb_char2bytes)(c, buf + idx);
9504+
else
9505+
#endif
9506+
buf[idx++] = c;
9507+
buf[idx] = NUL;
9508+
if (end != NUL && STRNCMP(buf, end, idx) == 0)
9509+
{
9510+
if (end[idx] == NUL)
9511+
break; /* Found the end of paste code. */
9512+
continue;
9513+
}
9514+
if (!drop)
9515+
{
9516+
switch (mode)
9517+
{
9518+
case PASTE_CMDLINE:
9519+
put_on_cmdline(buf, idx, TRUE);
9520+
break;
9521+
9522+
case PASTE_EX:
9523+
if (gap != NULL && ga_grow(gap, idx) == OK)
9524+
{
9525+
mch_memmove((char *)gap->ga_data + gap->ga_len,
9526+
buf, (size_t)idx);
9527+
gap->ga_len += idx;
9528+
}
9529+
break;
9530+
9531+
case PASTE_INSERT:
9532+
if (stop_arrow() == OK)
9533+
{
9534+
ins_char_bytes(buf, idx);
9535+
AppendToRedobuffLit(buf, idx);
9536+
}
9537+
break;
9538+
9539+
case PASTE_ONE_CHAR:
9540+
if (ret_char == -1)
9541+
{
9542+
#ifdef FEAT_MBYTE
9543+
if (has_mbyte)
9544+
ret_char = (*mb_ptr2char)(buf);
9545+
else
9546+
#endif
9547+
ret_char = buf[0];
9548+
}
9549+
break;
9550+
}
9551+
}
9552+
idx = 0;
9553+
}
9554+
--no_mapping;
9555+
allow_keys = save_allow_keys;
9556+
9557+
return ret_char;
9558+
}
9559+
94609560
#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
94619561
static void
94629562
ins_tabline(int c)

src/evalfunc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4231,7 +4231,7 @@ f_getchar(typval_T *argvars, typval_T *rettv)
42314231
{
42324232
if (argvars[0].v_type == VAR_UNKNOWN)
42334233
/* getchar(): blocking wait. */
4234-
n = safe_vgetc();
4234+
n = plain_vgetc();
42354235
else if (get_tv_number_chk(&argvars[0], &error) == 1)
42364236
/* getchar(1): only check if char avail */
42374237
n = vpeekc_any();
@@ -4240,7 +4240,7 @@ f_getchar(typval_T *argvars, typval_T *rettv)
42404240
n = 0;
42414241
else
42424242
/* getchar(0) and char avail: return char */
4243-
n = safe_vgetc();
4243+
n = plain_vgetc();
42444244

42454245
if (n == K_IGNORE)
42464246
continue;

src/ex_cmds.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5263,6 +5263,10 @@ do_sub(exarg_T *eap)
52635263
setmouse(); /* disable mouse in xterm */
52645264
#endif
52655265
curwin->w_cursor.col = regmatch.startpos[0].col;
5266+
#ifdef FEAT_CURSORBIND
5267+
if (curwin->w_p_crb)
5268+
do_check_cursorbind();
5269+
#endif
52665270

52675271
/* When 'cpoptions' contains "u" don't sync undo when
52685272
* asking for confirmation. */

src/getchar.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1817,6 +1817,12 @@ plain_vgetc(void)
18171817
{
18181818
c = safe_vgetc();
18191819
} while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
1820+
1821+
if (c == K_PS)
1822+
/* Only handle the first pasted character. Drop the rest, since we
1823+
* don't know what to do with it. */
1824+
c = bracketed_paste(PASTE_ONE_CHAR, FALSE, NULL);
1825+
18201826
return c;
18211827
}
18221828

@@ -1906,7 +1912,7 @@ vungetc(int c)
19061912
}
19071913

19081914
/*
1909-
* get a character:
1915+
* Get a character:
19101916
* 1. from the stuffbuffer
19111917
* This is used for abbreviated commands like "D" -> "d$".
19121918
* Also used to redo a command for ".".

src/keymap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ enum key_extra
398398
#define K_KMULTIPLY TERMCAP2KEY('K', '9') /* keypad * */
399399
#define K_KENTER TERMCAP2KEY('K', 'A') /* keypad Enter */
400400
#define K_KPOINT TERMCAP2KEY('K', 'B') /* keypad . or ,*/
401+
#define K_PS TERMCAP2KEY('P', 'S') /* paste start */
402+
#define K_PE TERMCAP2KEY('P', 'E') /* paste end */
401403

402404
#define K_K0 TERMCAP2KEY('K', 'C') /* keypad 0 */
403405
#define K_K1 TERMCAP2KEY('K', 'D') /* keypad 1 */

src/misc2.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,8 @@ static struct key_name_entry
22942294
{K_XDOWN, (char_u *)"xDown"},
22952295
{K_XLEFT, (char_u *)"xLeft"},
22962296
{K_XRIGHT, (char_u *)"xRight"},
2297+
{K_PS, (char_u *)"PasteStart"},
2298+
{K_PE, (char_u *)"PasteEnd"},
22972299

22982300
{K_F1, (char_u *)"F1"},
22992301
{K_F2, (char_u *)"F2"},

src/normal.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ static const struct nv_cmd
426426
#ifdef FEAT_AUTOCMD
427427
{K_CURSORHOLD, nv_cursorhold, NV_KEEPREG, 0},
428428
#endif
429+
{K_PS, nv_edit, 0, 0},
429430
};
430431

431432
/* Number of commands in nv_cmds[]. */
@@ -3860,7 +3861,7 @@ add_to_showcmd(int c)
38603861
K_VER_SCROLLBAR, K_HOR_SCROLLBAR,
38613862
K_LEFTMOUSE_NM, K_LEFTRELEASE_NM,
38623863
# endif
3863-
K_IGNORE,
3864+
K_IGNORE, K_PS,
38643865
K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE,
38653866
K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE,
38663867
K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
@@ -9049,6 +9050,7 @@ nv_esc(cmdarg_T *cap)
90499050

90509051
/*
90519052
* Handle "A", "a", "I", "i" and <Insert> commands.
9053+
* Also handle K_PS, start bracketed paste.
90529054
*/
90539055
static void
90549056
nv_edit(cmdarg_T *cap)
@@ -9076,6 +9078,9 @@ nv_edit(cmdarg_T *cap)
90769078
/* Only give this error when 'insertmode' is off. */
90779079
EMSG(_(e_modifiable));
90789080
clearop(cap->oap);
9081+
if (cap->cmdchar == K_PS)
9082+
/* drop the pasted text */
9083+
bracketed_paste(PASTE_INSERT, TRUE, NULL);
90799084
}
90809085
else if (!checkclearopq(cap->oap))
90819086
{
@@ -9107,6 +9112,7 @@ nv_edit(cmdarg_T *cap)
91079112
break;
91089113

91099114
case 'a': /* "a"ppend is like "i"nsert on the next character. */
9115+
case K_PS: /* bracketed paste works like "a"ppend */
91109116
#ifdef FEAT_VIRTUALEDIT
91119117
/* increment coladd when in virtual space, increment the
91129118
* column otherwise, also to append after an unprintable char */
@@ -9137,6 +9143,9 @@ nv_edit(cmdarg_T *cap)
91379143

91389144
invoke_edit(cap, FALSE, cap->cmdchar, FALSE);
91399145
}
9146+
else if (cap->cmdchar == K_PS)
9147+
/* drop the pasted text */
9148+
bracketed_paste(PASTE_INSERT, TRUE, NULL);
91409149
}
91419150

91429151
/*

src/option.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3108,6 +3108,8 @@ static struct vimoption options[] =
31083108
p_term("t_ZR", T_CZR)
31093109
p_term("t_8f", T_8F)
31103110
p_term("t_8b", T_8B)
3111+
p_term("t_BE", T_BE)
3112+
p_term("t_BD", T_BD)
31113113

31123114
/* terminal key codes are not in here */
31133115

src/proto/edit.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ void fixthisline(int (*get_the_indent)(void));
3838
void fix_indent(void);
3939
int in_cinkeys(int keytyped, int when, int line_is_empty);
4040
int hkmap(int c);
41+
int bracketed_paste(paste_mode_T mode, int drop, garray_T *gap);
4142
void ins_scroll(void);
4243
void ins_horscroll(void);
4344
int ins_copychar(linenr_T lnum);

0 commit comments

Comments
 (0)