diff options
-rw-r--r-- | runtime/scripts.vim | 13 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 1 | ||||
-rw-r--r-- | src/nvim/memline.c | 6 | ||||
-rw-r--r-- | src/nvim/screen.c | 20 | ||||
-rw-r--r-- | src/nvim/search.c | 4 | ||||
-rw-r--r-- | src/nvim/testdir/test_filetype.vim | 2 | ||||
-rw-r--r-- | src/nvim/ui_compositor.c | 5 | ||||
-rw-r--r-- | src/nvim/window.c | 109 | ||||
-rw-r--r-- | test/functional/ui/cmdline_spec.lua | 39 | ||||
-rw-r--r-- | test/functional/ui/float_spec.lua | 45 | ||||
-rw-r--r-- | test/functional/ui/screen.lua | 8 |
11 files changed, 183 insertions, 69 deletions
diff --git a/runtime/scripts.vim b/runtime/scripts.vim index ab66c0c0a1..8d460cd317 100644 --- a/runtime/scripts.vim +++ b/runtime/scripts.vim @@ -195,7 +195,7 @@ else if s:line1 =~# '^:$' call dist#ft#SetFileTypeSH(s:line1) " defined in filetype.vim - " Z shell scripts + " Z shell scripts elseif s:line1 =~# '^#compdef\>' || s:line1 =~# '^#autoload\>' || \ "\n".s:line1."\n".s:line2."\n".s:line3."\n".s:line4."\n".s:line5 =~# '\n\s*emulate\s\+\%(-[LR]\s\+\)\=[ckz]\=sh\>' set ft=zsh @@ -204,15 +204,20 @@ else elseif s:line1 =~# '^From \([a-zA-Z][a-zA-Z_0-9\.=-]*\(@[^ ]*\)\=\|-\) .* \(19\|20\)\d\d$' set ft=mail - " Mason + " Mason elseif s:line1 =~# '^<[%&].*>' set ft=mason - " Vim scripts (must have '" vim' as the first line to trigger this) + " Vim scripts (must have '" vim' as the first line to trigger this) elseif s:line1 =~# '^" *[vV]im$' set ft=vim - " MOO + " libcxx and libstdc++ standard library headers like "iostream" do not have + " an extension, recognize the Emacs file mode. + elseif s:line1 =~? '-\*-.*C++.*-\*-' + set ft=cpp + + " MOO elseif s:line1 =~# '^\*\* LambdaMOO Database, Format Version \%([1-3]\>\)\@!\d\+ \*\*$' set ft=moo diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 479d195966..1c1bfcad31 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1978,6 +1978,7 @@ static int command_line_changed(CommandLineState *s) static void abandon_cmdline(void) { XFREE_CLEAR(ccline.cmdbuff); + ccline.redraw_state = kCmdRedrawNone; if (msg_scrolled == 0) { compute_cmdrow(); } diff --git a/src/nvim/memline.c b/src/nvim/memline.c index a69669f680..b027459706 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1,9 +1,9 @@ // 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 -/* for debugging */ -/* #define CHECK(c, s) if (c) EMSG(s) */ -#define CHECK(c, s) +// for debugging +// #define CHECK(c, s) do { if (c) EMSG(s); } while (0) +#define CHECK(c, s) do { } while (0) /* * memline.c: Contains the functions for appending, deleting and changing the diff --git a/src/nvim/screen.c b/src/nvim/screen.c index d91b832e5a..d141520fef 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1709,7 +1709,6 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T int col; int txtcol; int off; - int ri; /* Build the fold line: * 1. Add the cmdwin_type for the command-line window @@ -1753,15 +1752,18 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T col += fdc; } -# define RL_MEMSET(p, v, l) if (wp->w_p_rl) { \ - for (ri = 0; ri < l; ri++) { \ - linebuf_attr[off + (wp->w_grid.Columns - (p) - (l)) + ri] = v; \ +# define RL_MEMSET(p, v, l) \ + do { \ + if (wp->w_p_rl) { \ + for (int ri = 0; ri < l; ri++) { \ + linebuf_attr[off + (wp->w_grid.Columns - (p) - (l)) + ri] = v; \ + } \ + } else { \ + for (int ri = 0; ri < l; ri++) { \ + linebuf_attr[off + (p) + ri] = v; \ + } \ } \ - } else { \ - for (ri = 0; ri < l; ri++) { \ - linebuf_attr[off + (p) + ri] = v; \ - } \ - } + } while (0) /* Set all attributes of the 'number' or 'relativenumber' column and the * text */ diff --git a/src/nvim/search.c b/src/nvim/search.c index 1f9ac93df0..ed18df3877 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -4344,8 +4344,8 @@ find_pattern_in_path( char_u *ptr, // pointer to search pattern int dir, // direction of expansion size_t len, // length of search pattern - int whole, // match whole words only - int skip_comments, // don't match inside comments + bool whole, // match whole words only + bool skip_comments, // don't match inside comments int type, // Type of search; are we looking for a type? // a macro? long count, diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 7a99a37be4..897f736d76 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -581,6 +581,8 @@ let s:script_checks = { \ 'cfengine': [['#!/path/cfengine']], \ 'erlang': [['#!/path/escript']], \ 'haskell': [['#!/path/haskell']], + \ 'cpp': [['// Standard iostream objects -*- C++ -*-'], + \ ['// -*- C++ -*-']], \ } func Test_script_detection() diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index 0c3e771eb8..d12a411019 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -329,7 +329,7 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, memcpy(linebuf+(col-startcol), grid->chars+off, n * sizeof(*linebuf)); memcpy(attrbuf+(col-startcol), grid->attrs+off, n * sizeof(*attrbuf)); - // 'pumblend' + // 'pumblend' and 'winblend' if (grid->blending) { for (int i = col-(int)startcol; i < until-startcol; i++) { bool thru = strequal((char *)linebuf[i], " "); // negative space @@ -467,7 +467,8 @@ static void ui_comp_grid_scroll(UI *ui, Integer grid, Integer top, bot += curgrid->comp_row; left += curgrid->comp_col; right += curgrid->comp_col; - if (!msg_scroll_mode && kv_size(layers) > curgrid->comp_index+1) { + bool covered = kv_size(layers) > curgrid->comp_index+1 || curgrid->blending; + if (!msg_scroll_mode && covered) { // TODO(bfredl): // 1. check if rectangles actually overlap // 2. calulate subareas that can scroll. diff --git a/src/nvim/window.c b/src/nvim/window.c index 1cf5d7fd92..a3b1efeaaa 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -90,36 +90,47 @@ do_window ( else Prenum1 = Prenum; -# define CHECK_CMDWIN if (cmdwin_type != 0) { EMSG(_(e_cmdwin)); break; } +# define CHECK_CMDWIN \ + do { \ + if (cmdwin_type != 0) { \ + EMSG(_(e_cmdwin)); \ + return; \ + } \ + } while (0) switch (nchar) { /* split current window in two parts, horizontally */ case 'S': case Ctrl_S: case 's': - CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */ - /* When splitting the quickfix window open a new buffer in it, - * don't replicate the quickfix buffer. */ - if (bt_quickfix(curbuf)) + CHECK_CMDWIN; + reset_VIsual_and_resel(); // stop Visual mode + // When splitting the quickfix window open a new buffer in it, + // don't replicate the quickfix buffer. + if (bt_quickfix(curbuf)) { goto newwindow; + } (void)win_split((int)Prenum, 0); break; /* split current window in two parts, vertically */ case Ctrl_V: case 'v': - CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */ - /* When splitting the quickfix window open a new buffer in it, - * don't replicate the quickfix buffer. */ - if (bt_quickfix(curbuf)) + CHECK_CMDWIN; + reset_VIsual_and_resel(); // stop Visual mode + // When splitting the quickfix window open a new buffer in it, + // don't replicate the quickfix buffer. + if (bt_quickfix(curbuf)) { goto newwindow; + } (void)win_split((int)Prenum, WSP_VERT); break; /* split current window and edit alternate file */ case Ctrl_HAT: case '^': - CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */ + CHECK_CMDWIN; + reset_VIsual_and_resel(); // stop Visual mode cmd_with_count("split #", (char_u *)cbuf, sizeof(cbuf), Prenum); do_cmdline_cmd(cbuf); break; @@ -127,7 +138,8 @@ do_window ( /* open new window */ case Ctrl_N: case 'n': - CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */ + CHECK_CMDWIN; + reset_VIsual_and_resel(); // stop Visual mode newwindow: if (Prenum) /* window height */ @@ -160,7 +172,8 @@ newwindow: /* close preview window */ case Ctrl_Z: case 'z': - CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */ + CHECK_CMDWIN; + reset_VIsual_and_resel(); // stop Visual mode do_cmdline_cmd("pclose"); break; @@ -183,7 +196,8 @@ newwindow: /* close all but current window */ case Ctrl_O: case 'o': - CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */ + CHECK_CMDWIN; + reset_VIsual_and_resel(); // stop Visual mode cmd_with_count("only", (char_u *)cbuf, sizeof(cbuf), Prenum); do_cmdline_cmd(cbuf); break; @@ -193,11 +207,11 @@ newwindow: case 'w': /* cursor to previous window with wrap around */ case 'W': - CHECK_CMDWIN - if (ONE_WINDOW && Prenum != 1) /* just one window */ + CHECK_CMDWIN; + if (ONE_WINDOW && Prenum != 1) { // just one window beep_flush(); - else { - if (Prenum) { /* go to specified window */ + } else { + if (Prenum) { // go to specified window for (wp = firstwin; --Prenum > 0; ) { if (wp->w_next == NULL) break; @@ -233,14 +247,16 @@ newwindow: case 'j': case K_DOWN: case Ctrl_J: - CHECK_CMDWIN win_goto_ver(FALSE, Prenum1); + CHECK_CMDWIN; + win_goto_ver(false, Prenum1); break; /* cursor to window above */ case 'k': case K_UP: case Ctrl_K: - CHECK_CMDWIN win_goto_ver(TRUE, Prenum1); + CHECK_CMDWIN; + win_goto_ver(true, Prenum1); break; /* cursor to left window */ @@ -248,14 +264,16 @@ newwindow: case K_LEFT: case Ctrl_H: case K_BS: - CHECK_CMDWIN win_goto_hor(TRUE, Prenum1); + CHECK_CMDWIN; + win_goto_hor(true, Prenum1); break; /* cursor to right window */ case 'l': case K_RIGHT: case Ctrl_L: - CHECK_CMDWIN win_goto_hor(FALSE, Prenum1); + CHECK_CMDWIN; + win_goto_hor(false, Prenum1); break; /* move window to new tab page */ @@ -309,20 +327,23 @@ newwindow: /* exchange current and next window */ case 'x': case Ctrl_X: - CHECK_CMDWIN win_exchange(Prenum); + CHECK_CMDWIN; + win_exchange(Prenum); break; /* rotate windows downwards */ case Ctrl_R: case 'r': - CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */ - win_rotate(FALSE, (int)Prenum1); /* downwards */ + CHECK_CMDWIN; + reset_VIsual_and_resel(); // stop Visual mode + win_rotate(false, (int)Prenum1); // downwards break; /* rotate windows upwards */ case 'R': - CHECK_CMDWIN reset_VIsual_and_resel(); /* stop Visual mode */ - win_rotate(TRUE, (int)Prenum1); /* upwards */ + CHECK_CMDWIN; + reset_VIsual_and_resel(); // stop Visual mode + win_rotate(true, (int)Prenum1); // upwards break; /* move window to the very top/bottom/left/right */ @@ -330,9 +351,10 @@ newwindow: case 'J': case 'H': case 'L': - CHECK_CMDWIN win_totop((int)Prenum, - ((nchar == 'H' || nchar == 'L') ? WSP_VERT : 0) - | ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT)); + CHECK_CMDWIN; + win_totop((int)Prenum, + ((nchar == 'H' || nchar == 'L') ? WSP_VERT : 0) + | ((nchar == 'H' || nchar == 'K') ? WSP_TOP : WSP_BOT)); break; /* make all windows the same height */ @@ -373,15 +395,16 @@ newwindow: /* jump to tag and split window if tag exists (in preview window) */ case '}': - CHECK_CMDWIN - if (Prenum) + CHECK_CMDWIN; + if (Prenum) { g_do_tagpreview = Prenum; - else + } else { g_do_tagpreview = p_pvh; + } FALLTHROUGH; case ']': case Ctrl_RSB: - CHECK_CMDWIN + CHECK_CMDWIN; // Keep visual mode, can select words to use as a tag. if (Prenum) postponed_split = Prenum; @@ -402,7 +425,7 @@ newwindow: case 'F': case Ctrl_F: wingotofile: - CHECK_CMDWIN + CHECK_CMDWIN; ptr = grab_file_name(Prenum1, &lnum); if (ptr != NULL) { @@ -434,11 +457,11 @@ wingotofile: FALLTHROUGH; case 'd': // Go to definition, using 'define' case Ctrl_D: - CHECK_CMDWIN - if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0) + CHECK_CMDWIN; + if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0) { break; - find_pattern_in_path(ptr, 0, len, TRUE, - Prenum == 0 ? TRUE : FALSE, + } + find_pattern_in_path(ptr, 0, len, true, Prenum == 0, type, Prenum1, ACTION_SPLIT, 1, MAXLNUM); curwin->w_set_curswant = TRUE; break; @@ -455,7 +478,7 @@ wingotofile: /* CTRL-W g extended commands */ case 'g': case Ctrl_G: - CHECK_CMDWIN + CHECK_CMDWIN; no_mapping++; if (xchar == NUL) { xchar = plain_vgetc(); @@ -1631,11 +1654,9 @@ static void win_exchange(long Prenum) redraw_win_later(wp, NOT_VALID); } -/* - * rotate windows: if upwards TRUE the second window becomes the first one - * if upwards FALSE the first window becomes the second one - */ -static void win_rotate(int upwards, int count) +// rotate windows: if upwards true the second window becomes the first one +// if upwards false the first window becomes the second one +static void win_rotate(bool upwards, int count) { win_T *wp1; win_T *wp2; diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index 915e7ae867..c63b726308 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -761,8 +761,42 @@ local function test_cmdline(linegrid) }}, wildmenu_items=expected, wildmenu_pos=0} end) + it("doesn't send invalid events when aborting mapping #10000", function() + command('cnoremap ab c') + + feed(':xa') + screen:expect{grid=[[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]], cmdline={{ + content = { { "x" } }, + firstc = ":", + pos = 1, + special = { "a", false } + }}} + + -- This used to send an invalid event where pos where larger than the total + -- lenght of content. Checked in _handle_cmdline_show. + feed('<esc>') + screen:expect([[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + end) + end +-- the representation of cmdline and cmdline_block contents changed with ext_linegrid +-- (which uses indexed highlights) so make sure to test both +describe('ui/ext_cmdline', function() test_cmdline(true) end) +describe('ui/ext_cmdline (legacy highlights)', function() test_cmdline(false) end) + describe('cmdline redraw', function() local screen before_each(function() @@ -813,8 +847,3 @@ describe('cmdline redraw', function() ]], unchanged=true} end) end) - --- the representation of cmdline and cmdline_block contents changed with ext_linegrid --- (which uses indexed highlights) so make sure to test both -describe('ui/ext_cmdline', function() test_cmdline(true) end) -describe('ui/ext_cmdline (legacy highlights)', function() test_cmdline(false) end) diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 3c7418167c..41ba542899 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -3774,6 +3774,8 @@ describe('floating windows', function() [4] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta}, [5] = {foreground = tonumber('0x990000'), background = tonumber('0xfff1ff')}, [6] = {foreground = tonumber('0x332533'), background = tonumber('0xfff1ff')}, + [7] = {background = tonumber('0xffcfff'), bold = true, foreground = tonumber('0x0000d8')}, + [8] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1} }) insert([[ Lorem ipsum dolor sit amet, consectetur @@ -3953,6 +3955,49 @@ describe('floating windows', function() | ]]) end + + -- Test scrolling by mouse + if multigrid then + meths.input_mouse('wheel', 'down', '', 4, 2, 2) + screen:expect{grid=[[ + ## grid 1 + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + [2:--------------------------------------------------]| + | + ## grid 2 + Ut enim ad minim veniam, quis nostrud | + exercitation ullamco laboris nisi ut aliquip ex | + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + dolore eu fugiat nulla pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + laborum^. | + ## grid 4 + {4:popup text}{1: }| + {8:~ }| + {8:~ }| + ]], float_pos={[4] = {{id = 1002}, "NW", 1, 2, 5, true}}} + else + meths.input_mouse('wheel', 'down', '', 0, 4, 7) + screen:expect([[ + Ut enim ad minim veniam, quis nostrud | + exercitation ullamco laboris nisi ut aliquip ex | + ea co{5:popup}{6: con}{5:text}{3:at}. Duis aute irure dolor in | + repre{7:~}{3:enderit in vol}uptate velit esse cillum | + dolor{7:~}{3: eu fugiat nul}la pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + laborum^. | + | + ]]) + end end) end diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 044e4cc39c..0367e85028 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -946,6 +946,14 @@ function Screen:_handle_cmdline_show(content, pos, firstc, prompt, indent, level if firstc == '' then firstc = nil end if prompt == '' then prompt = nil end if indent == 0 then indent = nil end + + -- check position is valid #10000 + local len = 0 + for _, chunk in ipairs(content) do + len = len + string.len(chunk[2]) + end + assert(pos <= len) + self.cmdline[level] = {content=content, pos=pos, firstc=firstc, prompt=prompt, indent=indent} end |