From ade51c1d898d8796093060b21289ac81ba4ecca1 Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Sat, 9 Jul 2016 13:43:18 -0400 Subject: terminal.c: Handle more special keys --- src/nvim/terminal.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index bd7b9fc58f..bfcc123161 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -762,6 +762,7 @@ static VTermKey convert_key(int key, VTermModifier *statep) switch (key) { case K_BS: return VTERM_KEY_BACKSPACE; + case K_S_TAB: *statep |= VTERM_MOD_SHIFT; case TAB: return VTERM_KEY_TAB; case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; @@ -801,6 +802,57 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_KMULTIPLY: return VTERM_KEY_KP_MULT; case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; + case K_S_F1: *statep |= VTERM_MOD_SHIFT; + case K_F1: return VTERM_KEY_FUNCTION(1); + case K_S_F2: *statep |= VTERM_MOD_SHIFT; + case K_F2: return VTERM_KEY_FUNCTION(2); + case K_S_F3: *statep |= VTERM_MOD_SHIFT; + case K_F3: return VTERM_KEY_FUNCTION(3); + case K_S_F4: *statep |= VTERM_MOD_SHIFT; + case K_F4: return VTERM_KEY_FUNCTION(4); + case K_S_F5: *statep |= VTERM_MOD_SHIFT; + case K_F5: return VTERM_KEY_FUNCTION(5); + case K_S_F6: *statep |= VTERM_MOD_SHIFT; + case K_F6: return VTERM_KEY_FUNCTION(6); + case K_S_F7: *statep |= VTERM_MOD_SHIFT; + case K_F7: return VTERM_KEY_FUNCTION(7); + case K_S_F8: *statep |= VTERM_MOD_SHIFT; + case K_F8: return VTERM_KEY_FUNCTION(8); + case K_S_F9: *statep |= VTERM_MOD_SHIFT; + case K_F9: return VTERM_KEY_FUNCTION(9); + case K_S_F10: *statep |= VTERM_MOD_SHIFT; + case K_F10: return VTERM_KEY_FUNCTION(10); + case K_S_F11: *statep |= VTERM_MOD_SHIFT; + case K_F11: return VTERM_KEY_FUNCTION(11); + case K_S_F12: *statep |= VTERM_MOD_SHIFT; + case K_F12: return VTERM_KEY_FUNCTION(12); + + case K_F13: return VTERM_KEY_FUNCTION(13); + case K_F14: return VTERM_KEY_FUNCTION(14); + case K_F15: return VTERM_KEY_FUNCTION(15); + case K_F16: return VTERM_KEY_FUNCTION(16); + case K_F17: return VTERM_KEY_FUNCTION(17); + case K_F18: return VTERM_KEY_FUNCTION(18); + case K_F19: return VTERM_KEY_FUNCTION(19); + case K_F20: return VTERM_KEY_FUNCTION(20); + case K_F21: return VTERM_KEY_FUNCTION(21); + case K_F22: return VTERM_KEY_FUNCTION(22); + case K_F23: return VTERM_KEY_FUNCTION(23); + case K_F24: return VTERM_KEY_FUNCTION(24); + case K_F25: return VTERM_KEY_FUNCTION(25); + case K_F26: return VTERM_KEY_FUNCTION(26); + case K_F27: return VTERM_KEY_FUNCTION(27); + case K_F28: return VTERM_KEY_FUNCTION(28); + case K_F29: return VTERM_KEY_FUNCTION(29); + case K_F30: return VTERM_KEY_FUNCTION(30); + case K_F31: return VTERM_KEY_FUNCTION(31); + case K_F32: return VTERM_KEY_FUNCTION(32); + case K_F33: return VTERM_KEY_FUNCTION(33); + case K_F34: return VTERM_KEY_FUNCTION(34); + case K_F35: return VTERM_KEY_FUNCTION(35); + case K_F36: return VTERM_KEY_FUNCTION(36); + case K_F37: return VTERM_KEY_FUNCTION(37); + default: return VTERM_KEY_NONE; } } -- cgit From d23403a1df624792077559badc1f5f1037d81f5d Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Sat, 9 Jul 2016 14:36:20 -0400 Subject: terminal.c: move mod logic into convert_modifiers --- src/nvim/terminal.c | 59 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index bfcc123161..94c8ef0858 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -749,27 +749,56 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data) // }}} // input handling {{{ -static void convert_modifiers(VTermModifier *statep) +static void convert_modifiers(int key, VTermModifier *statep) { if (mod_mask & MOD_MASK_SHIFT) { *statep |= VTERM_MOD_SHIFT; } if (mod_mask & MOD_MASK_CTRL) { *statep |= VTERM_MOD_CTRL; } if (mod_mask & MOD_MASK_ALT) { *statep |= VTERM_MOD_ALT; } + + switch(key) { + case K_S_TAB: + case K_S_LEFT: + case K_S_RIGHT: + case K_S_F1: + case K_S_F2: + case K_S_F3: + case K_S_F4: + case K_S_F5: + case K_S_F6: + case K_S_F7: + case K_S_F8: + case K_S_F9: + case K_S_F10: + case K_S_F11: + case K_S_F12: + *statep |= VTERM_MOD_SHIFT; + break; + + case K_C_LEFT: + case K_C_RIGHT: + *statep |= VTERM_MOD_CTRL; + break; + } } static VTermKey convert_key(int key, VTermModifier *statep) { - convert_modifiers(statep); + convert_modifiers(key, statep); switch (key) { case K_BS: return VTERM_KEY_BACKSPACE; - case K_S_TAB: *statep |= VTERM_MOD_SHIFT; + case K_S_TAB: case TAB: return VTERM_KEY_TAB; case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; case K_UP: return VTERM_KEY_UP; case K_DOWN: return VTERM_KEY_DOWN; + case K_S_LEFT: + case K_C_LEFT: case K_LEFT: return VTERM_KEY_LEFT; + case K_S_RIGHT: + case K_C_RIGHT: case K_RIGHT: return VTERM_KEY_RIGHT; case K_INS: return VTERM_KEY_INS; @@ -802,29 +831,29 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_KMULTIPLY: return VTERM_KEY_KP_MULT; case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; - case K_S_F1: *statep |= VTERM_MOD_SHIFT; + case K_S_F1: case K_F1: return VTERM_KEY_FUNCTION(1); - case K_S_F2: *statep |= VTERM_MOD_SHIFT; + case K_S_F2: case K_F2: return VTERM_KEY_FUNCTION(2); - case K_S_F3: *statep |= VTERM_MOD_SHIFT; + case K_S_F3: case K_F3: return VTERM_KEY_FUNCTION(3); - case K_S_F4: *statep |= VTERM_MOD_SHIFT; + case K_S_F4: case K_F4: return VTERM_KEY_FUNCTION(4); - case K_S_F5: *statep |= VTERM_MOD_SHIFT; + case K_S_F5: case K_F5: return VTERM_KEY_FUNCTION(5); - case K_S_F6: *statep |= VTERM_MOD_SHIFT; + case K_S_F6: case K_F6: return VTERM_KEY_FUNCTION(6); - case K_S_F7: *statep |= VTERM_MOD_SHIFT; + case K_S_F7: case K_F7: return VTERM_KEY_FUNCTION(7); - case K_S_F8: *statep |= VTERM_MOD_SHIFT; + case K_S_F8: case K_F8: return VTERM_KEY_FUNCTION(8); - case K_S_F9: *statep |= VTERM_MOD_SHIFT; + case K_S_F9: case K_F9: return VTERM_KEY_FUNCTION(9); - case K_S_F10: *statep |= VTERM_MOD_SHIFT; + case K_S_F10: case K_F10: return VTERM_KEY_FUNCTION(10); - case K_S_F11: *statep |= VTERM_MOD_SHIFT; + case K_S_F11: case K_F11: return VTERM_KEY_FUNCTION(11); - case K_S_F12: *statep |= VTERM_MOD_SHIFT; + case K_S_F12: case K_F12: return VTERM_KEY_FUNCTION(12); case K_F13: return VTERM_KEY_FUNCTION(13); -- cgit From 4fd4f66514da4dfcd5d84c709be89d57616be753 Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Sun, 10 Jul 2016 14:57:35 -0400 Subject: terminal.c: add more arrow key support --- src/nvim/terminal.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 94c8ef0858..df15921f41 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -755,8 +755,10 @@ static void convert_modifiers(int key, VTermModifier *statep) if (mod_mask & MOD_MASK_CTRL) { *statep |= VTERM_MOD_CTRL; } if (mod_mask & MOD_MASK_ALT) { *statep |= VTERM_MOD_ALT; } - switch(key) { + switch (key) { case K_S_TAB: + case K_S_UP: + case K_S_DOWN: case K_S_LEFT: case K_S_RIGHT: case K_S_F1: @@ -792,7 +794,9 @@ static VTermKey convert_key(int key, VTermModifier *statep) case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; + case K_S_UP: case K_UP: return VTERM_KEY_UP; + case K_S_DOWN: case K_DOWN: return VTERM_KEY_DOWN; case K_S_LEFT: case K_C_LEFT: -- cgit From 5ffa01c8b78292bef0646168da856c726c2e4bc7 Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Sun, 10 Jul 2016 20:04:09 -0400 Subject: terminal.c: handle ctrl+space and ctrl+@ --- src/nvim/terminal.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index df15921f41..c4a8a52816 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -512,6 +512,12 @@ void terminal_send(Terminal *term, char *data, size_t size) void terminal_send_key(Terminal *term, int c) { VTermModifier mod = VTERM_MOD_NONE; + + // Convert K_ZERO back to ASCII + if (c == K_ZERO) { + c = Ctrl_AT; + } + VTermKey key = convert_key(c, &mod); if (key) { -- cgit From a1d545f8e521e0f58633c42407e24d533111eb6c Mon Sep 17 00:00:00 2001 From: RJ Miller Date: Mon, 14 Nov 2016 18:33:28 -0500 Subject: terminal.c: label fallthrough on big switch --- src/nvim/terminal.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index c4a8a52816..30556a3835 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -795,20 +795,20 @@ static VTermKey convert_key(int key, VTermModifier *statep) switch (key) { case K_BS: return VTERM_KEY_BACKSPACE; - case K_S_TAB: + case K_S_TAB: // FALLTHROUGH case TAB: return VTERM_KEY_TAB; case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; - case K_S_UP: + case K_S_UP: // FALLTHROUGH case K_UP: return VTERM_KEY_UP; - case K_S_DOWN: + case K_S_DOWN: // FALLTHROUGH case K_DOWN: return VTERM_KEY_DOWN; - case K_S_LEFT: - case K_C_LEFT: + case K_S_LEFT: // FALLTHROUGH + case K_C_LEFT: // FALLTHROUGH case K_LEFT: return VTERM_KEY_LEFT; - case K_S_RIGHT: - case K_C_RIGHT: + case K_S_RIGHT: // FALLTHROUGH + case K_C_RIGHT: // FALLTHROUGH case K_RIGHT: return VTERM_KEY_RIGHT; case K_INS: return VTERM_KEY_INS; @@ -818,22 +818,22 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_PAGEUP: return VTERM_KEY_PAGEUP; case K_PAGEDOWN: return VTERM_KEY_PAGEDOWN; - case K_K0: + case K_K0: // FALLTHROUGH case K_KINS: return VTERM_KEY_KP_0; - case K_K1: + case K_K1: // FALLTHROUGH case K_KEND: return VTERM_KEY_KP_1; case K_K2: return VTERM_KEY_KP_2; - case K_K3: + case K_K3: // FALLTHROUGH case K_KPAGEDOWN: return VTERM_KEY_KP_3; case K_K4: return VTERM_KEY_KP_4; case K_K5: return VTERM_KEY_KP_5; case K_K6: return VTERM_KEY_KP_6; - case K_K7: + case K_K7: // FALLTHROUGH case K_KHOME: return VTERM_KEY_KP_7; case K_K8: return VTERM_KEY_KP_8; - case K_K9: + case K_K9: // FALLTHROUGH case K_KPAGEUP: return VTERM_KEY_KP_9; - case K_KDEL: + case K_KDEL: // FALLTHROUGH case K_KPOINT: return VTERM_KEY_KP_PERIOD; case K_KENTER: return VTERM_KEY_KP_ENTER; case K_KPLUS: return VTERM_KEY_KP_PLUS; @@ -841,29 +841,29 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_KMULTIPLY: return VTERM_KEY_KP_MULT; case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; - case K_S_F1: + case K_S_F1: // FALLTHROUGH case K_F1: return VTERM_KEY_FUNCTION(1); - case K_S_F2: + case K_S_F2: // FALLTHROUGH case K_F2: return VTERM_KEY_FUNCTION(2); - case K_S_F3: + case K_S_F3: // FALLTHROUGH case K_F3: return VTERM_KEY_FUNCTION(3); - case K_S_F4: + case K_S_F4: // FALLTHROUGH case K_F4: return VTERM_KEY_FUNCTION(4); - case K_S_F5: + case K_S_F5: // FALLTHROUGH case K_F5: return VTERM_KEY_FUNCTION(5); - case K_S_F6: + case K_S_F6: // FALLTHROUGH case K_F6: return VTERM_KEY_FUNCTION(6); - case K_S_F7: + case K_S_F7: // FALLTHROUGH case K_F7: return VTERM_KEY_FUNCTION(7); - case K_S_F8: + case K_S_F8: // FALLTHROUGH case K_F8: return VTERM_KEY_FUNCTION(8); - case K_S_F9: + case K_S_F9: // FALLTHROUGH case K_F9: return VTERM_KEY_FUNCTION(9); - case K_S_F10: + case K_S_F10: // FALLTHROUGH case K_F10: return VTERM_KEY_FUNCTION(10); - case K_S_F11: + case K_S_F11: // FALLTHROUGH case K_F11: return VTERM_KEY_FUNCTION(11); - case K_S_F12: + case K_S_F12: // FALLTHROUGH case K_F12: return VTERM_KEY_FUNCTION(12); case K_F13: return VTERM_KEY_FUNCTION(13); -- cgit From b2967a0320ec327d1271bb75d96156a5ff1c8758 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 5 Aug 2017 23:53:48 +0200 Subject: nvim -h: omit special-case options Group some options, and sort them alphabetically. `nvim -h` should fit on one (smallish) screen. Uncommon options don't need to be here, they live in the :help. --- src/nvim/main.c | 71 ++++++++++++++++++--------------------- src/nvim/testdir/test_startup.vim | 6 ++-- 2 files changed, 35 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 3f828d7be9..a665ad1de2 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1878,54 +1878,47 @@ static void usage(void) signal_stop(); // kill us with CTRL-C here, if you like mch_msg(_("Usage:\n")); - mch_msg(_(" nvim [arguments] [file ...] Edit specified file(s)\n")); - mch_msg(_(" nvim [arguments] - Read text from stdin\n")); - mch_msg(_(" nvim [arguments] -t Edit file where tag is defined\n")); - mch_msg(_(" nvim [arguments] -q [errorfile] Edit file with first error\n")); - mch_msg(_("\nArguments:\n")); + mch_msg(_(" nvim [options] [file ...] Edit file(s)\n")); + mch_msg(_(" nvim [options] - Read text from stdin\n")); + mch_msg(_(" nvim [options] -t Edit file where tag is defined\n")); + mch_msg(_(" nvim [options] -q [errorfile] Edit file with first error\n")); + mch_msg(_("\nOptions:\n")); mch_msg(_(" -- Only file names after this\n")); -#if !defined(UNIX) - mch_msg(_(" --literal Don't expand wildcards\n")); -#endif - mch_msg(_(" -e Ex mode\n")); - mch_msg(_(" -E Improved Ex mode\n")); - mch_msg(_(" -s Silent (batch) mode (only for ex mode)\n")); + mch_msg(_(" + Start at end of file\n")); + mch_msg(_(" --cmd Execute before any config\n")); + mch_msg(_(" +, -c Execute after config and first file\n")); + mch_msg("\n"); + mch_msg(_(" -b Binary mode\n")); mch_msg(_(" -d Diff mode\n")); - mch_msg(_(" -R Read-only mode\n")); - mch_msg(_(" -Z Restricted mode\n")); + mch_msg(_(" -e, -E Ex mode, Improved Ex mode\n")); + mch_msg(_(" -es Silent (batch) mode\n")); + mch_msg(_(" -h, --help Print this help message\n")); + mch_msg(_(" -i Use this shada file\n")); mch_msg(_(" -m Modifications (writing files) not allowed\n")); mch_msg(_(" -M Modifications in text not allowed\n")); - mch_msg(_(" -b Binary mode\n")); - mch_msg(_(" -l Lisp mode\n")); - mch_msg(_(" -A Arabic mode\n")); - mch_msg(_(" -F Farsi mode\n")); - mch_msg(_(" -H Hebrew mode\n")); - mch_msg(_(" -V[N][file] Be verbose [level N][log messages to file]\n")); - mch_msg(_(" -D Debugging mode\n")); mch_msg(_(" -n No swap file, use memory only\n")); - mch_msg(_(" -r, -L List swap files and exit\n")); - mch_msg(_(" -r Recover crashed session\n")); - mch_msg(_(" -u Use instead of the default\n")); - mch_msg(_(" -i Use instead of the default\n")); - mch_msg(_(" --noplugin Don't load plugin scripts\n")); - mch_msg(_(" -o[N] Open N windows (default: one for each file)\n")); - mch_msg(_(" -O[N] Like -o but split vertically\n")); - mch_msg(_(" -p[N] Open N tab pages (default: one for each file)\n")); - mch_msg(_(" + Start at end of file\n")); - mch_msg(_(" + Start at line \n")); - mch_msg(_(" +/ Start at first occurrence of \n")); - mch_msg(_(" --cmd Execute before loading any vimrc\n")); - mch_msg(_(" -c Execute after loading the first file\n")); + mch_msg(_(" -o[N] Open N windows (default: one per file)\n")); + mch_msg(_(" -O[N] Open N vertical windows (default: one per file)\n")); + mch_msg(_(" -p[N] Open N tab pages (default: one per file)\n")); + mch_msg(_(" -r, -L List swap files\n")); + mch_msg(_(" -r Recover edit state for this file\n")); + mch_msg(_(" -R Read-only mode\n")); mch_msg(_(" -S Source after loading the first file\n")); mch_msg(_(" -s Read Normal mode commands from \n")); - mch_msg(_(" -w Append all typed characters to \n")); - mch_msg(_(" -W Write all typed characters to \n")); - mch_msg(_(" --startuptime Write startup timing messages to \n")); - mch_msg(_(" --api-info Dump API metadata serialized to msgpack and exit\n")); + mch_msg(_(" -u Use this config file\n")); + mch_msg(_(" -v, --version Print version information\n")); + mch_msg(_(" -V[N][file] Verbose [level][file]\n")); + mch_msg(_(" -Z Restricted mode\n")); + mch_msg("\n"); + mch_msg(_(" --api-info Write msgpack-encoded API metadata to stdout\n")); mch_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n")); mch_msg(_(" --headless Don't start a user interface\n")); - mch_msg(_(" -v, --version Print version information and exit\n")); - mch_msg(_(" -h, --help Print this help message and exit\n")); +#if !defined(UNIX) + mch_msg(_(" --literal Don't expand wildcards\n")); +#endif + mch_msg(_(" --noplugin Don't load plugins\n")); + mch_msg(_(" --startuptime Write startup timing messages to \n")); + mch_msg(_("\nSee \":help startup-options\" for all options.\n")); } diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index 64f7f31294..5a38178bd5 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -76,11 +76,11 @@ func Test_help_arg() let found = [] for line in lines if line =~ '-R.*Read-only mode' - call add(found, 'Readonly mode') + call add(found, 'Readonly mode') endif " Watch out for a second --version line in the Gnome version. - if line =~ '--version.*Print version information and exit' - call add(found, "--version") + if line =~ '--version.*Print version information' + call add(found, "--version") endif endfor call assert_equal(['Readonly mode', '--version'], found) -- cgit From 6ca6a8134ddf62d3b6abc57185b096fd712cc873 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 17 Aug 2017 00:29:25 +0200 Subject: intro: remove byline #6984 --- src/nvim/version.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index f5b45caefc..e024982faf 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -1216,7 +1216,6 @@ void intro_message(int colon) static char *(lines[]) = { N_(NVIM_VERSION_LONG), "", - N_("by al."), N_("Nvim is open source and freely distributable"), N_("https://neovim.io/community"), "", -- cgit From af046a3a81c0d7ebc5219bf20c1463cb5ccd1b9b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 17 Aug 2017 21:23:28 +0200 Subject: version: tweak layout, doc --- src/nvim/version.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index e024982faf..2a3fdbd70d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -1089,13 +1089,7 @@ static void list_features(void) msg_putchar('\n'); } } else { - while (msg_col % width) { - int old_msg_col = msg_col; - msg_putchar(' '); - if (old_msg_col == msg_col) { - break; // XXX: Avoid infinite loop. - } - } + msg_putchar(' '); } } else { if (msg_col > 0) { @@ -1103,7 +1097,7 @@ static void list_features(void) } } } - MSG_PUTS("For differences from Vim, see :help vim-differences\n\n"); + MSG_PUTS("See \":help feature-compile\"\n\n"); } void list_version(void) @@ -1144,7 +1138,7 @@ void list_version(void) } #endif // ifdef HAVE_PATHDEF - version_msg(_("\n\nOptional features included (+) or not (-): ")); + version_msg(_("\n\nFeatures: ")); list_features(); -- cgit From b13070ec01844977f10cae38fc6f2a0fd9defad8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 17 Aug 2017 23:30:28 +0200 Subject: doc/api: nvim_out_write() and friends References #7178 --- src/nvim/api/vim.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2bc31b2812..cfbe34b848 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -484,7 +484,8 @@ void nvim_set_option(String name, Object value, Error *err) set_option_to(NULL, SREQ_GLOBAL, name, value, err); } -/// Writes a message to vim output buffer +/// Writes a message to the Vim output buffer. Does not append "\n", the +/// message is buffered (won't display) until a linefeed is written. /// /// @param str Message void nvim_out_write(String str) @@ -493,7 +494,8 @@ void nvim_out_write(String str) write_msg(str, false); } -/// Writes a message to vim error buffer +/// Writes a message to the Vim error buffer. Does not append "\n", the +/// message is buffered (won't display) until a linefeed is written. /// /// @param str Message void nvim_err_write(String str) @@ -502,8 +504,8 @@ void nvim_err_write(String str) write_msg(str, true); } -/// Writes a message to vim error buffer. Appends a linefeed to ensure all -/// contents are written. +/// Writes a message to the Vim error buffer. Appends "\n", so the buffer is +/// flushed (and displayed). /// /// @param str Message /// @see nvim_err_write() -- cgit From 9882e25dc44f1165e1edc8b3898356e493b6b3fe Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 20 Aug 2017 02:13:04 +0200 Subject: clipboard: avoid error flood during :redir redir_write(): - This is a "batch" operation which was not yet covered by start_batch_changes() adjust_clipboard_name(): - msg() and friends during :redir will, of course, cause redir_write() to try to capture that message, which causes recursion. - EMSG() here is trouble: if it interrupts :redir it is a mess. Rather than deal with the mess, show a non-error message. closes #7182 closes #7184 closes #7183 ref #6048 ref #7032 --- src/nvim/eval.c | 18 +++++++------- src/nvim/message.c | 2 ++ src/nvim/ops.c | 69 ++++++++++++++++++++++++++++++++---------------------- 3 files changed, 52 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ac22d75a83..d6ee13857a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -22775,7 +22775,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments) bool eval_has_provider(const char *name) { -#define check_provider(name) \ +#define CHECK_PROVIDER(name) \ if (has_##name == -1) { \ has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \ if (!has_##name) { \ @@ -22791,17 +22791,17 @@ bool eval_has_provider(const char *name) static int has_python3 = -1; static int has_ruby = -1; - if (!strcmp(name, "clipboard")) { - check_provider(clipboard); + if (strequal(name, "clipboard")) { + CHECK_PROVIDER(clipboard); return has_clipboard; - } else if (!strcmp(name, "python3")) { - check_provider(python3); + } else if (strequal(name, "python3")) { + CHECK_PROVIDER(python3); return has_python3; - } else if (!strcmp(name, "python")) { - check_provider(python); + } else if (strequal(name, "python")) { + CHECK_PROVIDER(python); return has_python; - } else if (!strcmp(name, "ruby")) { - check_provider(ruby); + } else if (strequal(name, "ruby")) { + CHECK_PROVIDER(ruby); return has_ruby; } diff --git a/src/nvim/message.c b/src/nvim/message.c index b90c475ede..fe4cb65779 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2519,6 +2519,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) if (redirecting()) { /* If the string doesn't start with CR or NL, go to msg_col */ if (*s != '\n' && *s != '\r') { + start_batch_changes(); while (cur_col < msg_col) { if (capture_ga) { ga_concat_len(capture_ga, " ", 1); @@ -2535,6 +2536,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) } cur_col++; } + end_batch_changes(); } size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 5c6f4d0d07..7bbc72b091 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -58,8 +58,8 @@ static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */ static bool clipboard_didwarn_unnamed = false; // for behavior between start_batch_changes() and end_batch_changes()) -static bool clipboard_delay_update = false; // delay clipboard update static int batch_change_count = 0; // inside a script +static bool clipboard_delay_update = false; // delay clipboard update static bool clipboard_needs_update = false; // clipboard was updated /* @@ -5524,7 +5524,7 @@ int get_default_register_name(void) } /// Determine if register `*name` should be used as a clipboard. -/// In an unnammed operation, `*name` is `NUL` and will be adjusted to `'*'/'+'` if +/// In an unnamed operation, `*name` is `NUL` and will be adjusted to */+ if /// `clipboard=unnamed[plus]` is set. /// /// @param name The name of register, or `NUL` if unnamed. @@ -5535,33 +5535,44 @@ int get_default_register_name(void) /// if the register isn't a clipboard or provider isn't available. static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) { - if (*name == '*' || *name == '+') { - if(!eval_has_provider("clipboard")) { - if (!quiet) { - EMSG("clipboard: No provider. Try \":CheckHealth\" or " - "\":h clipboard\"."); - } - return NULL; - } - return &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER]; - } else if ((*name == NUL) && (cb_flags & CB_UNNAMEDMASK)) { - if(!eval_has_provider("clipboard")) { - if (!quiet && !clipboard_didwarn_unnamed) { - msg((char_u *)"clipboard: No provider. Try \":CheckHealth\" or " - "\":h clipboard\"."); - clipboard_didwarn_unnamed = true; - } - return NULL; +#define MSG_NO_CLIP "clipboard: No provider. " \ + "Try \":CheckHealth\" or \":h clipboard\"." + + yankreg_T *target = NULL; + bool explicit_cb_reg = (*name == '*' || *name == '+'); + bool implicit_cb_reg = (*name == NUL) && (cb_flags & CB_UNNAMEDMASK); + int save_redir_off = redir_off; + if (!explicit_cb_reg && !implicit_cb_reg) { + goto end; + } + + if (!eval_has_provider("clipboard")) { + if (batch_change_count == 1 && explicit_cb_reg && !quiet) { + redir_off = true; // Avoid recursion from :redir + emsg(). + // Do NOT error (emsg()) here--if it interrupts :redir we get into + // a weird state, stuck in "redirect mode". + msg((char_u *)MSG_NO_CLIP); + } else if (batch_change_count == 1 && implicit_cb_reg + && !quiet && !clipboard_didwarn_unnamed) { + redir_off = true; // Avoid recursion from :redir + emsg(). + msg((char_u *)MSG_NO_CLIP); + clipboard_didwarn_unnamed = true; } + // ... else, be silent (avoid a flood of messages). + goto end; + } + + if (explicit_cb_reg) { + target = &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER]; + goto end; + } else { // unnamed register: "implicit" clipboard if (writing && clipboard_delay_update) { clipboard_needs_update = true; - return NULL; + goto end; } else if (!writing && clipboard_needs_update) { - // use the internal value - return NULL; + goto end; // use the internal value } - yankreg_T *target; if (cb_flags & CB_UNNAMEDPLUS) { *name = (cb_flags & CB_UNNAMED && writing) ? '"': '+'; target = &y_regs[PLUS_REGISTER]; @@ -5569,10 +5580,12 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) *name = '*'; target = &y_regs[STAR_REGISTER]; } - return target; // unnamed register + goto end; } - // don't do anything for other register names - return NULL; + +end: + redir_off = save_redir_off; + return target; } static bool get_clipboard(int name, yankreg_T **target, bool quiet) @@ -5740,7 +5753,7 @@ static void set_clipboard(int name, yankreg_T *reg) (void)eval_call_provider("clipboard", "set", args); } -/// Avoid clipboard (slow) during batch operations (i.e., a script). +/// Avoid slow things (clipboard) during batch operations (while/for-loops). void start_batch_changes(void) { if (++batch_change_count > 1) { @@ -5750,7 +5763,7 @@ void start_batch_changes(void) clipboard_needs_update = false; } -/// Update the clipboard after batch changes finished. +/// Counterpart to start_batch_changes(). void end_batch_changes(void) { if (--batch_change_count > 0) { -- cgit From cc7e344f8357d07b1df17df0b322152d5c50739b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 20 Aug 2017 18:53:58 +0200 Subject: clipboard: remove start_batch_changes() in redir_write() start_batch_changes() doesn't avoid invoking the clipboard once-per-line, because the loop is actually in ex_echo(), which calls redir_write() for each message. But we've already entered start_batch_changes() by then, so that was never the problem. redir_write at /home/vagrant/old.neovim/build/../src/nvim/message.c:2523 msg_puts_attr_len at /home/vagrant/old.neovim/build/../src/nvim/message.c:1600 msg_outtrans_len_attr at /home/vagrant/old.neovim/build/../src/nvim/message.c:1221 ex_echo at /home/vagrant/old.neovim/build/../src/nvim/eval.c:19433 do_one_cmd at /home/vagrant/old.neovim/build/../src/nvim/ex_docmd.c:2242 Trying to defer _explicit_ clipboard updates is difficult. :redir @+ | silent echo system('cat foo') | redir END is essentially equivalent to: for l in readfile('foo') let @+ .= l endfor We cannot make judgements about when to ignore a script's bad decisions. start_batch_changes() only works around the case of clipboard=unnamed, i.e. _implicit_ clipboard updates (`:g/foo/d`). Not explicit assignment. --- src/nvim/message.c | 2 -- src/nvim/ops.c | 7 +++++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/message.c b/src/nvim/message.c index fe4cb65779..b90c475ede 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2519,7 +2519,6 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) if (redirecting()) { /* If the string doesn't start with CR or NL, go to msg_col */ if (*s != '\n' && *s != '\r') { - start_batch_changes(); while (cur_col < msg_col) { if (capture_ga) { ga_concat_len(capture_ga, " ", 1); @@ -2536,7 +2535,6 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) } cur_col++; } - end_batch_changes(); } size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 7bbc72b091..6c873a96c0 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5558,7 +5558,7 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) msg((char_u *)MSG_NO_CLIP); clipboard_didwarn_unnamed = true; } - // ... else, be silent (avoid a flood of messages). + // ... else, be silent (don't flood during :while, :redir, etc.). goto end; } @@ -5567,10 +5567,12 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) goto end; } else { // unnamed register: "implicit" clipboard if (writing && clipboard_delay_update) { + // For "set" (copy), defer the clipboard call. clipboard_needs_update = true; goto end; } else if (!writing && clipboard_needs_update) { - goto end; // use the internal value + // For "get" (paste), use the internal value. + goto end; } if (cb_flags & CB_UNNAMEDPLUS) { @@ -5772,6 +5774,7 @@ void end_batch_changes(void) } clipboard_delay_update = false; if (clipboard_needs_update) { + // unnamed ("implicit" clipboard) set_clipboard(NUL, y_previous); clipboard_needs_update = false; } -- cgit From e006b1d98d92aead6aff565ed5d8b034772aa16c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 27 Jul 2017 00:30:57 +0200 Subject: log: some DEBUG-level stream logging --- src/nvim/event/process.c | 3 +-- src/nvim/event/rstream.c | 2 +- src/nvim/event/stream.c | 2 ++ src/nvim/event/wstream.c | 1 + src/nvim/msgpack_rpc/channel.c | 16 +++++++++++++--- src/nvim/normal.c | 1 + 6 files changed, 19 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index c936583841..8371d3cd48 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -233,8 +233,7 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL switch (proc->type) { case kProcessTypeUv: // Close the process's stdin. If the process doesn't close its own - // stdout/stderr, they will be closed when it exits(possibly due to being - // terminated after a timeout) + // stdout/stderr, they will be closed when it exits (voluntarily or not). process_close_in(proc); ILOG("Sending SIGTERM to pid %d", proc->pid); uv_kill(proc->pid, SIGTERM); diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 854af474b2..2c4db08b30 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -118,7 +118,7 @@ static void read_cb(uv_stream_t *uvstream, ssize_t cnt, const uv_buf_t *buf) // to `alloc_cb` will return the same unused pointer(`rbuffer_produced` // won't be called) && cnt != 0) { - DLOG("Closing Stream (%p): %s (%s)", stream, + DLOG("closing Stream: %p: %s (%s)", stream, uv_err_name((int)cnt), os_strerror((int)cnt)); // Read error or EOF, either way stop the stream and invoke the callback // with eof == true diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 60ceff9b24..7c865bfe1e 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -7,6 +7,7 @@ #include +#include "nvim/log.h" #include "nvim/rbuffer.h" #include "nvim/macros.h" #include "nvim/event/stream.h" @@ -81,6 +82,7 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data) FUNC_ATTR_NONNULL_ARG(1) { assert(!stream->closed); + DLOG("closing Stream: %p", stream); stream->closed = true; stream->close_cb = on_stream_close; stream->close_cb_data = data; diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index f453e5898d..320006890d 100644 --- a/src/nvim/event/wstream.c +++ b/src/nvim/event/wstream.c @@ -8,6 +8,7 @@ #include +#include "nvim/log.h" #include "nvim/event/loop.h" #include "nvim/event/wstream.h" #include "nvim/vim.h" diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 6fd1af1ba6..789cf1d4a8 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -133,6 +133,9 @@ uint64_t channel_from_process(Process *proc, uint64_t id, char *source) rstream_init(proc->out, 0); rstream_start(proc->out, receive_msgpack, channel); + DLOG("ch %" PRIu64 " in-stream=%p out-stream=%p", channel->id, proc->in, + proc->out); + return channel->id; } @@ -150,6 +153,8 @@ void channel_from_connection(SocketWatcher *watcher) wstream_init(&channel->data.stream, 0); rstream_init(&channel->data.stream, CHANNEL_BUFFER_SIZE); rstream_start(&channel->data.stream, receive_msgpack, channel); + + DLOG("ch %" PRIu64 " in/out-stream=%p", &channel->data.stream); } /// @param source description of source function, rplugin name, TCP addr, etc @@ -344,6 +349,9 @@ void channel_from_stdio(void) rstream_start(&channel->data.std.in, receive_msgpack, channel); // write stream wstream_init_fd(&main_loop, &channel->data.std.out, 1, 0); + + DLOG("ch %" PRIu64 " in-stream=%p out-stream=%p", channel->id, + &channel->data.std.in, &channel->data.std.out); } /// Creates a loopback channel. This is used to avoid deadlock @@ -363,6 +371,7 @@ void channel_process_exit(uint64_t id, int status) decref(channel); } +// rstream.c:read_event() invokes this as stream->read_cb(). static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data, bool eof) { @@ -379,7 +388,8 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c, } size_t count = rbuffer_size(rbuf); - DLOG("parsing %u bytes of msgpack data from Stream(%p)", count, stream); + DLOG("ch %" PRIu64 ": parsing %u bytes from msgpack Stream: %p", + channel->id, count, stream); // Feed the unpacker with data msgpack_unpacker_reserve_buffer(channel->unpacker, count); @@ -565,8 +575,8 @@ static bool channel_write(Channel *channel, WBuffer *buffer) char buf[256]; snprintf(buf, sizeof(buf), - "Before returning from a RPC call, ch %" PRIu64 " was " - "closed due to a failed write", + "ch %" PRIu64 ": stream write failed. " + "RPC canceled; closing channel", channel->id); call_set_error(channel, buf, ERROR_LOG_LEVEL); } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index c1676780d8..238378c474 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -13,6 +13,7 @@ #include #include +#include "nvim/log.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/normal.h" -- cgit From af993da4351d579aa24de08d806c8c1b90813106 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 27 Jul 2017 01:08:50 +0200 Subject: rpc: close channel if stream was closed f_jobstop()/f_rpcstop() .. process_stop() .. process_close_in(proc) closes the write-stream of a RPC channel. But there might be a pending RPC notification on the queue, which may get processed just before the channel is closed. To handle that case, check the Stream.closed in channel.c:receive_msgpack(). Before this change, the above scenario could trigger this assert(!stream->closed) in wstream_write(): 0x00007f96e1cd3428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 0x00007f96e1cd502a in __GI_abort () at abort.c:89 0x00007f96e1ccbbd7 in __assert_fail_base (fmt=, assertion=assertion@entry=0x768f9b "!stream->closed", file=file@entry=0x768f70 "../src/nvim/event/wstream.c", line=line@entry=77, function=function@entry=0x768fb0 <__PRETTY_FUNCTION__.13735> "wstream_write") at assert.c:92 0x00007f96e1ccbc82 in __GI___assert_fail (assertion=0x768f9b "!stream->closed", file=0x768f70 "../src/nvim/event/wstream.c", line=77, function=0x768fb0 <__PRETTY_FUNCTION__.13735> "wstream_write") at assert.c:101 0x00000000004d2c1f in wstream_write (stream=0x7f96e0a35078, buffer=0x7f96e09f9b40) at ../src/nvim/event/wstream.c:77 0x00000000005857b2 in channel_write (channel=0x7f96e0ae5800, buffer=0x7f96e09f9b40) at ../src/nvim/msgpack_rpc/channel.c:551 0x000000000058567d in on_request_event (argv=0x7ffed792efa0) at ../src/nvim/msgpack_rpc/channel.c:523 0x00000000005854c8 in handle_request (channel=0x7f96e0ae5800, request=0x7ffed792f1b8) at ../src/nvim/msgpack_rpc/channel.c:503 0x00000000005850cb in parse_msgpack (channel=0x7f96e0ae5800) at ../src/nvim/msgpack_rpc/channel.c:423 0x0000000000584f90 in receive_msgpack (stream=0x7f96e0a35218, rbuf=0x7f96e0d1d4c0, c=22, data=0x7f96e0ae5800, eof=false) at ../src/nvim/msgpack_rpc/channel.c:389 0x00000000004d0b20 in read_event (argv=0x7ffed792f4a8) at ../src/nvim/event/rstream.c:190 0x00000000004ce462 in multiqueue_process_events (this=0x7f96e18172d0) at ../src/nvim/event/multiqueue.c:150 0x000000000059b630 in nv_event (cap=0x7ffed792f620) at ../src/nvim/normal.c:7908 0x000000000058be69 in normal_execute (state=0x7ffed792f580, key=-25341) at ../src/nvim/normal.c:1137 0x0000000000652463 in state_enter (s=0x7ffed792f580) at ../src/nvim/state.c:61 0x000000000058a1fe in normal_enter (cmdwin=false, noexmode=false) at ../src/nvim/normal.c:467 0x00000000005500c2 in main (argc=2, argv=0x7ffed792f8d8) at ../src/nvim/main.c:554 Alternative approach suggested by bfredl is to use close_cb of the process. My unsuccessful attempt is below. (It seems close_cb is queued too late, which is the similar problem addressed by this commit): commit 75fc12c6ab15711bdb7b18c6d42ec9d157f5145e Author: Justin M. Keyes Date: Fri Aug 18 01:30:41 2017 +0200 rpc: use Stream's close_cb instead of explicit check in receive_msgpack() diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 8371d3cd482e..e52da23cdc40 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -416,6 +416,10 @@ static void on_process_exit(Process *proc) static void on_process_stream_close(Stream *stream, void *data) { Process *proc = data; + ILOG("on_process_stream_close"); + if (proc->stream_close_cb != NULL) { + proc->stream_close_cb(stream, proc->stream_close_data); + } decref(proc); } diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 5c00e8e7ecd5..34a8d54f6f8c 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -26,6 +26,11 @@ struct process { Stream *in, *out, *err; process_exit_cb cb; internal_process_cb internal_exit_cb, internal_close_cb; + + // Called when any of the process streams (in/out/err) closes. + stream_close_cb stream_close_cb; + void *stream_close_data; + bool closed, detach; MultiQueue *events; }; @@ -50,6 +55,8 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data) .closed = false, .internal_close_cb = NULL, .internal_exit_cb = NULL, + .stream_close_cb = NULL, + .stream_close_data = NULL, .detach = false }; } diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index 7c865bfe1e8c..c8720d1e45d9 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -95,7 +95,11 @@ void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data) void stream_close_handle(Stream *stream) FUNC_ATTR_NONNULL_ALL { + ILOG("stream=%d", stream); + // LOG_CALLSTACK(); if (stream->uvstream) { + // problem: this schedules on the queue, but channel.c:receive_msgpack may + // be processed before close_cb is called by libuv. uv_close((uv_handle_t *)stream->uvstream, close_cb); } else { uv_close((uv_handle_t *)&stream->uv.idle, close_cb); @@ -105,6 +109,7 @@ void stream_close_handle(Stream *stream) static void close_cb(uv_handle_t *handle) { Stream *stream = handle->data; + ILOG(">>>>>>>>>>>>>>>>>>>>>>> stream=%p stream->internal_close_cb=%p", stream, stream->internal_close_cb); if (stream->buffer) { rbuffer_free(stream->buffer); } diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 782eabe04e4a..dc2b794e366a 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -128,6 +128,8 @@ uint64_t channel_from_process(Process *proc, uint64_t id, char *source) source); incref(channel); // process channels are only closed by the exit_cb channel->data.proc = proc; + channel->data.proc->stream_close_cb = close_cb2; + channel->data.proc->stream_close_data = channel; wstream_init(proc->in, 0); rstream_init(proc->out, 0); @@ -387,17 +389,6 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c, goto end; } - if ((chan_wstream(channel) != NULL && chan_wstream(channel)->closed) - || (chan_rstream(channel) != NULL && chan_rstream(channel)->closed)) { - char buf[256]; - snprintf(buf, sizeof(buf), - "ch %" PRIu64 ": stream closed unexpectedly. " - "closing channel", - channel->id); - call_set_error(channel, buf, WARN_LOG_LEVEL); - goto end; - } - size_t count = rbuffer_size(rbuf); DLOG("ch %" PRIu64 ": parsing %u bytes from msgpack Stream: %p", channel->id, count, stream); @@ -571,23 +562,6 @@ static Stream *chan_wstream(Channel *chan) abort(); } -/// Returns the Stream that a Channel reads from. -static Stream *chan_rstream(Channel *chan) -{ - switch (chan->type) { - case kChannelTypeSocket: - return &chan->data.stream; - case kChannelTypeProc: - return chan->data.proc->out; - case kChannelTypeStdio: - return &chan->data.std.in; - case kChannelTypeInternal: - return NULL; - } - abort(); -} - - static bool channel_write(Channel *channel, WBuffer *buffer) { bool success = false; @@ -799,6 +773,12 @@ static void close_cb(Stream *stream, void *data) decref(data); } +static void close_cb2(Stream *stream, void *data) +{ + ILOG("close_cb2"); + close_channel(data); +} + /// @param source description of source function, rplugin name, TCP addr, etc static Channel *register_channel(ChannelType type, uint64_t id, MultiQueue *events, char *source) --- src/nvim/log.c | 2 +- src/nvim/log.h | 8 +++--- src/nvim/msgpack_rpc/channel.c | 61 +++++++++++++++++++++++++++++++++++------- src/nvim/msgpack_rpc/helpers.c | 2 +- 4 files changed, 57 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/nvim/log.c b/src/nvim/log.c index 3baf0b2ebd..436a8a4079 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -250,7 +250,7 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, static const char *log_levels[] = { [DEBUG_LOG_LEVEL] = "DEBUG", [INFO_LOG_LEVEL] = "INFO ", - [WARNING_LOG_LEVEL] = "WARN ", + [WARN_LOG_LEVEL] = "WARN ", [ERROR_LOG_LEVEL] = "ERROR", }; assert(log_level >= DEBUG_LOG_LEVEL && log_level <= ERROR_LOG_LEVEL); diff --git a/src/nvim/log.h b/src/nvim/log.h index 5064d9333b..d63bcc366c 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -6,7 +6,7 @@ #define DEBUG_LOG_LEVEL 0 #define INFO_LOG_LEVEL 1 -#define WARNING_LOG_LEVEL 2 +#define WARN_LOG_LEVEL 2 #define ERROR_LOG_LEVEL 3 #define DLOG(...) @@ -43,12 +43,12 @@ __VA_ARGS__) #endif -#if MIN_LOG_LEVEL <= WARNING_LOG_LEVEL +#if MIN_LOG_LEVEL <= WARN_LOG_LEVEL # undef WLOG # undef WLOGN -# define WLOG(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, true, \ +# define WLOG(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, true, \ __VA_ARGS__) -# define WLOGN(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, false, \ +# define WLOGN(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, false, \ __VA_ARGS__) #endif diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 789cf1d4a8..ed97f298d9 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -62,7 +62,7 @@ typedef struct { ChannelType type; msgpack_unpacker *unpacker; union { - Stream stream; + Stream stream; // bidirectional (socket) Process *proc; struct { Stream in; @@ -154,7 +154,8 @@ void channel_from_connection(SocketWatcher *watcher) rstream_init(&channel->data.stream, CHANNEL_BUFFER_SIZE); rstream_start(&channel->data.stream, receive_msgpack, channel); - DLOG("ch %" PRIu64 " in/out-stream=%p", &channel->data.stream); + DLOG("ch %" PRIu64 " in/out-stream=%p", channel->id, + &channel->data.stream); } /// @param source description of source function, rplugin name, TCP addr, etc @@ -383,7 +384,18 @@ static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c, char buf[256]; snprintf(buf, sizeof(buf), "ch %" PRIu64 " was closed by the client", channel->id); - call_set_error(channel, buf, WARNING_LOG_LEVEL); + call_set_error(channel, buf, WARN_LOG_LEVEL); + goto end; + } + + if ((chan_wstream(channel) != NULL && chan_wstream(channel)->closed) + || (chan_rstream(channel) != NULL && chan_rstream(channel)->closed)) { + char buf[256]; + snprintf(buf, sizeof(buf), + "ch %" PRIu64 ": stream closed unexpectedly. " + "closing channel", + channel->id); + call_set_error(channel, buf, WARN_LOG_LEVEL); goto end; } @@ -445,8 +457,8 @@ static void parse_msgpack(Channel *channel) // causes for this error(search for 'goto _failed') // // A not so uncommon cause for this might be deserializing objects with - // a high nesting level: msgpack will break when it's internal parse stack - // size exceeds MSGPACK_EMBED_STACK_SIZE(defined as 32 by default) + // a high nesting level: msgpack will break when its internal parse stack + // size exceeds MSGPACK_EMBED_STACK_SIZE (defined as 32 by default) send_error(channel, 0, "Invalid msgpack payload. " "This error can also happen when deserializing " "an object with high level of nesting"); @@ -544,6 +556,39 @@ static void on_request_event(void **argv) api_clear_error(&error); } +/// Returns the Stream that a Channel writes to. +static Stream *chan_wstream(Channel *chan) +{ + switch (chan->type) { + case kChannelTypeSocket: + return &chan->data.stream; + case kChannelTypeProc: + return chan->data.proc->in; + case kChannelTypeStdio: + return &chan->data.std.out; + case kChannelTypeInternal: + return NULL; + } + abort(); +} + +/// Returns the Stream that a Channel reads from. +static Stream *chan_rstream(Channel *chan) +{ + switch (chan->type) { + case kChannelTypeSocket: + return &chan->data.stream; + case kChannelTypeProc: + return chan->data.proc->out; + case kChannelTypeStdio: + return &chan->data.std.in; + case kChannelTypeInternal: + return NULL; + } + abort(); +} + + static bool channel_write(Channel *channel, WBuffer *buffer) { bool success = false; @@ -555,13 +600,9 @@ static bool channel_write(Channel *channel, WBuffer *buffer) switch (channel->type) { case kChannelTypeSocket: - success = wstream_write(&channel->data.stream, buffer); - break; case kChannelTypeProc: - success = wstream_write(channel->data.proc->in, buffer); - break; case kChannelTypeStdio: - success = wstream_write(&channel->data.std.out, buffer); + success = wstream_write(chan_wstream(channel), buffer); break; case kChannelTypeInternal: incref(channel); diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 444c6cc256..98e56dee3b 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -361,7 +361,7 @@ typedef struct { size_t idx; } APIToMPObjectStackItem; -/// Convert type used by Neovim API to msgpack +/// Convert type used by Nvim API to msgpack type. /// /// @param[in] result Object to convert. /// @param[out] res Structure that defines where conversion results are saved. -- cgit From 0f442c328e33a0c742df9283c1944c077d202a77 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 18 Aug 2017 14:13:28 +0200 Subject: channel.c:call_set_error(): fix memory leak --- src/nvim/msgpack_rpc/channel.c | 1 + src/nvim/msgpack_rpc/helpers.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index ed97f298d9..02f3854f47 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -868,6 +868,7 @@ static void call_set_error(Channel *channel, char *msg, int loglevel) ChannelCallFrame *frame = kv_A(channel->call_stack, i); frame->returned = true; frame->errored = true; + api_free_object(frame->result); frame->result = STRING_OBJ(cstr_to_string(msg)); } diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 98e56dee3b..fecae11d45 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -88,7 +88,12 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg) { bool ret = true; kvec_t(MPToAPIObjectStackItem) stack = KV_INITIAL_VALUE; - kv_push(stack, ((MPToAPIObjectStackItem) { obj, arg, false, 0 })); + kv_push(stack, ((MPToAPIObjectStackItem) { + .mobj = obj, + .aobj = arg, + .container = false, + .idx = 0, + })); while (ret && kv_size(stack)) { MPToAPIObjectStackItem cur = kv_last(stack); if (!cur.container) { -- cgit From 7d183e89f7c055c8f5217e91294123a5aa0a5e2d Mon Sep 17 00:00:00 2001 From: Drew Neil Date: Thu, 25 May 2017 10:11:34 +0100 Subject: Use Normal mode as default when opening a new terminal --- src/nvim/ex_docmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 6e7938046a..d1405978b3 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9835,7 +9835,7 @@ static void ex_terminal(exarg_T *eap) if (*eap->arg != NUL) { // Run {cmd} in 'shell'. char *name = (char *)vim_strsave_escaped(eap->arg, (char_u *)"\"\\"); snprintf(ex_cmd, sizeof(ex_cmd), - ":enew%s | call termopen(\"%s\") | startinsert", + ":enew%s | call termopen(\"%s\")", eap->forceit ? "!" : "", name); xfree(name); } else { // No {cmd}: run the job with tokenized 'shell'. @@ -9857,7 +9857,7 @@ static void ex_terminal(exarg_T *eap) shell_free_argv(argv); snprintf(ex_cmd, sizeof(ex_cmd), - ":enew%s | call termopen([%s]) | startinsert", + ":enew%s | call termopen([%s])", eap->forceit ? "!" : "", shell_argv + 1); } -- cgit From d2595ba1c4491a31d18211050e1abe86ea5379d3 Mon Sep 17 00:00:00 2001 From: Lech Lorens Date: Sun, 20 Aug 2017 12:14:27 +0200 Subject: vim-patch:8.0.0092 Problem: C indenting does not support nested namespaces that C++ 17 has. Solution: Add check that passes double colon inside a name. (Pauli, closes vim/vim#1214) https://github.com/vim/vim/commit/ca8b8d6956dd881de6446fc32c38e817a364a6cc --- src/nvim/indent_c.c | 33 ++++++++++++++++++++------------- src/nvim/version.c | 2 +- 2 files changed, 21 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index fd194a4080..4a6393ac36 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -515,34 +515,41 @@ int cin_isscopedecl(char_u *s) /* Maximum number of lines to search back for a "namespace" line. */ #define FIND_NAMESPACE_LIM 20 -/* - * Recognize a "namespace" scope declaration. - */ -static int cin_is_cpp_namespace(char_u *s) +// Recognize a "namespace" scope declaration. +static bool cin_is_cpp_namespace(char_u *s) { - char_u *p; - int has_name = FALSE; + char_u *p; + bool has_name = false; + bool has_name_start = false; s = cin_skipcomment(s); if (STRNCMP(s, "namespace", 9) == 0 && (s[9] == NUL || !vim_iswordc(s[9]))) { p = cin_skipcomment(skipwhite(s + 9)); while (*p != NUL) { if (ascii_iswhite(*p)) { - has_name = TRUE; /* found end of a name */ + has_name = true; // found end of a name p = cin_skipcomment(skipwhite(p)); } else if (*p == '{') { break; } else if (vim_iswordc(*p)) { - if (has_name) - return FALSE; /* word character after skipping past name */ - ++p; + has_name_start = true; + if (has_name) { + return false; // word character after skipping past name + } + p++; + } else if (p[0] == ':' && p[1] == ':' && vim_iswordc(p[2])) { + if (!has_name_start || has_name) { + return false; + } + // C++ 17 nested namespace + p += 3; } else { - return FALSE; + return false; } } - return TRUE; + return true; } - return FALSE; + return false; } /* diff --git a/src/nvim/version.c b/src/nvim/version.c index 2a3fdbd70d..68c41cee88 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -860,7 +860,7 @@ static const int included_patches[] = { // 95 NA // 94 NA // 93 NA - // 92, + 92, // 91, 90, // 89 NA -- cgit From a66eca78c2082aca112125f759be2ef3aa7ef832 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 21 Aug 2017 12:10:15 -0400 Subject: vim-patch:8.0.0308 Problem: When using a symbolic link, the package path will not be inserted at the right position in 'runtimepath'. (Dugan Chen, Norio Takagi) Solution: Resolve symbolic links when finding the right position in 'runtimepath'. (Hirohito Higashi) https://github.com/vim/vim/commit/2f9e575583c2ad3978ee3d0f790eeff7df56bd6c --- src/nvim/ex_cmds2.c | 28 +++++++++++++++++----------- src/nvim/version.c | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 33fe30cd5a..f8c470f213 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2498,6 +2498,7 @@ static int APP_BOTH; static void add_pack_plugin(char_u *fname, void *cookie) { char_u *p4, *p3, *p2, *p1, *p; + char_u *buf = NULL; char *const ffname = fix_fname((char *)fname); @@ -2525,26 +2526,30 @@ static void add_pack_plugin(char_u *fname, void *cookie) // Find "ffname" in "p_rtp", ignoring '/' vs '\' differences size_t fname_len = strlen(ffname); const char *insp = (const char *)p_rtp; - for (;;) { - if (path_fnamencmp(insp, ffname, fname_len) == 0) { - break; + buf = try_malloc(MAXPATHL); + if (buf == NULL) { + goto theend; + } + while (*insp != NUL) { + copy_option_part((char_u **)&insp, buf, MAXPATHL, ","); + add_pathsep((char *)buf); + char *const rtp_ffname = fix_fname((char *)buf); + if (rtp_ffname == NULL) { + goto theend; } - insp = strchr(insp, ','); - if (insp == NULL) { + bool match = path_fnamencmp(rtp_ffname, ffname, fname_len) == 0; + xfree(rtp_ffname); + if (match) { break; } - insp++; } - if (insp == NULL) { + if (*insp == NUL) { // not found, append at the end insp = (const char *)p_rtp + STRLEN(p_rtp); } else { // append after the matching directory. - insp += strlen(ffname); - while (*insp != NUL && *insp != ',') { - insp++; - } + insp--; } *p4 = c; @@ -2614,6 +2619,7 @@ static void add_pack_plugin(char_u *fname, void *cookie) } theend: + xfree(buf); xfree(ffname); } diff --git a/src/nvim/version.c b/src/nvim/version.c index 2a3fdbd70d..a190293d8e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -644,7 +644,7 @@ static const int included_patches[] = { 311, // 310, // 309, - // 308, + 308, 307, // 306, // 305, -- cgit From 24a556419627d3369f0a55b95dce07cb5316cf8b Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 21 Aug 2017 12:37:24 -0400 Subject: vim-patch:8.0.0325 Problem: Packadd test does not clean up symlink. Solution: Delete the link. (Hirohito Higashi) https://github.com/vim/vim/commit/913727e56761d57aaba61197c2d3485418dea7eb --- src/nvim/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index a190293d8e..a0c46c0e3d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -627,7 +627,7 @@ static const int included_patches[] = { // 328, // 327, // 326, - // 325, + 325, // 324, // 323, 322, -- cgit From 651c6f9b6ebcd76fbf65045ab877fdf38b9d3db2 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 21 Aug 2017 12:38:24 -0400 Subject: vim-patch:8.0.0326 Problem: Packadd test uses wrong directory name. Solution: Use the variable name value. (Hirohito Higashi) https://github.com/vim/vim/commit/24f8f543d4036c5d2ce4ea6973a174cf2176cb72 --- src/nvim/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index a0c46c0e3d..92c776c1e8 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -626,7 +626,7 @@ static const int included_patches[] = { // 329, // 328, // 327, - // 326, + 326, 325, // 324, // 323, -- cgit From fc7bf1c71d41dae7b8ab7e82b92ec0e8253b5291 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 21 Aug 2017 12:46:07 -0400 Subject: vim-patch:8.0.0437 Problem: The packadd test does not create the symlink correctly and does not test the right thing. Solution: Create the directory and symlink correctly. https://github.com/vim/vim/commit/644df41c44cbdfacdedbba55ef77a6c6031eccd8 --- src/nvim/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index 92c776c1e8..d4cbf32009 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -515,7 +515,7 @@ static const int included_patches[] = { // 440, // 439, // 438, - // 437, + 437, // 436, // 435, // 434, -- cgit From 622c3454dff35cae7ec93383bbf49f16621dc778 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 21 Aug 2017 12:47:58 -0400 Subject: vim-patch:8.0.0612 Problem: Package directories are added to 'runtimepath' only after loading non-package plugins. Solution: Split off the code to add package directories to 'runtimepath'. (Ingo Karkat, closes vim/vim#1680) https://github.com/vim/vim/commit/ce876aaa9a250a5a0d0e34b3a2625e51cf9bf5bb --- src/nvim/ex_cmds2.c | 26 +++++++++++++++++--------- src/nvim/globals.h | 3 +++ src/nvim/main.c | 13 ++++++++++++- src/nvim/testdir/test_startup.vim | 32 ++++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 5 files changed, 65 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index f8c470f213..df6b575c1c 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2623,23 +2623,31 @@ theend: xfree(ffname); } -static bool did_source_packages = false; +/// Add all packages in the "start" directory to 'runtimepath'. +void add_pack_start_dirs(void) +{ + do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT + add_pack_plugin, &APP_ADD_DIR); +} + +/// Load plugins from all packages in the "start" directory. +void load_start_packages(void) +{ + did_source_packages = true; + do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT + add_pack_plugin, &APP_LOAD); +} // ":packloadall" // Find plugins in the package directories and source them. -// "eap" is NULL when invoked during startup. void ex_packloadall(exarg_T *eap) { - if (!did_source_packages || (eap != NULL && eap->forceit)) { - did_source_packages = true; - + if (!did_source_packages || eap->forceit) { // First do a round to add all directories to 'runtimepath', then load // the plugins. This allows for plugins to use an autoload directory // of another plugin. - do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT - add_pack_plugin, &APP_ADD_DIR); - do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT - add_pack_plugin, &APP_LOAD); + add_pack_start_dirs(); + load_start_packages(); } } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 13ecafcbe3..2ee72cdb6a 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -407,6 +407,9 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE); /* ID of script being sourced or was sourced to define the current function. */ EXTERN scid_T current_SID INIT(= 0); + +EXTERN bool did_source_packages INIT(= false); + // Scope information for the code that indirectly triggered the current // provider function call EXTERN struct caller_scope { diff --git a/src/nvim/main.c b/src/nvim/main.c index a665ad1de2..6e85fbc130 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1291,10 +1291,21 @@ static void set_window_layout(mparm_T *paramp) static void load_plugins(void) { if (p_lpl) { + // First add all package directories to 'runtimepath', so that their + // autoload directories can be found. Only if not done already with a + // :packloadall command. + if (!did_source_packages) { + add_pack_start_dirs(); + } + source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_NOAFTER); // NOLINT TIME_MSG("loading plugins"); - ex_packloadall(NULL); + // Only source "start" packages if not done already with a :packloadall + // command. + if (!did_source_packages) { + load_start_packages(); + } TIME_MSG("loading packages"); source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_AFTER); diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index 5a38178bd5..2dce7faded 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -62,6 +62,38 @@ func Test_after_comes_later() call delete('Xafter', 'rf') endfunc +func Test_pack_in_rtp_when_plugins_run() + if !has('packages') + return + endif + let before = [ + \ 'set nocp viminfo+=nviminfo', + \ 'set guioptions+=M', + \ 'let $HOME = "/does/not/exist"', + \ 'set loadplugins', + \ 'set rtp=Xhere', + \ 'set packpath=Xhere', + \ 'set nomore', + \ ] + let after = [ + \ 'quit', + \ ] + call mkdir('Xhere/plugin', 'p') + call writefile(['redir! > Xtestout', 'silent set runtimepath?', 'silent! call foo#Trigger()', 'redir END'], 'Xhere/plugin/here.vim') + call mkdir('Xhere/pack/foo/start/foobar/autoload', 'p') + call writefile(['function! foo#Trigger()', 'echo "autoloaded foo"', 'endfunction'], 'Xhere/pack/foo/start/foobar/autoload/foo.vim') + + if RunVim(before, after, '') + + let lines = filter(readfile('Xtestout'), '!empty(v:val)') + call assert_match('Xhere[/\\]pack[/\\]foo[/\\]start[/\\]foobar', get(lines, 0)) + call assert_match('autoloaded foo', get(lines, 1)) + endif + + call delete('Xtestout') + call delete('Xhere', 'rf') +endfunc + func Test_help_arg() if !has('unix') && has('gui') " this doesn't work with gvim on MS-Windows diff --git a/src/nvim/version.c b/src/nvim/version.c index d4cbf32009..3313ffdfa9 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -340,7 +340,7 @@ static const int included_patches[] = { // 615, 614, // 613, - // 612, + 612, // 611, // 610, // 609, -- cgit From 41d180abb4693814be5833b0907e111ce46b3791 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 21 Aug 2017 12:54:22 -0400 Subject: vim-patch:8.0.0680 Problem: Plugins in start packages are sourced twice. (mseplowitz) Solution: Use the unmodified runtime path when loading plugins (test by Ingo Karkat, closes vim/vim#1801) https://github.com/vim/vim/commit/07ecfa64a18609a986f21d6132d04ee8934f3200 --- src/nvim/ex_cmds2.c | 43 +++++++++++++++++++++++++-------------- src/nvim/main.c | 10 ++++++++- src/nvim/testdir/test_startup.vim | 20 +++++++++++++----- src/nvim/version.c | 2 +- 4 files changed, 53 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index df6b575c1c..371f7b3bce 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2319,16 +2319,6 @@ static void source_callback(char_u *fname, void *cookie) (void)do_source(fname, false, DOSO_NONE); } -/// Source the file "name" from all directories in 'runtimepath'. -/// "name" can contain wildcards. -/// When "flags" has DIP_ALL: source all files, otherwise only the first one. -/// -/// return FAIL when no file could be sourced, OK otherwise. -int source_runtime(char_u *name, int flags) -{ - return do_in_runtimepath(name, flags, source_callback, NULL); -} - /// Find the file "name" in all directories in "path" and invoke /// "callback(fname, cookie)". /// "name" can contain wildcards. @@ -2434,21 +2424,21 @@ int do_in_path(char_u *path, char_u *name, int flags, return did_one ? OK : FAIL; } -/// Find "name" in 'runtimepath'. When found, invoke the callback function for +/// Find "name" in "path". When found, invoke the callback function for /// it: callback(fname, "cookie") /// When "flags" has DIP_ALL repeat for all matches, otherwise only the first /// one is used. /// Returns OK when at least one match found, FAIL otherwise. -/// If "name" is NULL calls callback for each entry in runtimepath. Cookie is +/// If "name" is NULL calls callback for each entry in "path". Cookie is /// passed by reference in this case, setting it to NULL indicates that callback /// has done its job. -int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback, - void *cookie) +int do_in_path_and_pp(char_u *path, char_u *name, int flags, + DoInRuntimepathCB callback, void *cookie) { int done = FAIL; if ((flags & DIP_NORTP) == 0) { - done = do_in_path(p_rtp, name, flags, callback, cookie); + done = do_in_path(path, name, flags, callback, cookie); } if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) { @@ -2476,6 +2466,29 @@ int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback, return done; } +/// Just like do_in_path_and_pp(), using 'runtimepath' for "path". +int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback, + void *cookie) +{ + return do_in_path_and_pp(p_rtp, name, flags, callback, cookie); +} + +/// Source the file "name" from all directories in 'runtimepath'. +/// "name" can contain wildcards. +/// When "flags" has DIP_ALL: source all files, otherwise only the first one. +/// +/// return FAIL when no file could be sourced, OK otherwise. +int source_runtime(char_u *name, int flags) +{ + return source_in_path(p_rtp, name, flags); +} + +/// Just like source_runtime(), but use "path" instead of 'runtimepath'. +int source_in_path(char_u *path, char_u *name, int flags) +{ + return do_in_path_and_pp(path, name, flags, source_callback, NULL); +} + // Expand wildcards in "pat" and invoke do_source() for each match. static void source_all_matches(char_u *pat) { diff --git a/src/nvim/main.c b/src/nvim/main.c index 6e85fbc130..f601fd7ea3 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1291,15 +1291,23 @@ static void set_window_layout(mparm_T *paramp) static void load_plugins(void) { if (p_lpl) { + char_u *rtp_copy = NULL; + // First add all package directories to 'runtimepath', so that their // autoload directories can be found. Only if not done already with a // :packloadall command. + // Make a copy of 'runtimepath', so that source_runtime does not use the + // pack directories. if (!did_source_packages) { + rtp_copy = vim_strsave(p_rtp); add_pack_start_dirs(); } - source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_NOAFTER); // NOLINT + source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy, + (char_u *)"plugin/**/*.vim", // NOLINT + DIP_ALL | DIP_NOAFTER); TIME_MSG("loading plugins"); + xfree(rtp_copy); // Only source "start" packages if not done already with a :packloadall // command. diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index 2dce7faded..11e26d03aa 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -24,28 +24,34 @@ func Test_after_comes_later() \ 'set guioptions+=M', \ 'let $HOME = "/does/not/exist"', \ 'set loadplugins', - \ 'set rtp=Xhere,Xafter', + \ 'set rtp=Xhere,Xafter,Xanother', \ 'set packpath=Xhere,Xafter', \ 'set nomore', + \ 'let g:sequence = ""', \ ] let after = [ \ 'redir! > Xtestout', \ 'scriptnames', \ 'redir END', + \ 'redir! > Xsequence', + \ 'echo g:sequence', + \ 'redir END', \ 'quit', \ ] call mkdir('Xhere/plugin', 'p') - call writefile(['let done = 1'], 'Xhere/plugin/here.vim') + call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim') + call mkdir('Xanother/plugin', 'p') + call writefile(['let g:sequence .= "another "'], 'Xanother/plugin/another.vim') call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p') - call writefile(['let done = 1'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim') + call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim') call mkdir('Xafter/plugin', 'p') - call writefile(['let done = 1'], 'Xafter/plugin/later.vim') + call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim') if RunVim(before, after, '') let lines = readfile('Xtestout') - let expected = ['Xbefore.vim', 'here.vim', 'foo.vim', 'later.vim', 'Xafter.vim'] + let expected = ['Xbefore.vim', 'here.vim', 'another.vim', 'foo.vim', 'later.vim', 'Xafter.vim'] let found = [] for line in lines for one in expected @@ -57,8 +63,12 @@ func Test_after_comes_later() call assert_equal(expected, found) endif + call assert_equal('here another pack after', substitute(join(readfile('Xsequence', 1), ''), '\s\+$', '', '')) + call delete('Xtestout') + call delete('Xsequence') call delete('Xhere', 'rf') + call delete('Xanother', 'rf') call delete('Xafter', 'rf') endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index 3313ffdfa9..598c3c3778 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -272,7 +272,7 @@ static const int included_patches[] = { // 683, // 682, // 681, - // 680, + 680, 679, 678, // 677, -- cgit From 4d91369fd752bec5a5ffc15dc094c794b09b1f12 Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Tue, 15 Aug 2017 18:03:06 +0200 Subject: syntax.c: register 'Normal' highlight group - :hi Normal works with -u NONE - Makes HL_TABLE and ATTR_ENTYRY a function instead of a macro so that in can be used in gdb. - Introduces ATTRENTRY_INIT to init attrentry_t --- src/nvim/syntax.c | 44 +++++++++++++++++++++++++++++++------------- src/nvim/syntax_defs.h | 10 ++++++++++ 2 files changed, 41 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index f0171fa525..9d9f794a56 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -81,7 +81,10 @@ struct hl_group { // highlight groups for 'highlight' option static garray_T highlight_ga = GA_EMPTY_INIT_VALUE; -#define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data))) +static inline struct hl_group * HL_TABLE(void) +{ + return ((struct hl_group *)((highlight_ga.ga_data))); +} #define MAX_HL_ID 20000 /* maximum value for a highlight ID. */ @@ -5958,6 +5961,7 @@ static char *highlight_init_light[] = "Title ctermfg=DarkMagenta gui=bold guifg=Magenta", "Visual guibg=LightGrey", "WarningMsg ctermfg=DarkRed guifg=Red", + "Normal gui=NONE", NULL }; @@ -5991,6 +5995,7 @@ static char *highlight_init_dark[] = "Title ctermfg=LightMagenta gui=bold guifg=Magenta", "Visual guibg=DarkGrey", "WarningMsg ctermfg=LightRed guifg=Red", + "Normal gui=NONE", NULL }; @@ -6707,14 +6712,16 @@ static void highlight_clear(int idx) } -/* - * Table with the specifications for an attribute number. - * Note that this table is used by ALL buffers. This is required because the - * GUI can redraw at any time for any buffer. - */ +/// Table with the specifications for an attribute number. +/// Note that this table is used by ALL buffers. This is required because the +/// GUI can redraw at any time for any buffer. +/// The attributes table static garray_T attr_table = GA_EMPTY_INIT_VALUE; -#define ATTR_ENTRY(idx) ((attrentry_T *)attr_table.ga_data)[idx] +static inline attrentry_T * ATTR_ENTRY(int idx) +{ + return &((attrentry_T *)attr_table.ga_data)[idx]; +} /// Return the attr number for a set of colors and font. @@ -6804,7 +6811,7 @@ int hl_combine_attr(int char_attr, int prim_attr) { attrentry_T *char_aep = NULL; attrentry_T *spell_aep; - attrentry_T new_en; + attrentry_T new_en = ATTRENTRY_INIT; if (char_attr == 0) { return prim_attr; @@ -6852,17 +6859,24 @@ int hl_combine_attr(int char_attr, int prim_attr) return get_attr_entry(&new_en); } +/// \note this function does not apply exclusively to cterm attr contrary +/// to what its name implies attrentry_T *syn_cterm_attr2entry(int attr) { attr -= ATTR_OFF; - if (attr >= attr_table.ga_len) /* did ":syntax clear" */ + if (attr >= attr_table.ga_len) { + // did ":syntax clear" return NULL; - return &(ATTR_ENTRY(attr)); + } + return ATTR_ENTRY(attr); } +/// \addtogroup LIST_XXX +/// @{ #define LIST_ATTR 1 #define LIST_STRING 2 #define LIST_INT 3 +/// @} static void highlight_list_one(int id) { @@ -7095,12 +7109,13 @@ set_hl_attr ( int idx /* index in array */ ) { - attrentry_T at_en; + attrentry_T at_en = ATTRENTRY_INIT; struct hl_group *sgp = HL_TABLE() + idx; - /* The "Normal" group doesn't need an attribute number */ - if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) + // The "Normal" group doesn't need an attribute number + if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) { return; + } at_en.cterm_ae_attr = sgp->sg_cterm; at_en.cterm_fg_color = sgp->sg_cterm_fg; @@ -7237,6 +7252,9 @@ static int syn_add_group(char_u *name) struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga); memset(hlgp, 0, sizeof(*hlgp)); hlgp->sg_name = name; + hlgp->sg_rgb_bg = -1; + hlgp->sg_rgb_fg = -1; + hlgp->sg_rgb_sp = -1; hlgp->sg_name_u = vim_strsave_up(name); return highlight_ga.ga_len; /* ID is index plus one */ diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h index 9f309451b0..56fadbe7f6 100644 --- a/src/nvim/syntax_defs.h +++ b/src/nvim/syntax_defs.h @@ -73,4 +73,14 @@ typedef struct attr_entry { int cterm_fg_color, cterm_bg_color; } attrentry_T; +#define ATTRENTRY_INIT { \ + .rgb_ae_attr = 0, \ + .cterm_ae_attr = 0, \ + .rgb_fg_color = -1, \ + .rgb_bg_color = -1, \ + .rgb_sp_color = -1, \ + .cterm_fg_color = 0, \ + .cterm_bg_color = 0, \ +} + #endif // NVIM_SYNTAX_DEFS_H -- cgit From 5f6ad863c6d28dce377590a1d33bc386d346cc27 Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Tue, 15 Aug 2017 18:07:37 +0200 Subject: syntax.c: style Converts some documentation to doxygen format + minor styling improvements. --- src/nvim/syntax.c | 187 +++++++++++++++++++++++++++--------------------------- src/nvim/window.c | 20 +++--- 2 files changed, 105 insertions(+), 102 deletions(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 9d9f794a56..65c0e2464a 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -103,10 +103,8 @@ static int include_none = 0; /* when 1 include "nvim/None" */ static int include_default = 0; /* when 1 include "nvim/default" */ static int include_link = 0; /* when 2 include "nvim/link" and "clear" */ -/* - * The "term", "cterm" and "gui" arguments can be any combination of the - * following names, separated by commas (but no spaces!). - */ +/// The "term", "cterm" and "gui" arguments can be any combination of the +/// following names, separated by commas (but no spaces!). static char *(hl_name_table[]) = {"bold", "standout", "underline", "undercurl", "italic", "reverse", "inverse", "NONE"}; @@ -1778,8 +1776,9 @@ syn_current_attr ( cur_si->si_trans_id = CUR_STATE( current_state.ga_len - 2).si_trans_id; } - } else + } else { cur_si->si_attr = syn_id2attr(syn_id); + } cur_si->si_cont_list = NULL; cur_si->si_next_list = next_list; check_keepend(); @@ -5255,12 +5254,10 @@ get_id_list ( /* * Handle full group name. */ - if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) + if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) { id = syn_check_group(name + 1, (int)(end - p)); - else { - /* - * Handle match of regexp with group names. - */ + } else { + // Handle match of regexp with group names. *name = '^'; STRCAT(name, "$"); regmatch.regprog = vim_regcomp(name, RE_MAGIC); @@ -5999,20 +5996,21 @@ static char *highlight_init_dark[] = NULL }; -void -init_highlight ( - int both, /* include groups where 'bg' doesn't matter */ - int reset /* clear group first */ -) + +/// Load colors from a file if "g:colors_name" is set, otherwise load builtin +/// colors +/// +/// @param both include groups where 'bg' doesn't matter +/// @param reset clear groups first +void +init_highlight(int both, int reset) { int i; char **pp; static int had_both = FALSE; - /* - * Try finding the color scheme file. Used when a color file was loaded - * and 'background' or 't_Co' is changed. - */ + // Try finding the color scheme file. Used when a color file was loaded + // and 'background' or 't_Co' is changed. char_u *p = get_var_value("g:colors_name"); if (p != NULL) { // Value of g:colors_name could be freed in load_colors() and make @@ -6031,33 +6029,34 @@ init_highlight ( if (both) { had_both = TRUE; pp = highlight_init_both; - for (i = 0; pp[i] != NULL; ++i) - do_highlight((char_u *)pp[i], reset, TRUE); - } else if (!had_both) - /* Don't do anything before the call with both == TRUE from main(). - * Not everything has been setup then, and that call will overrule - * everything anyway. */ + for (i = 0; pp[i] != NULL; i++) { + do_highlight((char_u *)pp[i], reset, true); + } + } else if (!had_both) { + // Don't do anything before the call with both == TRUE from main(). + // Not everything has been setup then, and that call will overrule + // everything anyway. return; + } - if (*p_bg == 'l') - pp = highlight_init_light; - else - pp = highlight_init_dark; - for (i = 0; pp[i] != NULL; ++i) - do_highlight((char_u *)pp[i], reset, TRUE); + pp = (*p_bg == 'l') ? highlight_init_light : highlight_init_dark; + + for (i = 0; pp[i] != NULL; i++) { + do_highlight((char_u *)pp[i], reset, true); + } /* Reverse looks ugly, but grey may not work for 8 colors. Thus let it * depend on the number of colors available. * With 8 colors brown is equal to yellow, need to use black for Search fg * to avoid Statement highlighted text disappears. * Clear the attributes, needed when changing the t_Co value. */ - if (t_colors > 8) + if (t_colors > 8) { do_highlight( (char_u *)(*p_bg == 'l' ? "Visual cterm=NONE ctermbg=LightGrey" - : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE, - TRUE); - else { + : "Visual cterm=NONE ctermbg=DarkGrey"), false, + true); + } else { do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE", FALSE, TRUE); if (*p_bg == 'l') @@ -6117,12 +6116,7 @@ int load_colors(char_u *name) /// "forceit" and "init" both TRUE. /// @param init TRUE when called for initializing void -do_highlight( - char_u *line, - int forceit, - int init -) -{ +do_highlight(char_u *line, int forceit, int init) { char_u *name_end; char_u *linep; char_u *key_start; @@ -6139,15 +6133,16 @@ do_highlight( int dolink = FALSE; int error = FALSE; int color; - int is_normal_group = FALSE; /* "Normal" group */ + bool is_normal_group = false; // "Normal" group /* * If no argument, list current highlighting. */ if (ends_excmd(*line)) { - for (int i = 1; i <= highlight_ga.ga_len && !got_int; ++i) - /* TODO: only call when the group has attributes set */ + for (int i = 1; i <= highlight_ga.ga_len && !got_int; i++) { + // todo(vim): only call when the group has attributes set highlight_list_one(i); + } return; } @@ -6275,12 +6270,12 @@ do_highlight( return; idx = id - 1; /* index is ID minus one */ - /* Return if "default" was used and the group already has settings. */ - if (dodefault && hl_has_settings(idx, TRUE)) + // Return if "default" was used and the group already has settings + if (dodefault && hl_has_settings(idx, true)) { return; + } - if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0) - is_normal_group = TRUE; + is_normal_group = (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0); /* Clear the highlighting for ":hi clear {group}" and ":hi clear". */ if (doclear || (forceit && init)) { @@ -6289,7 +6284,7 @@ do_highlight( HL_TABLE()[idx].sg_set = 0; } - if (!doclear) + if (!doclear) { while (!ends_excmd(*linep)) { key_start = linep; if (*linep == '=') { @@ -6395,12 +6390,12 @@ do_highlight( } } } else if (STRCMP(key, "FONT") == 0) { - /* in non-GUI fonts are simply ignored */ - } else if (STRCMP(key, - "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) { + // in non-GUI fonts are simply ignored + } else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) { if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) { - if (!init) + if (!init) { HL_TABLE()[idx].sg_set |= SG_CTERM; + } /* When setting the foreground color, and previously the "bold" * flag was set for a light color, reset it now */ @@ -6494,9 +6489,10 @@ do_highlight( * colors (on some terminals, e.g. "linux") */ if (color & 8) { HL_TABLE()[idx].sg_cterm |= HL_BOLD; - HL_TABLE()[idx].sg_cterm_bold = TRUE; - } else + HL_TABLE()[idx].sg_cterm_bold = true; + } else { HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; + } } color &= 7; // truncate to 8 colors } else if (t_colors == 16 || t_colors == 88 || t_colors >= 256) { @@ -6608,21 +6604,23 @@ do_highlight( /* * When highlighting has been given for a group, don't link it. */ - if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) + if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) { HL_TABLE()[idx].sg_link = 0; + } /* * Continue with next argument. */ linep = skipwhite(linep); } + } /* * If there is an error, and it's a new entry, remove it from the table. */ - if (error && idx == highlight_ga.ga_len) + if (error && idx == highlight_ga.ga_len) { syn_unadd_group(); - else { + } else { if (is_normal_group) { HL_TABLE()[idx].sg_attr = 0; // Need to update all groups, because they might be using "bg" and/or @@ -6630,16 +6628,17 @@ do_highlight( highlight_attr_set_all(); // If the normal group has changed, it is simpler to refresh every UI ui_refresh(); - } else + } else { set_hl_attr(idx); + } HL_TABLE()[idx].sg_scriptID = current_SID; redraw_all_later(NOT_VALID); } xfree(key); xfree(arg); - /* Only call highlight_changed() once, after sourcing a syntax file */ - need_highlight_changed = TRUE; + // Only call highlight_changed() once, after sourcing a syntax file + need_highlight_changed = true; } #if defined(EXITFREE) @@ -6715,7 +6714,6 @@ static void highlight_clear(int idx) /// Table with the specifications for an attribute number. /// Note that this table is used by ALL buffers. This is required because the /// GUI can redraw at any time for any buffer. -/// The attributes table static garray_T attr_table = GA_EMPTY_INIT_VALUE; static inline attrentry_T * ATTR_ENTRY(int idx) @@ -6915,7 +6913,13 @@ static void highlight_list_one(int id) last_set_msg(sgp->sg_scriptID); } -static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name) +/// Outputs a highlight when doing ":hi MyHighlight" +/// +/// @param type one of \ref LIST_XXX +/// @param iarg integer argument used if \p type == LIST_INT +/// @param sarg string used if \p type == LIST_STRING +static int highlight_list_arg(int id, int didh, int type, int iarg, + char_u *sarg, const char *name) { char_u buf[100]; char_u *ts; @@ -7055,24 +7059,23 @@ const char *highlight_color(const int id, const char *const what, return NULL; } -/* - * Output the syntax list header. - * Return TRUE when started a new line. - */ -static int -syn_list_header ( - int did_header, /* did header already */ - int outlen, /* length of string that comes */ - int id /* highlight group id */ -) +/// Output the syntax list header. +/// +/// @param did_header did header already +/// @param outlen length of string that comes +/// @param id highlight group id +/// @return true when started a new line. +static int +syn_list_header(int did_header, int outlen, int id) { int endcol = 19; int newline = TRUE; if (!did_header) { msg_putchar('\n'); - if (got_int) - return TRUE; + if (got_int) { + return true; + } msg_outtrans(HL_TABLE()[id - 1].sg_name); endcol = 15; } else if (msg_col + outlen + 1 >= Columns) { @@ -7139,10 +7142,10 @@ set_hl_attr ( } } -/* - * Lookup a highlight group name and return it's ID. - * If it is not found, 0 is returned. - */ +/// Lookup a highlight group name and return its ID. +/// +/// @param highlight name e.g. 'Cursor', 'Normal' +/// @return the highlight id, else 0 if \p name does not exist int syn_name2id(const char_u *name) { int i; @@ -7191,7 +7194,7 @@ int syn_namen2id(char_u *linep, int len) return id; } -/// Find highlight group name in the table and return it's ID. +/// Find highlight group name in the table and return its ID. /// If it doesn't exist yet, a new entry is created. /// /// @param pp Highlight group name @@ -7210,11 +7213,11 @@ int syn_check_group(char_u *pp, int len) return id; } -/* - * Add new highlight group and return it's ID. - * "name" must be an allocated string, it will be consumed. - * Return 0 for failure. - */ +/// Add new highlight group and return it's ID. +/// +/// @param name must be an allocated string, it will be consumed. +/// @return 0 for failure, else the allocated group id +/// @see syn_check_group syn_unadd_group static int syn_add_group(char_u *name) { char_u *p; @@ -7260,20 +7263,18 @@ static int syn_add_group(char_u *name) return highlight_ga.ga_len; /* ID is index plus one */ } -/* - * When, just after calling syn_add_group(), an error is discovered, this - * function deletes the new name. - */ +/// When, just after calling syn_add_group(), an error is discovered, this +/// function deletes the new name. static void syn_unadd_group(void) { - --highlight_ga.ga_len; + highlight_ga.ga_len--; xfree(HL_TABLE()[highlight_ga.ga_len].sg_name); xfree(HL_TABLE()[highlight_ga.ga_len].sg_name_u); } -/* - * Translate a group ID to highlight attributes. - */ + +/// Translate a group ID to highlight attributes. +/// @see syn_cterm_attr2entry int syn_id2attr(int hl_id) { struct hl_group *sgp; diff --git a/src/nvim/window.c b/src/nvim/window.c index 081fc98816..c2d0a9b3b1 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5515,11 +5515,14 @@ void restore_buffer(bufref_T *save_curbuf) } -// Add match to the match list of window 'wp'. The pattern 'pat' will be -// highlighted with the group 'grp' with priority 'prio'. -// Optionally, a desired ID 'id' can be specified (greater than or equal to 1). -// If no particular ID is desired, -1 must be specified for 'id'. -// Return ID of added match, -1 on failure. +/// Add match to the match list of window 'wp'. The pattern 'pat' will be +/// highlighted with the group 'grp' with priority 'prio'. +/// Optionally, a desired ID 'id' can be specified (greater than or equal to 1). +/// +/// @param[in] id a desired ID 'id' can be specified +/// (greater than or equal to 1). -1 must be specified if no +/// particular ID is desired +/// @return ID of added match, -1 on failure. int match_add(win_T *wp, const char *const grp, const char *const pat, int prio, int id, list_T *pos_list, const char *const conceal_char) @@ -5697,10 +5700,9 @@ fail: return -1; } -/* - * Delete match with ID 'id' in the match list of window 'wp'. - * Print error messages if 'perr' is TRUE. - */ + +/// Delete match with ID 'id' in the match list of window 'wp'. +/// Print error messages if 'perr' is TRUE. int match_delete(win_T *wp, int id, int perr) { matchitem_T *cur = wp->w_match_head; -- cgit From 85f3084e21e112a34d891d90cfaf37a7de726866 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 22 Aug 2017 20:31:54 +0200 Subject: clipboard: disallow recursion; show hint only once (#7203) - Show hint only once per session. - provider#clipboard#Call(): prevent recursion - provider#clear_stderr(): use has_key(), because :silent! is still captured by :redir. closes #7184 --- src/nvim/ops.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 6c873a96c0..c01840cfd0 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -55,12 +55,11 @@ static yankreg_T y_regs[NUM_REGISTERS]; static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */ -static bool clipboard_didwarn_unnamed = false; - // for behavior between start_batch_changes() and end_batch_changes()) static int batch_change_count = 0; // inside a script static bool clipboard_delay_update = false; // delay clipboard update static bool clipboard_needs_update = false; // clipboard was updated +static bool clipboard_didwarn = false; /* * structure used by block_prep, op_delete and op_yank for blockwise operators @@ -5541,22 +5540,17 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) yankreg_T *target = NULL; bool explicit_cb_reg = (*name == '*' || *name == '+'); bool implicit_cb_reg = (*name == NUL) && (cb_flags & CB_UNNAMEDMASK); - int save_redir_off = redir_off; if (!explicit_cb_reg && !implicit_cb_reg) { goto end; } if (!eval_has_provider("clipboard")) { - if (batch_change_count == 1 && explicit_cb_reg && !quiet) { - redir_off = true; // Avoid recursion from :redir + emsg(). + if (batch_change_count == 1 && !quiet + && (!clipboard_didwarn || (explicit_cb_reg && !redirecting()))) { + clipboard_didwarn = true; // Do NOT error (emsg()) here--if it interrupts :redir we get into // a weird state, stuck in "redirect mode". msg((char_u *)MSG_NO_CLIP); - } else if (batch_change_count == 1 && implicit_cb_reg - && !quiet && !clipboard_didwarn_unnamed) { - redir_off = true; // Avoid recursion from :redir + emsg(). - msg((char_u *)MSG_NO_CLIP); - clipboard_didwarn_unnamed = true; } // ... else, be silent (don't flood during :while, :redir, etc.). goto end; @@ -5586,7 +5580,6 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing) } end: - redir_off = save_redir_off; return target; } -- cgit From e5565891af5858965a65366ecb7f791abc988931 Mon Sep 17 00:00:00 2001 From: Yuto Tokunaga Date: Wed, 23 Aug 2017 07:55:00 +0900 Subject: win: wmain(): locale-independent argv (#7180) fix #7060 --- src/nvim/CMakeLists.txt | 5 +++++ src/nvim/main.c | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) (limited to 'src') diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 688912eda6..e2f1f16635 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -10,6 +10,11 @@ if(USE_GCOV) endif() endif() +if(WIN32) + # tell MinGW compiler to enable wmain + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -municode") +endif() + set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches) set(GENERATOR_DIR ${CMAKE_CURRENT_LIST_DIR}/generators) set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) diff --git a/src/nvim/main.c b/src/nvim/main.c index f601fd7ea3..af614762ac 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -7,6 +7,11 @@ #include #include +#ifdef WIN32 +# include +# include +#endif + #include #include "nvim/ascii.h" @@ -215,10 +220,28 @@ void early_init(void) #ifdef MAKE_LIB int nvim_main(int argc, char **argv) +#elif defined WIN32 +// don't use codepage encoded arguments. see #7060 +int wmain(int argc, wchar_t **argv_w) #else int main(int argc, char **argv) #endif { +#ifdef WIN32 + char *argv[argc]; + + for (size_t i = 0; i < (size_t)argc; i++) { + // get required buffer size + size_t dest_size = (size_t)WideCharToMultiByte( + CP_UTF8, 0, argv_w[i], -1, NULL, 0, NULL, NULL); + char *buf = (char *)xmallocz(dest_size); + // convert from utf16 (widechar) utf8 (multibyte) + WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, buf, (int)dest_size, + NULL, NULL); + argv[i] = buf; + } +#endif + argv0 = argv[0]; char_u *fname = NULL; // file name from command line -- cgit From 71df5dde6d99da73eaea1989a309ffe2a5c7689d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 23 Aug 2017 01:17:59 +0200 Subject: win: wmain(): use utf16_to_utf8() #7060 --- src/nvim/main.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index af614762ac..53a1342b2a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -220,24 +220,18 @@ void early_init(void) #ifdef MAKE_LIB int nvim_main(int argc, char **argv) -#elif defined WIN32 -// don't use codepage encoded arguments. see #7060 -int wmain(int argc, wchar_t **argv_w) +#elif defined(WIN32) +int wmain(int argc, wchar_t **argv_w) // multibyte args on Windows. #7060 #else int main(int argc, char **argv) #endif { #ifdef WIN32 char *argv[argc]; - - for (size_t i = 0; i < (size_t)argc; i++) { - // get required buffer size - size_t dest_size = (size_t)WideCharToMultiByte( - CP_UTF8, 0, argv_w[i], -1, NULL, 0, NULL, NULL); - char *buf = (char *)xmallocz(dest_size); - // convert from utf16 (widechar) utf8 (multibyte) - WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, buf, (int)dest_size, - NULL, NULL); + for (int i = 0; i < argc; i++) { + char *buf = NULL; + utf16_to_utf8(argv_w[i], &buf); + assert(buf); argv[i] = buf; } #endif -- cgit From 02e5eafa86c729cee238ed6166a560ed9a555fc8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 23 Aug 2017 01:30:25 +0200 Subject: win: expect utf8-encoded `argv` when built as a library --- src/nvim/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 53a1342b2a..024c56dd05 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -226,7 +226,7 @@ int wmain(int argc, wchar_t **argv_w) // multibyte args on Windows. #7060 int main(int argc, char **argv) #endif { -#ifdef WIN32 +#if defined(WIN32) && !defined(MAKE_LIB) char *argv[argc]; for (int i = 0; i < argc; i++) { char *buf = NULL; -- cgit From da84f7dcf9dab28a03b9a776f04d882c36fd77fb Mon Sep 17 00:00:00 2001 From: Fredrik Fornwall Date: Tue, 22 Aug 2017 11:49:54 +0200 Subject: tui: always use unibi_add_ext_str with unibi_get_ext_str #7204 When using an index returned by unibi_add_ext_str() we should always use unibi_get_ext_str() and not rely on the index being lower than unibi_string_begin_. Closes #7206 --- src/nvim/tui/tui.c | 62 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index b5af5b0333..e3eab72695 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -234,9 +234,9 @@ static void terminfo_start(UI *ui) unibi_out(ui, unibi_keypad_xmit); unibi_out(ui, unibi_clear_screen); // Enable bracketed paste - unibi_out(ui, data->unibi_ext.enable_bracketed_paste); + unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste); // Enable focus reporting - unibi_out(ui, data->unibi_ext.enable_focus_reporting); + unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting); uv_loop_init(&data->write_loop); if (data->out_isatty) { uv_tty_init(&data->write_loop, &data->output_handle.tty, data->out_fd, 0); @@ -263,9 +263,9 @@ static void terminfo_stop(UI *ui) unibi_out(ui, unibi_keypad_local); unibi_out(ui, unibi_exit_ca_mode); // Disable bracketed paste - unibi_out(ui, data->unibi_ext.disable_bracketed_paste); + unibi_out_ext(ui, data->unibi_ext.disable_bracketed_paste); // Disable focus reporting - unibi_out(ui, data->unibi_ext.disable_focus_reporting); + unibi_out_ext(ui, data->unibi_ext.disable_focus_reporting); flush_buf(ui, true); uv_tty_reset_mode(); uv_close((uv_handle_t *)&data->output_handle, NULL); @@ -426,14 +426,14 @@ static void update_attrs(UI *ui, HlAttrs attrs) data->params[0].i = (fg >> 16) & 0xff; // red data->params[1].i = (fg >> 8) & 0xff; // green data->params[2].i = fg & 0xff; // blue - unibi_out(ui, data->unibi_ext.set_rgb_foreground); + unibi_out_ext(ui, data->unibi_ext.set_rgb_foreground); } if (bg != -1) { data->params[0].i = (bg >> 16) & 0xff; // red data->params[1].i = (bg >> 8) & 0xff; // green data->params[2].i = bg & 0xff; // blue - unibi_out(ui, data->unibi_ext.set_rgb_background); + unibi_out_ext(ui, data->unibi_ext.set_rgb_background); } } else { if (fg != -1) { @@ -679,7 +679,7 @@ static void set_scroll_region(UI *ui) data->params[1].i = grid->bot; unibi_out(ui, unibi_change_scroll_region); if (grid->left != 0 || grid->right != ui->width - 1) { - unibi_out(ui, data->unibi_ext.enable_lr_margin); + unibi_out_ext(ui, data->unibi_ext.enable_lr_margin); if (data->can_set_lr_margin) { data->params[0].i = grid->left; data->params[1].i = grid->right; @@ -700,7 +700,7 @@ static void reset_scroll_region(UI *ui) UGrid *grid = &data->grid; if (0 <= data->unibi_ext.reset_scroll_region) { - unibi_out(ui, data->unibi_ext.reset_scroll_region); + unibi_out_ext(ui, data->unibi_ext.reset_scroll_region); } else { data->params[0].i = 0; data->params[1].i = ui->height - 1; @@ -717,7 +717,7 @@ static void reset_scroll_region(UI *ui) data->params[0].i = ui->width - 1; unibi_out(ui, unibi_set_right_margin_parm); } - unibi_out(ui, data->unibi_ext.disable_lr_margin); + unibi_out_ext(ui, data->unibi_ext.disable_lr_margin); } unibi_goto(ui, grid->row, grid->col); } @@ -730,7 +730,7 @@ static void tui_resize(UI *ui, Integer width, Integer height) if (!got_winch) { // Try to resize the terminal window. data->params[0].i = (int)height; data->params[1].i = (int)width; - unibi_out(ui, data->unibi_ext.resize_screen); + unibi_out_ext(ui, data->unibi_ext.resize_screen); // DECSLPP does not reset the scroll region. if (data->scroll_region_is_full_screen) { reset_scroll_region(ui); @@ -836,7 +836,7 @@ static void tui_mouse_on(UI *ui) { TUIData *data = ui->data; if (!data->mouse_enabled) { - unibi_out(ui, data->unibi_ext.enable_mouse); + unibi_out_ext(ui, data->unibi_ext.enable_mouse); data->mouse_enabled = true; } } @@ -845,7 +845,7 @@ static void tui_mouse_off(UI *ui) { TUIData *data = ui->data; if (data->mouse_enabled) { - unibi_out(ui, data->unibi_ext.disable_mouse); + unibi_out_ext(ui, data->unibi_ext.disable_mouse); data->mouse_enabled = false; } } @@ -864,7 +864,7 @@ static void tui_set_mode(UI *ui, ModeShape mode) if (attr > 0) { attrentry_T *aep = syn_cterm_attr2entry(attr); data->params[0].i = aep->rgb_bg_color; - unibi_out(ui, data->unibi_ext.set_cursor_color); + unibi_out_ext(ui, data->unibi_ext.set_cursor_color); } } @@ -875,7 +875,7 @@ static void tui_set_mode(UI *ui, ModeShape mode) default: WLOG("Unknown shape value %d", shape); break; } data->params[0].i = shape + (int)(c.blinkon == 0); - unibi_out(ui, data->unibi_ext.set_cursor_style); + unibi_out_ext(ui, data->unibi_ext.set_cursor_style); } /// @param mode editor mode @@ -1182,25 +1182,27 @@ static void unibi_goto(UI *ui, int row, int col) unibi_out(ui, unibi_cursor_address); } +#define UNIBI_OUT(fn) \ + do { \ + TUIData *data = ui->data; \ + const char *str = NULL; \ + if (unibi_index >= 0) { \ + str = fn(data->ut, (unsigned)unibi_index); \ + } \ + if (str) { \ + unibi_var_t vars[26 + 26] = { { 0 } }; \ + unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL); \ + } \ + } while (0) static void unibi_out(UI *ui, int unibi_index) { - TUIData *data = ui->data; - - const char *str = NULL; - - if (unibi_index >= 0) { - if (unibi_index < unibi_string_begin_) { - str = unibi_get_ext_str(data->ut, (unsigned)unibi_index); - } else { - str = unibi_get_str(data->ut, (unsigned)unibi_index); - } - } - - if (str) { - unibi_var_t vars[26 + 26] = {{0}}; - unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL); - } + UNIBI_OUT(unibi_get_str); +} +static void unibi_out_ext(UI *ui, int unibi_index) +{ + UNIBI_OUT(unibi_get_ext_str); } +#undef UNIBI_OUT static void out(void *ctx, const char *str, size_t len) { -- cgit From e1628fab0062c96b5211213f3e990cfd6dc4c1d2 Mon Sep 17 00:00:00 2001 From: Leonardo Brondani Schenkel Date: Thu, 24 Aug 2017 12:48:32 +0200 Subject: tui: support new iterm2, iTerm2.app terminfo entries iTerm2 got its own entry in Thomas Dickey's terminfo.src on 2017-08-16. Make sure that the new entry is handled in the same way as the old entry. closes #7209 closes #7214 --- src/nvim/tui/terminfo.c | 4 +++- src/nvim/tui/tui.c | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index b8fffcb7d6..586fafba97 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -104,7 +104,9 @@ unibi_term *load_builtin_terminfo(const char * term) return unibi_from_mem((const char *)interix_8colour_terminfo, sizeof interix_8colour_terminfo); } else if (terminfo_is_term_family(term, "iterm") - || terminfo_is_term_family(term, "iTerm.app")) { + || terminfo_is_term_family(term, "iterm2") + || terminfo_is_term_family(term, "iTerm.app") + || terminfo_is_term_family(term, "iTerm2.app")) { return unibi_from_mem((const char *)iterm_256colour_terminfo, sizeof iterm_256colour_terminfo); } else if (terminfo_is_term_family(term, "st")) { diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index e3eab72695..dd93053dbf 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1263,7 +1263,9 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, bool gnome = terminfo_is_term_family(term, "gnome") || terminfo_is_term_family(term, "vte"); bool iterm = terminfo_is_term_family(term, "iterm") - || terminfo_is_term_family(term, "iTerm.app"); + || terminfo_is_term_family(term, "iterm2") + || terminfo_is_term_family(term, "iTerm.app") + || terminfo_is_term_family(term, "iTerm2.app"); // None of the following work over SSH; see :help TERM . bool iterm_pretending_xterm = xterm && iterm_env; bool konsole_pretending_xterm = xterm && konsole; @@ -1535,7 +1537,9 @@ static void augment_terminfo(TUIData *data, const char *term, bool screen = terminfo_is_term_family(term, "screen"); bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX"); bool iterm = terminfo_is_term_family(term, "iterm") - || terminfo_is_term_family(term, "iTerm.app"); + || terminfo_is_term_family(term, "iterm2") + || terminfo_is_term_family(term, "iTerm.app") + || terminfo_is_term_family(term, "iTerm2.app"); // None of the following work over SSH; see :help TERM . bool iterm_pretending_xterm = xterm && iterm_env; -- cgit From 0e13b15fde1cc02cd1bb390d161cdc13afb96e39 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Wed, 30 Aug 2017 19:54:14 +0800 Subject: vim-patch:8.0.0209 Problem: When using :substitute with the "c" flag and 'cursorbind' is set the cursor is not updated in other windows. Solution: Call do_check_cursorbind(). (Masanori Misono) https://github.com/vim/vim/commit/41baa7983aa81b0343b053e6a672cf8224a10245 --- src/nvim/ex_cmds.c | 4 ++++ src/nvim/version.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index a555fb77e8..32dbf4cc69 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3500,6 +3500,10 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout) setmouse(); /* disable mouse in xterm */ curwin->w_cursor.col = regmatch.startpos[0].col; + if (curwin->w_p_crb) { + do_check_cursorbind(); + } + /* When 'cpoptions' contains "u" don't sync undo when * asking for confirmation. */ if (vim_strchr(p_cpo, CPO_UNDO) != NULL) diff --git a/src/nvim/version.c b/src/nvim/version.c index 53b44f8029..d7ebc26321 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -743,7 +743,7 @@ static const int included_patches[] = { // 212, // 211 NA // 210, - // 209, + 209, 208, // 207, // 206, -- cgit From 11429f94293b95394df436cb09d64a528fa387db Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Sun, 3 Sep 2017 16:58:32 +0800 Subject: vim-patch:8.0.0247 (#7232) Problem: Under some circumstances, one needs to type Ctrl-N or Ctrl-P twice to have a menu entry selected. (Lifepillar) Solution: call ins_compl_free(). (Christian Brabandt, closes vim/vim#1411) https://github.com/vim/vim/commit/aed6d0b81a14a81433c0f3c2c65cef935100db33 --- src/nvim/edit.c | 1 + src/nvim/testdir/test_popup.vim | 37 +++++++++++++++++++++++++++++++++---- src/nvim/version.c | 2 +- 3 files changed, 35 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/edit.c b/src/nvim/edit.c index ca62679fab..17f0b8ef82 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2406,6 +2406,7 @@ void set_completion(colnr_T startcol, list_T *list) ins_compl_prep(' '); } ins_compl_clear(); + ins_compl_free(); compl_direction = FORWARD; if (startcol > curwin->w_cursor.col) diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 519d855cd8..e1ba142d1c 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -7,10 +7,10 @@ func! ListMonths() if g:setting != '' exe ":set" g:setting endif - let mth=copy(g:months) + let mth = copy(g:months) let entered = strcharpart(getline('.'),0,col('.')) if !empty(entered) - let mth=filter(mth, 'v:val=~"^".entered') + let mth = filter(mth, 'v:val=~"^".entered') endif call complete(1, mth) return '' @@ -468,7 +468,7 @@ endfunc " auto-wrap text. func Test_completion_ctrl_e_without_autowrap() new - let tw_save=&tw + let tw_save = &tw set tw=78 let li = [ \ '" zzz', @@ -478,7 +478,7 @@ func Test_completion_ctrl_e_without_autowrap() call feedkeys("A\\\\", "tx") call assert_equal(li, getline(1, '$')) - let &tw=tw_save + let &tw = tw_save q! endfunc @@ -541,4 +541,33 @@ func Test_completion_comment_formatting() bwipe! endfunc +function! DummyCompleteSix() + call complete(1, ['Hello', 'World']) + return '' +endfunction + +" complete() correctly clears the list of autocomplete candidates +func Test_completion_clear_candidate_list() + new + %d + " select first entry from the completion popup + call feedkeys("a xxx\\=DummyCompleteSix()\", "tx") + call assert_equal('Hello', getline(1)) + %d + " select second entry from the completion popup + call feedkeys("a xxx\\=DummyCompleteSix()\\", "tx") + call assert_equal('World', getline(1)) + %d + " select original text + call feedkeys("a xxx\\=DummyCompleteSix()\\\", "tx") + call assert_equal(' xxx', getline(1)) + %d + " back at first entry from completion list + call feedkeys("a xxx\\=DummyCompleteSix()\\\\", "tx") + call assert_equal('Hello', getline(1)) + + bw! +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/version.c b/src/nvim/version.c index d7ebc26321..73ac3fa6ce 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -705,7 +705,7 @@ static const int included_patches[] = { 250, // 249 NA // 248, - // 247, + 247, // 246 NA // 245, // 244, -- cgit From 69a201d6c5504ded687a0603c2a6e88531deb5dc Mon Sep 17 00:00:00 2001 From: Albert Han Date: Sun, 3 Sep 2017 09:23:09 -0400 Subject: vim-patch:8.0.0125 Problem: Not enough testing for entering Ex commands. Solution: Add test for CTRL-\ e {expr}. (Dominique Pelle) https://github.com/vim/vim/commit/eaaa9bbda6ec0a8589a9b23720f95bffe01dc267 --- src/nvim/testdir/test_cmdline.vim | 17 +++++++++++++++++ src/nvim/version.c | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index bab700284f..2facffb067 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -230,9 +230,26 @@ func Test_paste_in_cmdline() call feedkeys("f;:aaa \\ bbb\\"\", 'tx') call assert_equal('"aaa a;b-c*d bbb', @:) + + call feedkeys(":\etoupper(getline(1))\\\"\", 'tx') + call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:) bwipe! endfunc +func Test_remove_char_in_cmdline() + call feedkeys(":abc def\\\\"\", 'tx') + call assert_equal('"abc ef', @:) + + call feedkeys(":abc def\\\\"\", 'tx') + call assert_equal('"abcdef', @:) + + call feedkeys(":abc def ghi\\\\"\", 'tx') + call assert_equal('"abc ghi', @:) + + call feedkeys(":abc def\\\\"\", 'tx') + call assert_equal('"def', @:) +endfunc + func Test_illegal_address() new 2;'( diff --git a/src/nvim/version.c b/src/nvim/version.c index 73ac3fa6ce..6e24e30a09 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -827,7 +827,7 @@ static const int included_patches[] = { 128, 127, 126, - // 125, + 125, 124, // 123 NA // 122 NA -- cgit From 541dde36e3302314e2646415dbfd2b79a6c2a1fc Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Sat, 2 Sep 2017 14:12:32 +0100 Subject: eventloop: K_EVENT should not finish operator normal_finish_command() and normal_prepare() assume that any pending operator needs to be finished after any subsequent key. Set `finish_op = false` in nv_event() to indicate that the pending operator shouldn't be finished in normal_execute(). This is how nv_visual() indicates that 'v' or 'V' in operator-pending mode should not finish the current pending operator. fixes #5398 fixes #6166 (partially; mappings are still interrupted) --- src/nvim/normal.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 238378c474..f9017164af 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -7958,6 +7958,7 @@ static void nv_event(cmdarg_T *cap) may_garbage_collect = false; multiqueue_process_events(main_loop.events); cap->retval |= CA_COMMAND_BUSY; // don't call edit() now + finish_op = false; } /// Trigger FocusGained event. -- cgit From f050aaabbb31b58ebac519a6f7014610f2b119f0 Mon Sep 17 00:00:00 2001 From: "Vadim A. Misbakh-Soloviov" Date: Mon, 4 Sep 2017 23:48:05 +0700 Subject: tui: DECSCUSR workaround for Konsole (#7236) closes #7235 --- src/nvim/tui/tui.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index dd93053dbf..1cbd02dfd9 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1448,7 +1448,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // teminfo entries. See // https://github.com/gnachman/iTerm2/pull/92 for more. // xterm even has an extended version that has a vertical bar. - if (true_xterm // per xterm ctlseqs doco (since version 282) + if (!konsole && (true_xterm // per xterm ctlseqs doco (since version 282) // per MinTTY 0.4.3-1 release notes from 2009 || putty // per https://bugzilla.gnome.org/show_bug.cgi?id=720821 @@ -1463,7 +1463,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // Allows forcing the use of DECSCUSR on linux type terminals, such as // console-terminal-emulator from the nosh toolset, which does indeed // implement the xterm extension: - || (linuxvt && (xterm_version || (vte_version > 0) || colorterm))) { + || (linuxvt && (xterm_version || (vte_version > 0) || colorterm)))) { data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q"); if (-1 == data->unibi_ext.reset_cursor_style) { -- cgit From b6b6e4a96f37ba6a54d194ecbc042d5ef7d595e6 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 28 Aug 2017 01:27:57 +0200 Subject: eventloop: FocusGained: schedule event instead of pseudokey closes #4840 closes #6164 --- src/nvim/aucmd.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/nvim/aucmd.h | 9 +++++++++ src/nvim/edit.c | 11 +---------- src/nvim/ex_getln.c | 8 -------- src/nvim/keymap.c | 2 -- src/nvim/keymap.h | 2 -- src/nvim/normal.c | 14 -------------- src/nvim/state.c | 5 +++-- src/nvim/terminal.c | 8 -------- src/nvim/tui/input.c | 13 +++++-------- 10 files changed, 66 insertions(+), 54 deletions(-) create mode 100644 src/nvim/aucmd.c create mode 100644 src/nvim/aucmd.h (limited to 'src') diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c new file mode 100644 index 0000000000..8b86d89bf2 --- /dev/null +++ b/src/nvim/aucmd.c @@ -0,0 +1,48 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +#include "nvim/os/os.h" +#include "nvim/fileio.h" +#include "nvim/vim.h" +#include "nvim/main.h" +#include "nvim/screen.h" +#include "nvim/ui.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "aucmd.c.generated.h" +#endif + +static void focusgained_event(void **argv) +{ + bool *gained = argv[0]; + do_autocmd_focusgained(*gained); + xfree(gained); +} +void aucmd_schedule_focusgained(bool gained) +{ + bool *gainedp = xmalloc(sizeof(*gainedp)); + *gainedp = gained; + loop_schedule(&main_loop, event_create(focusgained_event, 1, gainedp)); +} + +static void do_autocmd_focusgained(bool gained) + FUNC_ATTR_NONNULL_ALL +{ + static bool recursive = false; + + if (recursive) { + return; // disallow recursion + } + recursive = true; + bool has_any = has_event(EVENT_FOCUSGAINED) || has_event(EVENT_FOCUSLOST); + bool did_any = apply_autocmds((gained ? EVENT_FOCUSGAINED : EVENT_FOCUSLOST), + NULL, NULL, false, curbuf); + if (has_any && !did_any) { + // HACK: Reschedule, hoping that the next event-loop tick will pick this up + // during a "regular" state (as opposed to a weird implicit state, e.g. + // early_init()..win_alloc_first() which disables autocommands). + aucmd_schedule_focusgained(gained); + } + recursive = false; +} + diff --git a/src/nvim/aucmd.h b/src/nvim/aucmd.h new file mode 100644 index 0000000000..6570ba7a92 --- /dev/null +++ b/src/nvim/aucmd.h @@ -0,0 +1,9 @@ +#ifndef NVIM_AUCMD_H +#define NVIM_AUCMD_H + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "aucmd.h.generated.h" +#endif + +#endif // NVIM_AUCMD_H + diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 17f0b8ef82..2bafb77fef 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -974,14 +974,6 @@ static int insert_handle_key(InsertState *s) multiqueue_process_events(main_loop.events); break; - case K_FOCUSGAINED: // Neovim has been given focus - apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf); - break; - - case K_FOCUSLOST: // Neovim has lost focus - apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf); - break; - case K_HOME: // case K_KHOME: case K_S_HOME: @@ -3167,8 +3159,7 @@ static bool ins_compl_prep(int c) /* Ignore end of Select mode mapping and mouse scroll buttons. */ if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP - || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT - || c == K_FOCUSGAINED || c == K_FOCUSLOST) { + || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT) { return retval; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 5e216925df..fd7ad7a4b5 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1620,14 +1620,6 @@ static int command_line_handle_key(CommandLineState *s) } return command_line_not_changed(s); - case K_FOCUSGAINED: // Neovim has been given focus - apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf); - return command_line_not_changed(s); - - case K_FOCUSLOST: // Neovim has lost focus - apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf); - return command_line_not_changed(s); - default: // Normal character with no special meaning. Just set mod_mask // to 0x0 so that typing Shift-Space in the GUI doesn't enter diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 3d7ebb6382..cfe038693a 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -286,8 +286,6 @@ static struct key_name_entry { {K_SNR, (char_u *)"SNR"}, {K_PLUG, (char_u *)"Plug"}, {K_PASTE, (char_u *)"Paste"}, - {K_FOCUSGAINED, (char_u *)"FocusGained"}, - {K_FOCUSLOST, (char_u *)"FocusLost"}, {0, NULL} }; diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h index b8fed77a90..ee64854c98 100644 --- a/src/nvim/keymap.h +++ b/src/nvim/keymap.h @@ -428,8 +428,6 @@ enum key_extra { #define K_CMDWIN TERMCAP2KEY(KS_EXTRA, KE_CMDWIN) #define K_DROP TERMCAP2KEY(KS_EXTRA, KE_DROP) -#define K_FOCUSGAINED TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED) -#define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST) #define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT) #define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE) diff --git a/src/nvim/normal.c b/src/nvim/normal.c index f9017164af..6415bec846 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -345,8 +345,6 @@ static const struct nv_cmd { { K_F8, farsi_f8, 0, 0 }, { K_F9, farsi_f9, 0, 0 }, { K_EVENT, nv_event, NV_KEEPREG, 0 }, - { K_FOCUSGAINED, nv_focusgained, NV_KEEPREG, 0 }, - { K_FOCUSLOST, nv_focuslost, NV_KEEPREG, 0 }, }; /* Number of commands in nv_cmds[]. */ @@ -7961,18 +7959,6 @@ static void nv_event(cmdarg_T *cap) finish_op = false; } -/// Trigger FocusGained event. -static void nv_focusgained(cmdarg_T *cap) -{ - apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf); -} - -/// Trigger FocusLost event. -static void nv_focuslost(cmdarg_T *cap) -{ - apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf); -} - /* * Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos". */ diff --git a/src/nvim/state.c b/src/nvim/state.c index eb0b590a9b..24248ec66c 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -26,10 +26,11 @@ void state_enter(VimState *s) int check_result = s->check ? s->check(s) : 1; if (!check_result) { - break; + break; // Terminate this state. } else if (check_result == -1) { - continue; + continue; // check() again. } + // Execute this state. int key; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index deec930ebd..1c764d302d 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -432,14 +432,6 @@ static int terminal_execute(VimState *state, int key) TerminalState *s = (TerminalState *)state; switch (key) { - case K_FOCUSGAINED: // nvim has been given focus - apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf); - break; - - case K_FOCUSLOST: // nvim has lost focus - apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf); - break; - // Temporary fix until paste events gets implemented case K_PASTE: break; diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 03587d68f0..8bb5971bd4 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -8,6 +8,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" #include "nvim/main.h" +#include "nvim/aucmd.h" #include "nvim/os/os.h" #include "nvim/os/input.h" #include "nvim/event/rstream.h" @@ -280,9 +281,9 @@ static void timer_cb(TimeWatcher *watcher, void *data) /// Handle focus events. /// -/// If the upcoming sequence of bytes in the input stream matches either the -/// escape code for focus gained `[I` or focus lost `[O` then consume -/// that sequence and push the appropriate event into the input queue +/// If the upcoming sequence of bytes in the input stream matches the termcode +/// for "focus gained" or "focus lost", consume that sequence and schedule an +/// event on the main loop. /// /// @param input the input stream /// @return true iff handle_focus_event consumed some input @@ -294,11 +295,7 @@ static bool handle_focus_event(TermInput *input) // Advance past the sequence bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I'; rbuffer_consumed(input->read_stream.buffer, 3); - if (focus_gained) { - enqueue_input(input, FOCUSGAINED_KEY, sizeof(FOCUSGAINED_KEY) - 1); - } else { - enqueue_input(input, FOCUSLOST_KEY, sizeof(FOCUSLOST_KEY) - 1); - } + aucmd_schedule_focusgained(focus_gained); return true; } return false; -- cgit From 46fdacc5b5abb05d49c0f16fe5ffc4ceb7795dee Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 31 Aug 2017 23:20:30 +0200 Subject: doc: eventloop --- src/nvim/event/loop.c | 8 +++++++- src/nvim/event/loop.h | 22 ++++++++++++++++++++-- src/nvim/state.c | 8 +++++--- 3 files changed, 32 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 25701a1621..cc9088f776 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -59,7 +59,13 @@ void loop_poll_events(Loop *loop, int ms) multiqueue_process_events(loop->fast_events); } -// Schedule an event from another thread +/// Schedules an event from another thread. +/// +/// @note Event is queued into `fast_events`, which is processed outside of the +/// primary `events` queue by loop_poll_events(). For `main_loop`, that +/// means `fast_events` is NOT processed in an "editor mode" +/// (VimState.execute), so redraw and other side-effects are likely to be +/// skipped. void loop_schedule(Loop *loop, Event event) { uv_mutex_lock(&loop->mutex); diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index e7d7bdd483..b0ddc59469 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -16,10 +16,28 @@ KLIST_INIT(WatcherPtr, WatcherPtr, _noop) typedef struct loop { uv_loop_t uv; - MultiQueue *events, *fast_events, *thread_events; + MultiQueue *events; + MultiQueue *thread_events; + // Immediate events: + // "Events that should be processed after exiting uv_run() (to avoid + // recursion), but before returning from loop_poll_events()." + // 502aee690c980fcb3cfcb3f211dcfad06103db46 + // Practical consequence: these events are processed by + // state_enter()..os_inchar() + // whereas "regular" (main_loop.events) events are processed by + // state_enter()..VimState.execute() + // But state_enter()..os_inchar() can be "too early" if you want the event + // to trigger UI updates and other user-activity-related side-effects. + MultiQueue *fast_events; + + // used by process/job-control subsystem klist_t(WatcherPtr) *children; uv_signal_t children_watcher; - uv_timer_t children_kill_timer, poll_timer; + uv_timer_t children_kill_timer; + + // generic timer, used by loop_poll_events() + uv_timer_t poll_timer; + size_t children_stop_requests; uv_async_t async; uv_mutex_t mutex; diff --git a/src/nvim/state.c b/src/nvim/state.c index 24248ec66c..4d9032b7a5 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -49,11 +49,13 @@ getkey: ui_flush(); // Call `os_inchar` directly to block for events or user input without // consuming anything from `input_buffer`(os/input.c) or calling the - // mapping engine. If an event was put into the queue, we send K_EVENT - // directly. + // mapping engine. (void)os_inchar(NULL, 0, -1, 0); input_disable_events(); - key = !multiqueue_empty(main_loop.events) ? K_EVENT : safe_vgetc(); + // If an event was put into the queue, we send K_EVENT directly. + key = !multiqueue_empty(main_loop.events) + ? K_EVENT + : safe_vgetc(); } if (key == K_EVENT) { -- cgit From d30abd8857a41f439de01f8c0e6d1075acf124d9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 2 Sep 2017 11:35:14 +0200 Subject: eventloop: FocusGained: schedule the schedule main_loop.fast_events does not manifest as K_EVENT, because it is processed at a different stage than main_loop.events. In order to queue into main_loop.events, we need to go through the threadsafe loop_schedule(), which queues into main_loop.thread_events and eventually main_loop.fast_events. _Then_ it is safe to directly queue into main_loop.events. This makes it more likely that the event is treated as K_EVENT. --- src/nvim/aucmd.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c index 8b86d89bf2..a69881431e 100644 --- a/src/nvim/aucmd.c +++ b/src/nvim/aucmd.c @@ -14,15 +14,20 @@ static void focusgained_event(void **argv) { - bool *gained = argv[0]; - do_autocmd_focusgained(*gained); - xfree(gained); + bool *gainedp = argv[0]; + do_autocmd_focusgained(*gainedp); + xfree(gainedp); +} +static void schedule_event(void **argv) +{ + bool *gainedp = argv[0]; + multiqueue_put(main_loop.events, focusgained_event, 1, gainedp); } void aucmd_schedule_focusgained(bool gained) { bool *gainedp = xmalloc(sizeof(*gainedp)); *gainedp = gained; - loop_schedule(&main_loop, event_create(focusgained_event, 1, gainedp)); + loop_schedule(&main_loop, event_create(schedule_event, 1, gainedp)); } static void do_autocmd_focusgained(bool gained) @@ -34,15 +39,8 @@ static void do_autocmd_focusgained(bool gained) return; // disallow recursion } recursive = true; - bool has_any = has_event(EVENT_FOCUSGAINED) || has_event(EVENT_FOCUSLOST); - bool did_any = apply_autocmds((gained ? EVENT_FOCUSGAINED : EVENT_FOCUSLOST), - NULL, NULL, false, curbuf); - if (has_any && !did_any) { - // HACK: Reschedule, hoping that the next event-loop tick will pick this up - // during a "regular" state (as opposed to a weird implicit state, e.g. - // early_init()..win_alloc_first() which disables autocommands). - aucmd_schedule_focusgained(gained); - } + apply_autocmds((gained ? EVENT_FOCUSGAINED : EVENT_FOCUSLOST), + NULL, NULL, false, curbuf); recursive = false; } -- cgit From d47b538f39e3e9700a18f1cd72e561086f62d7f3 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 2 Sep 2017 11:35:44 +0200 Subject: eventloop: do not redraw in cmdline K_EVENT handler If :echo is done by an timer or event (such as FocusGained/FocusLost), redrawcmdline() clobbers it. --- src/nvim/ex_getln.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index fd7ad7a4b5..9bfa9e22df 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -441,8 +441,7 @@ static int command_line_execute(VimState *state, int key) if (s->c == K_EVENT) { multiqueue_process_events(main_loop.events); - redrawcmdline(); - return 1; + return command_line_not_changed(s); } if (KeyTyped) { -- cgit From 6c53c3ee55991d9b1ea61a8dc443038b478ca92a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 2 Sep 2017 11:35:48 +0200 Subject: eventloop: restore redraw in cmdline K_EVENT handler Restores behavior from commit: 02e86ef04cc1 --- src/nvim/ex_getln.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 9bfa9e22df..fd7ad7a4b5 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -441,7 +441,8 @@ static int command_line_execute(VimState *state, int key) if (s->c == K_EVENT) { multiqueue_process_events(main_loop.events); - return command_line_not_changed(s); + redrawcmdline(); + return 1; } if (KeyTyped) { -- cgit From 63c64705058e96368cbc1dcc3fc4f97fc51c73fe Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 2 Sep 2017 11:35:53 +0200 Subject: log: introduce `context` --- src/nvim/log.c | 40 ++++++++++++++++++++++++++-------------- src/nvim/log.h | 18 +++++++++--------- src/nvim/ui.c | 4 ++-- 3 files changed, 37 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/nvim/log.c b/src/nvim/log.c index 436a8a4079..a8451f7bc4 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -95,8 +95,12 @@ void log_unlock(void) uv_mutex_unlock(&mutex); } -bool do_log(int log_level, const char *func_name, int line_num, bool eol, - const char* fmt, ...) FUNC_ATTR_UNUSED +/// @param context description of a shared context or subsystem +/// @param func_name function name, or NULL +/// @param line_num source line number, or -1 +bool do_log(int log_level, const char *context, const char *func_name, + int line_num, bool eol, const char* fmt, ...) + FUNC_ATTR_UNUSED { if (log_level < MIN_LOG_LEVEL) { return false; @@ -112,8 +116,8 @@ bool do_log(int log_level, const char *func_name, int line_num, bool eol, va_list args; va_start(args, fmt); - ret = v_do_log_to_file(log_file, log_level, func_name, line_num, eol, - fmt, args); + ret = v_do_log_to_file(log_file, log_level, context, func_name, line_num, + eol, fmt, args); va_end(args); if (log_file != stderr && log_file != stdout) { @@ -151,7 +155,7 @@ FILE *open_log_file(void) static bool opening_log_file = false; // check if it's a recursive call if (opening_log_file) { - do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, true, + do_log_to_file(stderr, ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true, "Cannot LOG() recursively."); return stderr; } @@ -171,7 +175,7 @@ FILE *open_log_file(void) // - LOG() is called before early_init() // - Directory does not exist // - File is not writable - do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, true, + do_log_to_file(stderr, ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true, "Logging to stderr, failed to open $" LOG_FILE_ENV ": %s", log_file_path); return stderr; @@ -201,7 +205,7 @@ void log_callstack_to_file(FILE *log_file, const char *const func_name, // Now we have a command string like: // addr2line -e /path/to/exe -f -p 0x123 0x456 ... - do_log_to_file(log_file, DEBUG_LOG_LEVEL, func_name, line_num, true, + do_log_to_file(log_file, DEBUG_LOG_LEVEL, NULL, func_name, line_num, true, "trace:"); FILE *fp = popen(cmdbuf, "r"); char linebuf[IOSIZE]; @@ -230,22 +234,23 @@ end: } #endif -static bool do_log_to_file(FILE *log_file, int log_level, +static bool do_log_to_file(FILE *log_file, int log_level, const char *context, const char *func_name, int line_num, bool eol, const char* fmt, ...) { va_list args; va_start(args, fmt); - bool ret = v_do_log_to_file(log_file, log_level, func_name, line_num, eol, - fmt, args); + bool ret = v_do_log_to_file(log_file, log_level, context, func_name, + line_num, eol, fmt, args); va_end(args); return ret; } static bool v_do_log_to_file(FILE *log_file, int log_level, - const char *func_name, int line_num, bool eol, - const char* fmt, va_list args) + const char *context, const char *func_name, + int line_num, bool eol, const char* fmt, + va_list args) { static const char *log_levels[] = { [DEBUG_LOG_LEVEL] = "DEBUG", @@ -268,8 +273,15 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, // print the log message prefixed by the current timestamp and pid int64_t pid = os_get_pid(); - if (fprintf(log_file, "%s %s %" PRId64 "/%s:%d: ", date_time, - log_levels[log_level], pid, func_name, line_num) < 0) { + int rv = (line_num == -1 || func_name == NULL) + ? fprintf(log_file, "%s %s %" PRId64 " %s", date_time, + log_levels[log_level], pid, + (context == NULL ? "?:" : context)) + : fprintf(log_file, "%s %s %" PRId64 " %s%s:%d: ", date_time, + log_levels[log_level], pid, + (context == NULL ? "" : context), + func_name, line_num); + if (rv < 0) { return false; } if (vfprintf(log_file, fmt, args) < 0) { diff --git a/src/nvim/log.h b/src/nvim/log.h index d63bcc366c..f378b92039 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -22,42 +22,42 @@ # define MIN_LOG_LEVEL INFO_LOG_LEVEL #endif -#define LOG(level, ...) do_log((level), __func__, __LINE__, true, \ +#define LOG(level, ...) do_log((level), NULL, __func__, __LINE__, true, \ __VA_ARGS__) #if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL # undef DLOG # undef DLOGN -# define DLOG(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, true, \ +# define DLOG(...) do_log(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, true, \ __VA_ARGS__) -# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, false, \ +# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, false, \ __VA_ARGS__) #endif #if MIN_LOG_LEVEL <= INFO_LOG_LEVEL # undef ILOG # undef ILOGN -# define ILOG(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, true, \ +# define ILOG(...) do_log(INFO_LOG_LEVEL, NULL, __func__, __LINE__, true, \ __VA_ARGS__) -# define ILOGN(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, false, \ +# define ILOGN(...) do_log(INFO_LOG_LEVEL, NULL, __func__, __LINE__, false, \ __VA_ARGS__) #endif #if MIN_LOG_LEVEL <= WARN_LOG_LEVEL # undef WLOG # undef WLOGN -# define WLOG(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, true, \ +# define WLOG(...) do_log(WARN_LOG_LEVEL, NULL, __func__, __LINE__, true, \ __VA_ARGS__) -# define WLOGN(...) do_log(WARN_LOG_LEVEL, __func__, __LINE__, false, \ +# define WLOGN(...) do_log(WARN_LOG_LEVEL, NULL, __func__, __LINE__, false, \ __VA_ARGS__) #endif #if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL # undef ELOG # undef ELOGN -# define ELOG(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, true, \ +# define ELOG(...) do_log(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true, \ __VA_ARGS__) -# define ELOGN(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, false, \ +# define ELOGN(...) do_log(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, false, \ __VA_ARGS__) #endif diff --git a/src/nvim/ui.c b/src/nvim/ui.c index b85a01814d..01d3604159 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -71,10 +71,10 @@ static char uilog_last_event[1024] = { 0 }; uilog_seen++; \ } else { \ if (uilog_seen > 0) { \ - do_log(DEBUG_LOG_LEVEL, "ui", 0, true, \ + do_log(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, \ "%s (+%zu times...)", uilog_last_event, uilog_seen); \ } \ - DLOG("ui: " STR(funname)); \ + do_log(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, STR(funname)); \ uilog_seen = 0; \ xstrlcpy(uilog_last_event, STR(funname), sizeof(uilog_last_event)); \ } \ -- cgit From 8716994cf07e9c9dab4af31a0acf47c858a1b789 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 2 Sep 2017 17:04:42 +0200 Subject: lint --- src/nvim/keymap.c | 292 +++++++++++++++++++++++++++--------------------------- src/nvim/log.c | 4 +- 2 files changed, 148 insertions(+), 148 deletions(-) (limited to 'src') diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index cfe038693a..a75fe793ac 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -140,153 +140,153 @@ static char_u modifier_keys_table[] = }; static struct key_name_entry { - int key; /* Special key code or ascii value */ - char_u *name; /* Name of key */ + int key; // Special key code or ascii value + char *name; // Name of key } key_names_table[] = { - {' ', (char_u *)"Space"}, - {TAB, (char_u *)"Tab"}, - {K_TAB, (char_u *)"Tab"}, - {NL, (char_u *)"NL"}, - {NL, (char_u *)"NewLine"}, /* Alternative name */ - {NL, (char_u *)"LineFeed"}, /* Alternative name */ - {NL, (char_u *)"LF"}, /* Alternative name */ - {CAR, (char_u *)"CR"}, - {CAR, (char_u *)"Return"}, /* Alternative name */ - {CAR, (char_u *)"Enter"}, /* Alternative name */ - {K_BS, (char_u *)"BS"}, - {K_BS, (char_u *)"BackSpace"}, /* Alternative name */ - {ESC, (char_u *)"Esc"}, - {CSI, (char_u *)"CSI"}, - {K_CSI, (char_u *)"xCSI"}, - {'|', (char_u *)"Bar"}, - {'\\', (char_u *)"Bslash"}, - {K_DEL, (char_u *)"Del"}, - {K_DEL, (char_u *)"Delete"}, /* Alternative name */ - {K_KDEL, (char_u *)"kDel"}, - {K_UP, (char_u *)"Up"}, - {K_DOWN, (char_u *)"Down"}, - {K_LEFT, (char_u *)"Left"}, - {K_RIGHT, (char_u *)"Right"}, - {K_XUP, (char_u *)"xUp"}, - {K_XDOWN, (char_u *)"xDown"}, - {K_XLEFT, (char_u *)"xLeft"}, - {K_XRIGHT, (char_u *)"xRight"}, - - {K_F1, (char_u *)"F1"}, - {K_F2, (char_u *)"F2"}, - {K_F3, (char_u *)"F3"}, - {K_F4, (char_u *)"F4"}, - {K_F5, (char_u *)"F5"}, - {K_F6, (char_u *)"F6"}, - {K_F7, (char_u *)"F7"}, - {K_F8, (char_u *)"F8"}, - {K_F9, (char_u *)"F9"}, - {K_F10, (char_u *)"F10"}, - - {K_F11, (char_u *)"F11"}, - {K_F12, (char_u *)"F12"}, - {K_F13, (char_u *)"F13"}, - {K_F14, (char_u *)"F14"}, - {K_F15, (char_u *)"F15"}, - {K_F16, (char_u *)"F16"}, - {K_F17, (char_u *)"F17"}, - {K_F18, (char_u *)"F18"}, - {K_F19, (char_u *)"F19"}, - {K_F20, (char_u *)"F20"}, - - {K_F21, (char_u *)"F21"}, - {K_F22, (char_u *)"F22"}, - {K_F23, (char_u *)"F23"}, - {K_F24, (char_u *)"F24"}, - {K_F25, (char_u *)"F25"}, - {K_F26, (char_u *)"F26"}, - {K_F27, (char_u *)"F27"}, - {K_F28, (char_u *)"F28"}, - {K_F29, (char_u *)"F29"}, - {K_F30, (char_u *)"F30"}, - - {K_F31, (char_u *)"F31"}, - {K_F32, (char_u *)"F32"}, - {K_F33, (char_u *)"F33"}, - {K_F34, (char_u *)"F34"}, - {K_F35, (char_u *)"F35"}, - {K_F36, (char_u *)"F36"}, - {K_F37, (char_u *)"F37"}, - - {K_XF1, (char_u *)"xF1"}, - {K_XF2, (char_u *)"xF2"}, - {K_XF3, (char_u *)"xF3"}, - {K_XF4, (char_u *)"xF4"}, - - {K_HELP, (char_u *)"Help"}, - {K_UNDO, (char_u *)"Undo"}, - {K_INS, (char_u *)"Insert"}, - {K_INS, (char_u *)"Ins"}, /* Alternative name */ - {K_KINS, (char_u *)"kInsert"}, - {K_HOME, (char_u *)"Home"}, - {K_KHOME, (char_u *)"kHome"}, - {K_XHOME, (char_u *)"xHome"}, - {K_ZHOME, (char_u *)"zHome"}, - {K_END, (char_u *)"End"}, - {K_KEND, (char_u *)"kEnd"}, - {K_XEND, (char_u *)"xEnd"}, - {K_ZEND, (char_u *)"zEnd"}, - {K_PAGEUP, (char_u *)"PageUp"}, - {K_PAGEDOWN, (char_u *)"PageDown"}, - {K_KPAGEUP, (char_u *)"kPageUp"}, - {K_KPAGEDOWN, (char_u *)"kPageDown"}, - - {K_KPLUS, (char_u *)"kPlus"}, - {K_KMINUS, (char_u *)"kMinus"}, - {K_KDIVIDE, (char_u *)"kDivide"}, - {K_KMULTIPLY, (char_u *)"kMultiply"}, - {K_KENTER, (char_u *)"kEnter"}, - {K_KPOINT, (char_u *)"kPoint"}, - - {K_K0, (char_u *)"k0"}, - {K_K1, (char_u *)"k1"}, - {K_K2, (char_u *)"k2"}, - {K_K3, (char_u *)"k3"}, - {K_K4, (char_u *)"k4"}, - {K_K5, (char_u *)"k5"}, - {K_K6, (char_u *)"k6"}, - {K_K7, (char_u *)"k7"}, - {K_K8, (char_u *)"k8"}, - {K_K9, (char_u *)"k9"}, - - {'<', (char_u *)"lt"}, - - {K_MOUSE, (char_u *)"Mouse"}, - {K_LEFTMOUSE, (char_u *)"LeftMouse"}, - {K_LEFTMOUSE_NM, (char_u *)"LeftMouseNM"}, - {K_LEFTDRAG, (char_u *)"LeftDrag"}, - {K_LEFTRELEASE, (char_u *)"LeftRelease"}, - {K_LEFTRELEASE_NM, (char_u *)"LeftReleaseNM"}, - {K_MIDDLEMOUSE, (char_u *)"MiddleMouse"}, - {K_MIDDLEDRAG, (char_u *)"MiddleDrag"}, - {K_MIDDLERELEASE, (char_u *)"MiddleRelease"}, - {K_RIGHTMOUSE, (char_u *)"RightMouse"}, - {K_RIGHTDRAG, (char_u *)"RightDrag"}, - {K_RIGHTRELEASE, (char_u *)"RightRelease"}, - {K_MOUSEDOWN, (char_u *)"ScrollWheelUp"}, - {K_MOUSEUP, (char_u *)"ScrollWheelDown"}, - {K_MOUSELEFT, (char_u *)"ScrollWheelRight"}, - {K_MOUSERIGHT, (char_u *)"ScrollWheelLeft"}, - {K_MOUSEDOWN, (char_u *)"MouseDown"}, /* OBSOLETE: Use */ - {K_MOUSEUP, (char_u *)"MouseUp"}, /* ScrollWheelXXX instead */ - {K_X1MOUSE, (char_u *)"X1Mouse"}, - {K_X1DRAG, (char_u *)"X1Drag"}, - {K_X1RELEASE, (char_u *)"X1Release"}, - {K_X2MOUSE, (char_u *)"X2Mouse"}, - {K_X2DRAG, (char_u *)"X2Drag"}, - {K_X2RELEASE, (char_u *)"X2Release"}, - {K_DROP, (char_u *)"Drop"}, - {K_ZERO, (char_u *)"Nul"}, - {K_SNR, (char_u *)"SNR"}, - {K_PLUG, (char_u *)"Plug"}, - {K_PASTE, (char_u *)"Paste"}, - {0, NULL} + { ' ', "Space" }, + { TAB, "Tab" }, + { K_TAB, "Tab" }, + { NL, "NL" }, + { NL, "NewLine" }, // Alternative name + { NL, "LineFeed" }, // Alternative name + { NL, "LF" }, // Alternative name + { CAR, "CR" }, + { CAR, "Return" }, // Alternative name + { CAR, "Enter" }, // Alternative name + { K_BS, "BS" }, + { K_BS, "BackSpace" }, // Alternative name + { ESC, "Esc" }, + { CSI, "CSI" }, + { K_CSI, "xCSI" }, + { '|', "Bar" }, + { '\\', "Bslash" }, + { K_DEL, "Del" }, + { K_DEL, "Delete" }, // Alternative name + { K_KDEL, "kDel" }, + { K_UP, "Up" }, + { K_DOWN, "Down" }, + { K_LEFT, "Left" }, + { K_RIGHT, "Right" }, + { K_XUP, "xUp" }, + { K_XDOWN, "xDown" }, + { K_XLEFT, "xLeft" }, + { K_XRIGHT, "xRight" }, + + { K_F1, "F1" }, + { K_F2, "F2" }, + { K_F3, "F3" }, + { K_F4, "F4" }, + { K_F5, "F5" }, + { K_F6, "F6" }, + { K_F7, "F7" }, + { K_F8, "F8" }, + { K_F9, "F9" }, + { K_F10, "F10" }, + + { K_F11, "F11" }, + { K_F12, "F12" }, + { K_F13, "F13" }, + { K_F14, "F14" }, + { K_F15, "F15" }, + { K_F16, "F16" }, + { K_F17, "F17" }, + { K_F18, "F18" }, + { K_F19, "F19" }, + { K_F20, "F20" }, + + { K_F21, "F21" }, + { K_F22, "F22" }, + { K_F23, "F23" }, + { K_F24, "F24" }, + { K_F25, "F25" }, + { K_F26, "F26" }, + { K_F27, "F27" }, + { K_F28, "F28" }, + { K_F29, "F29" }, + { K_F30, "F30" }, + + { K_F31, "F31" }, + { K_F32, "F32" }, + { K_F33, "F33" }, + { K_F34, "F34" }, + { K_F35, "F35" }, + { K_F36, "F36" }, + { K_F37, "F37" }, + + { K_XF1, "xF1" }, + { K_XF2, "xF2" }, + { K_XF3, "xF3" }, + { K_XF4, "xF4" }, + + { K_HELP, "Help" }, + { K_UNDO, "Undo" }, + { K_INS, "Insert" }, + { K_INS, "Ins" }, // Alternative name + { K_KINS, "kInsert" }, + { K_HOME, "Home" }, + { K_KHOME, "kHome" }, + { K_XHOME, "xHome" }, + { K_ZHOME, "zHome" }, + { K_END, "End" }, + { K_KEND, "kEnd" }, + { K_XEND, "xEnd" }, + { K_ZEND, "zEnd" }, + { K_PAGEUP, "PageUp" }, + { K_PAGEDOWN, "PageDown" }, + { K_KPAGEUP, "kPageUp" }, + { K_KPAGEDOWN, "kPageDown" }, + + { K_KPLUS, "kPlus" }, + { K_KMINUS, "kMinus" }, + { K_KDIVIDE, "kDivide" }, + { K_KMULTIPLY, "kMultiply" }, + { K_KENTER, "kEnter" }, + { K_KPOINT, "kPoint" }, + + { K_K0, "k0" }, + { K_K1, "k1" }, + { K_K2, "k2" }, + { K_K3, "k3" }, + { K_K4, "k4" }, + { K_K5, "k5" }, + { K_K6, "k6" }, + { K_K7, "k7" }, + { K_K8, "k8" }, + { K_K9, "k9" }, + + { '<', "lt" }, + + { K_MOUSE, "Mouse" }, + { K_LEFTMOUSE, "LeftMouse" }, + { K_LEFTMOUSE_NM, "LeftMouseNM" }, + { K_LEFTDRAG, "LeftDrag" }, + { K_LEFTRELEASE, "LeftRelease" }, + { K_LEFTRELEASE_NM, "LeftReleaseNM" }, + { K_MIDDLEMOUSE, "MiddleMouse" }, + { K_MIDDLEDRAG, "MiddleDrag" }, + { K_MIDDLERELEASE, "MiddleRelease" }, + { K_RIGHTMOUSE, "RightMouse" }, + { K_RIGHTDRAG, "RightDrag" }, + { K_RIGHTRELEASE, "RightRelease" }, + { K_MOUSEDOWN, "ScrollWheelUp" }, + { K_MOUSEUP, "ScrollWheelDown" }, + { K_MOUSELEFT, "ScrollWheelRight" }, + { K_MOUSERIGHT, "ScrollWheelLeft" }, + { K_MOUSEDOWN, "MouseDown" }, // OBSOLETE: Use + { K_MOUSEUP, "MouseUp" }, // ScrollWheelXXX instead + { K_X1MOUSE, "X1Mouse" }, + { K_X1DRAG, "X1Drag" }, + { K_X1RELEASE, "X1Release" }, + { K_X2MOUSE, "X2Mouse" }, + { K_X2DRAG, "X2Drag" }, + { K_X2RELEASE, "X2Release" }, + { K_DROP, "Drop" }, + { K_ZERO, "Nul" }, + { K_SNR, "SNR" }, + { K_PLUG, "Plug" }, + { K_PASTE, "Paste" }, + { 0, NULL } }; static struct mousetable { @@ -719,7 +719,7 @@ int find_special_key_in_table(int c) */ int get_special_key_code(const char_u *name) { - char_u *table_name; + char *table_name; int i, j; for (i = 0; key_names_table[i].name != NULL; i++) { diff --git a/src/nvim/log.c b/src/nvim/log.c index a8451f7bc4..7bfe5c4089 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -99,7 +99,7 @@ void log_unlock(void) /// @param func_name function name, or NULL /// @param line_num source line number, or -1 bool do_log(int log_level, const char *context, const char *func_name, - int line_num, bool eol, const char* fmt, ...) + int line_num, bool eol, const char *fmt, ...) FUNC_ATTR_UNUSED { if (log_level < MIN_LOG_LEVEL) { @@ -249,7 +249,7 @@ static bool do_log_to_file(FILE *log_file, int log_level, const char *context, static bool v_do_log_to_file(FILE *log_file, int log_level, const char *context, const char *func_name, - int line_num, bool eol, const char* fmt, + int line_num, bool eol, const char *fmt, va_list args) { static const char *log_levels[] = { -- cgit From c00a33ed19c1372bf5880e2f32adf37c9bea165b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 3 Sep 2017 14:31:38 +0200 Subject: eventloop: loop_schedule_deferred() Generalize the "schedule schedule" technique. --- src/nvim/aucmd.c | 9 ++------- src/nvim/event/loop.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c index a69881431e..fc421116ea 100644 --- a/src/nvim/aucmd.c +++ b/src/nvim/aucmd.c @@ -5,7 +5,6 @@ #include "nvim/fileio.h" #include "nvim/vim.h" #include "nvim/main.h" -#include "nvim/screen.h" #include "nvim/ui.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -18,16 +17,12 @@ static void focusgained_event(void **argv) do_autocmd_focusgained(*gainedp); xfree(gainedp); } -static void schedule_event(void **argv) -{ - bool *gainedp = argv[0]; - multiqueue_put(main_loop.events, focusgained_event, 1, gainedp); -} void aucmd_schedule_focusgained(bool gained) { bool *gainedp = xmalloc(sizeof(*gainedp)); *gainedp = gained; - loop_schedule(&main_loop, event_create(schedule_event, 1, gainedp)); + loop_schedule_deferred(&main_loop, + event_create(focusgained_event, 1, gainedp)); } static void do_autocmd_focusgained(bool gained) diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index cc9088f776..570db6dfc3 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -74,6 +74,24 @@ void loop_schedule(Loop *loop, Event event) uv_mutex_unlock(&loop->mutex); } +/// Schedules an event from another thread. Unlike loop_schedule(), the event +/// is forwarded to `Loop.events`, instead of being processed immediately. +/// +/// @see loop_schedule +void loop_schedule_deferred(Loop *loop, Event event) +{ + Event *eventp = xmalloc(sizeof(*eventp)); + *eventp = event; + loop_schedule(loop, event_create(loop_deferred_event, 2, loop, eventp)); +} +static void loop_deferred_event(void **argv) +{ + Loop *loop = argv[0]; + Event *eventp = argv[1]; + multiqueue_put_event(loop->events, *eventp); + xfree(eventp); +} + void loop_on_put(MultiQueue *queue, void *data) { Loop *loop = data; -- cgit From cdd9e868efdad1f1eb9febfabb5f8671e75b95b9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 2 Sep 2017 19:51:49 +0200 Subject: doc: channel, eventloop --- src/nvim/api/ui.c | 1 + src/nvim/api/vim.c | 28 ++++++++-------------------- src/nvim/event/loop.c | 1 + src/nvim/msgpack_rpc/channel.c | 10 ++++------ 4 files changed, 14 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 573be23d8e..bbbd5ab2dc 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -215,6 +215,7 @@ static void ui_set_option(UI *ui, String name, Object value, Error *error) #undef UI_EXT_OPTION } +/// Pushes data into UI.UIData, to be consumed later by remote_ui_flush(). static void push_call(UI *ui, char *name, Array args) { Array call = ARRAY_DICT_INIT; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index cfbe34b848..ab893a4c0f 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -255,12 +255,11 @@ free_vim_args: return rv; } -/// Execute lua code. Parameters might be passed, they are available inside -/// the chunk as `...`. The chunk can return a value. +/// Execute lua code. Parameters (if any) are available as `...` inside the +/// chunk. The chunk can return a value. /// -/// To evaluate an expression, it must be prefixed with "return ". For -/// instance, to call a lua function with arguments sent in and get its -/// return value back, use the code "return my_function(...)". +/// Only statements are executed. To evaluate an expression, prefix it +/// with `return`: return my_function(...) /// /// @param code lua code to execute /// @param args Arguments to the code @@ -423,29 +422,18 @@ void nvim_del_var(String name, Error *err) dict_set_var(&globvardict, name, NIL, true, false, err); } -/// Sets a global variable -/// /// @deprecated -/// -/// @param name Variable name -/// @param value Variable value -/// @param[out] err Error details, if any +/// @see nvim_set_var /// @return Old value or nil if there was no previous value. -/// -/// @warning It may return nil if there was no previous value -/// or if previous value was `v:null`. +/// @warning May return nil if there was no previous value +/// OR if previous value was `v:null`. Object vim_set_var(String name, Object value, Error *err) { return dict_set_var(&globvardict, name, value, false, true, err); } -/// Removes a global variable -/// /// @deprecated -/// -/// @param name Variable name -/// @param[out] err Error details, if any -/// @return Old value +/// @see nvim_del_var Object vim_del_var(String name, Error *err) { return dict_set_var(&globvardict, name, NIL, true, true, err); diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 570db6dfc3..5adf16c0f3 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -66,6 +66,7 @@ void loop_poll_events(Loop *loop, int ms) /// means `fast_events` is NOT processed in an "editor mode" /// (VimState.execute), so redraw and other side-effects are likely to be /// skipped. +/// @see loop_schedule_deferred void loop_schedule(Loop *loop, Event event) { uv_mutex_lock(&loop->mutex); diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 02f3854f47..88232a55de 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -188,12 +188,11 @@ uint64_t channel_connect(bool tcp, const char *address, int timeout, return channel->id; } -/// Sends event/arguments to channel +/// Publishes an event to a channel. /// -/// @param id The channel id. If 0, the event will be sent to all -/// channels that have subscribed to the event type -/// @param name The event name, an arbitrary string -/// @param args Array with event arguments +/// @param id Channel id. 0 means "broadcast to all subscribed channels" +/// @param name Event name (application-defined) +/// @param args Array of event arguments /// @return True if the event was sent successfully, false otherwise. bool channel_send_event(uint64_t id, const char *name, Array args) { @@ -215,7 +214,6 @@ bool channel_send_event(uint64_t id, const char *name, Array args) send_event(channel, name, args); } } else { - // TODO(tarruda): Implement event broadcasting in vimscript broadcast_event(name, args); } -- cgit From 82795c2c3a429b2725af882cad4317bed8f1b741 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Wed, 6 Sep 2017 01:04:57 +0800 Subject: vim-patch: 8.0.0{181,182,188} (#7152) vim-patch:8.0.0181 Problem: When 'cursorbind' and 'cursorcolumn' are both on, the column highlignt in non-current windows is wrong. Solution: Add validate_cursor(). (Masanori Misono, closes vim/vim#1372) https://github.com/vim/vim/commit/519d7785f4437762c07b2e04217f83a069a8c663 vim-patch:8.0.0182 Problem: When 'cursorbind' and 'cursorline' are set, but 'cursorcolumn' is not, then the cursor line highlighting is not updated. (Hirohito Higashi) Solution: Call redraw_later() with NOT_VALID. https://github.com/vim/vim/commit/e47683a0913f102b6ae08c8848d5aa675d99b188 vim-patch:8.0.0188 Problem: Using NOT_VALID for redraw_later() to update the cursor line/column highlighting is not efficient. Solution: Call validate_cursor() when 'cul' or 'cuc' is set. https://github.com/vim/vim/commit/9506cad7a1a6e52a613f356de969cbd980815777 --- src/nvim/move.c | 13 +++++++++---- src/nvim/version.c | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/move.c b/src/nvim/move.c index 4d646f5a4b..9693132846 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -2164,16 +2164,21 @@ void do_check_cursorbind(void) int restart_edit_save = restart_edit; restart_edit = true; check_cursor(); + if (curwin->w_p_cul || curwin->w_p_cuc) { + validate_cursor(); + } restart_edit = restart_edit_save; } - /* Correct cursor for multi-byte character. */ - if (has_mbyte) + // Correct cursor for multi-byte character. + if (has_mbyte) { mb_adjust_cursor(); + } redraw_later(VALID); - /* Only scroll when 'scrollbind' hasn't done this. */ - if (!curwin->w_p_scb) + // Only scroll when 'scrollbind' hasn't done this. + if (!curwin->w_p_scb) { update_topline(); + } curwin->w_redr_status = true; } } diff --git a/src/nvim/version.c b/src/nvim/version.c index 6e24e30a09..ce1cc03c1f 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -764,14 +764,14 @@ static const int included_patches[] = { // 191 NA 190, // 189, - // 188, + 188, // 187 NA // 186, // 185, // 184, // 183, - // 182, - // 181, + 182, + 181, // 180, 179, 178, -- cgit From 06f8ad5b2af59f61f053387d1347f6b1eada850e Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 9 Sep 2017 13:57:27 +0200 Subject: terminal.c: need maketitle() in terminal-mode normal_redraw() usually takes care of this, but that doesn't happen during terminal-mode. regression by c484323dc67f steps to reproduce: nvim -u NORC --cmd 'execute("set titlestring=" . $NVIM_LISTEN_ADDRESS) | set title | startinsert | !sleep 1' term://sh closes #7248 --- src/nvim/screen.c | 2 +- src/nvim/terminal.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 95973354bc..921ef06c7b 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -5847,7 +5847,7 @@ static void screen_start_highlight(int attr) ui_start_highlight(attr); } -void screen_stop_highlight(void) +static void screen_stop_highlight(void) { ui_stop_highlight(); screen_attr = 0; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index d4517af3ff..4a9acf2559 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -1259,6 +1259,10 @@ static void redraw(bool restore_cursor) update_screen(0); } + if (need_maketitle) { // Update title in terminal-mode. #7248 + maketitle(); + } + if (restore_cursor) { ui_cursor_goto(save_row, save_col); } else if (term) { -- cgit From 26d08dfd0d9d2f8e3685a4fe083588519bd5dac0 Mon Sep 17 00:00:00 2001 From: KillTheMule Date: Mon, 28 Aug 2017 21:33:31 +0200 Subject: inccommand: fix optimization logic #7224 Before this change the preview changes in the buffer viewport were limited to the size of the preview window ('cmdwinheight'). closes #7220 --- src/nvim/ex_cmds.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 32dbf4cc69..4b3e02e5fd 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3332,10 +3332,12 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout) sub = regtilde(sub, p_magic); // Check for a match on each line. + // If preview: limit to max('cmdwinheight', viewport). linenr_T line2 = eap->line2; for (linenr_T lnum = eap->line1; - lnum <= line2 && !(got_quit || aborting()) - && (!preview || matched_lines.size <= (size_t)p_cwh); + lnum <= line2 && !got_quit && !aborting() + && (!preview || matched_lines.size < (size_t)p_cwh + || lnum <= curwin->w_botline); lnum++) { long nmatch = vim_regexec_multi(®match, curwin, curbuf, lnum, (colnr_T)0, NULL); -- cgit From 713a957e9c90fc1c57935e33346347807595f946 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Sun, 10 Sep 2017 18:21:52 +0800 Subject: vim-patch:8.0.0282 vim-patch:8.0.0291 (#7255) vim-patch:8.0.0291 Problem: Visual block insertion does not insert in all lines. Solution: Don't bail out of insert too early. Add a test. (Christian Brabandt, closes vim/vim#1290) https://github.com/vim/vim/commit/23fa81d2223cd9bb7c51829c48047b2976bc2d11 vim-patch:8.0.0282 Problem: When doing a Visual selection and using "I" to go to insert mode, CTRL-O needs to be used twice to go to Normal mode. (Coacher) Solution: Check for the return value of edit(). (Christian Brabandt, closes #1290) https://github.com/vim/vim/commit/0b5c93a7f266cd8c90ea27bdaf9f7214a95d64d7 --- src/nvim/normal.c | 5 ++++- src/nvim/ops.c | 2 +- src/nvim/testdir/test_visual.vim | 13 +++++++++++++ src/nvim/version.c | 4 ++-- 4 files changed, 20 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 6415bec846..c40ed58550 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1942,8 +1942,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) * the lines. */ auto_format(false, true); - if (restart_edit == 0) + if (restart_edit == 0) { restart_edit = restart_edit_save; + } else { + cap->retval |= CA_COMMAND_BUSY; + } } break; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index c01840cfd0..99dc4670f1 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2060,7 +2060,7 @@ void op_insert(oparg_T *oap, long count1) } t1 = oap->start; - edit(NUL, false, (linenr_T)count1); + (void)edit(NUL, false, (linenr_T)count1); // When a tab was inserted, and the characters in front of the tab // have been converted to a tab as well, the column of the cursor diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index cf0e535937..74c26e3d66 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -15,3 +15,16 @@ func Test_block_shift_multibyte() call assert_equal(' ヹxxx', getline(2)) q! endfunc + +func Test_Visual_ctrl_o() + new + call setline(1, ['one', 'two', 'three']) + call cursor(1,2) + set noshowmode + set tw=0 + call feedkeys("\jjlIa\\:set tw=88\\", 'tx') + call assert_equal(['oane', 'tawo', 'tahree'], getline(1, 3)) + call assert_equal(88, &tw) + set tw& + bw! +endfu diff --git a/src/nvim/version.c b/src/nvim/version.c index ce1cc03c1f..e7061fff9d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -661,7 +661,7 @@ static const int included_patches[] = { // 294, // 293, // 292, - // 291, + 291, 290, // 289, // 288 NA @@ -670,7 +670,7 @@ static const int included_patches[] = { // 285 NA // 284 NA // 283, - // 282, + 282, // 281 NA 280, // 279 NA -- cgit From ceade2fe53175555c44fdc4b65530f18aeb17591 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Sun, 10 Sep 2017 18:52:43 +0800 Subject: vim-patch:8.0.0186 (#7154) Problem: The error message from assert_notequal() is confusing. Solution: Only mention the expected value. https://github.com/vim/vim/commit/5869cf060e60cc09e71b2b3bd85f0576ec78f9f5 --- src/nvim/eval.c | 24 +++++++++++++----------- src/nvim/version.c | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d6ee13857a..5ee91d417a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6747,6 +6747,8 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, } else { if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) { ga_concat(gap, (char_u *)"Pattern "); + } else if (atype == ASSERT_NOTEQUAL) { + ga_concat(gap, (char_u *)"Expected not equal to "); } else { ga_concat(gap, (char_u *)"Expected "); } @@ -6757,18 +6759,18 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, } else { ga_concat(gap, exp_str); } - tofree = (char_u *)encode_tv2string(got_tv, NULL); - if (atype == ASSERT_MATCH) { - ga_concat(gap, (char_u *)" does not match "); - } else if (atype == ASSERT_NOTMATCH) { - ga_concat(gap, (char_u *)" does match "); - } else if (atype == ASSERT_NOTEQUAL) { - ga_concat(gap, (char_u *)" differs from "); - } else { - ga_concat(gap, (char_u *)" but got "); + if (atype != ASSERT_NOTEQUAL) { + if (atype == ASSERT_MATCH) { + ga_concat(gap, (char_u *)" does not match "); + } else if (atype == ASSERT_NOTMATCH) { + ga_concat(gap, (char_u *)" does match "); + } else { + ga_concat(gap, (char_u *)" but got "); + } + tofree = (char_u *)encode_tv2string(got_tv, NULL); + ga_concat(gap, tofree); + xfree(tofree); } - ga_concat(gap, tofree); - xfree(tofree); } } diff --git a/src/nvim/version.c b/src/nvim/version.c index e7061fff9d..4c0071f248 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -766,7 +766,7 @@ static const int included_patches[] = { // 189, 188, // 187 NA - // 186, + 186, // 185, // 184, // 183, -- cgit From d2cbc311855114b7736919a344a82e303d4a8164 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Mon, 11 Sep 2017 22:17:41 +0800 Subject: Vim-patch 8.0.0300 (#7258) vim-patch:8.0.0300 Problem: Cannot stop diffing hidden buffers. (Daniel Hahler) Solution: When using :diffoff! make the whole list if diffed buffers empty. (closes vim/vim#736) https://github.com/vim/vim/commit/25ea0544587dd45088512fec9d7a685e35fea679 --- src/nvim/diff.c | 19 +++++++++++++++++++ src/nvim/testdir/test_diffmode.vim | 37 +++++++++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 3 files changed, 57 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 17de4284ce..cc0f3b2629 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -135,6 +135,20 @@ void diff_buf_add(buf_T *buf) EMSGN(_("E96: Cannot diff more than %" PRId64 " buffers"), DB_COUNT); } +/// +/// Remove all buffers to make diffs for. +/// +static void diff_buf_clear(void) +{ + for (int i = 0; i < DB_COUNT; i++) { + if (curtab->tp_diffbuf[i] != NULL) { + curtab->tp_diffbuf[i] = NULL; + curtab->tp_diff_invalid = true; + diff_redraw(true); + } + } +} + /// Find buffer "buf" in the list of diff buffers for the current tab page. /// /// @param buf The buffer to find. @@ -1175,6 +1189,11 @@ void ex_diffoff(exarg_T *eap) diffwin |= wp->w_p_diff; } + // Also remove hidden buffers from the list. + if (eap->forceit) { + diff_buf_clear(); + } + // Remove "hor" from from 'scrollopt' if there are no diff windows left. if (!diffwin && (vim_strchr(p_sbo, 'h') != NULL)) { do_cmdline_cmd("set sbo-=hor"); diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index f40e06ff33..8ee82bd538 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -212,6 +212,7 @@ func Test_diffoff() call setline(1, ['One', '', 'Two', 'Three']) diffthis redraw + call assert_notequal(normattr, screenattr(1, 1)) diffoff! redraw call assert_equal(normattr, screenattr(1, 1)) @@ -219,6 +220,42 @@ func Test_diffoff() bwipe! endfunc +func Test_diffoff_hidden() + set diffopt=filler,foldcolumn:0 + e! one + call setline(1, ['Two', 'Three']) + let normattr = screenattr(1, 1) + diffthis + botright vert new two + call setline(1, ['One', 'Four']) + diffthis + redraw + call assert_notequal(normattr, screenattr(1, 1)) + set hidden + close + redraw + " diffing with hidden buffer two + call assert_notequal(normattr, screenattr(1, 1)) + diffoff + redraw + call assert_equal(normattr, screenattr(1, 1)) + diffthis + redraw + " still diffing with hidden buffer two + call assert_notequal(normattr, screenattr(1, 1)) + diffoff! + redraw + call assert_equal(normattr, screenattr(1, 1)) + diffthis + redraw + " no longer diffing with hidden buffer two + call assert_equal(normattr, screenattr(1, 1)) + + bwipe! + bwipe! + set hidden& diffopt& +endfunc + func Test_setting_cursor() new Xtest1 put =range(1,90) diff --git a/src/nvim/version.c b/src/nvim/version.c index 4c0071f248..6f38776a60 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -652,7 +652,7 @@ static const int included_patches[] = { // 303, // 302, // 301, - // 300, + 300, // 299, // 298, 297, -- cgit From 6d0f87a0bd9c683f21c20e29145f375ca77c2792 Mon Sep 17 00:00:00 2001 From: KillTheMule Date: Sat, 9 Sep 2017 11:38:19 +0200 Subject: 'inccommand': fix 'gdefault' lockup #7261 closes #7244 ref #7249 --- src/nvim/ex_cmds.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 4b3e02e5fd..99bf07c3fb 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3665,9 +3665,38 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout) * use "\=col("."). */ curwin->w_cursor.col = regmatch.startpos[0].col; + // When the match included the "$" of the last line it may + // go beyond the last line of the buffer. + if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1) { + nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1; + skip_match = true; + } + // 3. Substitute the string. During 'inccommand' preview only do this if // there is a replace pattern. - if (!preview || has_second_delim) { + if (preview && !has_second_delim) { + // For a multi-line match, make a copy of the last matched + // line and continue in that one. + if (nmatch > 1) { + sub_firstlnum += nmatch - 1; + xfree(sub_firstline); + sub_firstline = vim_strsave(ml_get(sub_firstlnum)); + // When going beyond the last line, stop substituting. + if (sub_firstlnum <= line2) { + do_again = true; + } else { + subflags.do_all = false; + } + } + + if (skip_match) { + // Already hit end of the buffer, sub_firstlnum is one + // less than what it ought to be. + xfree(sub_firstline); + sub_firstline = vim_strsave((char_u *)""); + copycol = 0; + } + } else if (!preview || has_second_delim) { if (subflags.do_count) { // prevent accidentally changing the buffer by a function save_ma = curbuf->b_p_ma; @@ -3691,13 +3720,6 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout) goto skip; } - // When the match included the "$" of the last line it may - // go beyond the last line of the buffer. - if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1) { - nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1; - skip_match = true; - } - // Need room for: // - result so far in new_start (not for first sub in line) // - original text up to match -- cgit From 2736f0cb5631dec43064c77f504a7bc160aaeeb1 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 12 Sep 2017 23:45:31 +0200 Subject: ex_cmds.c:do_sub(): macroize duplicate code --- src/nvim/ex_cmds.c | 76 +++++++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 99bf07c3fb..918e7a0c91 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3672,31 +3672,38 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout) skip_match = true; } - // 3. Substitute the string. During 'inccommand' preview only do this if - // there is a replace pattern. +#define ADJUST_SUB_FIRSTLNUM() \ + do { \ + /* For a multi-line match, make a copy of the last matched */ \ + /* line and continue in that one. */ \ + if (nmatch > 1) { \ + sub_firstlnum += nmatch - 1; \ + xfree(sub_firstline); \ + sub_firstline = vim_strsave(ml_get(sub_firstlnum)); \ + /* When going beyond the last line, stop substituting. */ \ + if (sub_firstlnum <= line2) { \ + do_again = true; \ + } else { \ + subflags.do_all = false; \ + } \ + } \ + if (skip_match) { \ + /* Already hit end of the buffer, sub_firstlnum is one */ \ + /* less than what it ought to be. */ \ + xfree(sub_firstline); \ + sub_firstline = vim_strsave((char_u *)""); \ + copycol = 0; \ + } \ + } while (0) + if (preview && !has_second_delim) { - // For a multi-line match, make a copy of the last matched - // line and continue in that one. - if (nmatch > 1) { - sub_firstlnum += nmatch - 1; - xfree(sub_firstline); - sub_firstline = vim_strsave(ml_get(sub_firstlnum)); - // When going beyond the last line, stop substituting. - if (sub_firstlnum <= line2) { - do_again = true; - } else { - subflags.do_all = false; - } - } + ADJUST_SUB_FIRSTLNUM(); + goto skip; + } - if (skip_match) { - // Already hit end of the buffer, sub_firstlnum is one - // less than what it ought to be. - xfree(sub_firstline); - sub_firstline = vim_strsave((char_u *)""); - copycol = 0; - } - } else if (!preview || has_second_delim) { + // 3. Substitute the string. During 'inccommand' preview only do this if + // there is a replace pattern. + if (!preview || has_second_delim) { if (subflags.do_count) { // prevent accidentally changing the buffer by a function save_ma = curbuf->b_p_ma; @@ -3750,30 +3757,10 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout) // is beyond the end of the line after the substitution. curwin->w_cursor.col = 0; - // For a multi-line match, make a copy of the last matched - // line and continue in that one. - if (nmatch > 1) { - sub_firstlnum += nmatch - 1; - xfree(sub_firstline); - sub_firstline = vim_strsave(ml_get(sub_firstlnum)); - // When going beyond the last line, stop substituting. - if (sub_firstlnum <= line2) { - do_again = true; - } else { - subflags.do_all = false; - } - } - // Remember next character to be copied. copycol = regmatch.endpos[0].col; - if (skip_match) { - // Already hit end of the buffer, sub_firstlnum is one - // less than what it ought to be. - xfree(sub_firstline); - sub_firstline = vim_strsave((char_u *)""); - copycol = 0; - } + ADJUST_SUB_FIRSTLNUM(); // Now the trick is to replace CTRL-M chars with a real line // break. This would make it impossible to insert a CTRL-M in @@ -4030,6 +4017,7 @@ skip: kv_destroy(matched_lines); return preview_buf; +#undef ADJUST_SUB_FIRSTLNUM } // NOLINT(readability/fn_size) /* -- cgit From 47019bb167e2b2d28c8648d39781c66e3ec02c00 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 16 Sep 2017 11:20:26 +0200 Subject: getchar.c: add TERM_FOCUS to MAP_HASH (#7271) vim-patch:8.0.1108 https://github.com/vim/vim/commit/69fbc9e1dab176f345719436cd89d854df0a2abd --- src/nvim/getchar.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index a22b716bb6..f5949333bd 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -92,17 +92,15 @@ static int typeahead_char = 0; /* typeahead char that's not flushed */ */ static int block_redo = FALSE; -/* - * Make a hash value for a mapping. - * "mode" is the lower 4 bits of the State for the mapping. - * "c1" is the first character of the "lhs". - * Returns a value between 0 and 255, index in maphash. - * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode. - */ +// Make a hash value for a mapping. +// "mode" is the lower 4 bits of the State for the mapping. +// "c1" is the first character of the "lhs". +// Returns a value between 0 and 255, index in maphash. +// Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode. #define MAP_HASH(mode, \ c1) (((mode) & \ (NORMAL + VISUAL + SELECTMODE + \ - OP_PENDING)) ? (c1) : ((c1) ^ 0x80)) + OP_PENDING + TERM_FOCUS)) ? (c1) : ((c1) ^ 0x80)) // Each mapping is put in one of the MAX_MAPHASH hash lists, // to speed up finding it. -- cgit From b9cba41106e380556ddf731d8fbfcc9c84f8e225 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 16 Sep 2017 23:13:35 -0400 Subject: tui: Use unibi_var_from_num when available As of unibilium 1.2.1, directly manipulating unibi_var_t is deprecated. ../src/nvim/tui/tui.c: In function 'update_attrs': ../src/nvim/tui/tui.c:321:7: warning: 'i' is deprecated: use unibi_var_from_num or unibi_num_from_var instead [-Wdeprecated-declarations] data->params[0].i = (fg >> 16) & 0xff; // red ^~~~ In file included from ../src/nvim/tui/tui.c:12:0: /usr/include/unibilium.h:632:9: note: declared here int i UNIBI_DEPRECATED("use unibi_var_from_num or unibi_num_from_var instead"); ^ All use should go through unibi_{num,str}_from_var and unibi_var_from_{num,str}. Wrap access of unibi_var_t behind a new UNIBI_SET_NUM_VAR macro which uses the new functions when they're available. --- src/nvim/tui/tui.c | 94 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 1cbd02dfd9..256772489d 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -52,6 +52,15 @@ #define LINUXSET0C "\x1b[?0c" #define LINUXSET1C "\x1b[?1c" +#ifdef NVIM_UNIBI_HAS_VAR_FROM +#define UNIBI_SET_NUM_VAR(var, num) \ + do { \ + (var) = unibi_var_from_num((num)); \ + } while (0) +#else +#define UNIBI_SET_NUM_VAR(var, num) (var).i = (num); +#endif + // Per the commentary in terminfo, only a minus sign is a true suffix // separator. bool terminfo_is_term_family(const char *term, const char *family) @@ -391,15 +400,15 @@ static void update_attrs(UI *ui, HlAttrs attrs) if (unibi_get_str(data->ut, unibi_set_attributes)) { if (attrs.bold || attrs.reverse || attrs.underline || attrs.undercurl) { - data->params[0].i = 0; // standout - data->params[1].i = attrs.underline || attrs.undercurl; - data->params[2].i = attrs.reverse; - data->params[3].i = 0; // blink - data->params[4].i = 0; // dim - data->params[5].i = attrs.bold; - data->params[6].i = 0; // blank - data->params[7].i = 0; // protect - data->params[8].i = 0; // alternate character set + UNIBI_SET_NUM_VAR(data->params[0], 0); // standout + UNIBI_SET_NUM_VAR(data->params[1], attrs.underline || attrs.undercurl); + UNIBI_SET_NUM_VAR(data->params[2], attrs.reverse); + UNIBI_SET_NUM_VAR(data->params[3], 0); // blink + UNIBI_SET_NUM_VAR(data->params[4], 0); // dim + UNIBI_SET_NUM_VAR(data->params[5], attrs.bold); + UNIBI_SET_NUM_VAR(data->params[6], 0); // blank + UNIBI_SET_NUM_VAR(data->params[7], 0); // protect + UNIBI_SET_NUM_VAR(data->params[8], 0); // alternate character set unibi_out(ui, unibi_set_attributes); } else if (!data->default_attr) { unibi_out(ui, unibi_exit_attribute_mode); @@ -423,26 +432,26 @@ static void update_attrs(UI *ui, HlAttrs attrs) } if (ui->rgb) { if (fg != -1) { - data->params[0].i = (fg >> 16) & 0xff; // red - data->params[1].i = (fg >> 8) & 0xff; // green - data->params[2].i = fg & 0xff; // blue + UNIBI_SET_NUM_VAR(data->params[0], (fg >> 16) & 0xff); // red + UNIBI_SET_NUM_VAR(data->params[1], (fg >> 8) & 0xff); // green + UNIBI_SET_NUM_VAR(data->params[2], fg & 0xff); // blue unibi_out_ext(ui, data->unibi_ext.set_rgb_foreground); } if (bg != -1) { - data->params[0].i = (bg >> 16) & 0xff; // red - data->params[1].i = (bg >> 8) & 0xff; // green - data->params[2].i = bg & 0xff; // blue + UNIBI_SET_NUM_VAR(data->params[0], (bg >> 16) & 0xff); // red + UNIBI_SET_NUM_VAR(data->params[1], (bg >> 8) & 0xff); // green + UNIBI_SET_NUM_VAR(data->params[2], bg & 0xff); // blue unibi_out_ext(ui, data->unibi_ext.set_rgb_background); } } else { if (fg != -1) { - data->params[0].i = fg; + UNIBI_SET_NUM_VAR(data->params[0], fg); unibi_out(ui, unibi_set_a_foreground); } if (bg != -1) { - data->params[0].i = bg; + UNIBI_SET_NUM_VAR(data->params[0], bg); unibi_out(ui, unibi_set_a_background); } } @@ -558,7 +567,7 @@ static void cursor_goto(UI *ui, int row, int col) unibi_out(ui, unibi_cursor_left); } } else { - data->params[0].i = n; + UNIBI_SET_NUM_VAR(data->params[0], n); unibi_out(ui, unibi_parm_left_cursor); } ugrid_goto(grid, row, col); @@ -570,7 +579,7 @@ static void cursor_goto(UI *ui, int row, int col) unibi_out(ui, unibi_cursor_right); } } else { - data->params[0].i = n; + UNIBI_SET_NUM_VAR(data->params[0], n); unibi_out(ui, unibi_parm_right_cursor); } ugrid_goto(grid, row, col); @@ -585,7 +594,7 @@ static void cursor_goto(UI *ui, int row, int col) unibi_out(ui, unibi_cursor_down); } } else { - data->params[0].i = n; + UNIBI_SET_NUM_VAR(data->params[0], n); unibi_out(ui, unibi_parm_down_cursor); } ugrid_goto(grid, row, col); @@ -597,7 +606,7 @@ static void cursor_goto(UI *ui, int row, int col) unibi_out(ui, unibi_cursor_up); } } else { - data->params[0].i = n; + UNIBI_SET_NUM_VAR(data->params[0], n); unibi_out(ui, unibi_parm_up_cursor); } ugrid_goto(grid, row, col); @@ -675,19 +684,19 @@ static void set_scroll_region(UI *ui) TUIData *data = ui->data; UGrid *grid = &data->grid; - data->params[0].i = grid->top; - data->params[1].i = grid->bot; + UNIBI_SET_NUM_VAR(data->params[0], grid->top); + UNIBI_SET_NUM_VAR(data->params[1], grid->bot); unibi_out(ui, unibi_change_scroll_region); if (grid->left != 0 || grid->right != ui->width - 1) { unibi_out_ext(ui, data->unibi_ext.enable_lr_margin); if (data->can_set_lr_margin) { - data->params[0].i = grid->left; - data->params[1].i = grid->right; + UNIBI_SET_NUM_VAR(data->params[0], grid->left); + UNIBI_SET_NUM_VAR(data->params[1], grid->right); unibi_out(ui, unibi_set_lr_margin); } else { - data->params[0].i = grid->left; + UNIBI_SET_NUM_VAR(data->params[0], grid->left); unibi_out(ui, unibi_set_left_margin_parm); - data->params[0].i = grid->right; + UNIBI_SET_NUM_VAR(data->params[0], grid->right); unibi_out(ui, unibi_set_right_margin_parm); } } @@ -702,19 +711,19 @@ static void reset_scroll_region(UI *ui) if (0 <= data->unibi_ext.reset_scroll_region) { unibi_out_ext(ui, data->unibi_ext.reset_scroll_region); } else { - data->params[0].i = 0; - data->params[1].i = ui->height - 1; + UNIBI_SET_NUM_VAR(data->params[0], 0); + UNIBI_SET_NUM_VAR(data->params[1], ui->height - 1); unibi_out(ui, unibi_change_scroll_region); } if (grid->left != 0 || grid->right != ui->width - 1) { if (data->can_set_lr_margin) { - data->params[0].i = 0; - data->params[1].i = ui->width - 1; + UNIBI_SET_NUM_VAR(data->params[0], 0); + UNIBI_SET_NUM_VAR(data->params[1], ui->width - 1); unibi_out(ui, unibi_set_lr_margin); } else { - data->params[0].i = 0; + UNIBI_SET_NUM_VAR(data->params[0], 0); unibi_out(ui, unibi_set_left_margin_parm); - data->params[0].i = ui->width - 1; + UNIBI_SET_NUM_VAR(data->params[0], ui->width - 1); unibi_out(ui, unibi_set_right_margin_parm); } unibi_out_ext(ui, data->unibi_ext.disable_lr_margin); @@ -728,8 +737,8 @@ static void tui_resize(UI *ui, Integer width, Integer height) ugrid_resize(&data->grid, (int)width, (int)height); if (!got_winch) { // Try to resize the terminal window. - data->params[0].i = (int)height; - data->params[1].i = (int)width; + UNIBI_SET_NUM_VAR(data->params[0], (int)height); + UNIBI_SET_NUM_VAR(data->params[1], (int)width); unibi_out_ext(ui, data->unibi_ext.resize_screen); // DECSLPP does not reset the scroll region. if (data->scroll_region_is_full_screen) { @@ -863,7 +872,7 @@ static void tui_set_mode(UI *ui, ModeShape mode) int attr = syn_id2attr(c.id); if (attr > 0) { attrentry_T *aep = syn_cterm_attr2entry(attr); - data->params[0].i = aep->rgb_bg_color; + UNIBI_SET_NUM_VAR(data->params[0], aep->rgb_bg_color); unibi_out_ext(ui, data->unibi_ext.set_cursor_color); } } @@ -874,7 +883,7 @@ static void tui_set_mode(UI *ui, ModeShape mode) case SHAPE_VER: shape = 5; break; default: WLOG("Unknown shape value %d", shape); break; } - data->params[0].i = shape + (int)(c.blinkon == 0); + UNIBI_SET_NUM_VAR(data->params[0], shape + (int)(c.blinkon == 0)); unibi_out_ext(ui, data->unibi_ext.set_cursor_style); } @@ -927,14 +936,14 @@ static void tui_scroll(UI *ui, Integer count) if (count == 1) { unibi_out(ui, unibi_delete_line); } else { - data->params[0].i = (int)count; + UNIBI_SET_NUM_VAR(data->params[0], (int)count); unibi_out(ui, unibi_parm_delete_line); } } else { if (count == -1) { unibi_out(ui, unibi_insert_line); } else { - data->params[0].i = -(int)count; + UNIBI_SET_NUM_VAR(data->params[0], -(int)count); unibi_out(ui, unibi_parm_insert_line); } } @@ -1177,8 +1186,8 @@ end: static void unibi_goto(UI *ui, int row, int col) { TUIData *data = ui->data; - data->params[0].i = row; - data->params[1].i = col; + UNIBI_SET_NUM_VAR(data->params[0], row); + UNIBI_SET_NUM_VAR(data->params[1], col); unibi_out(ui, unibi_cursor_address); } @@ -1190,7 +1199,8 @@ static void unibi_goto(UI *ui, int row, int col) str = fn(data->ut, (unsigned)unibi_index); \ } \ if (str) { \ - unibi_var_t vars[26 + 26] = { { 0 } }; \ + unibi_var_t vars[26 + 26]; \ + memset(&vars, 0, sizeof(vars)); \ unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL); \ } \ } while (0) -- cgit From e53af2b1f50c4662698f4a7c42a6008955a73426 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Mon, 18 Sep 2017 01:43:45 +0800 Subject: vim-patch:8.0.0305 (#7265) Problem: Invalid memory access when option has duplicate flag. Solution: Correct pointer computation. (Dominique Pelle, closes vim/vim#1442) https://github.com/vim/vim/commit/aaaf57d8a936efe420190c077e4a74041cc6c72e --- src/nvim/option.c | 7 ++++--- src/nvim/testdir/test_options.vim | 6 ++++++ src/nvim/version.c | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 8ba10fd38a..74250e83e6 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1749,7 +1749,7 @@ do_set ( if (flags & P_FLAGLIST) { // Remove flags that appear twice. - for (s = newval; *s; s++) { + for (s = newval; *s;) { // if options have P_FLAGLIST and P_ONECOMMA such as // 'whichwrap' if (flags & P_ONECOMMA) { @@ -1757,15 +1757,16 @@ do_set ( && vim_strchr(s + 2, *s) != NULL) { // Remove the duplicated value and the next comma. STRMOVE(s, s + 2); - s -= 2; + continue; } } else { if ((!(flags & P_COMMA) || *s != ',') && vim_strchr(s + 1, *s) != NULL) { STRMOVE(s, s + 1); - s--; + continue; } } + s++; } } diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index 5ee0919e18..2ffe63787b 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -13,6 +13,12 @@ function! Test_whichwrap() set whichwrap+=h,l call assert_equal('b,s,h,l', &whichwrap) + set whichwrap=h,h + call assert_equal('h', &whichwrap) + + set whichwrap=h,h,h + call assert_equal('h', &whichwrap) + set whichwrap& endfunction diff --git a/src/nvim/version.c b/src/nvim/version.c index 6f38776a60..f5df256d3d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -647,7 +647,7 @@ static const int included_patches[] = { 308, 307, // 306, - // 305, + 305, // 304, // 303, // 302, -- cgit From 009c695f0a6c6da322f89e0f621d59d596e712fa Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Mon, 18 Sep 2017 01:56:08 +0800 Subject: vim-patch:8.0.0302 NA (#7264) (NA: Nvim removed the ability to set termcodes directly.) Problem: Cannot set terminal key codes with :let. Solution: Make it work. https://github.com/vim/vim/commit/e353c402e63b9b0a0bc06acf390e352d9e7eeaeb --- src/nvim/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/version.c b/src/nvim/version.c index f5df256d3d..e4142dea98 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -650,7 +650,7 @@ static const int included_patches[] = { 305, // 304, // 303, - // 302, + // 302, NA // 301, 300, // 299, -- cgit From cf59d617bc6d2aabb487c4d6be8082160a633a39 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Mon, 18 Sep 2017 02:04:17 +0800 Subject: vim-patch:8.0.0324 (#7279) Problem: Illegal memory access with "1;y". Solution: Call check_cursor() instead of check_cursor_lnum(). (Dominique Pelle, closes vim/vim#1455) https://github.com/vim/vim/commit/f1f6f3f7df2938b3583e341482d96c1d53124c51 --- src/nvim/ex_docmd.c | 4 ++-- src/nvim/testdir/test_cmdline.vim | 14 +++++++++++++- src/nvim/version.c | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index d1405978b3..bef5fd287e 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1668,8 +1668,8 @@ static char_u * do_one_cmd(char_u **cmdlinep, if (*ea.cmd == ';') { if (!ea.skip) { curwin->w_cursor.lnum = ea.line2; - // Don't leave the cursor on an illegal line (caused by ';') - check_cursor_lnum(); + // don't leave the cursor on an illegal line or column + check_cursor(); } } else if (*ea.cmd != ',') { break; diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 2facffb067..c0f04f4730 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -250,9 +250,21 @@ func Test_remove_char_in_cmdline() call assert_equal('"def', @:) endfunc -func Test_illegal_address() +func Test_illegal_address1() new 2;'( 2;') quit endfunc + +func Test_illegal_address2() + call writefile(['c', 'x', ' x', '.', '1;y'], 'Xtest.vim') + new + source Xtest.vim + " Trigger calling validate_cursor() + diffsp Xtest.vim + quit! + bwipe! + call delete('Xtest.vim') +endfunc + diff --git a/src/nvim/version.c b/src/nvim/version.c index e4142dea98..1f040b214b 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -628,7 +628,7 @@ static const int included_patches[] = { // 327, 326, 325, - // 324, + 324, // 323, 322, // 321, -- cgit From 12efbf897de28f00523885ceb99fb7cf41ed82e6 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Mon, 18 Sep 2017 02:05:22 +0800 Subject: vim-patch:8.0.0327 (#7281) Problem: The E11 error message in the command line window is not translated. Solution: use _(). (Hirohito Higashi) https://github.com/vim/vim/commit/75c19464ed7fb6024af64747379e61abc4e4a483 --- src/nvim/ex_docmd.c | 2 +- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index bef5fd287e..f9442a4cf6 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1813,7 +1813,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, if (text_locked() && !(ea.argt & CMDWIN) && !IS_USER_CMDIDX(ea.cmdidx)) { // Command not allowed when editing the command line. - errormsg = get_text_locked_msg(); + errormsg = (char_u *)_(get_text_locked_msg()); goto doend; } /* Disallow editing another buffer when "curbuf_lock" is set. diff --git a/src/nvim/version.c b/src/nvim/version.c index 1f040b214b..675ebb17b0 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -625,7 +625,7 @@ static const int included_patches[] = { // 330, // 329, // 328, - // 327, + 327, 326, 325, 324, -- cgit From f8dcd319d9338cccc66ae481d5865e8816794306 Mon Sep 17 00:00:00 2001 From: Michael Schupikov Date: Sat, 23 Sep 2017 08:32:29 +0200 Subject: vim-patch:8.0.0294 (#7305) Problem: Argument list is not stored correctly in a session file. (lgpasquale) Solution: Use "$argadd" instead of "argadd". (closes vim/vim#1434) https://github.com/vim/vim/commit/79da563cf9220b9abb83455a68d995684133ea56 Signed-off-by: Michael Schupikov --- src/nvim/ex_docmd.c | 2 +- src/nvim/testdir/Makefile | 1 + src/nvim/testdir/test_mksession.vim | 15 +++++++++++++++ src/nvim/version.c | 2 +- 4 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 src/nvim/testdir/test_mksession.vim (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index f9442a4cf6..47e23b6e80 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9378,7 +9378,7 @@ ses_arglist ( (void)vim_FullName((char *)s, (char *)buf, MAXPATHL, FALSE); s = buf; } - if (fputs("argadd ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL + if (fputs("$argadd ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL || put_eol(fd) == FAIL) { xfree(buf); return FAIL; diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 96de7224c5..9133bfc0a2 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -58,6 +58,7 @@ NEW_TESTS ?= \ test_match.res \ test_matchadd_conceal.res \ test_matchadd_conceal_utf8.res \ + test_mksession.res \ test_nested_function.res \ test_normal.res \ test_quickfix.res \ diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim new file mode 100644 index 0000000000..2238213850 --- /dev/null +++ b/src/nvim/testdir/test_mksession.vim @@ -0,0 +1,15 @@ +" Tests for sessions + +" Verify that arglist is stored correctly to the session file. +func Test_mksession_arglist() + argdel * + next file1 file2 file3 file4 + mksession! Xtest_mks.out + source Xtest_mks.out + call assert_equal(['file1', 'file2', 'file3', 'file4'], argv()) + + call delete('Xtest_mks.out') + argdel * +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/version.c b/src/nvim/version.c index 675ebb17b0..d4f9c0232f 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -658,7 +658,7 @@ static const int included_patches[] = { 297, // 296, // 295, - // 294, + 294, // 293, // 292, 291, -- cgit From 094bc39d017df34796bf92f50f5261d6ac33e83d Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 22 Sep 2017 10:07:35 -0400 Subject: Move definition of cstrchr above the functions which call it Functions with FUNC_ATTR_ALWAYS_INLINE need to be defined before they are called to work around bugs with some compiler versions. When the body is after the use of the function, compilation will fail with /home/niko/build/neovim/src/nvim/regexp.c: In function 'regmatch': /home/niko/build/neovim/build/src/nvim/auto/regexp.c.generated.h:77: sorry, unimplemented: inlining failed in call to 'cstrchr': function body not available /home/niko/build/neovim/src/nvim/regexp.c:4193: sorry, unimplemented: called from here --- src/nvim/regexp.c | 77 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 847b2f273e..ae611a0005 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -3316,6 +3316,47 @@ bt_regexec_nl ( return (int)r; } +/// Wrapper around strchr which accounts for case-insensitive searches and +/// non-ASCII characters. +/// +/// This function is used a lot for simple searches, keep it fast! +/// +/// @param s string to search +/// @param c character to find in @a s +/// +/// @return NULL if no match, otherwise pointer to the position in @a s +static inline char_u *cstrchr(const char_u *const s, const int c) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_ALWAYS_INLINE +{ + if (!rex.reg_ic) { + return vim_strchr(s, c); + } + + // Use folded case for UTF-8, slow! For ASCII use libc strpbrk which is + // expected to be highly optimized. + if (c > 0x80) { + const int folded_c = utf_fold(c); + for (const char_u *p = s; *p != NUL; p += utfc_ptr2len(p)) { + if (utf_fold(utf_ptr2char(p)) == folded_c) { + return (char_u *)p; + } + } + return NULL; + } + + int cc; + if (ASCII_ISUPPER(c)) { + cc = TOLOWER_ASC(c); + } else if (ASCII_ISLOWER(c)) { + cc = TOUPPER_ASC(c); + } else { + return vim_strchr(s, c); + } + + char tofind[] = { (char)c, (char)cc, NUL }; + return (char_u *)strpbrk((const char *)s, tofind); +} /// Matches a regexp against multiple lines. /// "rmp->regprog" is a compiled regexp as returned by vim_regcomp(). @@ -6320,42 +6361,6 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n) return result; } -/* - * cstrchr: This function is used a lot for simple searches, keep it fast! - */ -static inline char_u *cstrchr(const char_u *const s, const int c) - FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL - FUNC_ATTR_ALWAYS_INLINE -{ - if (!rex.reg_ic) { - return vim_strchr(s, c); - } - - // Use folded case for UTF-8, slow! For ASCII use libc strpbrk which is - // expected to be highly optimized. - if (c > 0x80) { - const int folded_c = utf_fold(c); - for (const char_u *p = s; *p != NUL; p += utfc_ptr2len(p)) { - if (utf_fold(utf_ptr2char(p)) == folded_c) { - return (char_u *)p; - } - } - return NULL; - } - - int cc; - if (ASCII_ISUPPER(c)) { - cc = TOLOWER_ASC(c); - } else if (ASCII_ISLOWER(c)) { - cc = TOUPPER_ASC(c); - } else { - return vim_strchr(s, c); - } - - char tofind[] = { (char)c, (char)cc, NUL }; - return (char_u *)strpbrk((const char *)s, tofind); -} - /*************************************************************** * regsub stuff * ***************************************************************/ -- cgit From 3ab6a519fca63d1fcb5eeb98437697a7abaca7b0 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sun, 24 Sep 2017 09:29:08 +0800 Subject: vim-patch:8.0.0328 Problem: The "zero count" error doesn't have a number. (Hirohito Higashi) Solution: Give it a number and be more specific about the error. https://github.com/vim/vim/commit/23a5558cfd860401aa694f0302d621887440f031 --- src/nvim/globals.h | 5 +++-- src/nvim/version.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 2ee72cdb6a..300e506854 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1146,8 +1146,9 @@ EXTERN char_u e_winheight[] INIT(= N_( EXTERN char_u e_winwidth[] INIT(= N_( "E592: 'winwidth' cannot be smaller than 'winminwidth'")); EXTERN char_u e_write[] INIT(= N_("E80: Error while writing")); -EXTERN char_u e_zerocount[] INIT(= N_("Zero count")); -EXTERN char_u e_usingsid[] INIT(= N_("E81: Using not in a script context")); +EXTERN char_u e_zerocount[] INIT(= N_("E939: Positive count required")); +EXTERN char_u e_usingsid[] INIT(= N_( + "E81: Using not in a script context")); EXTERN char_u e_intern2[] INIT(= N_("E685: Internal error: %s")); EXTERN char_u e_maxmempat[] INIT(= N_( "E363: pattern uses more memory than 'maxmempattern'")); diff --git a/src/nvim/version.c b/src/nvim/version.c index d4f9c0232f..09a62a3b0e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -624,7 +624,7 @@ static const int included_patches[] = { 331, // 330, // 329, - // 328, + 328, 327, 326, 325, -- cgit From 006425b8b683711cfb4f89074034ec1fe2085d40 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sun, 24 Sep 2017 09:48:52 +0800 Subject: vim-patch:8.0.0330 Problem: Illegal memory access after "vapo". (Dominique Pelle) Solution: Fix the cursor column. https://github.com/vim/vim/commit/84b2a381451e9068b09ef6d85f5e8cf1598e7355 --- src/nvim/search.c | 12 ++++++++---- src/nvim/testdir/test_visual.vim | 7 +++++++ src/nvim/version.c | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/search.c b/src/nvim/search.c index 1bf2317d2a..387614fd09 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3557,11 +3557,15 @@ extend: --start_lnum; if (VIsual_active) { - /* Problem: when doing "Vipipip" nothing happens in a single white - * line, we get stuck there. Trap this here. */ - if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum) + // Problem: when doing "Vipipip" nothing happens in a single white + // line, we get stuck there. Trap this here. + if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum) { goto extend; - VIsual.lnum = start_lnum; + } + if (VIsual.lnum != start_lnum) { + VIsual.lnum = start_lnum; + VIsual.col = 0; + } VIsual_mode = 'V'; redraw_curbuf_later(INVERTED); /* update the inversion */ showmode(); diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index 74c26e3d66..8cb59ca32a 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -28,3 +28,10 @@ func Test_Visual_ctrl_o() set tw& bw! endfu + +func Test_Visual_vapo() + new + normal oxx + normal vapo + bwipe! +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index d4f9c0232f..b642777d8a 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -622,7 +622,7 @@ static const int included_patches[] = { // 333, // 332, 331, - // 330, + 330, // 329, // 328, 327, -- cgit From 2b53a565b991fc329ab7af683ec50e9cfcac557f Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sun, 24 Sep 2017 10:05:53 +0800 Subject: vim-patch:8.0.0333 Problem: Illegal memory access when 'complete' ends in a backslash. Solution: Check for trailing backslash. (Dominique Pelle, closes vim/vim#1478) https://github.com/vim/vim/commit/226c53429109f24e31c17016aedfd7fbf7a9aa50 --- src/nvim/option.c | 7 ++++--- src/nvim/testdir/test_options.vim | 10 ++++++++++ src/nvim/version.c | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 74250e83e6..13aadb71bb 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2997,9 +2997,10 @@ did_set_string_option ( if (s[-1] == 'k' || s[-1] == 's') { /* skip optional filename after 'k' and 's' */ while (*s && *s != ',' && *s != ' ') { - if (*s == '\\') - ++s; - ++s; + if (*s == '\\' && s[1] != NUL) { + s++; + } + s++; } } else { if (errbuf != NULL) { diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index 2ffe63787b..8a9d793a2e 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -103,3 +103,13 @@ func Test_keymap_valid() call assert_fails(":set kmp=trunc\x00name", "E544:") call assert_fails(":set kmp=trunc\x00name", "trunc") endfunc + +func Test_complete() + " Trailing single backslash used to cause invalid memory access. + set complete=s\ + new + call feedkeys("i\\", 'xt') + bwipe! + set complete& +endfun + diff --git a/src/nvim/version.c b/src/nvim/version.c index d4f9c0232f..7470b07655 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -619,7 +619,7 @@ static const int included_patches[] = { // 336, // 335, // 334, - // 333, + 333, // 332, 331, // 330, -- cgit From 2b4a52f901bf4cc9a88c45eea39c303028091dd3 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Sun, 24 Sep 2017 23:20:45 +0800 Subject: vim-patch:8.0.0091 (#7312) Problem: Test_help_complete sometimes fails in MS-Windows console. Solution: Use getcompletion() instead of feedkeys() and command line completion. (Hirohito Higashi) https://github.com/vim/vim/commit/9f0e423c2818c0cacd0810f9c3c67cbb6b80963d --- src/nvim/testdir/test_help_tagjump.vim | 57 ++++++++++++++-------------------- src/nvim/version.c | 2 +- 2 files changed, 25 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_help_tagjump.vim b/src/nvim/testdir/test_help_tagjump.vim index 1ca0f722cf..65d99c644c 100644 --- a/src/nvim/testdir/test_help_tagjump.vim +++ b/src/nvim/testdir/test_help_tagjump.vim @@ -89,17 +89,8 @@ func s:doc_config_teardown() endif endfunc -func s:get_cmd_compl_list(cmd) - let list = [] - let str = '' - for cnt in range(1, 999) - call feedkeys(a:cmd . repeat("\", cnt) . "'\let str='\", 'tx') - if str ==# a:cmd[1:] - break - endif - call add(list, str) - endfor - return list +func s:get_help_compl_list(cmd) + return getcompletion(a:cmd, 'help') endfunc func Test_help_complete() @@ -111,49 +102,49 @@ func Test_help_complete() if has('multi_lang') set helplang= endif - let list = s:get_cmd_compl_list(":h test") - call assert_equal(['h test-col', 'h test-char'], list) + let list = s:get_help_compl_list("test") + call assert_equal(['test-col', 'test-char'], list) if has('multi_lang') " 'helplang=ab' and help file lang is 'en' set helplang=ab - let list = s:get_cmd_compl_list(":h test") - call assert_equal(['h test-col', 'h test-char'], list) + let list = s:get_help_compl_list("test") + call assert_equal(['test-col', 'test-char'], list) " 'helplang=' and help file lang is 'en' and 'ab' set rtp+=Xdir1/doc-ab set helplang= - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col@en', 'h test-col@ab', - \ 'h test-char@en', 'h test-char@ab']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col@en', 'test-col@ab', + \ 'test-char@en', 'test-char@ab']), sort(list)) " 'helplang=ab' and help file lang is 'en' and 'ab' set helplang=ab - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col', 'h test-col@en', - \ 'h test-char', 'h test-char@en']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col', 'test-col@en', + \ 'test-char', 'test-char@en']), sort(list)) " 'helplang=' and help file lang is 'en', 'ab' and 'ja' set rtp+=Xdir1/doc-ja set helplang= - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col@en', 'h test-col@ab', - \ 'h test-col@ja', 'h test-char@en', - \ 'h test-char@ab', 'h test-char@ja']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col@en', 'test-col@ab', + \ 'test-col@ja', 'test-char@en', + \ 'test-char@ab', 'test-char@ja']), sort(list)) " 'helplang=ab' and help file lang is 'en', 'ab' and 'ja' set helplang=ab - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col', 'h test-col@en', - \ 'h test-col@ja', 'h test-char', - \ 'h test-char@en', 'h test-char@ja']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col', 'test-col@en', + \ 'test-col@ja', 'test-char', + \ 'test-char@en', 'test-char@ja']), sort(list)) " 'helplang=ab,ja' and help file lang is 'en', 'ab' and 'ja' set helplang=ab,ja - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col', 'h test-col@ja', - \ 'h test-col@en', 'h test-char', - \ 'h test-char@ja', 'h test-char@en']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col', 'test-col@ja', + \ 'test-col@en', 'test-char', + \ 'test-char@ja', 'test-char@en']), sort(list)) endif catch call assert_exception('X') diff --git a/src/nvim/version.c b/src/nvim/version.c index d4f9c0232f..16523380cc 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -861,7 +861,7 @@ static const int included_patches[] = { // 94 NA // 93 NA 92, - // 91, + 91, 90, // 89 NA 88, -- cgit From 1c7f396f0cba3e87c4c1cae041489e28d59d1306 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 26 Sep 2017 15:32:31 -0400 Subject: vim-patch:8.0.0112 Problem: Tests 92 and 93 are old style. Solution: Make test92 and test93 new style. (Hirohito Higashi, closes vim/vim#1289) https://github.com/vim/vim/commit/eca626fcdb73d480660c78b9f84cc043fa561922 --- src/nvim/testdir/test_mksession.vim | 102 +++++++++++++++++++++++++++++- src/nvim/testdir/test_mksession_utf8.vim | 104 +++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 3 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 src/nvim/testdir/test_mksession_utf8.vim (limited to 'src') diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 2238213850..928f065efb 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -1,4 +1,104 @@ -" Tests for sessions +" Test for :mksession, :mkview and :loadview in latin1 encoding + +scriptencoding latin1 + +if !has('multi_byte') || !has('mksession') + finish +endif + +func Test_mksession() + tabnew + let wrap_save = &wrap + set sessionoptions=buffers splitbelow fileencoding=latin1 + call setline(1, [ + \ 'start:', + \ 'no multibyte chAracter', + \ ' one leaDing tab', + \ ' four leadinG spaces', + \ 'two consecutive tabs', + \ 'two tabs in one line', + \ 'one multibyteCharacter', + \ 'a two multiByte characters', + \ 'A three mulTibyte characters' + \ ]) + let tmpfile = tempname() + exec 'w! ' . tmpfile + /^start: + set wrap + vsplit + norm! j16| + split + norm! j16| + split + norm! j16| + split + norm! j8| + split + norm! j8| + split + norm! j16| + split + norm! j16| + split + norm! j16| + wincmd l + + set nowrap + /^start: + norm! j16|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + norm! j08|3zl + split + norm! j08|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + call wincol() + mksession! test_mks.out + let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"') + let expected = [ + \ 'normal! 016|', + \ 'normal! 016|', + \ 'normal! 016|', + \ 'normal! 08|', + \ 'normal! 08|', + \ 'normal! 016|', + \ 'normal! 016|', + \ 'normal! 016|', + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'", + \ " normal! 08|", + \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'", + \ " normal! 08|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|" + \ ] + call assert_equal(expected, li) + tabclose! + + call delete('test_mks.out') + call delete(tmpfile) + let &wrap = wrap_save +endfunc " Verify that arglist is stored correctly to the session file. func Test_mksession_arglist() diff --git a/src/nvim/testdir/test_mksession_utf8.vim b/src/nvim/testdir/test_mksession_utf8.vim new file mode 100644 index 0000000000..c05a1d3b6d --- /dev/null +++ b/src/nvim/testdir/test_mksession_utf8.vim @@ -0,0 +1,104 @@ +" Test for :mksession, :mkview and :loadview in utf-8 encoding + +set encoding=utf-8 +scriptencoding utf-8 + +if !has('multi_byte') || !has('mksession') + finish +endif + +func Test_mksession_utf8() + tabnew + let wrap_save = &wrap + set sessionoptions=buffers splitbelow fileencoding=utf-8 + call setline(1, [ + \ 'start:', + \ 'no multibyte chAracter', + \ ' one leaDing tab', + \ ' four leadinG spaces', + \ 'two consecutive tabs', + \ 'two tabs in one line', + \ 'one … multibyteCharacter', + \ 'a “b” two multiByte characters', + \ '“c”1€ three mulTibyte characters' + \ ]) + let tmpfile = tempname() + exec 'w! ' . tmpfile + /^start: + set wrap + vsplit + norm! j16| + split + norm! j16| + split + norm! j16| + split + norm! j8| + split + norm! j8| + split + norm! j16| + split + norm! j16| + split + norm! j16| + wincmd l + + set nowrap + /^start: + norm! j16|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + norm! j08|3zl + split + norm! j08|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + call wincol() + mksession! test_mks.out + let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"') + let expected = [ + \ 'normal! 016|', + \ 'normal! 016|', + \ 'normal! 016|', + \ 'normal! 08|', + \ 'normal! 08|', + \ 'normal! 016|', + \ 'normal! 016|', + \ 'normal! 016|', + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'", + \ " normal! 08|", + \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'", + \ " normal! 08|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|", + \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", + \ " normal! 016|" + \ ] + call assert_equal(expected, li) + tabclose! + + call delete('test_mks.out') + call delete(tmpfile) + let &wrap = wrap_save +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/version.c b/src/nvim/version.c index a060b4a74f..80018f6eab 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -840,7 +840,7 @@ static const int included_patches[] = { // 115 NA // 114 NA // 113 NA - // 112, + 112, 111, 110, // 109 NA -- cgit From 5bb2a19417e33ef573411b2069ab3d8095f7a9fa Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 26 Sep 2017 15:39:41 -0400 Subject: vim-patch:8.0.0253 Problem: When creating a session when winminheight is 2 or larger and loading that session gives an error. Solution: Also set winminheight before setting winheight to 1. (Rafael Bodill, neovim vim/vim#5717) https://github.com/vim/vim/commit/36ae89c550a4f0a380606c3fb4a054957ad698f0 --- src/nvim/ex_docmd.c | 2 ++ src/nvim/testdir/test_mksession.vim | 9 +++++++++ src/nvim/version.c | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 47e23b6e80..5145c65bc7 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -8933,6 +8933,8 @@ makeopens ( // resized when moving between windows. // Do this before restoring the view, so that the topline and the // cursor can be set. This is done again below. + // winminheight and winminwidth need to be set to avoid an error if the + // user has set winheight or winwidth. if (put_line(fd, "set winminheight=1 winminwidth=1 winheight=1 winwidth=1") == FAIL) { return FAIL; diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 928f065efb..284bafab75 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -100,6 +100,15 @@ func Test_mksession() let &wrap = wrap_save endfunc +func Test_mksession_winheight() + new + set winheight=10 winminheight=2 + mksession! test_mks.out + source test_mks.out + + " call delete('test_mks.out') +endfunc + " Verify that arglist is stored correctly to the session file. func Test_mksession_arglist() argdel * diff --git a/src/nvim/version.c b/src/nvim/version.c index 80018f6eab..f2686eacec 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -699,7 +699,7 @@ static const int included_patches[] = { // 256, // 255, // 254, - // 253, + 253, // 252, // 251, 250, -- cgit From 43da7ea27b3391a9e74c658b90a5ed1cae926d40 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 26 Sep 2017 15:50:09 -0400 Subject: vim-patch:8.0.0258 Problem: mksession test leaves file behind. Solution: Delete the file. Rename files to start with "X". https://github.com/vim/vim/commit/c9b56b2ceb4662f87c39ea07ba5090a073fd6286 --- src/nvim/testdir/test_mksession.vim | 14 +++++++------- src/nvim/version.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 284bafab75..7158b31a14 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -21,7 +21,7 @@ func Test_mksession() \ 'a two multiByte characters', \ 'A three mulTibyte characters' \ ]) - let tmpfile = tempname() + let tmpfile = 'Xtemp' exec 'w! ' . tmpfile /^start: set wrap @@ -62,8 +62,8 @@ func Test_mksession() norm! j016|3zl split call wincol() - mksession! test_mks.out - let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"') + mksession! Xtest_mks.out + let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"') let expected = [ \ 'normal! 016|', \ 'normal! 016|', @@ -95,7 +95,7 @@ func Test_mksession() call assert_equal(expected, li) tabclose! - call delete('test_mks.out') + call delete('Xtest_mks.out') call delete(tmpfile) let &wrap = wrap_save endfunc @@ -103,10 +103,10 @@ endfunc func Test_mksession_winheight() new set winheight=10 winminheight=2 - mksession! test_mks.out - source test_mks.out + mksession! Xtest_mks.out + source Xtest_mks.out - " call delete('test_mks.out') + call delete('Xtest_mks.out') endfunc " Verify that arglist is stored correctly to the session file. diff --git a/src/nvim/version.c b/src/nvim/version.c index f2686eacec..580ed592ca 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -694,7 +694,7 @@ static const int included_patches[] = { // 261, // 260 NA 259, - // 258, + 258, // 257 NA // 256, // 255, -- cgit From 25d4cd7e2830265505b0f6f88e6d08b4954af6eb Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 26 Sep 2017 15:52:21 -0400 Subject: vim-patch:8.0.1024 Problem: Manual folds are lost when a session file has the same buffer in two windows. (Jeansen) Solution: Use ":edit" only once. (Christian Brabandt, closes vim/vim#1958) https://github.com/vim/vim/commit/4bebc9a0565670b853d227f81a9a31eafdb47eed --- src/nvim/ex_docmd.c | 43 ++++++---- src/nvim/testdir/test_mksession.vim | 32 ++++++++ src/nvim/version.c | 151 ++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 5145c65bc7..87d9e10619 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -8813,7 +8813,7 @@ makeopens ( buf->b_wininfo == NULL ? (int64_t)1L : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0 - || ses_fname(fd, buf, &ssop_flags) == FAIL) + || ses_fname(fd, buf, &ssop_flags, true) == FAIL) return FAIL; } } @@ -8885,7 +8885,7 @@ makeopens ( && !bt_nofile(wp->w_buffer) ) { if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0 - || ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL) + || ses_fname(fd, wp->w_buffer, &ssop_flags, true) == FAIL) return FAIL; need_tabnew = FALSE; if (!wp->w_arg_idx_invalid) @@ -9223,21 +9223,30 @@ put_view ( if (wp->w_buffer->b_ffname != NULL && (!bt_nofile(wp->w_buffer) || wp->w_buffer->terminal) ) { - /* - * Editing a file in this buffer: use ":edit file". - * This may have side effects! (e.g., compressed or network file). - */ - if (fputs("edit ", fd) < 0 - || ses_fname(fd, wp->w_buffer, flagp) == FAIL) + // Editing a file in this buffer: use ":edit file". + // This may have side effects! (e.g., compressed or network file). + // + // Note, if a buffer for that file already exists, use :badd to + // edit that buffer, to not lose folding information (:edit resets + // folds in other buffers) + if (fputs("if bufexists('", fd) < 0 + || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL + || fputs("') | buffer ", fd) < 0 + || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL + || fputs(" | else | edit ", fd) < 0 + || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL + || fputs(" | endif", fd) < 0 + || put_eol(fd) == FAIL) { return FAIL; + } } else { /* No file in this buffer, just make it empty. */ if (put_line(fd, "enew") == FAIL) return FAIL; if (wp->w_buffer->b_ffname != NULL) { - /* The buffer does have a name, but it's not a file name. */ + // The buffer does have a name, but it's not a file name. if (fputs("file ", fd) < 0 - || ses_fname(fd, wp->w_buffer, flagp) == FAIL) + || ses_fname(fd, wp->w_buffer, flagp, true) == FAIL) return FAIL; } do_cursor = FALSE; @@ -9391,12 +9400,10 @@ ses_arglist ( return OK; } -/* - * Write a buffer name to the session file. - * Also ends the line. - * Returns FAIL if writing fails. - */ -static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp) +/// Write a buffer name to the session file. +/// Also ends the line, if "add_eol" is true. +/// Returns FAIL if writing fails. +static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp, bool add_eol) { char_u *name; @@ -9413,8 +9420,10 @@ static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp) name = buf->b_sfname; else name = buf->b_ffname; - if (ses_put_fname(fd, name, flagp) == FAIL || put_eol(fd) == FAIL) + if (ses_put_fname(fd, name, flagp) == FAIL + || (add_eol && put_eol(fd) == FAIL)) { return FAIL; + } return OK; } diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 7158b31a14..13fb07c7e0 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -121,4 +121,36 @@ func Test_mksession_arglist() argdel * endfunc + +func Test_mksession_one_buffer_two_windows() + edit Xtest1 + new Xtest2 + split + mksession! Xtest_mks.out + let lines = readfile('Xtest_mks.out') + let count1 = 0 + let count2 = 0 + let count2buf = 0 + for line in lines + if line =~ 'edit \f*Xtest1$' + let count1 += 1 + endif + if line =~ 'edit \f\{-}Xtest2' + let count2 += 1 + endif + if line =~ 'buffer \f\{-}Xtest2' + let count2buf += 1 + endif + endfor + call assert_equal(1, count1, 'Xtest1 count') + call assert_equal(2, count2, 'Xtest2 count') + call assert_equal(2, count2buf, 'Xtest2 buffer count') + + close + bwipe! + !cp Xtest_mks.out /tmp + call delete('Xtest_mks.out') +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/version.c b/src/nvim/version.c index 580ed592ca..9f75f75d4f 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -77,6 +77,157 @@ static char *features[] = { // clang-format off static const int included_patches[] = { + // 1026, + // 1025, + 1024, + // 1023, + // 1022, + // 1021, + // 1020, + // 1019, + // 1018, + // 1017, + // 1016, + // 1015, + // 1014, + // 1013, + // 1012, + // 1011, + // 1010, + // 1009, + // 1008, + // 1007, + // 1006, + // 1005, + // 1004, + // 1003, + // 1002, + // 1001, + // 1000, + // 999, + // 998, + // 997, + // 996, + // 995, + // 994, + // 993, + // 992, + // 991, + // 990, + // 989, + // 988, + // 987, + // 986, + // 985, + // 984, + // 983, + // 982, + // 981, + // 980, + // 979, + // 978, + // 977, + // 976, + // 975, + // 974, + // 973, + // 972, + // 971, + // 970, + // 969, + // 968, + // 967, + // 966, + // 965, + // 964, + // 963, + // 962, + // 961, + // 960, + // 959, + // 958, + // 957, + // 956, + // 955, + // 954, + // 953, + // 952, + // 951, + // 950, + // 949, + // 948, + // 947, + // 946, + // 945, + // 944, + // 943, + // 942, + // 941, + // 940, + // 939, + // 938, + // 937, + // 936, + // 935, + // 934, + // 933, + // 932, + // 931, + // 930, + // 929, + // 928, + // 927, + // 926, + // 925, + // 924, + // 923, + // 922, + // 921, + // 920, + // 919, + // 918, + // 917, + // 916, + // 915, + // 914, + // 913, + // 912, + // 911, + // 910, + // 909, + // 908, + // 907, + // 906, + // 905, + // 904, + // 903, + // 902, + // 901, + // 900, + // 899, + // 898, + // 897, + // 896, + // 895, + // 894, + // 893, + // 892, + // 891, + // 890, + // 889, + // 888, + // 887, + // 886, + // 885, + // 884, + // 883, + // 882, + // 881, + // 880, + // 879, + // 878, + // 877, + // 876, // 875, // 874, // 873, -- cgit From e0197a4d76420e611e9da2f437f01cb31d65cdb0 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 26 Sep 2017 16:04:01 -0400 Subject: vim-patch:8.0.1025 Problem: Stray copy command in test. Solution: Remove the copy command. https://github.com/vim/vim/commit/4e83961985abb78757b135f29ac4ffde675247af --- src/nvim/testdir/test_mksession.vim | 1 - src/nvim/version.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 13fb07c7e0..4774cf4af5 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -148,7 +148,6 @@ func Test_mksession_one_buffer_two_windows() close bwipe! - !cp Xtest_mks.out /tmp call delete('Xtest_mks.out') endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index 9f75f75d4f..fa8b495703 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -78,7 +78,7 @@ static char *features[] = { // clang-format off static const int included_patches[] = { // 1026, - // 1025, + 1025, 1024, // 1023, // 1022, -- cgit From f66307475db14858310f103600b42f23ff7ce48e Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 26 Sep 2017 16:08:15 -0400 Subject: lint --- src/nvim/ex_docmd.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 87d9e10619..3130747e08 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -8810,11 +8810,12 @@ makeopens ( && buf->b_fname != NULL && buf->b_p_bl) { if (fprintf(fd, "badd +%" PRId64 " ", - buf->b_wininfo == NULL ? - (int64_t)1L : - (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0 - || ses_fname(fd, buf, &ssop_flags, true) == FAIL) + buf->b_wininfo == NULL + ? (int64_t)1L + : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0 + || ses_fname(fd, buf, &ssop_flags, true) == FAIL) { return FAIL; + } } } @@ -8885,11 +8886,13 @@ makeopens ( && !bt_nofile(wp->w_buffer) ) { if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0 - || ses_fname(fd, wp->w_buffer, &ssop_flags, true) == FAIL) + || ses_fname(fd, wp->w_buffer, &ssop_flags, true) == FAIL) { return FAIL; - need_tabnew = FALSE; - if (!wp->w_arg_idx_invalid) + } + need_tabnew = false; + if (!wp->w_arg_idx_invalid) { edited_win = wp; + } break; } } @@ -9240,16 +9243,18 @@ put_view ( return FAIL; } } else { - /* No file in this buffer, just make it empty. */ - if (put_line(fd, "enew") == FAIL) + // No file in this buffer, just make it empty. + if (put_line(fd, "enew") == FAIL) { return FAIL; + } if (wp->w_buffer->b_ffname != NULL) { // The buffer does have a name, but it's not a file name. if (fputs("file ", fd) < 0 - || ses_fname(fd, wp->w_buffer, flagp, true) == FAIL) + || ses_fname(fd, wp->w_buffer, flagp, true) == FAIL) { return FAIL; + } } - do_cursor = FALSE; + do_cursor = false; } } -- cgit From 36f13ceb0ab384f0cad9813ae02792a1cf13021a Mon Sep 17 00:00:00 2001 From: ckelsel Date: Wed, 27 Sep 2017 20:05:17 +0800 Subject: vim-patch:8.0.0131 Problem: Not enough test coverage for syntax commands. Solution: Add more tests. (Dominique Pelle) https://github.com/vim/vim/commit/73b484c4da00011317dc68ada4f5dfc6515ad263 --- src/nvim/testdir/test_syntax.vim | 78 +++++++++++++++++++++++++++++++++++++++- src/nvim/version.c | 2 +- 2 files changed, 78 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index af2cbbfe8e..584b6f024a 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -50,7 +50,7 @@ func Test_syn_iskeyword() setlocal isk-=_ call assert_equal('DLTD_BY', GetSyntaxItem('DLTD')) /\/:norm! ygn - let b2=@0 + let b2 = @0 call assert_equal('DLTD', @0) syn iskeyword clear @@ -76,3 +76,79 @@ func Test_syntax_after_reload() call assert_true(exists('g:gotit')) call delete('Xsomefile') endfunc + +func Test_syntime() + if !has('profile') + finish + endif + + syntax on + syntime on + let a = execute('syntime report') + call assert_equal("\nNo Syntax items defined for this buffer", a) + + view ../memfile_test.c + setfiletype cpp + redraw + let a = execute('syntime report') + call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) + call assert_match(' \d*\.\d* \+[^0]\d* .* cppRawString ', a) + call assert_match(' \d*\.\d* \+[^0]\d* .* cppNumber ', a) + + syntime off + syntime clear + let a = execute('syntime report') + call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) + call assert_notmatch('.* cppRawString *', a) + call assert_notmatch('.* cppNumber*', a) + call assert_notmatch('[1-9]', a) + + call assert_fails('syntime abc', 'E475') + + syntax clear + let a = execute('syntime report') + call assert_equal("\nNo Syntax items defined for this buffer", a) + + bd +endfunc + +func Test_syntax_list() + syntax on + let a = execute('syntax list') + call assert_equal("\nNo Syntax items defined for this buffer", a) + + view ../memfile_test.c + setfiletype c + + let a = execute('syntax list') + call assert_match('cInclude*', a) + call assert_match('cDefine', a) + + let a = execute('syntax list cDefine') + call assert_notmatch('cInclude*', a) + call assert_match('cDefine', a) + call assert_match(' links to Macro$', a) + + call assert_fails('syntax list ABCD', 'E28:') + call assert_fails('syntax list @ABCD', 'E392:') + + syntax clear + let a = execute('syntax list') + call assert_equal("\nNo Syntax items defined for this buffer", a) + + bd +endfunc + +func Test_syntax_completion() + call feedkeys(":syn \\\"\", 'tx') + call assert_equal('"syn case clear cluster conceal enable include iskeyword keyword list manual match off on region reset spell sync', @:) + + call feedkeys(":syn case \\\"\", 'tx') + call assert_equal('"syn case ignore match', @:) + + call feedkeys(":syn list \\\"\", 'tx') + call assert_match('^"syn list Boolean Character ', @:) + + call feedkeys(":syn match \\\"\", 'tx') + call assert_match('^"syn match Boolean Character ', @:) +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index b0d4e194fa..bf53f16e8d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -972,7 +972,7 @@ static const int included_patches[] = { 134, 133, // 132, - // 131, + 131, // 130 NA // 129 NA 128, -- cgit From 65c97961ecdcfa89bb0ce9ff88f1e84e4d926f21 Mon Sep 17 00:00:00 2001 From: ckelsel Date: Wed, 27 Sep 2017 20:06:35 +0800 Subject: vim-patch:8.0.0132 Problem: Test fails because of using :finish. Solution: Change to return. https://github.com/vim/vim/commit/4c8980b717f73042f1d625ee255fa74eddb989ba --- src/nvim/testdir/test_syntax.vim | 2 +- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index 584b6f024a..73594f0f55 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -79,7 +79,7 @@ endfunc func Test_syntime() if !has('profile') - finish + return endif syntax on diff --git a/src/nvim/version.c b/src/nvim/version.c index bf53f16e8d..6b57185b50 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -971,7 +971,7 @@ static const int included_patches[] = { 135, 134, 133, - // 132, + 132, 131, // 130 NA // 129 NA -- cgit From f1242c2a26f51c53c6f248666023a919f93d72fa Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 27 Sep 2017 08:27:31 -0400 Subject: oldtest: Run test_mksession_utf8 tests --- src/nvim/testdir/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 9133bfc0a2..38caa8815d 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -59,6 +59,7 @@ NEW_TESTS ?= \ test_matchadd_conceal.res \ test_matchadd_conceal_utf8.res \ test_mksession.res \ + test_mksession_utf8.res \ test_nested_function.res \ test_normal.res \ test_quickfix.res \ -- cgit From f97ca6b3339ca04477296c834a159d40d2201ccd Mon Sep 17 00:00:00 2001 From: ckelsel Date: Thu, 28 Sep 2017 11:47:26 +0800 Subject: vim-patch:8.0.0155 Problem: When sorting zero elements a NULL pointer is passed to qsort(), which ubsan warns for. Solution: Don't call qsort() if there are no elements. (Dominique Pelle) https://github.com/vim/vim/commit/a216255a4faa91a15e7005ac319f2f62294f3f9e --- src/nvim/syntax.c | 9 ++++++--- src/nvim/version.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 65c0e2464a..5781424d2b 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -5845,9 +5845,12 @@ static void syntime_report(void) } } - /* sort on total time */ - qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T), - syn_compare_syntime); + // Sort on total time. Skip if there are no items to avoid passing NULL + // pointer to qsort(). + if (ga.ga_len > 1) { + qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T), + syn_compare_syntime); + } MSG_PUTS_TITLE(_( " TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN")); diff --git a/src/nvim/version.c b/src/nvim/version.c index 6b57185b50..1432a92998 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -948,7 +948,7 @@ static const int included_patches[] = { 158, // 157, 156, - // 155, + 155, // 154, // 153, // 152 NA -- cgit From ba7277cfb4e2556f246446d06b53f3427f28130f Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Wed, 26 Jul 2017 23:28:26 +0200 Subject: Adds nvim_get_hl_by_name/by_id ...in order to retrieve highlights. Added test/functional/api/highlight_spec.lua HL_NORMAL is not really a good name, since it's more like an empty attribute than the normal's one. If one pays attention, syn_cterm_attr2entry is never called with attr=0 because it's always special cased before. I suggest in subsequent PRs we remove the ATTR_OFF and just insert an EMPTY ATTR/RESET_ATTR/UNINITIALIZED for id 0. --- src/nvim/api/ui.c | 34 +----------- src/nvim/api/vim.c | 37 +++++++++++++ src/nvim/syntax.c | 22 +++----- src/nvim/tui/tui.c | 6 +-- src/nvim/ugrid.c | 4 +- src/nvim/ugrid.h | 2 - src/nvim/ui.c | 149 ++++++++++++++++++++++++++++++++++++++++------------- src/nvim/ui.h | 3 ++ 8 files changed, 166 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index bbbd5ab2dc..afbee09c1c 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -242,39 +242,7 @@ static void push_call(UI *ui, char *name, Array args) static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) { Array args = ARRAY_DICT_INIT; - Dictionary hl = ARRAY_DICT_INIT; - - if (attrs.bold) { - PUT(hl, "bold", BOOLEAN_OBJ(true)); - } - - if (attrs.underline) { - PUT(hl, "underline", BOOLEAN_OBJ(true)); - } - - if (attrs.undercurl) { - PUT(hl, "undercurl", BOOLEAN_OBJ(true)); - } - - if (attrs.italic) { - PUT(hl, "italic", BOOLEAN_OBJ(true)); - } - - if (attrs.reverse) { - PUT(hl, "reverse", BOOLEAN_OBJ(true)); - } - - if (attrs.foreground != -1) { - PUT(hl, "foreground", INTEGER_OBJ(attrs.foreground)); - } - - if (attrs.background != -1) { - PUT(hl, "background", INTEGER_OBJ(attrs.background)); - } - - if (attrs.special != -1) { - PUT(hl, "special", INTEGER_OBJ(attrs.special)); - } + Dictionary hl = hlattrs2dict(attrs); ADD(args, DICTIONARY_OBJ(hl)); push_call(ui, "highlight_set", args); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index ab893a4c0f..0459d9235d 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -33,6 +33,7 @@ #include "nvim/syntax.h" #include "nvim/getchar.h" #include "nvim/os/input.h" +#include "nvim/ui.h" #define LINE_BUFFER_SIZE 4096 @@ -55,6 +56,42 @@ void nvim_command(String command, Error *err) try_end(err); } +/// Retrieves highlight description from its name +/// +/// @param name Highlight group name +/// @return a highlight description e.g. {'bold': true, 'bg': 123, 'fg': 42} +/// @see nvim_get_hl_by_id +Dictionary nvim_get_hl_by_name(String name, Error *err) + FUNC_API_SINCE(3) +{ + Dictionary result = ARRAY_DICT_INIT; + int id = syn_name2id((const char_u *)name.data); + + if (id == 0) { + api_set_error(err, kErrorTypeException, "Invalid highlight name %s", + name.data); + return result; + } + result = nvim_get_hl_by_id(id, err); + return result; +} + +/// Retrieves highlight description from its id +/// +/// @param hl_id highlight id as returned by hlID() +/// @see nvim_get_hl_by_name +Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) + FUNC_API_SINCE(3) +{ + Dictionary dic = ARRAY_DICT_INIT; + if (syn_get_final_id((int)hl_id) == 0) { + api_set_error(err, kErrorTypeException, "Invalid highlight id %d", hl_id); + return dic; + } + int attrcode = syn_id2attr((int)hl_id); + return get_attr_by_id(attrcode, err); +} + /// Passes input keys to Nvim. /// On VimL error: Does not fail, but updates v:errmsg. /// diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 65c0e2464a..fdb7196fc4 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -42,6 +42,7 @@ #include "nvim/ui.h" #include "nvim/os/os.h" #include "nvim/os/time.h" +#include "nvim/api/private/helpers.h" static bool did_syntax_onoff = false; @@ -6622,7 +6623,6 @@ do_highlight(char_u *line, int forceit, int init) { syn_unadd_group(); } else { if (is_normal_group) { - HL_TABLE()[idx].sg_attr = 0; // Need to update all groups, because they might be using "bg" and/or // "fg", which have been changed now. highlight_attr_set_all(); @@ -6826,7 +6826,7 @@ int hl_combine_attr(int char_attr, int prim_attr) // Copy all attributes from char_aep to the new entry new_en = *char_aep; } else { - memset(&new_en, 0, sizeof(new_en)); + new_en = (attrentry_T)ATTRENTRY_INIT; } spell_aep = syn_cterm_attr2entry(prim_attr); @@ -6859,6 +6859,7 @@ int hl_combine_attr(int char_attr, int prim_attr) /// \note this function does not apply exclusively to cterm attr contrary /// to what its name implies +/// \warn don't call it with attr 0 (i.e., the null attribute) attrentry_T *syn_cterm_attr2entry(int attr) { attr -= ATTR_OFF; @@ -7103,22 +7104,15 @@ syn_list_header(int did_header, int outlen, int id) return newline; } -/* - * Set the attribute numbers for a highlight group. - * Called after one of the attributes has changed. - */ -static void -set_hl_attr ( - int idx /* index in array */ -) +/// Set the attribute numbers for a highlight group. +/// Called after one of the attributes has changed. +/// @param idx corrected highlight index +static void +set_hl_attr(int idx) { attrentry_T at_en = ATTRENTRY_INIT; struct hl_group *sgp = HL_TABLE() + idx; - // The "Normal" group doesn't need an attribute number - if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) { - return; - } at_en.cterm_ae_attr = sgp->sg_cterm; at_en.cterm_fg_color = sgp->sg_cterm_fg; diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 256772489d..8e0e905bcd 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -288,7 +288,7 @@ static void terminfo_stop(UI *ui) static void tui_terminal_start(UI *ui) { TUIData *data = ui->data; - data->print_attrs = EMPTY_ATTRS; + data->print_attrs = HLATTRS_INIT; ugrid_init(&data->grid); terminfo_start(ui); update_size(ui); @@ -628,7 +628,7 @@ static void clear_region(UI *ui, int top, int bot, int left, int right) if (grid->bg == -1 && right == ui->width -1) { // Background is set to the default color and the right edge matches the // screen end, try to use terminal codes for clearing the requested area. - HlAttrs clear_attrs = EMPTY_ATTRS; + HlAttrs clear_attrs = HLATTRS_INIT; clear_attrs.foreground = grid->fg; clear_attrs.background = grid->bg; update_attrs(ui, clear_attrs); @@ -926,7 +926,7 @@ static void tui_scroll(UI *ui, Integer count) cursor_goto(ui, grid->top, grid->left); // also set default color attributes or some terminals can become funny if (scroll_clears_to_current_colour) { - HlAttrs clear_attrs = EMPTY_ATTRS; + HlAttrs clear_attrs = HLATTRS_INIT; clear_attrs.foreground = grid->fg; clear_attrs.background = grid->bg; update_attrs(ui, clear_attrs); diff --git a/src/nvim/ugrid.c b/src/nvim/ugrid.c index 7a0a16687e..2b5e96ee60 100644 --- a/src/nvim/ugrid.c +++ b/src/nvim/ugrid.c @@ -16,7 +16,7 @@ void ugrid_init(UGrid *grid) { - grid->attrs = EMPTY_ATTRS; + grid->attrs = HLATTRS_INIT; grid->fg = grid->bg = -1; grid->cells = NULL; } @@ -118,7 +118,7 @@ UCell *ugrid_put(UGrid *grid, uint8_t *text, size_t size) static void clear_region(UGrid *grid, int top, int bot, int left, int right) { - HlAttrs clear_attrs = EMPTY_ATTRS; + HlAttrs clear_attrs = HLATTRS_INIT; clear_attrs.foreground = grid->fg; clear_attrs.background = grid->bg; UGRID_FOREACH_CELL(grid, top, bot, left, right, { diff --git a/src/nvim/ugrid.h b/src/nvim/ugrid.h index 268362bf1b..1cf047502d 100644 --- a/src/nvim/ugrid.h +++ b/src/nvim/ugrid.h @@ -21,8 +21,6 @@ struct ugrid { UCell **cells; }; -#define EMPTY_ATTRS ((HlAttrs){ false, false, false, false, false, -1, -1, -1 }) - #define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \ do { \ for (int row = top; row <= bot; row++) { \ diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 01d3604159..184ae56cf2 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -166,6 +166,115 @@ void ui_event(char *name, Array args) } } +/// Retrieves attribute description from its id +/// +/// @param attr_id attribute id +Dictionary get_attr_by_id(Integer attr_id, Error *err) +{ + HlAttrs attrs = HLATTRS_INIT; + Dictionary dic = ARRAY_DICT_INIT; + + if (attr_id == 0) { + goto end; + } + + attrentry_T *aep = syn_cterm_attr2entry((int)attr_id); + if (!aep) { + api_set_error(err, kErrorTypeException, + "Invalid attribute id %d", attr_id); + return dic; + } + + attrs = attrentry2hlattrs(aep, p_tgc); + +end: + return hlattrs2dict(attrs); +} + + +/// Converts an attrentry_T into an HlAttrs +/// +/// @param[in] aep data to convert +/// @param use_rgb use 'gui*' settings if true, else resorts to 'cterm*' +HlAttrs attrentry2hlattrs(const attrentry_T *aep, bool use_rgb) +{ + assert(aep); + + HlAttrs attrs = HLATTRS_INIT; + int mask = 0; + + mask = use_rgb ? aep->rgb_ae_attr : aep->cterm_ae_attr; + + attrs.bold = mask & HL_BOLD; + attrs.underline = mask & HL_UNDERLINE; + attrs.undercurl = mask & HL_UNDERCURL; + attrs.italic = mask & HL_ITALIC; + attrs.reverse = mask & (HL_INVERSE | HL_STANDOUT); + + if (use_rgb) { + if (aep->rgb_fg_color != -1) { + attrs.foreground = aep->rgb_fg_color; + } + + if (aep->rgb_bg_color != -1) { + attrs.background = aep->rgb_bg_color; + } + + if (aep->rgb_sp_color != -1) { + attrs.special = aep->rgb_sp_color; + } + } else { + if (cterm_normal_fg_color != aep->cterm_fg_color) { + attrs.foreground = aep->cterm_fg_color - 1; + } + + if (cterm_normal_bg_color != aep->cterm_bg_color) { + attrs.background = aep->cterm_bg_color - 1; + } + } + + return attrs; +} + +Dictionary hlattrs2dict(HlAttrs attrs) +{ + Dictionary hl = ARRAY_DICT_INIT; + + if (attrs.bold) { + PUT(hl, "bold", BOOLEAN_OBJ(true)); + } + + if (attrs.underline) { + PUT(hl, "underline", BOOLEAN_OBJ(true)); + } + + if (attrs.undercurl) { + PUT(hl, "undercurl", BOOLEAN_OBJ(true)); + } + + if (attrs.italic) { + PUT(hl, "italic", BOOLEAN_OBJ(true)); + } + + if (attrs.reverse) { + PUT(hl, "reverse", BOOLEAN_OBJ(true)); + } + + if (attrs.foreground != -1) { + PUT(hl, "foreground", INTEGER_OBJ(attrs.foreground)); + } + + if (attrs.background != -1) { + PUT(hl, "background", INTEGER_OBJ(attrs.background)); + } + + if (attrs.special != -1) { + PUT(hl, "special", INTEGER_OBJ(attrs.special)); + } + + return hl; +} + void ui_refresh(void) { if (!ui_active()) { @@ -405,54 +514,20 @@ void ui_flush(void) static void set_highlight_args(int attr_code) { - HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1, -1 }; + HlAttrs rgb_attrs = HLATTRS_INIT; HlAttrs cterm_attrs = rgb_attrs; if (attr_code == HL_NORMAL) { goto end; } - - int rgb_mask = 0; - int cterm_mask = 0; attrentry_T *aep = syn_cterm_attr2entry(attr_code); if (!aep) { goto end; } - rgb_mask = aep->rgb_ae_attr; - cterm_mask = aep->cterm_ae_attr; - - rgb_attrs.bold = rgb_mask & HL_BOLD; - rgb_attrs.underline = rgb_mask & HL_UNDERLINE; - rgb_attrs.undercurl = rgb_mask & HL_UNDERCURL; - rgb_attrs.italic = rgb_mask & HL_ITALIC; - rgb_attrs.reverse = rgb_mask & (HL_INVERSE | HL_STANDOUT); - cterm_attrs.bold = cterm_mask & HL_BOLD; - cterm_attrs.underline = cterm_mask & HL_UNDERLINE; - cterm_attrs.undercurl = cterm_mask & HL_UNDERCURL; - cterm_attrs.italic = cterm_mask & HL_ITALIC; - cterm_attrs.reverse = cterm_mask & (HL_INVERSE | HL_STANDOUT); - - if (aep->rgb_fg_color != normal_fg) { - rgb_attrs.foreground = aep->rgb_fg_color; - } - - if (aep->rgb_bg_color != normal_bg) { - rgb_attrs.background = aep->rgb_bg_color; - } - - if (aep->rgb_sp_color != normal_sp) { - rgb_attrs.special = aep->rgb_sp_color; - } - - if (cterm_normal_fg_color != aep->cterm_fg_color) { - cterm_attrs.foreground = aep->cterm_fg_color - 1; - } - - if (cterm_normal_bg_color != aep->cterm_bg_color) { - cterm_attrs.background = aep->cterm_bg_color - 1; - } + rgb_attrs = attrentry2hlattrs(aep, true); + cterm_attrs = attrentry2hlattrs(aep, false); end: UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs)); diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 064f77fee1..f1ea0716e6 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -21,6 +21,9 @@ typedef struct { int foreground, background, special; } HlAttrs; +#define HLATTRS_INIT \ + ((HlAttrs){ false, false, false, false, false, -1, -1, -1 }) + typedef struct ui_t UI; struct ui_t { -- cgit From e3a2cca3878f44252eccdc1918cc8854145de860 Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Sun, 27 Aug 2017 00:33:36 +0200 Subject: Increased test coverage for RGB and cterm --- src/nvim/api/vim.c | 4 ++-- src/nvim/syntax.c | 26 ++++++++++++++++++++++++++ src/nvim/ui.c | 25 ------------------------- 3 files changed, 28 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 0459d9235d..bf3e4bc6a0 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -78,7 +78,7 @@ Dictionary nvim_get_hl_by_name(String name, Error *err) /// Retrieves highlight description from its id /// -/// @param hl_id highlight id as returned by hlID() +/// @param hl_id highlight id as returned by |hlID()| /// @see nvim_get_hl_by_name Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) FUNC_API_SINCE(3) @@ -89,7 +89,7 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) return dic; } int attrcode = syn_id2attr((int)hl_id); - return get_attr_by_id(attrcode, err); + return hl_get_attr_by_id(attrcode, err); } /// Passes input keys to Nvim. diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index fdb7196fc4..2f48cc8757 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -8221,6 +8221,32 @@ RgbValue name_to_color(const uint8_t *name) return -1; } +/// Retrieves attribute description from its id +/// +/// @param attr_id attribute id +Dictionary hl_get_attr_by_id(Integer attr_id, Error *err) +{ + HlAttrs attrs = HLATTRS_INIT; + Dictionary dic = ARRAY_DICT_INIT; + + if (attr_id == 0) { + goto end; + } + + attrentry_T *aep = syn_cterm_attr2entry((int)attr_id); + if (!aep) { + api_set_error(err, kErrorTypeException, + "Invalid attribute id %d", attr_id); + return dic; + } + + attrs = attrentry2hlattrs(aep, p_tgc); + +end: + return hlattrs2dict(attrs); +} + + /************************************** * End of Highlighting stuff * **************************************/ diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 184ae56cf2..afe7a51d43 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -166,31 +166,6 @@ void ui_event(char *name, Array args) } } -/// Retrieves attribute description from its id -/// -/// @param attr_id attribute id -Dictionary get_attr_by_id(Integer attr_id, Error *err) -{ - HlAttrs attrs = HLATTRS_INIT; - Dictionary dic = ARRAY_DICT_INIT; - - if (attr_id == 0) { - goto end; - } - - attrentry_T *aep = syn_cterm_attr2entry((int)attr_id); - if (!aep) { - api_set_error(err, kErrorTypeException, - "Invalid attribute id %d", attr_id); - return dic; - } - - attrs = attrentry2hlattrs(aep, p_tgc); - -end: - return hlattrs2dict(attrs); -} - /// Converts an attrentry_T into an HlAttrs /// -- cgit From 3a006486397d611234abd9b429bce0b44d6b7747 Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Sun, 3 Sep 2017 05:25:57 +0200 Subject: Changed prototypes to accept a boolean "rgb" --- src/nvim/api/vim.c | 10 ++++++---- src/nvim/syntax.c | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index bf3e4bc6a0..0c3c497533 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -59,9 +59,10 @@ void nvim_command(String command, Error *err) /// Retrieves highlight description from its name /// /// @param name Highlight group name +/// @param rgb True to export GUI values /// @return a highlight description e.g. {'bold': true, 'bg': 123, 'fg': 42} /// @see nvim_get_hl_by_id -Dictionary nvim_get_hl_by_name(String name, Error *err) +Dictionary nvim_get_hl_by_name(String name, Boolean rgb, Error *err) FUNC_API_SINCE(3) { Dictionary result = ARRAY_DICT_INIT; @@ -72,15 +73,16 @@ Dictionary nvim_get_hl_by_name(String name, Error *err) name.data); return result; } - result = nvim_get_hl_by_id(id, err); + result = nvim_get_hl_by_id(id, rgb, err); return result; } /// Retrieves highlight description from its id /// /// @param hl_id highlight id as returned by |hlID()| +/// @param rgb True to export GUI values /// @see nvim_get_hl_by_name -Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) +Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Error *err) FUNC_API_SINCE(3) { Dictionary dic = ARRAY_DICT_INIT; @@ -89,7 +91,7 @@ Dictionary nvim_get_hl_by_id(Integer hl_id, Error *err) return dic; } int attrcode = syn_id2attr((int)hl_id); - return hl_get_attr_by_id(attrcode, err); + return hl_get_attr_by_id(attrcode, rgb, err); } /// Passes input keys to Nvim. diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 2f48cc8757..32567a63de 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -8224,7 +8224,7 @@ RgbValue name_to_color(const uint8_t *name) /// Retrieves attribute description from its id /// /// @param attr_id attribute id -Dictionary hl_get_attr_by_id(Integer attr_id, Error *err) +Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) { HlAttrs attrs = HLATTRS_INIT; Dictionary dic = ARRAY_DICT_INIT; @@ -8240,7 +8240,7 @@ Dictionary hl_get_attr_by_id(Integer attr_id, Error *err) return dic; } - attrs = attrentry2hlattrs(aep, p_tgc); + attrs = attrentry2hlattrs(aep, rgb); end: return hlattrs2dict(attrs); -- cgit From 481e40cc8ca061f5c3a68f56f30ee96e9086da4d Mon Sep 17 00:00:00 2001 From: Matthieu Coudron Date: Sat, 30 Sep 2017 11:44:50 +0900 Subject: Remove duplicate ATTRENTRY_INIT --- src/nvim/syntax.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 32567a63de..933baad901 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6825,8 +6825,6 @@ int hl_combine_attr(int char_attr, int prim_attr) if (char_aep != NULL) { // Copy all attributes from char_aep to the new entry new_en = *char_aep; - } else { - new_en = (attrentry_T)ATTRENTRY_INIT; } spell_aep = syn_cterm_attr2entry(prim_attr); -- cgit From 2b133101cf67b523c2503ef715dfb9ebfa732da2 Mon Sep 17 00:00:00 2001 From: Ignas Anikevicius Date: Mon, 18 Sep 2017 21:06:55 +0300 Subject: win: vim_FullName(): force backslashes #7287 - Replace obvious cases of '/' literal with PATHSEP. (There are still some remaining cases that need closer inspection.) - Fixup tests: ui/screen_basic closes #7117 ref https://github.com/neovim/neovim/issues/2471#issuecomment-271193714 --- src/nvim/path.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/path.c b/src/nvim/path.c index f2339c8046..51adcfb135 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1690,6 +1690,9 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force) if (strlen(fname) > (len - 1)) { xstrlcpy(buf, fname, len); // truncate +#ifdef WIN32 + slash_adjust(buf); +#endif return FAIL; } @@ -1702,6 +1705,9 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force) if (rv == FAIL) { xstrlcpy(buf, fname, len); // something failed; use the filename } +#ifdef WIN32 + slash_adjust(buf); +#endif return rv; } @@ -2196,11 +2202,11 @@ static int path_get_absolute_path(const char_u *fname, char_u *buf, // expand it if forced or not an absolute path if (force || !path_is_absolute_path(fname)) { - if ((p = vim_strrchr(fname, '/')) != NULL) { + if ((p = vim_strrchr(fname, PATHSEP)) != NULL) { // relative to root if (p == fname) { // only one path component - relative_directory[0] = '/'; + relative_directory[0] = PATHSEP; relative_directory[1] = NUL; } else { assert(p >= fname); -- cgit From 235fda5f86d80b1aa7d7cbcb41e3399c556b7455 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Tue, 3 Oct 2017 14:53:11 -0400 Subject: Stub ngettext when libintl isn't available This should have been included in #6547 as part of vim-patch:7.4.2152. Closes #7352 --- src/nvim/gettext.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/nvim/gettext.h b/src/nvim/gettext.h index aa0e97233e..60317b8484 100644 --- a/src/nvim/gettext.h +++ b/src/nvim/gettext.h @@ -13,6 +13,7 @@ #else # define _(x) ((char *)(x)) # define N_(x) x +# define ngettext(x, xs, n) ((n) == 1 ? (x) : (xs)) # define bindtextdomain(x, y) // empty # define bind_textdomain_codeset(x, y) // empty # define textdomain(x) // empty -- cgit From 5f4d2edeeea4d05761811d652dee8067fdbbae2a Mon Sep 17 00:00:00 2001 From: nate Date: Sat, 19 Aug 2017 18:33:14 -0700 Subject: 'titleold': set UI title on exit #7191 closes #7129 ref #4063 --- src/nvim/buffer.c | 13 ++++++++++--- src/nvim/globals.h | 1 + src/nvim/option.c | 1 + src/nvim/os_unix.c | 7 +++++++ 4 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 724a8578ac..950010b13b 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3069,9 +3069,16 @@ static bool ti_change(char_u *str, char_u **last) /// Set current window title void resettitle(void) { - ui_call_set_title(cstr_as_string((char *)lasttitle)); - ui_call_set_icon(cstr_as_string((char *)lasticon)); - ui_flush(); + // if icon change, should the title be reset too? + if (p_icon) { + ui_call_set_title(cstr_as_string((char *)lasttitle)); + ui_call_set_icon(cstr_as_string((char *)lasticon)); + } else if (p_title) { + ui_call_set_title(cstr_as_string((char *)lasttitle)); + } + if (p_title || p_icon) { + ui_flush(); + } } # if defined(EXITFREE) diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 300e506854..62bb817c4c 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -279,6 +279,7 @@ EXTERN int need_wait_return INIT(= 0); /* need to wait for return later */ EXTERN int did_wait_return INIT(= FALSE); /* wait_return() was used and nothing written since then */ EXTERN int need_maketitle INIT(= TRUE); /* call maketitle() soon */ +EXTERN int did_enable_title INIT(= FALSE); /* did set title */ EXTERN int quit_more INIT(= FALSE); /* 'q' hit at "--more--" msg */ #if defined(UNIX) || defined(MACOS_X) diff --git a/src/nvim/option.c b/src/nvim/option.c index 13aadb71bb..3a7499f195 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1953,6 +1953,7 @@ did_set_title ( if (starting != NO_SCREEN) { maketitle(); resettitle(); + did_enable_title = true; } } diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 692bcc97f4..5855a874c4 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -15,6 +15,7 @@ #include #include "nvim/api/private/handle.h" +#include "nvim/api/private/helpers.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/os_unix.h" @@ -137,6 +138,12 @@ void mch_exit(int r) FUNC_ATTR_NORETURN { exiting = true; + if ((p_title + || (did_enable_title + && (p_titlestring == NULL || STRLEN(p_titlestring) == 0))) + && p_titleold != NULL) { + ui_call_set_title(cstr_as_string((char *)p_titleold)); + } ui_builtin_stop(); ui_flush(); ml_close_all(true); // remove all memfiles -- cgit From 70e84a7c4c7bfad9b3a0ec18fd219f51205c03f8 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 5 Oct 2017 09:14:18 +0200 Subject: 'titleold': simplify behavior - default 'titleold' to empty - set title on exit if 'title' is enabled and 'titleold' is non-empty - update docs --- src/nvim/buffer.c | 5 +---- src/nvim/globals.h | 1 - src/nvim/option.c | 1 - src/nvim/options.lua | 2 +- src/nvim/os_unix.c | 5 +---- 5 files changed, 3 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 950010b13b..fbfb4e02ea 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3069,14 +3069,11 @@ static bool ti_change(char_u *str, char_u **last) /// Set current window title void resettitle(void) { - // if icon change, should the title be reset too? if (p_icon) { - ui_call_set_title(cstr_as_string((char *)lasttitle)); ui_call_set_icon(cstr_as_string((char *)lasticon)); - } else if (p_title) { - ui_call_set_title(cstr_as_string((char *)lasttitle)); } if (p_title || p_icon) { + ui_call_set_title(cstr_as_string((char *)lasttitle)); ui_flush(); } } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 62bb817c4c..300e506854 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -279,7 +279,6 @@ EXTERN int need_wait_return INIT(= 0); /* need to wait for return later */ EXTERN int did_wait_return INIT(= FALSE); /* wait_return() was used and nothing written since then */ EXTERN int need_maketitle INIT(= TRUE); /* call maketitle() soon */ -EXTERN int did_enable_title INIT(= FALSE); /* did set title */ EXTERN int quit_more INIT(= FALSE); /* 'q' hit at "--more--" msg */ #if defined(UNIX) || defined(MACOS_X) diff --git a/src/nvim/option.c b/src/nvim/option.c index 3a7499f195..13aadb71bb 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1953,7 +1953,6 @@ did_set_title ( if (starting != NO_SCREEN) { maketitle(); resettitle(); - did_enable_title = true; } } diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 103227f6b5..84ccb2e28d 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2498,7 +2498,7 @@ return { no_mkrc=true, vi_def=true, varname='p_titleold', - defaults={if_true={vi=N_("Thanks for flying Vim")}} + defaults={if_true={vi=N_("")}} }, { full_name='titlestring', diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 5855a874c4..2748de7329 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -138,10 +138,7 @@ void mch_exit(int r) FUNC_ATTR_NORETURN { exiting = true; - if ((p_title - || (did_enable_title - && (p_titlestring == NULL || STRLEN(p_titlestring) == 0))) - && p_titleold != NULL) { + if (p_title && *p_titleold != NUL) { ui_call_set_title(cstr_as_string((char *)p_titleold)); } ui_builtin_stop(); -- cgit From 73b50de925c10aaf0db2ffed47ec8459b0730cd1 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 5 Oct 2017 09:49:17 +0200 Subject: 'titleold': move logic to getout() --- src/nvim/main.c | 5 +++++ src/nvim/os_unix.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/main.c b/src/nvim/main.c index 024c56dd05..ea7a58bda3 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -649,6 +649,11 @@ void getout(int exitval) /* Position the cursor again, the autocommands may have moved it */ ui_cursor_goto((int)Rows - 1, 0); + // Apply 'titleold'. + if (p_title && *p_titleold != NUL) { + ui_call_set_title(cstr_as_string((char *)p_titleold)); + } + #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) iconv_end(); #endif diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 2748de7329..692bcc97f4 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -15,7 +15,6 @@ #include #include "nvim/api/private/handle.h" -#include "nvim/api/private/helpers.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/os_unix.h" @@ -138,9 +137,6 @@ void mch_exit(int r) FUNC_ATTR_NORETURN { exiting = true; - if (p_title && *p_titleold != NUL) { - ui_call_set_title(cstr_as_string((char *)p_titleold)); - } ui_builtin_stop(); ui_flush(); ml_close_all(true); // remove all memfiles -- cgit From a4019bc9f6478941fe75879e81d37bd628bc94c5 Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Sat, 7 Oct 2017 06:45:23 -0400 Subject: eval.c: ga_concat_esc() #7357 vim-patch:2368917d8f0c0a997eac7a51ddfaa748dc528392 closes #7256 --- src/nvim/eval.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 5ee91d417a..86b99c2783 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6733,6 +6733,39 @@ static void prepare_assert_error(garray_T *gap) } } +// Append "str" to "gap", escaping unprintable characters. +// Changes NL to \n, CR to \r, etc. +static void ga_concat_esc(garray_T *gap, char_u *str) +{ + char_u *p; + char_u buf[NUMBUFLEN]; + + if (str == NULL) { + ga_concat(gap, (char_u *)"NULL"); + return; + } + + for (p = str; *p != NUL; p++) { + switch (*p) { + case BS: ga_concat(gap, (char_u *)"\\b"); break; + case ESC: ga_concat(gap, (char_u *)"\\e"); break; + case FF: ga_concat(gap, (char_u *)"\\f"); break; + case NL: ga_concat(gap, (char_u *)"\\n"); break; + case TAB: ga_concat(gap, (char_u *)"\\t"); break; + case CAR: ga_concat(gap, (char_u *)"\\r"); break; + case '\\': ga_concat(gap, (char_u *)"\\\\"); break; + default: + if (*p < ' ') { + vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); + ga_concat(gap, buf); + } else { + ga_append(gap, *p); + } + break; + } + } +} + // Fill "gap" with information about an assert error. static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, @@ -6753,11 +6786,11 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, ga_concat(gap, (char_u *)"Expected "); } if (exp_str == NULL) { - tofree = (char_u *) encode_tv2string(exp_tv, NULL); - ga_concat(gap, tofree); + tofree = (char_u *)encode_tv2string(exp_tv, NULL); + ga_concat_esc(gap, tofree); xfree(tofree); } else { - ga_concat(gap, exp_str); + ga_concat_esc(gap, exp_str); } if (atype != ASSERT_NOTEQUAL) { if (atype == ASSERT_MATCH) { @@ -6768,7 +6801,7 @@ static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, ga_concat(gap, (char_u *)" but got "); } tofree = (char_u *)encode_tv2string(got_tv, NULL); - ga_concat(gap, tofree); + ga_concat_esc(gap, tofree); xfree(tofree); } } -- cgit From 9ad7529f705c883e13fba9a014696fb37318145f Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Sat, 7 Oct 2017 20:32:37 +0800 Subject: vim-patch:8.0.0157 (#7362) Problem: No command line completion for ":syntax spell" and ":syntax sync". Solution: Implement the completion. (Dominique Pelle) https://github.com/vim/vim/commit/2d02839050a2557bf36dab37ccd9f92168a757d1 --- src/nvim/syntax.c | 36 +++++++++++++++++++++++++++++------- src/nvim/testdir/test_syntax.vim | 8 ++++++++ src/nvim/version.c | 2 +- 3 files changed, 38 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 65c0e2464a..ddc3f5c27b 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -5567,8 +5567,10 @@ bool syntax_present(win_T *win) static enum { - EXP_SUBCMD, /* expand ":syn" sub-commands */ - EXP_CASE /* expand ":syn case" arguments */ + EXP_SUBCMD, // expand ":syn" sub-commands + EXP_CASE, // expand ":syn case" arguments + EXP_SPELL, // expand ":syn spell" arguments + EXP_SYNC // expand ":syn sync" arguments } expand_what; /* @@ -5612,6 +5614,10 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg) xp->xp_context = EXPAND_NOTHING; } else if (STRNICMP(arg, "case", p - arg) == 0) { expand_what = EXP_CASE; + } else if (STRNICMP(arg, "spell", p - arg) == 0) { + expand_what = EXP_SPELL; + } else if (STRNICMP(arg, "sync", p - arg) == 0) { + expand_what = EXP_SYNC; } else if (STRNICMP(arg, "keyword", p - arg) == 0 || STRNICMP(arg, "region", p - arg) == 0 || STRNICMP(arg, "match", p - arg) == 0 @@ -5624,17 +5630,33 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg) } } -static char *(case_args[]) = {"match", "ignore", NULL}; - /* * Function given to ExpandGeneric() to obtain the list syntax names for * expansion. */ char_u *get_syntax_name(expand_T *xp, int idx) { - if (expand_what == EXP_SUBCMD) - return (char_u *)subcommands[idx].name; - return (char_u *)case_args[idx]; + switch (expand_what) { + case EXP_SUBCMD: + return (char_u *)subcommands[idx].name; + case EXP_CASE: { + static char *case_args[] = { "match", "ignore", NULL }; + return (char_u *)case_args[idx]; + } + case EXP_SPELL: { + static char *spell_args[] = + { "toplevel", "notoplevel", "default", NULL }; + return (char_u *)spell_args[idx]; + } + case EXP_SYNC: { + static char *sync_args[] = + { "ccomment", "clear", "fromstart", + "linebreaks=", "linecont", "lines=", "match", + "maxlines=", "minlines=", "region", NULL }; + return (char_u *)sync_args[idx]; + } + } + return NULL; } diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index af2cbbfe8e..05e930d984 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -76,3 +76,11 @@ func Test_syntax_after_reload() call assert_true(exists('g:gotit')) call delete('Xsomefile') endfunc + +func Test_syntax_completion() + call feedkeys(":syn spell \\\"\", 'tx') + call assert_equal('"syn spell default notoplevel toplevel', @:) + + call feedkeys(":syn sync \\\"\", 'tx') + call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:) +endfunc diff --git a/src/nvim/version.c b/src/nvim/version.c index b0d4e194fa..76897088a1 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -946,7 +946,7 @@ static const int included_patches[] = { // 160, 159, 158, - // 157, + 157, 156, // 155, // 154, -- cgit From 7a832c312f13bd6be9350952cdac3bd30613a824 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 7 Oct 2017 15:55:25 +0200 Subject: syntax: 'cursorcolumn', 'colorcolumn': low priority #6380 --- src/nvim/screen.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 921ef06c7b..a6418a6f27 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2201,16 +2201,16 @@ win_line ( int change_end = -1; /* last col of changed area */ colnr_T trailcol = MAXCOL; /* start of trailing spaces */ int need_showbreak = false; // overlong line, skip first x chars - int line_attr = 0; /* attribute for the whole line */ - matchitem_T *cur; /* points to the match list */ - match_T *shl; /* points to search_hl or a match */ - int shl_flag; /* flag to indicate whether search_hl - has been processed or not */ - int prevcol_hl_flag; /* flag to indicate whether prevcol - equals startcol of search_hl or one - of the matches */ - int prev_c = 0; /* previous Arabic character */ - int prev_c1 = 0; /* first composing char for prev_c */ + int line_attr = 0; // attribute for the whole line + matchitem_T *cur; // points to the match list + match_T *shl; // points to search_hl or a match + int shl_flag; // flag to indicate whether search_hl + // has been processed or not + int prevcol_hl_flag; // flag to indicate whether prevcol + // equals startcol of search_hl or one + // of the matches + int prev_c = 0; // previous Arabic character + int prev_c1 = 0; // first composing char for prev_c int did_line_attr = 0; bool search_attr_from_match = false; // if search_attr is from :match @@ -3594,15 +3594,13 @@ win_line ( && lcs_eol_one > 0) { // Display a '$' after the line or highlight an extra // character if the line break is included. - // For a diff line the highlighting continues after the - // "$". + // For a diff line the highlighting continues after the "$". if (diff_hlf == (hlf_T)0 && line_attr == 0) { - /* In virtualedit, visual selections may extend - * beyond end of line. */ + // In virtualedit, visual selections may extend beyond end of line. if (area_highlighting && virtual_active() - && tocol != MAXCOL && vcol < tocol) + && tocol != MAXCOL && vcol < tocol) { n_extra = 0; - else { + } else { p_extra = at_end_str; n_extra = 1; c_extra = NUL; @@ -4035,10 +4033,10 @@ win_line ( if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol && lnum != wp->w_cursor.lnum) { vcol_save_attr = char_attr; - char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUC)); + char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUC), char_attr); } else if (draw_color_col && VCOL_HLC == *color_cols) { vcol_save_attr = char_attr; - char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_MC)); + char_attr = hl_combine_attr(win_hl_attr(wp, HLF_MC), char_attr); } } -- cgit From d1874ab2821d076397290cc154d87ec2dc352c79 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 7 Oct 2017 16:06:46 +0200 Subject: syntax: 'cursorline': low priority #6380 --- src/nvim/screen.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/nvim/screen.c b/src/nvim/screen.c index a6418a6f27..5659f30f64 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2202,6 +2202,7 @@ win_line ( colnr_T trailcol = MAXCOL; /* start of trailing spaces */ int need_showbreak = false; // overlong line, skip first x chars int line_attr = 0; // attribute for the whole line + int line_attr_low_priority = 0; // current line, lowest priority matchitem_T *cur; // points to the match list match_T *shl; // points to search_hl or a match int shl_flag; // flag to indicate whether search_hl @@ -2427,10 +2428,17 @@ win_line ( filler_lines = wp->w_topfill; filler_todo = filler_lines; - /* If this line has a sign with line highlighting set line_attr. */ + // 'cursorline' highlighting for the current window. Not when Visual mode is + // active, because it's not clear what is selected then. + if (wp->w_p_cul && lnum == wp->w_cursor.lnum + && !(wp == curwin && VIsual_active)) { + line_attr_low_priority = win_hl_attr(wp, HLF_CUL); + } + v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL); - if (v != 0) - line_attr = sign_get_attr((int)v, TRUE); + if (v != 0) { + line_attr = sign_get_attr((int)v, true); + } // Highlight the current line in the quickfix window. if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) { @@ -2441,7 +2449,7 @@ win_line ( line_attr = hl_combine_attr(wp->w_hl_attr_normal, line_attr); } - if (line_attr != 0) { + if (line_attr_low_priority || line_attr) { area_highlighting = true; } @@ -2663,20 +2671,6 @@ win_line ( cur = cur->next; } - /* Cursor line highlighting for 'cursorline' in the current window. Not - * when Visual mode is active, because it's not clear what is selected - * then. */ - if (wp->w_p_cul && lnum == wp->w_cursor.lnum - && !(wp == curwin && VIsual_active)) { - if (line_attr != 0 && !(State & INSERT) && bt_quickfix(wp->w_buffer) - && qf_current_entry(wp) == lnum) { - line_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), line_attr); - } else { - line_attr = win_hl_attr(wp, HLF_CUL); - } - area_highlighting = true; - } - off = (unsigned)(current_ScreenLine - ScreenLines); col = 0; if (wp->w_p_rl) { @@ -3595,7 +3589,9 @@ win_line ( // Display a '$' after the line or highlight an extra // character if the line break is included. // For a diff line the highlighting continues after the "$". - if (diff_hlf == (hlf_T)0 && line_attr == 0) { + if (diff_hlf == (hlf_T)0 + && line_attr == 0 + && line_attr_low_priority == 0) { // In virtualedit, visual selections may extend beyond end of line. if (area_highlighting && virtual_active() && tocol != MAXCOL && vcol < tocol) { @@ -3659,7 +3655,7 @@ win_line ( (col < wp->w_width))) { c = ' '; ptr--; // put it back at the NUL - } else if ((diff_hlf != (hlf_T)0 || line_attr != 0) + } else if ((diff_hlf != (hlf_T)0 || line_attr_low_priority || line_attr) && (wp->w_p_rl ? (col >= 0) : (col - boguscols < wp->w_width))) { @@ -3671,7 +3667,8 @@ win_line ( did_line_attr++; // don't do search HL for the rest of the line - if (line_attr != 0 && char_attr == search_attr && col > 0) { + if ((line_attr_low_priority || line_attr) + && char_attr == search_attr && col > 0) { char_attr = line_attr; } if (diff_hlf == HLF_TXD) { @@ -4040,6 +4037,9 @@ win_line ( } } + // Apply `line_attr_low_priority` now, so that everthing can override it. + char_attr = hl_combine_attr(line_attr_low_priority, char_attr); + /* * Store character to be displayed. * Skip characters that are left of the screen for 'nowrap'. -- cgit From c0e45d97b0cbc700cd6f2b9733c15875339262df Mon Sep 17 00:00:00 2001 From: ckelsel Date: Sat, 30 Sep 2017 21:43:03 +0800 Subject: vim-patch:8.0.0148 #7344 Problem: When a C preprocessor statement has two line continuations the following line does not have the right indent. (Ken Takata) Solution: Add the indent of the previous continuation line. (Hirohito Higashi) https://github.com/vim/vim/commit/c6aa475a27e3ed1645446b014c32ebf68d005d49 --- src/nvim/indent_c.c | 82 +++++++++++++++++++++++++++++++---------------------- src/nvim/version.c | 2 +- 2 files changed, 49 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 4a6393ac36..279d45bb0a 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -734,16 +734,20 @@ static int cin_ispreproc(char_u *s) return FALSE; } -/* - * Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a - * continuation line of a preprocessor statement. Decrease "*lnump" to the - * start and return the line in "*pp". - */ -static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump) +/// Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a +/// continuation line of a preprocessor statement. Decrease "*lnump" to the +/// start and return the line in "*pp". +/// Put the amount of indent in "*amount". +static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount) { char_u *line = *pp; linenr_T lnum = *lnump; - int retval = FALSE; + int retval = false; + int candidate_amount = *amount; + + if (*line != NUL && line[STRLEN(line) - 1] == '\\') { + candidate_amount = get_indent_lnum(lnum); + } for (;; ) { if (cin_ispreproc(line)) { @@ -758,8 +762,12 @@ static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump) break; } - if (lnum != *lnump) + if (lnum != *lnump) { *pp = ml_get(*lnump); + } + if (retval) { + *amount = candidate_amount; + } return retval; } @@ -1994,10 +2002,12 @@ int get_c_indent(void) amount = -1; for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum) { l = skipwhite(ml_get(lnum)); - if (cin_nocode(l)) /* skip comment lines */ + if (cin_nocode(l)) { // skip comment lines continue; - if (cin_ispreproc_cont(&l, &lnum)) - continue; /* ignore #define, #if, etc. */ + } + if (cin_ispreproc_cont(&l, &lnum, &amount)) { + continue; // ignore #define, #if, etc. + } curwin->w_cursor.lnum = lnum; /* Skip a comment or raw string. XXX */ @@ -2353,15 +2363,14 @@ int get_c_indent(void) * up with it. */ if (curwin->w_cursor.lnum <= ourscope) { - /* we reached end of scope: - * if looking for an enum or structure initialization - * go further back: - * if it is an initializer (enum xxx or xxx =), then - * don't add ind_continuation, otherwise it is a variable - * declaration: - * int x, - * here; <-- add ind_continuation - */ + // We reached end of scope: + // If looking for a enum or structure initialization + // go further back: + // If it is an initializer (enum xxx or xxx =), then + // don't add ind_continuation, otherwise it is a variable + // declaration: + // int x, + // here; <-- add ind_continuation if (lookfor == LOOKFOR_ENUM_OR_INIT) { if (curwin->w_cursor.lnum == 0 || curwin->w_cursor.lnum @@ -2389,11 +2398,12 @@ int get_c_indent(void) continue; } - /* - * Skip preprocessor directives and blank lines. - */ - if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) + // + // Skip preprocessor directives and blank lines. + // + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) { continue; + } if (cin_nocode(l)) continue; @@ -2497,9 +2507,10 @@ int get_c_indent(void) continue; } - /* Skip preprocessor directives and blank lines. */ - if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) + // Skip preprocessor directives and blank lines. + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) { continue; + } /* Finally the actual check for "namespace". */ if (cin_is_cpp_namespace(l)) { @@ -2662,9 +2673,10 @@ int get_c_indent(void) * unlocked it) */ l = get_cursor_line_ptr(); - if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum) - || cin_nocode(l)) + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount) + || cin_nocode(l)) { continue; + } /* * Are we at the start of a cpp base class declaration or @@ -3309,11 +3321,12 @@ term_again: break; } - /* - * Skip preprocessor directives and blank lines. - */ - if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)) + // + // Skip preprocessor directives and blank lines. + // + if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) { continue; + } if (cin_nocode(l)) continue; @@ -3405,9 +3418,10 @@ term_again: while (curwin->w_cursor.lnum > 1) { look = ml_get(--curwin->w_cursor.lnum); - if (!(cin_nocode(look) || cin_ispreproc_cont( - &look, &curwin->w_cursor.lnum))) + if (!(cin_nocode(look) + || cin_ispreproc_cont(&look, &curwin->w_cursor.lnum, &amount))) { break; + } } if (curwin->w_cursor.lnum > 0 && cin_ends_in(look, (char_u *)"}", NULL)) diff --git a/src/nvim/version.c b/src/nvim/version.c index 76897088a1..8bcf8c7a59 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -955,7 +955,7 @@ static const int included_patches[] = { // 151, 150, 149, - // 148, + 148, 147, 146, // 145 NA -- cgit From e3ca1e604630d930ddc49fccb9a1541d381b1915 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Sat, 7 Oct 2017 23:20:34 +0800 Subject: vim-patch:8.0.0142 (#7335) see also #7082 Problem: Normal colors are wrong with 'termguicolors'. Solution: Initialize to INVALCOLOR instead of zero. (Ben Jackson, closes vim/vim#1344) https://github.com/vim/vim/commit/0cdb72aa38c4a0140c94d56bf8bc17cb30260ebf --- src/nvim/syntax.c | 2 -- src/nvim/version.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index ddc3f5c27b..8de81f02df 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6847,8 +6847,6 @@ int hl_combine_attr(int char_attr, int prim_attr) if (char_aep != NULL) { // Copy all attributes from char_aep to the new entry new_en = *char_aep; - } else { - memset(&new_en, 0, sizeof(new_en)); } spell_aep = syn_cterm_attr2entry(prim_attr); diff --git a/src/nvim/version.c b/src/nvim/version.c index 8bcf8c7a59..8015d7520d 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -961,7 +961,7 @@ static const int included_patches[] = { // 145 NA // 144 NA 143, - // 142, + 142, // 141, // 140, // 139 NA -- cgit From d916ea107a243768ff5b272a0bf2522e42f51b65 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 7 Oct 2017 18:05:02 +0200 Subject: resettitle(): remove conditions (#7360) These conditions were added in #7358 for no apparent reason. ref https://github.com/neovim/neovim/pull/7358#discussion_r143064448 --- src/nvim/buffer.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index fbfb4e02ea..fc5bb90973 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3069,13 +3069,9 @@ static bool ti_change(char_u *str, char_u **last) /// Set current window title void resettitle(void) { - if (p_icon) { - ui_call_set_icon(cstr_as_string((char *)lasticon)); - } - if (p_title || p_icon) { - ui_call_set_title(cstr_as_string((char *)lasttitle)); - ui_flush(); - } + ui_call_set_icon(cstr_as_string((char *)lasticon)); + ui_call_set_title(cstr_as_string((char *)lasttitle)); + ui_flush(); } # if defined(EXITFREE) -- cgit From 1663599bebd7bd360f116b003b9f572b01d7a8d8 Mon Sep 17 00:00:00 2001 From: KunMing Xie Date: Mon, 9 Oct 2017 00:52:57 +0800 Subject: vim-patch:8.0.0164 (#7368) Problem: Outdated and misplaced comments. Solution: Fix the comments. https://github.com/vim/vim/commit/caa55b65c204946d160c1b743c5f8f3b506dc4d3 --- src/nvim/charset.c | 2 +- src/nvim/eval.c | 2 +- src/nvim/getchar.c | 25 ++++++++++--------------- src/nvim/version.c | 2 +- 4 files changed, 13 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 403ef65c4f..577fc13a31 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -762,7 +762,7 @@ bool vim_isIDc(int c) } /// Check that "c" is a keyword character: -/// Letters and characters from 'iskeyword' option for current buffer. +/// Letters and characters from 'iskeyword' option for the current buffer. /// For multi-byte characters mb_get_class() is used (builtin rules). /// /// @param c character to check diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 86b99c2783..b2a0d9a767 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17528,7 +17528,7 @@ static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_dict_add_nr(dict, S_LEN("skipcol"), (varnumber_T)curwin->w_skipcol); } -/// Writes list of strings to file +/// Write "list" of strings to file "fd". /// /// @param fp File to write to. /// @param[in] list List to write. diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index f5949333bd..4f8a8528a0 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -868,20 +868,15 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, bool silent) addlen = (int)STRLEN(str); - /* - * Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off] - */ if (offset == 0 && addlen <= typebuf.tb_off) { + // Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off] typebuf.tb_off -= addlen; memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen); - } - /* - * Need to allocate a new buffer. - * In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4 - * characters. We add some extra room to avoid having to allocate too - * often. - */ - else { + } else { + // Need to allocate a new buffer. + // In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4 + // characters. We add some extra room to avoid having to allocate too + // often. newoff = MAXMAPLEN + 4; newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4); if (newlen < 0) { /* string is getting too long */ @@ -1663,10 +1658,10 @@ static int vgetorpeek(int advance) } if (c != NUL && !got_int) { if (advance) { - /* KeyTyped = FALSE; When the command that stuffed something - * was typed, behave like the stuffed command was typed. - * needed for CTRL-W CTRl-] to open a fold, for example. */ - KeyStuffed = TRUE; + // KeyTyped = FALSE; When the command that stuffed something + // was typed, behave like the stuffed command was typed. + // needed for CTRL-W CTRL-] to open a fold, for example. + KeyStuffed = true; } if (typebuf.tb_no_abbr_cnt == 0) typebuf.tb_no_abbr_cnt = 1; /* no abbreviations now */ diff --git a/src/nvim/version.c b/src/nvim/version.c index 8015d7520d..11ae3f11b6 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -939,7 +939,7 @@ static const int included_patches[] = { 167, // 166, 165, - // 164, + 164, // 163 NA // 162 NA // 161 NA -- cgit From 52517321d1859c31fef14aa75d784615693fcecb Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 8 Oct 2017 20:23:11 +0200 Subject: test: nvim_get_hl_by_name/by_id #7082 - test all properties - test failure modes --- src/nvim/api/vim.c | 1 - src/nvim/syntax.c | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index bc89ffefe6..98f4410347 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -33,7 +33,6 @@ #include "nvim/syntax.h" #include "nvim/getchar.h" #include "nvim/os/input.h" -#include "nvim/ui.h" #define LINE_BUFFER_SIZE 4096 diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index f59495f660..0224b28c2a 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -7127,8 +7127,7 @@ syn_list_header(int did_header, int outlen, int id) /// Set the attribute numbers for a highlight group. /// Called after one of the attributes has changed. /// @param idx corrected highlight index -static void -set_hl_attr(int idx) +static void set_hl_attr(int idx) { attrentry_T at_en = ATTRENTRY_INIT; struct hl_group *sgp = HL_TABLE() + idx; @@ -8241,9 +8240,7 @@ RgbValue name_to_color(const uint8_t *name) return -1; } -/// Retrieves attribute description from its id -/// -/// @param attr_id attribute id +/// Gets highlight description for id `attr_id` as a map. Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) { HlAttrs attrs = HLATTRS_INIT; @@ -8256,7 +8253,7 @@ Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) attrentry_T *aep = syn_cterm_attr2entry((int)attr_id); if (!aep) { api_set_error(err, kErrorTypeException, - "Invalid attribute id %d", attr_id); + "Invalid attribute id: %d", attr_id); return dic; } -- cgit From dc513f761897f0ea09a511d19254f5c10b68e7fa Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 12 Oct 2017 00:49:47 -0400 Subject: getcmdline_prompt: Temporarily disable msg_silent so prompt is displayed vim-patch:7.4.1636 Closes #7378 --- src/nvim/ex_getln.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index fd7ad7a4b5..80f9b47340 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1863,9 +1863,13 @@ char *getcmdline_prompt(const char firstc, const char *const prompt, ccline.input_fn = (firstc == '@'); ccline.highlight_callback = highlight_callback; + int msg_silent_saved = msg_silent; + msg_silent = 0; + char *const ret = (char *)getcmdline(firstc, 1L, 0); restore_cmdline(&save_ccline); + msg_silent = msg_silent_saved; // Restore msg_col, the prompt from input() may have changed it. // But only if called recursively and the commandline is therefore being // restored to an old one; if not, the input() prompt stays on the screen, -- cgit From 4b3e51d4ee3018cf59d81578e2320b79fb614652 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Tue, 10 Oct 2017 18:42:01 +0200 Subject: ops: save and restore clipboard batch status when entering cmdline window --- src/nvim/ex_getln.c | 2 ++ src/nvim/ops.c | 26 +++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 80f9b47340..54e5bcb9ff 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -5718,6 +5718,7 @@ static int ex_window(void) i = RedrawingDisabled; RedrawingDisabled = 0; + int save_count = save_batch_count(); /* * Call the main loop until or CTRL-C is typed. @@ -5726,6 +5727,7 @@ static int ex_window(void) normal_enter(true, false); RedrawingDisabled = i; + restore_batch_count(save_count); int save_KeyTyped = KeyTyped; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 99dc4670f1..e7bc20698b 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5755,7 +5755,6 @@ void start_batch_changes(void) return; } clipboard_delay_update = true; - clipboard_needs_update = false; } /// Counterpart to start_batch_changes(). @@ -5767,12 +5766,37 @@ void end_batch_changes(void) } clipboard_delay_update = false; if (clipboard_needs_update) { + // must be before, as set_clipboard will invoke + // start/end_batch_changes recursively + clipboard_needs_update = false; // unnamed ("implicit" clipboard) set_clipboard(NUL, y_previous); + } +} + +int save_batch_count(void) +{ + int save_count = batch_change_count; + batch_change_count = 0; + clipboard_delay_update = false; + if (clipboard_needs_update) { clipboard_needs_update = false; + // unnamed ("implicit" clipboard) + set_clipboard(NUL, y_previous); } + return save_count; } +void restore_batch_count(int save_count) +{ + assert(batch_change_count == 0); + batch_change_count = save_count; + if (batch_change_count > 0) { + clipboard_delay_update = true; + } +} + + /// Check whether register is empty static inline bool reg_empty(const yankreg_T *const reg) FUNC_ATTR_PURE -- cgit