diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/autocmd.c | 20 | ||||
| -rw-r--r-- | src/nvim/grid_defs.h | 8 | ||||
| -rw-r--r-- | src/nvim/mouse.c | 17 | ||||
| -rw-r--r-- | src/nvim/screen.c | 3 | ||||
| -rw-r--r-- | src/nvim/testdir/test_autocmd.vim | 16 | ||||
| -rw-r--r-- | src/nvim/testdir/test_startup.vim | 161 | ||||
| -rw-r--r-- | src/nvim/ui_compositor.c | 17 | ||||
| -rw-r--r-- | src/nvim/window.c | 2 |
8 files changed, 206 insertions, 38 deletions
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 3de2e0f342..2ddb925d40 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -968,7 +968,7 @@ static int do_autocmd_event(event_T event, // Implementation of ":doautocmd [group] event [fname]". // Return OK for success, FAIL for failure; int do_doautocmd(char_u *arg, - int do_msg, // give message for no matching autocmds? + bool do_msg, // give message for no matching autocmds? bool *did_something) { char_u *fname; @@ -1017,11 +1017,12 @@ int do_doautocmd(char_u *arg, // ":doautoall": execute autocommands for each loaded buffer. void ex_doautoall(exarg_T *eap) { - int retval; + int retval = OK; aco_save_T aco; char_u *arg = eap->arg; int call_do_modelines = check_nomodeline(&arg); bufref_T bufref; + bool did_aucmd; // This is a bit tricky: For some commands curwin->w_buffer needs to be // equal to curbuf, but for some buffers there may not be a window. @@ -1029,14 +1030,14 @@ void ex_doautoall(exarg_T *eap) // gives problems when the autocommands make changes to the list of // buffers or windows... FOR_ALL_BUFFERS(buf) { - if (buf->b_ml.ml_mfp == NULL) { + // Only do loaded buffers and skip the current buffer, it's done last. + if (buf->b_ml.ml_mfp == NULL || buf == curbuf) { continue; } // Find a window for this buffer and save some values. aucmd_prepbuf(&aco, buf); set_bufref(&bufref, buf); - bool did_aucmd; // execute the autocommands for this buffer retval = do_doautocmd(arg, false, &did_aucmd); @@ -1052,10 +1053,19 @@ void ex_doautoall(exarg_T *eap) // Stop if there is some error or buffer was deleted. if (retval == FAIL || !bufref_valid(&bufref)) { + retval = FAIL; break; } } + // Execute autocommands for the current buffer last. + if (retval == OK) { + (void)do_doautocmd(arg, false, &did_aucmd); + if (call_do_modelines && did_aucmd) { + do_modelines(0); + } + } + check_cursor(); // just in case lines got deleted } @@ -1661,11 +1671,13 @@ static bool apply_autocmds_group(event_T event, did_filetype = false; while (au_pending_free_buf != NULL) { buf_T *b = au_pending_free_buf->b_next; + xfree(au_pending_free_buf); au_pending_free_buf = b; } while (au_pending_free_win != NULL) { win_T *w = au_pending_free_win->w_next; + xfree(au_pending_free_win); au_pending_free_win = w; } diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h index e14aae73d8..752be4f5a8 100644 --- a/src/nvim/grid_defs.h +++ b/src/nvim/grid_defs.h @@ -76,6 +76,12 @@ typedef struct { int comp_row; int comp_col; + // Requested width and height of the grid upon resize. Used by + // `ui_compositor` to correctly determine which regions need to + // be redrawn. + int comp_width; + int comp_height; + // z-index of the grid. Grids with higher index is draw on top. // default_grid.comp_index is always zero. size_t comp_index; @@ -86,6 +92,6 @@ typedef struct { } ScreenGrid; #define SCREEN_GRID_INIT { 0, NULL, NULL, NULL, NULL, NULL, 0, 0, false, \ - false, 0, 0, false, true, 0, 0, 0, false } + false, 0, 0, false, true, 0, 0, 0, 0, 0, false } #endif // NVIM_GRID_DEFS_H diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index f28658aa29..9dc85797b4 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -717,23 +717,22 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // Check clicked cell is foldcolumn int mouse_check_fold(void) { - int grid = mouse_grid; - int row = mouse_row; - int col = mouse_col; + int click_grid = mouse_grid; + int click_row = mouse_row; + int click_col = mouse_col; int mouse_char = ' '; win_T *wp; - wp = mouse_find_win(&grid, &row, &col); + wp = mouse_find_win(&click_grid, &click_row, &click_col); if (wp && mouse_row >= 0 && mouse_row < Rows && mouse_col >= 0 && mouse_col <= Columns) { int multigrid = ui_has(kUIMultigrid); ScreenGrid *gp = multigrid ? &wp->w_grid : &default_grid; int fdc = win_fdccol_count(wp); - - row = multigrid && mouse_grid == 0 ? row : mouse_row; - col = multigrid && mouse_grid == 0 ? col : mouse_col; + int row = multigrid && mouse_grid == 0 ? click_row : mouse_row; + int col = multigrid && mouse_grid == 0 ? click_col : mouse_col; // Remember the character under the mouse, might be one of foldclose or // foldopen fillchars in the fold column. @@ -743,8 +742,8 @@ int mouse_check_fold(void) } // Check for position outside of the fold column. - if (wp->w_p_rl ? col < wp->w_width_inner - fdc : - col >= fdc + (cmdwin_type == 0 ? 0 : 1)) { + if (wp->w_p_rl ? click_col < wp->w_width_inner - fdc : + click_col >= fdc + (cmdwin_type == 0 ? 0 : 1)) { mouse_char = ' '; } } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index aa3a7ae7ed..467cac4f27 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -6274,6 +6274,9 @@ retry: tab_page_click_defs = new_tab_page_click_defs; tab_page_click_defs_size = Columns; + default_grid.comp_height = Rows; + default_grid.comp_width = Columns; + default_grid.row_offset = 0; default_grid.col_offset = 0; default_grid.handle = DEFAULT_GRID_HANDLE; diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 1f3a45a9ab..7788e09d43 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -1922,20 +1922,28 @@ func Test_autocmd_window() %bw! edit one.txt tabnew two.txt + vnew three.txt + tabnew four.txt + tabprevious let g:blist = [] - augroup aucmd_win_test + augroup aucmd_win_test1 au! au BufEnter * call add(g:blist, [expand('<afile>'), \ win_gettype(bufwinnr(expand('<afile>')))]) augroup END doautoall BufEnter - call assert_equal([['one.txt', 'autocmd'], ['two.txt', '']], g:blist) + call assert_equal([ + \ ['one.txt', 'autocmd'], + \ ['two.txt', ''], + \ ['four.txt', 'autocmd'], + \ ['three.txt', ''], + \ ], g:blist) - augroup aucmd_win_test + augroup aucmd_win_test1 au! augroup END - augroup! aucmd_win_test + augroup! aucmd_win_test1 %bw! endfunc diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index e6ad92f483..eebf85af6f 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -111,10 +111,8 @@ func Test_pack_in_rtp_when_plugins_run() endfunc func Test_help_arg() - if !has('unix') && has('gui') - " this doesn't work with gvim on MS-Windows - return - endif + CheckNotMSWindows + if RunVim([], [], '--help >Xtestout') let lines = readfile('Xtestout') call assert_true(len(lines) > 20) @@ -412,6 +410,134 @@ func Test_A_F_H_arg() call delete('Xtestout') endfunc +" Test the --echo-wid argument (for GTK GUI only). +func Test_echo_wid() + CheckCanRunGui + CheckFeature gui_gtk + + if RunVim([], [], '-g --echo-wid -cq >Xtest_echo_wid') + let lines = readfile('Xtest_echo_wid') + call assert_equal(1, len(lines)) + call assert_match('^WID: \d\+$', lines[0]) + endif + + call delete('Xtest_echo_wid') +endfunction + +" Test the -reverse and +reverse arguments (for GUI only). +func Test_reverse() + CheckCanRunGui + CheckNotMSWindows + + let after =<< trim [CODE] + call writefile([&background], "Xtest_reverse") + qall + [CODE] + if RunVim([], after, '-f -g -reverse') + let lines = readfile('Xtest_reverse') + call assert_equal(['dark'], lines) + endif + if RunVim([], after, '-f -g +reverse') + let lines = readfile('Xtest_reverse') + call assert_equal(['light'], lines) + endif + + call delete('Xtest_reverse') +endfunc + +" Test the -background and -foreground arguments (for GUI only). +func Test_background_foreground() + CheckCanRunGui + CheckNotMSWindows + + " Is there a better way to check the effect of -background & -foreground + " other than merely looking at &background (dark or light)? + let after =<< trim [CODE] + call writefile([&background], "Xtest_fg_bg") + qall + [CODE] + if RunVim([], after, '-f -g -background darkred -foreground yellow') + let lines = readfile('Xtest_fg_bg') + call assert_equal(['dark'], lines) + endif + if RunVim([], after, '-f -g -background ivory -foreground darkgreen') + let lines = readfile('Xtest_fg_bg') + call assert_equal(['light'], lines) + endif + + call delete('Xtest_fg_bg') +endfunc + +" Test the -font argument (for GUI only). +func Test_font() + CheckCanRunGui + CheckNotMSWindows + + if has('gui_gtk') + let font = 'Courier 14' + elseif has('gui_motif') || has('gui_athena') + let font = '-misc-fixed-bold-*' + else + throw 'Skipped: test does not set a valid font for this GUI' + endif + + let after =<< trim [CODE] + call writefile([&guifont], "Xtest_font") + qall + [CODE] + + if RunVim([], after, '--nofork -g -font "' .. font .. '"') + let lines = readfile('Xtest_font') + call assert_equal([font], lines) + endif + + call delete('Xtest_font') +endfunc + +" Test the -geometry argument (for GUI only). +func Test_geometry() + CheckCanRunGui + CheckNotMSWindows + + if has('gui_motif') || has('gui_athena') + " FIXME: With GUI Athena or Motif, the value of getwinposx(), + " getwinposy() and getwinpos() do not match exactly the + " value given in -geometry. Why? + " So only check &columns and &lines for those GUIs. + let after =<< trim [CODE] + call writefile([&columns, &lines], "Xtest_geometry") + qall + [CODE] + if RunVim([], after, '-f -g -geometry 31x13+41+43') + let lines = readfile('Xtest_geometry') + call assert_equal(['31', '13'], lines) + endif + else + let after =<< trim [CODE] + call writefile([&columns, &lines, getwinposx(), getwinposy(), string(getwinpos())], "Xtest_geometry") + qall + [CODE] + if RunVim([], after, '-f -g -geometry 31x13+41+43') + let lines = readfile('Xtest_geometry') + call assert_equal(['31', '13', '41', '43', '[41, 43]'], lines) + endif + endif + + call delete('Xtest_geometry') +endfunc + +" Test the -iconic argument (for GUI only). +func Test_iconic() + CheckCanRunGui + CheckNotMSWindows + + call RunVim([], [], '-f -g -iconic -cq') + + " TODO: currently only start vim iconified, but does not + " check that vim is iconified. How could this be checked? +endfunc + + func Test_invalid_args() if !has('unix') || has('gui_running') " can't get output of Vim. @@ -777,17 +903,12 @@ func Test_progname() let prognames = ['nvim'] for progname in prognames - if empty($DISPLAY) - if progname =~# 'g' - " Can't run gvim, gview (etc.) if $DISPLAY is not setup. - continue - endif - if has('gui') && (progname ==# 'evim' || progname ==# 'eview') - " evim or eview will start the GUI if there is gui support. - " So don't try to start them either if $DISPLAY is not setup. - continue - endif - endif + let run_with_gui = (progname =~# 'g') || (has('gui') && (progname ==# 'evim' || progname ==# 'eview')) + + if empty($DISPLAY) && run_with_gui + " Can't run gvim, gview (etc.) if $DISPLAY is not setup. + continue + endif exe 'silent !ln -s -f ' ..exepath(GetVimProg()) .. ' Xprogname/' .. progname @@ -801,7 +922,15 @@ func Test_progname() if progname =~# 'g' && !has('gui') call assert_equal("E25: GUI cannot be used: Not enabled at compile time\n", stdout_stderr, progname) else - call assert_equal('', stdout_stderr, progname) + " GUI motif can output some warnings like this: + " Warning: + " Name: subMenu + " Class: XmCascadeButton + " Illegal mnemonic character; Could not convert X KEYSYM to a keycode + " So don't check that stderr is empty with GUI Motif. + if run_with_gui && !has('gui_motif') + call assert_equal('', stdout_stderr, progname) + endif call assert_equal(expectations[progname], readfile('Xprogname_out'), progname) endif diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index 06efc9fa99..946215d957 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -127,6 +127,9 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width, bool valid, bool on_top) { bool moved; + + grid->comp_height = height; + grid->comp_width = width; if (grid->comp_index != 0) { moved = (row != grid->comp_row) || (col != grid->comp_col); if (ui_comp_should_draw()) { @@ -334,17 +337,25 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, sattr_T *bg_attrs = &default_grid.attrs[default_grid.line_offset[row] +(size_t)startcol]; + int grid_width, grid_height; while (col < endcol) { int until = 0; for (size_t i = 0; i < kv_size(layers); i++) { ScreenGrid *g = kv_A(layers, i); - if (g->comp_row > row || row >= g->comp_row + g->Rows + // compose_line may have been called after a shrinking operation but + // before the resize has actually been applied. Therefore, we need to + // first check to see if any grids have pending updates to width/height, + // to ensure that we don't accidentally put any characters into `linebuf` + // that have been invalidated. + grid_width = MIN(g->Columns, g->comp_width); + grid_height = MIN(g->Rows, g->comp_height); + if (g->comp_row > row || row >= g->comp_row + grid_height || g->comp_disabled) { continue; } - if (g->comp_col <= col && col < g->comp_col+g->Columns) { + if (g->comp_col <= col && col < g->comp_col + grid_width) { grid = g; - until = g->comp_col+g->Columns; + until = g->comp_col + grid_width; } else if (g->comp_col > col) { until = MIN(until, g->comp_col); } diff --git a/src/nvim/window.c b/src/nvim/window.c index 7558e0e3ba..aa8d8727e7 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -710,7 +710,7 @@ int win_fdccol_count(win_T *wp) } -static void ui_ext_win_position(win_T *wp) +void ui_ext_win_position(win_T *wp) { if (!wp->w_floating) { ui_call_win_pos(wp->w_grid.handle, wp->handle, wp->w_winrow, |