diff options
-rw-r--r-- | runtime/doc/cmdline.txt | 4 | ||||
-rw-r--r-- | runtime/doc/insert.txt | 4 | ||||
-rw-r--r-- | runtime/doc/intro.txt | 2 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 2 | ||||
-rw-r--r-- | runtime/doc/visual.txt | 5 | ||||
-rw-r--r-- | src/nvim/edit.c | 8 | ||||
-rw-r--r-- | src/nvim/getchar.c | 11 | ||||
-rw-r--r-- | test/functional/normal/meta_key_spec.lua | 22 | ||||
-rw-r--r-- | test/functional/visual/meta_key_spec.lua | 22 |
9 files changed, 68 insertions, 12 deletions
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index 163dc81804..f7a281cb88 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -224,6 +224,10 @@ CTRL-[ *c_CTRL-[* *c_<Esc>* *c_Esc* present in 'cpoptions', start entered command. Note: If your <Esc> key is hard to hit on your keyboard, train yourself to use CTRL-[. + *c_META* *c_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 a + command-line mode mapping. *c_CTRL-C* CTRL-C quit command-line without executing diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index e53af5074b..c4b93a2a27 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -42,9 +42,9 @@ char action ~ abbreviation. 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. + 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. + 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/intro.txt b/runtime/doc/intro.txt index 59b1f44e39..d858985e3f 100644 --- a/runtime/doc/intro.txt +++ b/runtime/doc/intro.txt @@ -382,6 +382,8 @@ Note: <k1>, ..., <k9> and <kPoint> will not work. - Nvim supports mapping multibyte chars with modifiers such as `<M-รค>`. Which combinations actually work depends on the the UI or host terminal. +- When a key is pressed using a meta or alt modifier and no mapping exists + for that keypress, Nvim behaves as though <Esc> was pressed before the key. *<>* Examples are often given in the <> notation. Sometimes this is just to make diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 3090be82f2..ae60c1c5e8 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -195,7 +195,7 @@ Input/Mappings: <M-1>, <M-BS>, <M-Del>, <M-Ins>, <M-/>, <M-\>, <M-Space>, <M-Enter>, etc. Case-sensitive: <M-a> and <M-A> are two different keycodes. - ALT in insert-mode behaves like <Esc> if not mapped. |i_ALT| + ALT behaves like <Esc> if not mapped. |i_ALT| |v_ALT| |c_ALT| Normal commands: |g<Tab>| goes to the last-accessed tabpage. diff --git a/runtime/doc/visual.txt b/runtime/doc/visual.txt index 0052382044..fd3d93ed98 100644 --- a/runtime/doc/visual.txt +++ b/runtime/doc/visual.txt @@ -159,7 +159,10 @@ If you want to highlight exactly the same area as the last time, you can use *v_<Esc>* <Esc> In Visual mode: Stop Visual mode. - + *v_META* *v_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 a + visual-mode mapping. *v_CTRL-C* CTRL-C In Visual mode: Stop Visual mode. When insert mode is pending (the mode message shows diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 1e149da1dc..de2346a9d8 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1254,14 +1254,6 @@ check_pum: 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); - u_sync(false); - break; - } - if (!p_paste) { // Trigger InsertCharPre. char_u *str = do_insert_char_pre(s->c); diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index ecb3931b82..cbd9582f8b 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1528,6 +1528,17 @@ int vgetc(void) c = utf_ptr2char(buf); } + // If mappings are enabled (i.e., not Ctrl-v) and the user directly typed + // something with a meta- or alt- modifier that was not mapped, interpret + // <M-x> as <Esc>x rather than as an unbound meta keypress. #8213 + if (!no_mapping && KeyTyped + && (mod_mask == MOD_MASK_ALT || mod_mask == MOD_MASK_META)) { + mod_mask = 0; + stuffcharReadbuff(c); + u_sync(false); + c = ESC; + } + break; } } diff --git a/test/functional/normal/meta_key_spec.lua b/test/functional/normal/meta_key_spec.lua new file mode 100644 index 0000000000..9f9fad67d2 --- /dev/null +++ b/test/functional/normal/meta_key_spec.lua @@ -0,0 +1,22 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local command = helpers.command +local expect = helpers.expect + +describe('meta-keys-in-normal-mode', function() + before_each(function() + clear() + end) + + it('ALT/META', function() + -- Unmapped ALT-chords behave as Esc+c + insert('hello') + feed('0<A-x><M-x>') + expect('llo') + -- Mapped ALT-chord behaves as mapped. + command('nnoremap <M-l> Ameta-l<Esc>') + command('nnoremap <A-j> Aalt-j<Esc>') + feed('<A-j><M-l>') + expect('lloalt-jmeta-l') + end) +end) diff --git a/test/functional/visual/meta_key_spec.lua b/test/functional/visual/meta_key_spec.lua new file mode 100644 index 0000000000..11f7203da0 --- /dev/null +++ b/test/functional/visual/meta_key_spec.lua @@ -0,0 +1,22 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local command = helpers.command +local expect = helpers.expect + +describe('meta-keys-in-visual-mode', function() + before_each(function() + clear() + end) + + it('ALT/META', function() + -- Unmapped ALT-chords behave as Esc+c + insert('peaches') + feed('viw<A-x>viw<M-x>') + expect('peach') + -- Mapped ALT-chord behaves as mapped. + command('vnoremap <M-l> Ameta-l<Esc>') + command('vnoremap <A-j> Aalt-j<Esc>') + feed('viw<A-j>viw<M-l>') + expect('peachalt-jmeta-l') + end) +end) |