Patch 8.1.2350
Problem: Other text for CTRL-V in Insert mode with modifyOtherKeys.
Solution: Convert the Escape sequence back to key as if modifyOtherKeys is
not set, and use CTRL-SHIFT-V to get the Escape sequence itself.
(closes #5254)
Files: runtime/doc/insert.txt, runtime/doc/cmdline.txt, src/edit.c,
src/proto/edit.pro, src/term.c, src/proto/term.pro, src/getchar.c,
src/proto/getchar.pro, src/testdir/test_termcodes.vim,
src/ex_getln.c
*** ../vim-8.1.2349/runtime/doc/insert.txt 2019-10-20 18:17:08.367431701
+0200
--- runtime/doc/insert.txt 2019-11-26 19:28:14.541539868 +0100
***************
*** 194,202 ****
decimal, octal or hexadecimal value of a character
|i_CTRL-V_digit|.
The characters typed right after CTRL-V are not considered for
! mapping. {Vi: no decimal byte entry}
Note: When CTRL-V is mapped (e.g., to paste text) you can
often use CTRL-Q instead |i_CTRL-Q|.
*i_CTRL-Q*
CTRL-Q Same as CTRL-V.
--- 193,208 ----
decimal, octal or hexadecimal value of a character
|i_CTRL-V_digit|.
The characters typed right after CTRL-V are not considered for
! mapping.
Note: When CTRL-V is mapped (e.g., to paste text) you can
often use CTRL-Q instead |i_CTRL-Q|.
+ When |modifyOtherKeys| is enabled then special Escape sequence
+ is converted back to what it was without |modifyOtherKeys|,
+ unless the Shift key is also pressed.
+
+ *i_CTRL-SHIFT-V*
+ CTRL-SHIFT-V Works just like CTRL-V, unless |modifyOtherKeys| is active,
+ then it inserts the Escape sequence for a key with modifiers.
*i_CTRL-Q*
CTRL-Q Same as CTRL-V.
*** ../vim-8.1.2349/runtime/doc/cmdline.txt 2019-09-09 18:35:28.119252725
+0200
--- runtime/doc/cmdline.txt 2019-11-26 19:27:57.641739370 +0100
***************
*** 77,86 ****
--- 77,93 ----
way as in Insert mode (see above, |i_CTRL-V|).
Note: Under Windows CTRL-V is often mapped to paste text.
Use CTRL-Q instead then.
+ When |modifyOtherKeys| is enabled then special Escape sequence
+ is converted back to what it was without |modifyOtherKeys|,
+ unless the Shift key is also pressed.
*c_CTRL-Q*
CTRL-Q Same as CTRL-V. But with some terminals it is used for
control flow, it doesn't work then.
+ CTRL-SHIFT-V *c_CTRL-SHIFT-V* *c_CTRL-SHIFT-Q*
+ CTRL-SHIFT-Q Works just like CTRL-V, unless |modifyOtherKeys| is active,
+ then it inserts the Escape sequence for a key with modifiers.
+
*c_<Left>* *c_Left*
<Left> cursor left
*c_<Right>* *c_Right*
*** ../vim-8.1.2349/src/edit.c 2019-11-26 14:28:11.781313275 +0100
--- src/edit.c 2019-11-26 19:02:23.741606074 +0100
***************
*** 1531,1536 ****
--- 1531,1537 ----
{
int c;
int did_putchar = FALSE;
+ int prev_mod_mask = mod_mask;
/* may need to redraw when no more chars available now */
ins_redraw(FALSE);
***************
*** 1554,1559 ****
--- 1555,1566 ----
#ifdef FEAT_CMDL_INFO
clear_showcmd();
#endif
+
+ if ((c == ESC || c == CSI) && !(prev_mod_mask & MOD_MASK_SHIFT))
+ // Using CTRL-V: Change any modifyOtherKeys ESC sequence to a normal
+ // key. Don't do this for CTRL-SHIFT-V.
+ c = decodeModifyOtherKeys(c);
+
insert_special(c, FALSE, TRUE);
#ifdef FEAT_RIGHTLEFT
revins_chars++;
***************
*** 1562,1567 ****
--- 1569,1627 ----
}
/*
+ * After getting an ESC or CSI for a literal key: If the typeahead buffer
+ * contains a modifyOtherKeys sequence then decode it and return the result.
+ * Otherwise return "c".
+ * Note that this doesn't wait for characters, they must be in the typeahead
+ * buffer already.
+ */
+ int
+ decodeModifyOtherKeys(int c)
+ {
+ char_u *p = typebuf.tb_buf + typebuf.tb_off;
+ int idx;
+ int form = 0;
+ int argidx = 0;
+ int arg[2] = {0, 0};
+
+ // Recognize:
+ // form 0: {lead}{key};{modifier}u
+ // form 1: {lead}27;{modifier};{key}~
+ if ((c == CSI || (c == ESC && *p == '[')) && typebuf.tb_len >= 4)
+ {
+ idx = (*p == '[');
+ if (p[idx] == '2' && p[idx + 1] == '7' && p[idx + 2] == ';')
+ {
+ form = 1;
+ idx += 3;
+ }
+ while (idx < typebuf.tb_len && argidx < 2)
+ {
+ if (p[idx] == ';')
+ ++argidx;
+ else if (VIM_ISDIGIT(p[idx]))
+ arg[argidx] = arg[argidx] * 10 + (p[idx] - '0');
+ else
+ break;
+ ++idx;
+ }
+ if (idx < typebuf.tb_len
+ && p[idx] == (form == 1 ? '~' : 'u')
+ && argidx == 1)
+ {
+ // Match, consume the code.
+ typebuf.tb_off += idx + 1;
+ typebuf.tb_len -= idx + 1;
+
+ mod_mask = decode_modifiers(arg[!form]);
+ c = merge_modifyOtherKeys(arg[form]);
+ }
+ }
+
+ return c;
+ }
+
+ /*
* Put a character directly onto the screen. It's not stored in a buffer.
* Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
*/
*** ../vim-8.1.2349/src/proto/edit.pro 2019-10-09 22:52:49.000043746 +0200
--- src/proto/edit.pro 2019-11-26 18:46:12.734060440 +0100
***************
*** 2,7 ****
--- 2,8 ----
int edit(int cmdchar, int startln, long count);
int ins_need_undo_get(void);
void ins_redraw(int ready);
+ int decodeModifyOtherKeys(int c);
void edit_putchar(int c, int highlight);
char_u *prompt_text(void);
int prompt_curpos_editable(void);
*** ../vim-8.1.2349/src/term.c 2019-11-21 22:14:14.357810945 +0100
--- src/term.c 2019-11-26 18:57:34.625375262 +0100
***************
*** 4277,4283 ****
/*
* Decode a modifier number as xterm provides it into MOD_MASK bits.
*/
! static int
decode_modifiers(int n)
{
int code = n - 1;
--- 4277,4283 ----
/*
* Decode a modifier number as xterm provides it into MOD_MASK bits.
*/
! int
decode_modifiers(int n)
{
int code = n - 1;
*** ../vim-8.1.2349/src/proto/term.pro 2019-11-21 22:14:14.357810945 +0100
--- src/proto/term.pro 2019-11-26 18:54:58.233056654 +0100
***************
*** 65,70 ****
--- 65,71 ----
void del_termcode(char_u *name);
void set_mouse_topline(win_T *wp);
int is_mouse_topline(win_T *wp);
+ int decode_modifiers(int n);
int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen);
void term_get_fg_color(char_u *r, char_u *g, char_u *b);
void term_get_bg_color(char_u *r, char_u *g, char_u *b);
*** ../vim-8.1.2349/src/getchar.c 2019-11-22 20:55:22.403621863 +0100
--- src/getchar.c 2019-11-26 19:00:05.013542417 +0100
***************
*** 1525,1530 ****
--- 1525,1562 ----
}
/*
+ * Convert "c" plus "mod_mask" to merge the effect of modifyOtherKeys into the
+ * character.
+ */
+ int
+ merge_modifyOtherKeys(int c_arg)
+ {
+ int c = c_arg;
+
+ if (mod_mask & MOD_MASK_CTRL)
+ {
+ if ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_'))
+ {
+ c &= 0x1f;
+ mod_mask &= ~MOD_MASK_CTRL;
+ }
+ else if (c == '6')
+ {
+ // CTRL-6 is equivalent to CTRL-^
+ c = 0x1e;
+ mod_mask &= ~MOD_MASK_CTRL;
+ }
+ }
+ if ((mod_mask & (MOD_MASK_META | MOD_MASK_ALT))
+ && c >= 0 && c <= 127)
+ {
+ c += 0x80;
+ mod_mask &= ~(MOD_MASK_META|MOD_MASK_ALT);
+ }
+ return c;
+ }
+
+ /*
* Get the next input character.
* Can return a special key or a multi-byte character.
* Can return NUL when called recursively, use safe_vgetc() if that's not
***************
*** 1765,1794 ****
}
if (!no_reduce_keys)
- {
// A modifier was not used for a mapping, apply it to ASCII
// keys. Shift would already have been applied.
! if (mod_mask & MOD_MASK_CTRL)
! {
! if ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_'))
! {
! c &= 0x1f;
! mod_mask &= ~MOD_MASK_CTRL;
! }
! else if (c == '6')
! {
! // CTRL-6 is equivalent to CTRL-^
! c = 0x1e;
! mod_mask &= ~MOD_MASK_CTRL;
! }
! }
! if ((mod_mask & (MOD_MASK_META | MOD_MASK_ALT))
! && c >= 0 && c <= 127)
! {
! c += 0x80;
! mod_mask &= ~(MOD_MASK_META|MOD_MASK_ALT);
! }
! }
break;
}
--- 1797,1805 ----
}
if (!no_reduce_keys)
// A modifier was not used for a mapping, apply it to ASCII
// keys. Shift would already have been applied.
! c = merge_modifyOtherKeys(c);
break;
}
*** ../vim-8.1.2349/src/proto/getchar.pro 2019-09-15 21:00:51.362604284
+0200
--- src/proto/getchar.pro 2019-11-26 18:59:10.113494756 +0100
***************
*** 37,42 ****
--- 37,43 ----
void close_all_scripts(void);
int using_script(void);
void before_blocking(void);
+ int merge_modifyOtherKeys(int c_arg);
int vgetc(void);
int safe_vgetc(void);
int plain_vgetc(void);
*** ../vim-8.1.2349/src/testdir/test_termcodes.vim 2019-11-26
14:28:11.785313279 +0100
--- src/testdir/test_termcodes.vim 2019-11-26 19:21:32.395606616 +0100
***************
*** 1349,1351 ****
--- 1349,1396 ----
call RunTest_mapping_works_with_mods(function('GetEscCodeCSI27'), 'C-S-A',
8)
call RunTest_mapping_works_with_mods(function('GetEscCodeCSIu'), 'C-S-A', 8)
endfunc
+
+ func Test_insert_literal()
+ set timeoutlen=10
+ new
+ " CTRL-V CTRL-X inserts a ^X
+ call feedkeys('a' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('X', '5')
.. "\<Esc>", 'Lx!')
+ call assert_equal("\<C-X>", getline(1))
+
+ call setline(1, '')
+ call feedkeys('a' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('X', '5')
.. "\<Esc>", 'Lx!')
+ call assert_equal("\<C-X>", getline(1))
+
+ " CTRL-SHIFT-V CTRL-X inserts escape sequencd
+ call setline(1, '')
+ call feedkeys('a' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('X', '5')
.. "\<Esc>", 'Lx!')
+ call assert_equal("\<Esc>[88;5u", getline(1))
+
+ call setline(1, '')
+ call feedkeys('a' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('X', '5')
.. "\<Esc>", 'Lx!')
+ call assert_equal("\<Esc>[27;5;88~", getline(1))
+
+ bwipe!
+ set timeoutlen&
+ endfunc
+
+ func Test_cmdline_literal()
+ set timeoutlen=10
+
+ " CTRL-V CTRL-Y inserts a ^Y
+ call feedkeys(':' .. GetEscCodeCSIu('V', '5') .. GetEscCodeCSIu('Y', '5')
.. "\<C-B>\"\<CR>", 'Lx!')
+ call assert_equal("\"\<C-Y>", @:)
+
+ call feedkeys(':' .. GetEscCodeCSI27('V', '5') .. GetEscCodeCSI27('Y', '5')
.. "\<C-B>\"\<CR>", 'Lx!')
+ call assert_equal("\"\<C-Y>", @:)
+
+ " CTRL-SHIFT-V CTRL-Y inserts escape sequencd
+ call feedkeys(':' .. GetEscCodeCSIu('V', '6') .. GetEscCodeCSIu('Y', '5')
.. "\<C-B>\"\<CR>", 'Lx!')
+ call assert_equal("\"\<Esc>[89;5u", @:)
+
+ call setline(1, '')
+ call feedkeys(':' .. GetEscCodeCSI27('V', '6') .. GetEscCodeCSI27('Y', '5')
.. "\<C-B>\"\<CR>", 'Lx!')
+ call assert_equal("\"\<Esc>[27;5;89~", @:)
+
+ set timeoutlen&
+ endfunc
*** ../vim-8.1.2349/src/ex_getln.c 2019-11-26 14:28:11.781313275 +0100
--- src/ex_getln.c 2019-11-26 19:13:29.857230642 +0100
***************
*** 2208,2225 ****
case Ctrl_V:
case Ctrl_Q:
- ignore_drag_release = TRUE;
- putcmdline('^', TRUE);
- c = get_literal(); /* get next (two) character(s) */
- do_abbr = FALSE; /* don't do abbreviation now */
- extra_char = NUL;
- /* may need to remove ^ when composing char was typed */
- if (enc_utf8 && utf_iscomposing(c) && !cmd_silent)
{
! draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
! msg_putchar(' ');
! cursorcmd();
}
break;
#ifdef FEAT_DIGRAPHS
--- 2208,2238 ----
case Ctrl_V:
case Ctrl_Q:
{
! int prev_mod_mask = mod_mask;
!
! ignore_drag_release = TRUE;
! putcmdline('^', TRUE);
! c = get_literal(); // get next (two) character(s)
! do_abbr = FALSE; // don't do abbreviation now
! extra_char = NUL;
! // may need to remove ^ when composing char was typed
! if (enc_utf8 && utf_iscomposing(c) && !cmd_silent)
! {
! draw_cmdline(ccline.cmdpos,
! ccline.cmdlen - ccline.cmdpos);
! msg_putchar(' ');
! cursorcmd();
! }
!
! if ((c == ESC || c == CSI)
! && !(prev_mod_mask & MOD_MASK_SHIFT))
! // Using CTRL-V: Change any modifyOtherKeys ESC
! // sequence to a normal key. Don't do this for
! // CTRL-SHIFT-V.
! c = decodeModifyOtherKeys(c);
}
+
break;
#ifdef FEAT_DIGRAPHS
*** ../vim-8.1.2349/src/version.c 2019-11-26 17:04:53.445152907 +0100
--- src/version.c 2019-11-26 19:28:26.545400388 +0100
***************
*** 739,740 ****
--- 739,742 ----
{ /* Add new patch number below this line */
+ /**/
+ 2350,
/**/
--
hundred-and-one symptoms of being an internet addict:
126. You brag to all of your friends about your date Saturday night...but
you don't tell them it was only in a chat room.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/201911261833.xAQIXpmF019490%40masaka.moolenaar.net.