@@ -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
94629562ins_tabline (int c )
0 commit comments