aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-04-04 01:08:07 +0200
committerJustin M. Keyes <justinkz@gmail.com>2018-04-04 03:23:15 +0200
commit224ebc0078f29ac3189d7fbd9a59b386ae2ee303 (patch)
treed59733a73a7c7202b8badaba95d3f2bcc886ac77
parent98e71123900fbdf26a16a43297a1f58118cde41b (diff)
downloadrneovim-224ebc0078f29ac3189d7fbd9a59b386ae2ee303.tar.gz
rneovim-224ebc0078f29ac3189d7fbd9a59b386ae2ee303.tar.bz2
rneovim-224ebc0078f29ac3189d7fbd9a59b386ae2ee303.zip
insert-mode: interpret unmapped META as ESC
closes #2454 closes #8213 ref #7972
-rw-r--r--runtime/doc/insert.txt9
-rw-r--r--runtime/doc/options.txt9
-rw-r--r--src/nvim/edit.c24
-rw-r--r--src/nvim/getchar.c4
-rw-r--r--src/nvim/keymap.h2
-rw-r--r--test/functional/insert/insert_spec.lua41
-rw-r--r--test/functional/insert/last_inserted_spec.lua22
-rw-r--r--test/functional/terminal/tui_spec.lua14
8 files changed, 73 insertions, 52 deletions
diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt
index 9ae35bea52..1feff0723b 100644
--- a/runtime/doc/insert.txt
+++ b/runtime/doc/insert.txt
@@ -40,10 +40,11 @@ char action ~
*i_CTRL-[* *i_<Esc>*
<Esc> or CTRL-[ End insert or Replace mode, go back to Normal mode. Finish
abbreviation.
- Note: If your <Esc> key is hard to hit on your keyboard, train
- yourself to use CTRL-[.
- If Esc doesn't work and you are using a Mac, try CTRL-Esc.
- Or disable Listening under Accessibility preferences.
+ Note: If your <Esc> key is hard to hit, try CTRL-[ instead.
+ *i_META* *i_ALT*
+ |ALT| (|META|) acts like <Esc> if the chord is not mapped.
+ For example <A-x> acts like <Esc>x if <A-x> does not have an
+ insert-mode mapping.
*i_CTRL-C*
CTRL-C Quit insert mode, go back to Normal mode. Do not check for
abbreviations. Does not trigger the |InsertLeave| autocommand
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index d9ce668962..0b7c61ea18 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -6290,15 +6290,14 @@ A jump table for the options with a short description can be found at |Q_op|.
*'timeoutlen'* *'tm'*
'timeoutlen' 'tm' number (default 1000)
global
- The time in milliseconds that is waited for a mapped sequence to
- complete.
+ Time in milliseconds to wait for a mapped sequence to complete.
*'ttimeoutlen'* *'ttm'*
'ttimeoutlen' 'ttm' number (default 50)
global
- The time in milliseconds that is waited for a key code
- sequence to complete. Also used for CTRL-\ CTRL-N and CTRL-\ CTRL-G
- when part of a command has been typed.
+ Time in milliseconds to wait for a key code sequence to complete. Also
+ used for CTRL-\ CTRL-N and CTRL-\ CTRL-G when part of a command has
+ been typed.
*'title'* *'notitle'*
'title' boolean (default off)
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index b772a944f4..117d89d24c 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -847,7 +847,7 @@ static int insert_handle_key(InsertState *s)
case ' ':
- if (mod_mask != 4) {
+ if (mod_mask != MOD_MASK_CTRL) {
goto normalchar;
}
// FALLTHROUGH
@@ -1180,6 +1180,14 @@ static int insert_handle_key(InsertState *s)
normalchar:
// Insert a normal character.
+
+ if (mod_mask == MOD_MASK_ALT || mod_mask == MOD_MASK_META) {
+ // Unmapped ALT/META chord behaves like ESC+c. #8213
+ stuffcharReadbuff(ESC);
+ stuffcharReadbuff(s->c);
+ break;
+ }
+
if (!p_paste) {
// Trigger InsertCharPre.
char_u *str = do_insert_char_pre(s->c);
@@ -1432,7 +1440,7 @@ static void ins_ctrl_v(void)
* line and will not removed by the redraw */
edit_unputchar();
clear_showcmd();
- insert_special(c, FALSE, TRUE);
+ insert_special(c, true, true);
revins_chars++;
revins_legal++;
}
@@ -5054,13 +5062,11 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
char_u *p;
int len;
- /*
- * Special function key, translate into "<Key>". Up to the last '>' is
- * inserted with ins_str(), so as not to replace characters in replace
- * mode.
- * Only use mod_mask for special keys, to avoid things like <S-Space>,
- * unless 'allow_modmask' is TRUE.
- */
+ // Special function key, translate into "<Key>". Up to the last '>' is
+ // inserted with ins_str(), so as not to replace characters in replace
+ // mode.
+ // Only use mod_mask for special keys, to avoid things like <S-Space>,
+ // unless 'allow_modmask' is TRUE.
if (mod_mask & MOD_MASK_CMD) { // Command-key never produces a normal key.
allow_modmask = true;
}
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 5d4e61d56a..03929a58b6 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1577,7 +1577,7 @@ vungetc ( /* unget one character (can only be done once!) */
old_mouse_col = mouse_col;
}
-/// get a character:
+/// Gets a character:
/// 1. from the stuffbuffer
/// This is used for abbreviated commands like "D" -> "d$".
/// Also used to redo a command for ".".
@@ -1595,7 +1595,7 @@ vungetc ( /* unget one character (can only be done once!) */
/// if "advance" is FALSE (vpeekc()):
/// just look whether there is a character available.
///
-/// When "no_mapping" is zero, checks for mappings in the current mode.
+/// When `no_mapping` (global) is zero, checks for mappings in the current mode.
/// Only returns one byte (of a multi-byte character).
/// K_SPECIAL and CSI may be escaped, need to get two more bytes then.
static int vgetorpeek(int advance)
diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h
index 00e9cf6ed3..c64691e8ea 100644
--- a/src/nvim/keymap.h
+++ b/src/nvim/keymap.h
@@ -443,7 +443,7 @@ enum key_extra {
#define MOD_MASK_2CLICK 0x20 // use MOD_MASK_MULTI_CLICK
#define MOD_MASK_3CLICK 0x40 // use MOD_MASK_MULTI_CLICK
#define MOD_MASK_4CLICK 0x60 // use MOD_MASK_MULTI_CLICK
-#define MOD_MASK_CMD 0x80 // "super" key (OSX/Mac: command-key)
+#define MOD_MASK_CMD 0x80 // "super" key (macOS: command-key)
#define MOD_MASK_MULTI_CLICK (MOD_MASK_2CLICK|MOD_MASK_3CLICK| \
MOD_MASK_4CLICK)
diff --git a/test/functional/insert/insert_spec.lua b/test/functional/insert/insert_spec.lua
new file mode 100644
index 0000000000..427954f5a6
--- /dev/null
+++ b/test/functional/insert/insert_spec.lua
@@ -0,0 +1,41 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local command = helpers.command
+local eq = helpers.eq
+local expect = helpers.expect
+local funcs = helpers.funcs
+
+describe('insert-mode', function()
+ before_each(function()
+ clear()
+ end)
+
+ it('CTRL-@', function()
+ -- Inserts last-inserted text, leaves insert-mode.
+ insert('hello')
+ feed('i<C-@>x')
+ expect('hellhello')
+
+ -- C-Space is the same as C-@.
+ -- CTRL-SPC inserts last-inserted text, leaves insert-mode.
+ feed('i<C-Space>x')
+ expect('hellhellhello')
+
+ -- CTRL-A inserts last inserted text
+ feed('i<C-A>x')
+ expect('hellhellhellhelloxo')
+ end)
+
+ it('ALT/META #8213', function()
+ -- Mapped ALT-chord behaves as mapped.
+ command('inoremap <M-l> meta-l')
+ command('inoremap <A-j> alt-j')
+ feed('i<M-l> xxx <A-j><M-h>a<A-h>')
+ expect('meta-l xxx alt-j')
+ eq({ 0, 1, 14, 0, }, funcs.getpos('.'))
+ -- Unmapped ALT-chord behaves as ESC+c.
+ command('iunmap <M-l>')
+ feed('0i<M-l>')
+ eq({ 0, 1, 2, 0, }, funcs.getpos('.'))
+ end)
+end)
diff --git a/test/functional/insert/last_inserted_spec.lua b/test/functional/insert/last_inserted_spec.lua
deleted file mode 100644
index dce23a3790..0000000000
--- a/test/functional/insert/last_inserted_spec.lua
+++ /dev/null
@@ -1,22 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
-local expect = helpers.expect
-
-clear()
-
-describe('insert-mode', function()
- it('CTRL-@ inserts last-inserted text, leaves insert-mode', function()
- insert('hello')
- feed('i<C-@>x')
- expect('hellhello')
- end)
- -- C-Space is the same as C-@
- it('CTRL-SPC inserts last-inserted text, leaves insert-mode', function()
- feed('i<C-Space>x')
- expect('hellhellhello')
- end)
- it('CTRL-A inserts last inserted text', function()
- feed('i<C-A>x')
- expect('hellhellhellhelloxo')
- end)
-end)
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 171745eb57..2f9abfd3f6 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -115,16 +115,12 @@ describe('tui', function()
]])
end)
- it('does not mangle unmapped ALT-key chord', function()
- -- Vim represents ALT/META by setting the "high bit" of the modified key;
- -- we do _not_. #3982
- --
- -- Example: for input ALT+j:
- -- * Vim (Nvim prior to #3982) sets high-bit, inserts "ê".
- -- * Nvim (after #3982) inserts "j".
- feed_data('i\027j')
+ it('interprets ESC+key as ALT chord', function()
+ -- Vim represents ALT/META by setting the "high bit" of the modified key:
+ -- ALT+j inserts "ê". Nvim does not (#3982).
+ feed_data('i\022\027j')
screen:expect([[
- j{1: } |
+ <M-j>{1: } |
{4:~ }|
{4:~ }|
{4:~ }|