From 2f06413dfb3624381f112b7d8661fde659c279e7 Mon Sep 17 00:00:00 2001 From: Matt Wozniski Date: Sun, 4 Oct 2020 02:37:45 -0400 Subject: [PATCH] Treat unmapped ALT/META as ESC+c in all modes In #8226 and were changed to behave like x in insert mode when no mapping exists. This commit backs out that change and replaces it with a more general one that makes unmapped ALT and META keypresses as +char in all modes. This fixes an unnecessary and confusing inconsistency between modes. --- runtime/doc/cmdline.txt | 4 ++++ runtime/doc/insert.txt | 4 ++-- runtime/doc/intro.txt | 2 ++ runtime/doc/vim_diff.txt | 2 +- runtime/doc/visual.txt | 5 ++++- src/nvim/edit.c | 8 -------- src/nvim/getchar.c | 11 +++++++++++ test/functional/normal/meta_key_spec.lua | 22 ++++++++++++++++++++++ test/functional/visual/meta_key_spec.lua | 22 ++++++++++++++++++++++ 9 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 test/functional/normal/meta_key_spec.lua create mode 100644 test/functional/visual/meta_key_spec.lua 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_* *c_Esc* present in 'cpoptions', start entered command. Note: If your key is hard to hit on your keyboard, train yourself to use CTRL-[. + *c_META* *c_ALT* + ALT (|META|) acts like if the chord is not mapped. + For example acts like x if 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 key is hard to hit, try CTRL-[ instead. *i_META* *i_ALT* - ALT (|META|) acts like if the chord is not mapped. + ALT (|META|) acts like if the chord is not mapped. For example acts like x if 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: , ..., and will not work. - Nvim supports mapping multibyte chars with modifiers such as ``. 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 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: , , , , , , , , etc. Case-sensitive: and are two different keycodes. - ALT in insert-mode behaves like if not mapped. |i_ALT| + ALT behaves like if not mapped. |i_ALT| |v_ALT| |c_ALT| Normal commands: |g| 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_* In Visual mode: Stop Visual mode. - + *v_META* *v_ALT* + ALT (|META|) acts like if the chord is not mapped. + For example acts like x if 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 + // as 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') + expect('llo') + -- Mapped ALT-chord behaves as mapped. + command('nnoremap Ameta-l') + command('nnoremap Aalt-j') + feed('') + 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('viwviw') + expect('peach') + -- Mapped ALT-chord behaves as mapped. + command('vnoremap Ameta-l') + command('vnoremap Aalt-j') + feed('viwviw') + expect('peachalt-jmeta-l') + end) +end)