diff options
-rw-r--r-- | src/nvim/keymap.c | 32 | ||||
-rw-r--r-- | src/nvim/terminal.c | 26 | ||||
-rw-r--r-- | test/functional/terminal/tui_spec.lua | 21 |
3 files changed, 46 insertions, 33 deletions
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 04d6cbf5e3..b2fd929714 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -18,6 +18,9 @@ #include "nvim/strings.h" #include "nvim/mouse.h" +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "keymap.c.generated.h" +#endif /* * Some useful tables. @@ -637,11 +640,11 @@ find_special_key ( key = DEL; } - /* - * Normal Key with modifier: Try to make a single byte code. - */ - if (!IS_SPECIAL(key)) + // Normal Key with modifier: + // Try to make a single byte code (except for Alt/Meta modifiers). + if (!IS_SPECIAL(key)) { key = extract_modifiers(key, &modifiers); + } *modp = modifiers; *srcp = end_of_name; @@ -652,11 +655,9 @@ find_special_key ( return 0; } -/* - * Try to include modifiers in the key. - * Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc. - */ -int extract_modifiers(int key, int *modp) +/// Try to include modifiers (except alt/meta) in the key. +/// Changes "Shift-a" to 'A', "Ctrl-@" to <Nul>, etc. +static int extract_modifiers(int key, int *modp) { int modifiers = *modp; @@ -665,19 +666,12 @@ int extract_modifiers(int key, int *modp) modifiers &= ~MOD_MASK_SHIFT; } if ((modifiers & MOD_MASK_CTRL) - && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key)) - ) { + && ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))) { key = Ctrl_chr(key); modifiers &= ~MOD_MASK_CTRL; - /* <C-@> is <Nul> */ - if (key == 0) + if (key == 0) { // <C-@> is <Nul> key = K_ZERO; - } - if ((modifiers & MOD_MASK_ALT) && key < 0x80 - && !enc_dbcs /* avoid creating a lead byte */ - ) { - key |= 0x80; - modifiers &= ~MOD_MASK_ALT; /* remove the META modifier */ + } } *modp = modifiers; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index adf3f725a2..6045acd1cb 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -1,5 +1,5 @@ -// VT220/xterm-like terminal emulator implementation for Neovim. Powered by -// libvterm(http://www.leonerd.org.uk/code/libvterm/). +// VT220/xterm-like terminal emulator implementation for nvim. Powered by +// libvterm (http://www.leonerd.org.uk/code/libvterm/). // // libvterm is a pure C99 terminal emulation library with abstract input and // display. This means that the library needs to read data from the master fd @@ -10,31 +10,31 @@ // vterm_keyboard_key/vterm_keyboard_unichar, which generates byte streams that // must be fed back to the master fd. // -// This implementation uses Neovim buffers as the display mechanism for both +// This implementation uses nvim buffers as the display mechanism for both // the visible screen and the scrollback buffer. When focused, the window // "pins" to the bottom of the buffer and mirrors libvterm screen state. // // When a line becomes invisible due to a decrease in screen height or because // a line was pushed up during normal terminal output, we store the line -// information in the scrollback buffer, which is mirrored in the Neovim buffer +// information in the scrollback buffer, which is mirrored in the nvim buffer // by appending lines just above the visible part of the buffer. // // When the screen height increases, libvterm will ask for a row in the -// scrollback buffer, which is mirrored in the Neovim buffer displaying lines +// scrollback buffer, which is mirrored in the nvim buffer displaying lines // that were previously invisible. // -// The vterm->Neovim synchronization is performed in intervals of 10 +// The vterm->nvim synchronization is performed in intervals of 10 // milliseconds. This is done to minimize screen updates when receiving large // bursts of data. // // This module is decoupled from the processes that normally feed it data, so -// it's possible to use it as a general purpose console buffer(possibly as a -// log/display mechanism for Neovim in the future) +// it's possible to use it as a general purpose console buffer (possibly as a +// log/display mechanism for nvim in the future) // -// Inspired by vimshell(http://www.wana.at/vimshell/) and -// Conque(https://code.google.com/p/conque/). Libvterm usage instructions (plus +// Inspired by vimshell (http://www.wana.at/vimshell/) and +// Conque (https://code.google.com/p/conque/). Libvterm usage instructions (plus // some extra code) were taken from -// pangoterm(http://www.leonerd.org.uk/code/pangoterm/) +// pangoterm (http://www.leonerd.org.uk/code/pangoterm/) #include <assert.h> #include <stdio.h> #include <stdint.h> @@ -402,11 +402,11 @@ static int terminal_execute(VimState *state, int key) TerminalState *s = (TerminalState *)state; switch (key) { - case K_FOCUSGAINED: // Neovim has been given focus + case K_FOCUSGAINED: // nvim has been given focus apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf); break; - case K_FOCUSLOST: // Neovim has lost focus + case K_FOCUSLOST: // nvim has lost focus apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf); break; diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 14700a2622..838d05a6df 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -53,7 +53,7 @@ describe('tui', function() ]]) end) - it('interprets leading esc byte as the alt modifier', function() + it('interprets leading <Esc> byte as ALT modifier in normal-mode', function() local keys = 'dfghjkl' for c in keys:gmatch('.') do execute('nnoremap <a-'..c..'> ialt-'..c..'<cr><esc>') @@ -80,6 +80,25 @@ 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('i\x1bj') + screen:expect([[ + j{1: } | + ~ | + ~ | + ~ | + [No Name] [+] | + -- INSERT -- | + -- TERMINAL -- | + ]]) + end) + it('accepts ascii control sequences', function() feed('i') feed('\x16\x07') -- ctrl+g |