diff options
-rw-r--r-- | runtime/doc/starting.txt | 7 | ||||
-rwxr-xr-x | src/clint.py | 3 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 11 | ||||
-rw-r--r-- | src/nvim/globals.h | 7 | ||||
-rw-r--r-- | src/nvim/main.c | 15 | ||||
-rw-r--r-- | src/nvim/message.c | 8 | ||||
-rw-r--r-- | src/nvim/misc1.c | 2 | ||||
-rw-r--r-- | src/nvim/os/win_defs.h | 9 | ||||
-rw-r--r-- | src/nvim/screen.c | 36 | ||||
-rw-r--r-- | src/nvim/state.c | 1 | ||||
-rw-r--r-- | src/nvim/terminal.c | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test49.vim | 3 | ||||
-rw-r--r-- | src/nvim/version.c | 225 | ||||
-rw-r--r-- | test/functional/helpers.lua | 2 | ||||
-rw-r--r-- | test/functional/ui/wildmode_spec.lua | 168 |
15 files changed, 418 insertions, 85 deletions
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 91915406cb..4cfc98d5b6 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -53,7 +53,7 @@ filename One or more file names. The first one will be the current < Starting in Ex mode: > nvim -e - nvim -E -< Start editing in silent mode. See |-s-ex|. +< Start editing in |silent-mode|. *-t* *-tag* -t {tag} A tag. "tag" is looked up in the tags file, the associated @@ -200,7 +200,7 @@ argument. *-E* -E Start Vim in improved Ex mode |gQ|. - *-s-ex* + *-s-ex* *silent-mode* -s Silent or batch mode. Only when "-s" is preceded by the "-e" argument. Otherwise see |-s|, which does take an argument while this use of "-s" doesn't. To be used when Vim is used @@ -221,7 +221,7 @@ argument. Initializations are skipped (except the ones given with the "-u" argument). Example: > - vim -e -s < thefilter thefile + vim -es < thefilter thefile < *-b* -b Binary mode. File I/O will only recognize <NL> to separate @@ -351,6 +351,7 @@ argument. *--headless* --headless Do not start the built-in UI. + See also |silent-mode|, which does start a (limited) UI. ============================================================================== 2. Initialization *initialization* *startup* diff --git a/src/clint.py b/src/clint.py index 69a061d2ab..4a41650ec4 100755 --- a/src/clint.py +++ b/src/clint.py @@ -2613,7 +2613,8 @@ def CheckBraces(filename, clean_lines, linenum, error): func_start_linenum += 1 else: - if clean_lines.lines[func_start_linenum].endswith('{'): + func_start = clean_lines.lines[func_start_linenum] + if not func_start.startswith('enum ') and func_start.endswith('{'): error(filename, func_start_linenum, 'readability/braces', 5, 'Brace starting function body must be placed ' diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 1d81a39dfe..ecd5c81822 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -12,6 +12,7 @@ #include <inttypes.h> #include "nvim/assert.h" +#include "nvim/log.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/arabic.h" @@ -472,11 +473,12 @@ static int command_line_execute(VimState *state, int key) } // free expanded names when finished walking through matches - if (s->xpc.xp_numfiles != -1 - && !(s->c == p_wc && KeyTyped) && s->c != p_wcm + if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A && s->c != Ctrl_L) { - (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE); + if (s->xpc.xp_numfiles != -1) { + (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE); + } s->did_wild_list = false; if (!p_wmnu || (s->c != K_UP && s->c != K_DOWN)) { s->xpc.xp_context = EXPAND_NOTHING; @@ -1222,6 +1224,7 @@ static int command_line_handle_key(CommandLineState *s) break; // Use ^D as normal char instead } + wild_menu_showing = WM_LIST; redrawcmd(); return 1; // don't do incremental search now @@ -1452,7 +1455,7 @@ static int command_line_handle_key(CommandLineState *s) if (s->hiscnt != s->i) { // jumped to other entry char_u *p; - int len; + int len = 0; int old_firstc; xfree(ccline.cmdbuff); diff --git a/src/nvim/globals.h b/src/nvim/globals.h index f08812600f..13ecafcbe3 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -931,8 +931,11 @@ EXTERN char_u langmap_mapchar[256]; /* mapping for language keys */ EXTERN int save_p_ls INIT(= -1); /* Save 'laststatus' setting */ EXTERN int save_p_wmh INIT(= -1); /* Save 'winminheight' setting */ EXTERN int wild_menu_showing INIT(= 0); -# define WM_SHOWN 1 /* wildmenu showing */ -# define WM_SCROLLED 2 /* wildmenu showing with scroll */ +enum { + WM_SHOWN = 1, ///< wildmenu showing + WM_SCROLLED = 2, ///< wildmenu showing with scroll + WM_LIST = 3, ///< cmdline CTRL-D +}; EXTERN char breakat_flags[256]; /* which characters are in 'breakat' */ diff --git a/src/nvim/main.c b/src/nvim/main.c index 7dcf00c26b..a46c1a58f8 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -98,10 +98,8 @@ typedef struct { bool input_isatty; // stdin is a terminal bool output_isatty; // stdout is a terminal bool err_isatty; // stderr is a terminal - bool headless; // Dont try to start an user interface - // or read/write to stdio(unless - // embedding) - int no_swap_file; /* "-n" argument used */ + bool headless; // Do not start the builtin UI. + int no_swap_file; // "-n" argument used int use_debug_break_level; int window_count; /* number of windows to use */ int window_layout; /* 0, WIN_HOR, WIN_VER or WIN_TABS */ @@ -932,10 +930,11 @@ static void command_line_scan(mparm_T *parmp) break; case 's': - if (exmode_active) /* "-s" silent (batch) mode */ - silent_mode = TRUE; - else /* "-s {scriptin}" read from script file */ - want_argument = TRUE; + if (exmode_active) { // "-es" silent (batch) mode + silent_mode = true; + } else { // "-s {scriptin}" read from script file + want_argument = true; + } break; case 't': /* "-t {tag}" or "-t{tag}" jump to tag */ diff --git a/src/nvim/message.c b/src/nvim/message.c index 36f9ca84ed..28c88f5a14 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2722,9 +2722,11 @@ do_dialog ( int c; int i; - /* Don't output anything in silent mode ("ex -s") */ - if (silent_mode) - return dfltbutton; /* return default option */ + if (silent_mode // No dialogs in silent mode ("ex -s") + || !ui_active() // Without a UI Nvim waits for input forever. + ) { + return dfltbutton; // return default option + } oldState = State; diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 835b9c7b20..5270687a4d 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2203,7 +2203,7 @@ change_warning ( set_vim_var_string(VV_WARNINGMSG, _(w_readonly), -1); msg_clr_eos(); (void)msg_end(); - if (msg_silent == 0 && !silent_mode) { + if (msg_silent == 0 && !silent_mode && ui_active()) { ui_flush(); os_delay(1000L, true); /* give the user time to think about it */ } diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 7ed70f6092..8fd2e51f8b 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -30,8 +30,13 @@ #define USE_CRNL -// We have our own RGB macro in macros.h. -#undef RGB +// Windows defines a RGB macro that produces 0x00bbggrr color values for use +// with GDI. Our macro is different, and we don't use GDI. +#if defined(RGB) +# undef RGB + // Duplicated from macros.h to avoid include-order sensitivity. +# define RGB(r, g, b) ((r << 16) | (g << 8) | b) +#endif #ifdef _MSC_VER # ifndef inline diff --git a/src/nvim/screen.c b/src/nvim/screen.c index bcc996679b..cd4f4de40f 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -86,6 +86,7 @@ #include <stdbool.h> #include <string.h> +#include "nvim/log.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/arabic.h" @@ -4874,11 +4875,14 @@ void win_redr_status(win_T *wp) int this_ru_col; static int busy = FALSE; - /* It's possible to get here recursively when 'statusline' (indirectly) - * invokes ":redrawstatus". Simply ignore the call then. */ - if (busy) + // May get here recursively when 'statusline' (indirectly) + // invokes ":redrawstatus". Simply ignore the call then. + if (busy + // Also ignore if wildmenu is showing. + || (wild_menu_showing != 0 && !ui_is_external(kUIWildmenu))) { return; - busy = TRUE; + } + busy = true; wp->w_redr_status = FALSE; if (wp->w_status_height == 0) { @@ -6441,13 +6445,11 @@ void setcursor(void) } } -/* - * insert 'line_count' lines at 'row' in window 'wp' - * if 'invalid' is TRUE the wp->w_lines[].wl_lnum is invalidated. - * if 'mayclear' is TRUE the screen will be cleared if it is faster than - * scrolling. - * Returns FAIL if the lines are not inserted, OK for success. - */ +/// Insert 'line_count' lines at 'row' in window 'wp'. +/// If 'invalid' is TRUE the wp->w_lines[].wl_lnum is invalidated. +/// If 'mayclear' is TRUE the screen will be cleared if it is faster than +/// scrolling. +/// Returns FAIL if the lines are not inserted, OK for success. int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear) { int did_delete; @@ -6510,13 +6512,11 @@ int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear) return OK; } -/* - * delete "line_count" window lines at "row" in window "wp" - * If "invalid" is TRUE curwin->w_lines[] is invalidated. - * If "mayclear" is TRUE the screen will be cleared if it is faster than - * scrolling - * Return OK for success, FAIL if the lines are not deleted. - */ +/// Delete "line_count" window lines at "row" in window "wp". +/// If "invalid" is TRUE curwin->w_lines[] is invalidated. +/// If "mayclear" is TRUE the screen will be cleared if it is faster than +/// scrolling +/// Return OK for success, FAIL if the lines are not deleted. int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear) { int retval; diff --git a/src/nvim/state.c b/src/nvim/state.c index be6aa21664..eb0b590a9b 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -6,6 +6,7 @@ #include "nvim/lib/kvec.h" #include "nvim/ascii.h" +#include "nvim/log.h" #include "nvim/state.h" #include "nvim/vim.h" #include "nvim/main.h" diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 099f49f09b..deec930ebd 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -43,6 +43,7 @@ #include <vterm.h> +#include "nvim/log.h" #include "nvim/vim.h" #include "nvim/terminal.h" #include "nvim/message.h" @@ -1010,7 +1011,10 @@ static void refresh_terminal(Terminal *term) // Calls refresh_terminal() on all invalidated_terminals. static void refresh_timer_cb(TimeWatcher *watcher, void *data) { - if (exiting) { // Cannot redraw (requires event loop) during teardown/exit. + if (exiting // Cannot redraw (requires event loop) during teardown/exit. + // WM_LIST (^D) is not redrawn, unlike the normal wildmenu. So we must + // skip redraws to keep it visible. + || wild_menu_showing == WM_LIST) { goto end; } Terminal *term; diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim index a0e170dea4..467abcd9b9 100644 --- a/src/nvim/testdir/test49.vim +++ b/src/nvim/testdir/test49.vim @@ -481,12 +481,9 @@ function! ExtraVim(...) bwipeout let g:Xpath = g:Xpath + sum - " FIXME(nvim): delete() of a file used by a subprocess hangs TSAN build on travis CI. - if !empty($TRAVIS) " Delete the extra script and the resultfile. call delete(extra_script) call delete(resultfile) - endif " Switch back to the buffer that was active when this function was entered. exec "buffer" current_buffnr diff --git a/src/nvim/version.c b/src/nvim/version.c index f2b56e0108..81152bbaa4 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -77,6 +77,229 @@ static char *features[] = { // clang-format off static const int included_patches[] = { + // 875, + // 874, + // 873, + // 872, + // 871, + // 870, + // 869, + // 868, + // 867, + // 866, + // 865, + // 864, + // 863, + // 862, + // 861, + // 860, + // 859, + // 858, + // 857, + // 856, + // 855, + // 854, + // 853, + // 852, + // 851, + // 850, + // 849, + // 848, + // 847, + // 846, + // 845, + // 844, + // 843, + // 842, + // 841, + // 840, + // 839, + // 838, + // 837, + // 836, + // 835, + // 834, + // 833, + // 832, + // 831, + // 830, + // 829, + // 828, + // 827, + // 826, + // 825, + // 824, + // 823, + // 822, + // 821, + // 820, + // 819, + // 818, + // 817, + // 816, + // 815, + // 814, + // 813, + // 812, + // 811, + // 810, + // 809, + // 808, + // 807, + // 806, + // 805, + // 804, + // 803, + // 802, + // 801, + // 800, + // 799, + // 798, + // 797, + // 796, + // 795, + // 794, + // 793, + // 792, + // 791, + // 790, + // 789, + // 788, + // 787, + // 786, + // 785, + // 784, + // 783, + // 782, + // 781, + // 780, + // 779, + // 778, + // 777, + // 776, + // 775, + // 774, + // 773, + // 772, + // 771, + // 770, + // 769, + // 768, + // 767, + // 766, + // 765, + // 764, + // 763, + // 762, + // 761, + // 760, + // 759, + // 758, + // 757, + // 756, + // 755, + // 754, + // 753, + // 752, + // 751, + // 750, + // 749, + // 748, + // 747, + // 746, + // 745, + // 744, + // 743, + // 742, + // 741, + // 740, + // 739, + // 738, + // 737, + // 736, + // 735, + // 734, + // 733, + // 732, + // 731, + // 730, + // 729, + // 728, + // 727, + // 726, + // 725, + // 724, + // 723, + // 722, + // 721, + // 720, + // 719, + // 718, + // 717, + // 716, + // 715, + // 714, + // 713, + // 712, + // 711, + 710, + // 709, + // 708, + // 707, + // 706, + // 705, + // 704, + // 703, + // 702, + // 701, + // 700, + // 699, + // 698, + // 697, + // 696, + // 695, + // 694, + // 693, + // 692, + // 691, + // 690, + // 689, + // 688, + // 687, + // 686, + // 685, + // 684, + // 683, + // 682, + // 681, + // 680, + // 679, + // 678, + // 677, + // 676, + // 675, + // 674, + // 673, + // 672, + // 671, + // 670, + // 669, + // 668, + // 667, + // 666, + // 665, + // 664, + // 663, + // 662, + // 661, + // 660, + // 659, + // 658, + // 657, + // 656, + // 655, + // 654, + // 653, 652, // 651, // 650, @@ -583,7 +806,7 @@ static const int included_patches[] = { // 149, // 148, // 147, - // 146, + 146, // 145 NA // 144 NA // 143, diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index f4b2a8dfdc..848f1ef477 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -367,7 +367,7 @@ end local function set_shell_powershell() source([[ set shell=powershell shellquote=\" shellpipe=\| shellredir=> - set shellcmdflag=\ -NoProfile\ -ExecutionPolicy\ RemoteSigned\ -Command + set shellcmdflag=\ -NoLogo\ -NoProfile\ -ExecutionPolicy\ RemoteSigned\ -Command let &shellxquote=' ' ]]) end diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua index 052cdd55a1..41a751c284 100644 --- a/test/functional/ui/wildmode_spec.lua +++ b/test/functional/ui/wildmode_spec.lua @@ -1,57 +1,151 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, command = helpers.clear, helpers.feed, helpers.command +local iswin = helpers.iswin local funcs = helpers.funcs +local eq = helpers.eq +local eval = helpers.eval +local retry = helpers.retry -if helpers.pending_win32(pending) then return end - -describe("'wildmode'", function() +describe("'wildmenu'", function() local screen - before_each(function() clear() screen = Screen.new(25, 5) screen:attach() end) - after_each(function() screen:detach() end) - describe("'wildmenu'", function() - it(':sign <tab> shows wildmenu completions', function() - command('set wildmode=full') - command('set wildmenu') - feed(':sign <tab>') - screen:expect([[ - | - ~ | - ~ | - define jump list > | - :sign define^ | - ]]) - end) + it(':sign <tab> shows wildmenu completions', function() + command('set wildmode=full') + command('set wildmenu') + feed(':sign <tab>') + screen:expect([[ + | + ~ | + ~ | + define jump list > | + :sign define^ | + ]]) + end) - it('does not crash after cycling back to original text', function() - command('set wildmode=full') - feed(':j<Tab><Tab><Tab>') - screen:expect([[ - | - ~ | - ~ | - join jumps | - :j^ | - ]]) - -- This would cause nvim to crash before #6650 - feed('<BS><Tab>') - screen:expect([[ - | - ~ | - ~ | - ! # & < = > @ > | - :!^ | - ]]) + it('does not crash after cycling back to original text', function() + command('set wildmode=full') + feed(':j<Tab><Tab><Tab>') + screen:expect([[ + | + ~ | + ~ | + join jumps | + :j^ | + ]]) + -- This would cause nvim to crash before #6650 + feed('<BS><Tab>') + screen:expect([[ + | + ~ | + ~ | + ! # & < = > @ > | + :!^ | + ]]) + end) + + it('is preserved during :terminal activity', function() + -- Because this test verifies a _lack_ of activity after screen:sleep(), we + -- must wait the full timeout. So make it reasonable. + screen.timeout = 1000 + + command('set wildmenu wildmode=full') + command('set scrollback=4') + if iswin() then + if helpers.pending_win32(pending) then return end + -- feed([[:terminal 1,2,3,4,5 | foreach-object -process {echo $_; sleep 0.1}]]) + else + feed([[:terminal for i in $(seq 1 5000); do printf 'foo\nfoo\nfoo\n'; sleep 0.1; done<cr>]]) + end + + feed([[<C-\><C-N>gg]]) + feed([[:sign <Tab>]]) -- Invoke wildmenu. + screen:sleep(50) -- Allow some terminal output. + screen:expect([[ + foo | + foo | + foo | + define jump list > | + :sign define^ | + ]]) + + -- cmdline CTRL-D display should also be preserved. + feed([[<C-\><C-N>]]) + feed([[:sign <C-D>]]) -- Invoke cmdline CTRL-D. + screen:sleep(50) -- Allow some terminal output. + screen:expect([[ + :sign | + define place | + jump undefine | + list unplace | + :sign ^ | + ]]) + + -- Exiting cmdline should show the buffer. + feed([[<C-\><C-N>]]) + screen:expect([[ + ^foo | + foo | + foo | + foo | + | + ]]) + end) + + it('ignores :redrawstatus called from a timer #7108', function() + -- Because this test verifies a _lack_ of activity after screen:sleep(), we + -- must wait the full timeout. So make it reasonable. + screen.timeout = 1000 + + command('set wildmenu wildmode=full') + command([[call timer_start(10, {->execute('redrawstatus')}, {'repeat':-1})]]) + feed([[<C-\><C-N>]]) + feed([[:sign <Tab>]]) -- Invoke wildmenu. + screen:sleep(30) -- Allow some timer activity. + screen:expect([[ + | + ~ | + ~ | + define jump list > | + :sign define^ | + ]]) + end) + + it('with laststatus=0, :vsplit, :term #2255', function() + -- Because this test verifies a _lack_ of activity after screen:sleep(), we + -- must wait the full timeout. So make it reasonable. + screen.timeout = 1000 + + if not iswin() then + command('set shell=sh') -- Need a predictable "$" prompt. + end + command('set laststatus=0') + command('vsplit') + command('term') + + -- Check for a shell prompt to verify that the terminal loaded. + retry(nil, nil, function() + if iswin() then + eq('Microsoft', eval("matchstr(join(getline(1, '$')), 'Microsoft')")) + else + eq('$', eval([[matchstr(getline(1), '\$')]])) + end end) + + feed([[<C-\><C-N>]]) + feed([[:<Tab>]]) -- Invoke wildmenu. + screen:sleep(10) -- Flush + -- Check only the last 2 lines, because the shell output is + -- system-dependent. + screen:expect('! # & < = > @ > \n:!^', nil, nil, nil, true) end) end) |