diff options
-rw-r--r-- | src/nvim/edit.c | 6 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 8 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 4 | ||||
-rw-r--r-- | src/nvim/globals.h | 4 | ||||
-rw-r--r-- | src/nvim/option.c | 9 | ||||
-rw-r--r-- | src/nvim/screen.c | 2 | ||||
-rw-r--r-- | src/nvim/search.c | 10 | ||||
-rw-r--r-- | src/nvim/shada.c | 3 | ||||
-rw-r--r-- | src/nvim/tag.c | 9 | ||||
-rw-r--r-- | src/nvim/testdir/test_cmdline.vim | 44 | ||||
-rw-r--r-- | src/nvim/testdir/test_mksession.vim | 11 | ||||
-rw-r--r-- | src/nvim/testdir/test_popup.vim | 30 | ||||
-rw-r--r-- | src/nvim/vim.h | 3 | ||||
-rw-r--r-- | src/nvim/window.c | 41 |
14 files changed, 142 insertions, 42 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index ca64cc091d..16c4882975 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -5541,13 +5541,15 @@ insertchar ( // 'paste' is set).. // Don't do this when there an InsertCharPre autocommand is defined, // because we need to fire the event for every character. + // Do the check for InsertCharPre before the call to vpeekc() because the + // InsertCharPre autocommand could change the input buffer. if (!ISSPECIAL(c) && (!has_mbyte || (*mb_char2len)(c) == 1) + && !has_event(EVENT_INSERTCHARPRE) && vpeekc() != NUL && !(State & REPLACE_FLAG) && !cindent_on() - && !p_ri - && !has_event(EVENT_INSERTCHARPRE)) { + && !p_ri) { #define INPUT_BUFLEN 100 char_u buf[INPUT_BUFLEN + 1]; int i; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index b880ec4f6d..85ec4efd3a 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9990,12 +9990,18 @@ static void ex_set(exarg_T *eap) (void)do_set(eap->arg, flags); } +void set_no_hlsearch(bool flag) +{ + no_hlsearch = flag; + set_vim_var_nr(VV_HLSEARCH, !no_hlsearch && p_hls); +} + /* * ":nohlsearch" */ static void ex_nohlsearch(exarg_T *eap) { - SET_NO_HLSEARCH(TRUE); + set_no_hlsearch(true); redraw_all_later(SOME_VALID); } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 4f35555098..f00367d9ca 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1830,7 +1830,7 @@ static int command_line_changed(CommandLineState *s) // If there is no command line, don't do anything if (ccline.cmdlen == 0) { i = 0; - SET_NO_HLSEARCH(true); // turn off previous highlight + set_no_hlsearch(true); // turn off previous highlight redraw_all_later(SOME_VALID); } else { int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK; @@ -1888,7 +1888,7 @@ static int command_line_changed(CommandLineState *s) // Disable 'hlsearch' highlighting if the pattern matches // everything. Avoids a flash when typing "foo\|". if (empty_pattern(ccline.cmdbuff)) { - SET_NO_HLSEARCH(true); + set_no_hlsearch(true); } validate_cursor(); diff --git a/src/nvim/globals.h b/src/nvim/globals.h index ad321963fe..9a7b5425bf 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -862,8 +862,8 @@ EXTERN char_u wim_flags[4]; # define STL_IN_TITLE 2 EXTERN int stl_syntax INIT(= 0); -/* don't use 'hlsearch' temporarily */ -EXTERN int no_hlsearch INIT(= FALSE); +// don't use 'hlsearch' temporarily +EXTERN bool no_hlsearch INIT(= false); /* Page number used for %N in 'pageheader' and 'guitablabel'. */ EXTERN linenr_T printer_page_num; diff --git a/src/nvim/option.c b/src/nvim/option.c index d1753526a7..ed9128dbbf 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3959,7 +3959,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, redraw_all_later(SOME_VALID); } else if ((int *)varp == &p_hls) { // when 'hlsearch' is set or reset: reset no_hlsearch - SET_NO_HLSEARCH(false); + set_no_hlsearch(false); } else if ((int *)varp == &curwin->w_p_scb) { // when 'scrollbind' is set: snapshot the current position to avoid a jump // at the end of normal_cmd() @@ -4330,19 +4330,26 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, // Number options that need some action when changed if (pp == &p_wh) { + // 'winheight' if (!ONE_WINDOW && curwin->w_height < p_wh) { win_setheight((int)p_wh); } } else if (pp == &p_hh) { + // 'helpheight' if (!ONE_WINDOW && curbuf->b_help && curwin->w_height < p_hh) { win_setheight((int)p_hh); } } else if (pp == &p_wmh) { + // 'winminheight' win_setminheight(); } else if (pp == &p_wiw) { + // 'winwidth' if (!ONE_WINDOW && curwin->w_width < p_wiw) { win_setwidth((int)p_wiw); } + } else if (pp == &p_wmw) { + // 'winminwidth' + win_setminwidth(); } else if (pp == &p_ls) { last_status(false); // (re)set last window status line. } else if (pp == &p_stal) { diff --git a/src/nvim/screen.c b/src/nvim/screen.c index b9469686b5..13eb088813 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -5762,7 +5762,7 @@ next_search_hl ( if (shl == &search_hl) { // don't free regprog in the match list, it's a copy vim_regfree(shl->rm.regprog); - SET_NO_HLSEARCH(TRUE); + set_no_hlsearch(true); } shl->rm.regprog = NULL; shl->lnum = 0; diff --git a/src/nvim/search.c b/src/nvim/search.c index 26549208a8..7d1c19d68c 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -100,7 +100,7 @@ static struct spat saved_spats[2]; // searching static struct spat saved_last_search_spat; static int saved_last_idx = 0; -static int saved_no_hlsearch = 0; +static bool saved_no_hlsearch = false; static char_u *mr_pattern = NULL; // pattern used by search_regcomp() static int mr_pattern_alloced = false; // mr_pattern was allocated @@ -248,7 +248,7 @@ void save_re_pat(int idx, char_u *pat, int magic) /* If 'hlsearch' set and search pat changed: need redraw. */ if (p_hls) redraw_all_later(SOME_VALID); - SET_NO_HLSEARCH(FALSE); + set_no_hlsearch(false); } } @@ -281,7 +281,7 @@ void restore_search_patterns(void) free_spat(&spats[1]); spats[1] = saved_spats[1]; last_idx = saved_last_idx; - SET_NO_HLSEARCH(saved_no_hlsearch); + set_no_hlsearch(saved_no_hlsearch); } } @@ -330,7 +330,7 @@ void restore_last_search_pattern(void) spats[RE_SEARCH] = saved_last_search_spat; set_vv_searchforward(); last_idx = saved_last_idx; - SET_NO_HLSEARCH(saved_no_hlsearch); + set_no_hlsearch(saved_no_hlsearch); } char_u *last_search_pattern(void) @@ -1048,7 +1048,7 @@ int do_search( */ if (no_hlsearch && !(options & SEARCH_KEEP)) { redraw_all_later(SOME_VALID); - SET_NO_HLSEARCH(FALSE); + set_no_hlsearch(false); } /* diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 69e6d61464..50f8990cf6 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -32,6 +32,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" +#include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" #include "nvim/search.h" #include "nvim/regexp.h" @@ -1274,7 +1275,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) if (cur_entry.data.search_pattern.is_last_used) { set_last_used_pattern( cur_entry.data.search_pattern.is_substitute_pattern); - SET_NO_HLSEARCH(!cur_entry.data.search_pattern.highlighted); + set_no_hlsearch(!cur_entry.data.search_pattern.highlighted); } // Do not free shada entry: its allocated memory was saved above. break; diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 88676abc2e..beee3c7594 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2310,7 +2310,6 @@ static int jumpto_tag( int retval = FAIL; int getfile_result = GETFILE_UNUSED; int search_options; - int save_no_hlsearch; win_T *curwin_save = NULL; char_u *full_fname = NULL; const bool old_KeyTyped = KeyTyped; // getting the file may reset it @@ -2453,9 +2452,9 @@ static int jumpto_tag( secure = 1; ++sandbox; save_magic = p_magic; - p_magic = FALSE; /* always execute with 'nomagic' */ - /* Save value of no_hlsearch, jumping to a tag is not a real search */ - save_no_hlsearch = no_hlsearch; + p_magic = false; // always execute with 'nomagic' + // Save value of no_hlsearch, jumping to a tag is not a real search + const bool save_no_hlsearch = no_hlsearch; /* * If 'cpoptions' contains 't', store the search pattern for the "n" @@ -2560,7 +2559,7 @@ static int jumpto_tag( --sandbox; /* restore no_hlsearch when keeping the old search pattern */ if (search_options) { - SET_NO_HLSEARCH(save_no_hlsearch); + set_no_hlsearch(save_no_hlsearch); } // Return OK if jumped to another file (at least we found the file!). diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index f43ea0e923..e6aafd964b 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -15,14 +15,48 @@ func Test_complete_list() endfunc func Test_complete_wildmenu() - call writefile(['testfile1'], 'Xtestfile1') - call writefile(['testfile2'], 'Xtestfile2') + call mkdir('Xdir1/Xdir2', 'p') + call writefile(['testfile1'], 'Xdir1/Xtestfile1') + call writefile(['testfile2'], 'Xdir1/Xtestfile2') + call writefile(['testfile3'], 'Xdir1/Xdir2/Xtestfile3') + call writefile(['testfile3'], 'Xdir1/Xdir2/Xtestfile4') set wildmenu - call feedkeys(":e Xtestf\t\t\r", "tx") + + " Pressing <Tab> completes, and moves to next files when pressing again. + call feedkeys(":e Xdir1/\<Tab>\<Tab>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + call feedkeys(":e Xdir1/\<Tab>\<Tab>\<Tab>\<CR>", 'tx') + call assert_equal('testfile2', getline(1)) + + " <S-Tab> is like <Tab> but begin with the last match and then go to + " previous. + call feedkeys(":e Xdir1/Xtest\<S-Tab>\<CR>", 'tx') call assert_equal('testfile2', getline(1)) + call feedkeys(":e Xdir1/Xtest\<S-Tab>\<S-Tab>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) - call delete('Xtestfile1') - call delete('Xtestfile2') + " <Left>/<Right> to move to previous/next file. + call feedkeys(":e Xdir1/\<Tab>\<Right>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + call feedkeys(":e Xdir1/\<Tab>\<Right>\<Right>\<CR>", 'tx') + call assert_equal('testfile2', getline(1)) + call feedkeys(":e Xdir1/\<Tab>\<Right>\<Right>\<Left>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + + " <Up>/<Down> to go up/down directories. + call feedkeys(":e Xdir1/\<Tab>\<Down>\<CR>", 'tx') + call assert_equal('testfile3', getline(1)) + call feedkeys(":e Xdir1/\<Tab>\<Down>\<Up>\<Right>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + + " cleanup + %bwipe + call delete('Xdir1/Xdir2/Xtestfile4') + call delete('Xdir1/Xdir2/Xtestfile3') + call delete('Xdir1/Xtestfile2') + call delete('Xdir1/Xtestfile1') + call delete('Xdir1/Xdir2', 'd') + call delete('Xdir1', 'd') set nowildmenu endfunc diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 0e56ed2ff3..b7169444d1 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -106,13 +106,22 @@ endfunc func Test_mksession_winheight() new - set winheight=10 winminheight=2 + set winheight=10 + set winminheight=2 mksession! Xtest_mks.out source Xtest_mks.out call delete('Xtest_mks.out') endfunc +func Test_mksession_large_winheight() + set winheight=999 + mksession! Xtest_mks_winheight.out + set winheight& + source Xtest_mks_winheight.out + call delete('Xtest_mks_winheight.out') +endfunc + " Verify that arglist is stored correctly to the session file. func Test_mksession_arglist() argdel * diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 162df4b76e..53df30bb19 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -746,6 +746,36 @@ func Test_popup_complete_backwards() bwipe! endfunc +fun! Test_complete_o_tab() + throw 'skipped: Nvim does not support test_override()' + let s:o_char_pressed = 0 + + fun! s:act_on_text_changed() + if s:o_char_pressed + let s:o_char_pressed = 0 + call feedkeys("\<c-x>\<c-n>", 'i') + endif + endf + + set completeopt=menu,noselect + new + imap <expr> <buffer> <tab> pumvisible() ? "\<c-p>" : "X" + autocmd! InsertCharPre <buffer> let s:o_char_pressed = (v:char ==# 'o') + autocmd! TextChangedI <buffer> call <sid>act_on_text_changed() + call setline(1, ['hoard', 'hoax', 'hoarse', '']) + let l:expected = ['hoard', 'hoax', 'hoarse', 'hoax', 'hoax'] + call cursor(4,1) + call test_override("char_avail", 1) + call feedkeys("Ahoa\<tab>\<tab>\<c-y>\<esc>", 'tx') + call feedkeys("oho\<tab>\<tab>\<c-y>\<esc>", 'tx') + call assert_equal(l:expected, getline(1,'$')) + + call test_override("char_avail", 0) + bwipe! + set completeopt& + delfunc s:act_on_text_changed +endf + func Test_popup_complete_info_01() new inoremap <buffer><F5> <C-R>=complete_info().mode<CR> diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 60737014b3..51f143a3d7 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -296,9 +296,6 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() #include "nvim/buffer_defs.h" // buffer and windows #include "nvim/ex_cmds_defs.h" // Ex command defines -# define SET_NO_HLSEARCH(flag) no_hlsearch = (flag); set_vim_var_nr( \ - VV_HLSEARCH, !no_hlsearch && p_hls) - // Used for flags in do_in_path() #define DIP_ALL 0x01 // all matches, not just the first one #define DIP_DIR 0x02 // find directories instead of files diff --git a/src/nvim/window.c b/src/nvim/window.c index 0e8cfcedf5..6861e19ca7 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5229,27 +5229,42 @@ static void frame_setwidth(frame_T *curfrp, int width) } } -/* - * Check 'winminheight' for a valid value. - */ +// Check 'winminheight' for a valid value and reduce it if needed. void win_setminheight(void) { - int room; - int first = TRUE; + bool first = true; - /* loop until there is a 'winminheight' that is possible */ + // loop until there is a 'winminheight' that is possible while (p_wmh > 0) { - /* TODO: handle vertical splits */ - room = -p_wh; - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - room += wp->w_height - p_wmh; + const int room = Rows - p_ch; + const int needed = frame_minheight(topframe, NULL); + if (room >= needed) { + break; + } + p_wmh--; + if (first) { + EMSG(_(e_noroom)); + first = false; } - if (room >= 0) + } +} + +// Check 'winminwidth' for a valid value and reduce it if needed. +void win_setminwidth(void) +{ + bool first = true; + + // loop until there is a 'winminheight' that is possible + while (p_wmw > 0) { + const int room = Columns; + const int needed = frame_minwidth(topframe, NULL); + if (room >= needed) { break; - --p_wmh; + } + p_wmw--; if (first) { EMSG(_(e_noroom)); - first = FALSE; + first = false; } } } |