diff options
-rw-r--r-- | runtime/doc/lua.txt | 2 | ||||
-rw-r--r-- | runtime/lua/vim/filetype.lua | 1 | ||||
-rw-r--r-- | runtime/lua/vim/fs.lua | 2 | ||||
-rw-r--r-- | src/nvim/arglist.c | 2 | ||||
-rw-r--r-- | src/nvim/linematch.c | 8 | ||||
-rw-r--r-- | src/nvim/main.c | 3 | ||||
-rw-r--r-- | src/nvim/memory.c | 2 | ||||
-rw-r--r-- | src/nvim/regexp.c | 2 | ||||
-rw-r--r-- | src/nvim/regexp_bt.c | 13 | ||||
-rw-r--r-- | src/nvim/regexp_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/regexp_nfa.c | 16 | ||||
-rw-r--r-- | src/nvim/search.c | 21 | ||||
-rw-r--r-- | src/nvim/testdir/test_filetype.vim | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_fold.vim | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_highlight.vim | 4 | ||||
-rw-r--r-- | src/nvim/testdir/test_search.vim | 26 | ||||
-rw-r--r-- | test/functional/core/startup_spec.lua | 64 | ||||
-rw-r--r-- | test/functional/ui/spell_spec.lua | 2 |
18 files changed, 146 insertions, 30 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 4055d93f6a..b506226697 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -2280,7 +2280,7 @@ find({names}, {opts}) *vim.fs.find()* searches are recursive and may search through many directories! If {stop} is non-nil, then the search stops when the directory given in {stop} is reached. The search terminates when {limit} (default 1) matches are found. - The search can be narrowed to find only files or or only directories by + The search can be narrowed to find only files or only directories by specifying {type} to be "file" or "directory", respectively. Parameters: ~ diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 5e086c8abf..dbad747f8f 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -1909,6 +1909,7 @@ local pattern = { ['Prl.*%..*'] = starsetf('jam'), ['.*%.properties_..'] = 'jproperties', ['.*%.properties_.._..'] = 'jproperties', + ['org%.eclipse%..*%.prefs'] = 'jproperties', ['.*%.properties_.._.._.*'] = starsetf('jproperties'), ['Kconfig%..*'] = starsetf('kconfig'), ['.*%.[Ss][Uu][Bb]'] = 'krl', diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index c7c053852d..d128c15233 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -73,7 +73,7 @@ end --- searches are recursive and may search through many directories! If {stop} --- is non-nil, then the search stops when the directory given in {stop} is --- reached. The search terminates when {limit} (default 1) matches are found. ---- The search can be narrowed to find only files or or only directories by +--- The search can be narrowed to find only files or only directories by --- specifying {type} to be "file" or "directory", respectively. --- ---@param names (string|table|fun(name: string): boolean) Names of the files diff --git a/src/nvim/arglist.c b/src/nvim/arglist.c index 73c86addac..8621e48754 100644 --- a/src/nvim/arglist.c +++ b/src/nvim/arglist.c @@ -1092,7 +1092,7 @@ static void do_arg_all(int count, int forceit, int keep_tabs) last_curtab = curtab; win_enter(lastwin, false); - // Open upto "count" windows. + // Open up to "count" windows. arg_all_open_windows(&aall, count); // Remove the "lock" on the argument list. diff --git a/src/nvim/linematch.c b/src/nvim/linematch.c index e11562ba68..ebedda9b4d 100644 --- a/src/nvim/linematch.c +++ b/src/nvim/linematch.c @@ -290,18 +290,18 @@ static void populate_tensor(int *df_iters, const size_t ch_dim, diffcmppath_T *d /// algorithm to find an optimal alignment of lines of a diff block with 2 or /// more files. The algorithm is generalized to work for any number of files -/// which corresponds to another dimmension added to the tensor used in the +/// which corresponds to another dimension added to the tensor used in the /// algorithm /// /// for questions and information about the linematch algorithm please contact /// Jonathon White (jonathonwhite@protonmail.com) /// -/// for explanation, a summary of the algorithm in 3 dimmensions (3 files +/// for explanation, a summary of the algorithm in 3 dimensions (3 files /// compared) follows /// /// The 3d case (for 3 buffers) of the algorithm implemented when diffopt /// 'linematch' is enabled. The algorithm constructs a 3d tensor to -/// compare a diff between 3 buffers. The dimmensions of the tensor are +/// compare a diff between 3 buffers. The dimensions of the tensor are /// the length of the diff in each buffer plus 1 A path is constructed by /// moving from one edge of the cube/3d tensor to the opposite edge. /// Motions from one cell of the cube to the next represent decisions. In @@ -324,7 +324,7 @@ static void populate_tensor(int *df_iters, const size_t ch_dim, diffcmppath_T *d /// the one which results in the local highest score. The total highest /// scored path is, then in the end represented by the cell in the /// opposite corner from the start location. The entire algorithm -/// consits of populating the 3d cube with the optimal paths from which +/// consists of populating the 3d cube with the optimal paths from which /// it may have came. /// /// Optimizations: diff --git a/src/nvim/main.c b/src/nvim/main.c index a369ca0256..78b59887e7 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1919,7 +1919,8 @@ static bool do_user_initialization(void) xfree(user_vimrc); xfree(init_lua_path); - return false; + do_exrc = p_exrc; + return do_exrc; } xfree(init_lua_path); diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 60c29492bb..8bc871344c 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -553,7 +553,7 @@ static void arena_free_reuse_blks(void) } } -/// Finnish the allocations in an arena. +/// Finish the allocations in an arena. /// /// This does not immediately free the memory, but leaves existing allocated /// objects valid, and returns an opaque ArenaMem handle, which can be used to diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 7b1199fd3b..d61a185fcc 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -958,10 +958,12 @@ static unsigned reg_tofreelen; typedef struct { regmatch_T *reg_match; regmmatch_T *reg_mmatch; + char_u **reg_startp; char_u **reg_endp; lpos_T *reg_startpos; lpos_T *reg_endpos; + win_T *reg_win; buf_T *reg_buf; linenr_T reg_firstlnum; diff --git a/src/nvim/regexp_bt.c b/src/nvim/regexp_bt.c index b430c95a6e..19b89bef74 100644 --- a/src/nvim/regexp_bt.c +++ b/src/nvim/regexp_bt.c @@ -4930,15 +4930,16 @@ static long regtry(bt_regprog_T *prog, colnr_T col, proftime_T *tm, int *timed_o /// Match a regexp against a string ("line" points to the string) or multiple /// lines (if "line" is NULL, use reg_getline()). /// -/// @param col column to start search +/// @param startcol column to start looking for match /// @param tm timeout limit or NULL /// @param timed_out flag set on timeout or NULL /// /// @return 0 for failure, or number of lines contained in the match. -static long bt_regexec_both(char_u *line, colnr_T col, proftime_T *tm, int *timed_out) +static long bt_regexec_both(char_u *line, colnr_T startcol, proftime_T *tm, int *timed_out) { bt_regprog_T *prog; char_u *s; + colnr_T col = startcol; long retval = 0L; // Create "regstack" and "backpos" if they are not allocated yet. @@ -5113,10 +5114,18 @@ theend: || (end->lnum == start->lnum && end->col < start->col)) { rex.reg_mmatch->endpos[0] = rex.reg_mmatch->startpos[0]; } + + // startpos[0] may be set by "\zs", also return the column where + // the whole pattern matched. + rex.reg_mmatch->rmm_matchcol = col; } else { if (rex.reg_match->endp[0] < rex.reg_match->startp[0]) { rex.reg_match->endp[0] = rex.reg_match->startp[0]; } + + // startpos[0] may be set by "\zs", also return the column where + // the whole pattern matched. + rex.reg_match->rm_matchcol = col; } } diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h index ee32b8d13a..a3b77f295a 100644 --- a/src/nvim/regexp_defs.h +++ b/src/nvim/regexp_defs.h @@ -49,6 +49,8 @@ typedef struct { regprog_T *regprog; lpos_T startpos[NSUBEXP]; lpos_T endpos[NSUBEXP]; + + colnr_T rmm_matchcol; ///< match start without "\zs" int rmm_ic; colnr_T rmm_maxcol; /// when not zero: maximum column } regmmatch_T; @@ -128,6 +130,8 @@ typedef struct { regprog_T *regprog; char *startp[NSUBEXP]; char *endp[NSUBEXP]; + + colnr_T rm_matchcol; ///< match start without "\zs" bool rm_ic; } regmatch_T; diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index da6892274a..7361b31456 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -7385,7 +7385,13 @@ static long nfa_regexec_both(char_u *line, colnr_T startcol, proftime_T *tm, int // If match_text is set it contains the full text that must match. // Nothing else to try. Doesn't handle combining chars well. if (prog->match_text != NULL && !rex.reg_icombine) { - return find_match_text(col, prog->regstart, prog->match_text); + retval = find_match_text(col, prog->regstart, prog->match_text); + if (REG_MULTI) { + rex.reg_mmatch->rmm_matchcol = col; + } else { + rex.reg_match->rm_matchcol = col; + } + return retval; } } @@ -7421,10 +7427,18 @@ theend: || (end->lnum == start->lnum && end->col < start->col)) { rex.reg_mmatch->endpos[0] = rex.reg_mmatch->startpos[0]; } + + // startpos[0] may be set by "\zs", also return the column where + // the whole pattern matched. + rex.reg_mmatch->rmm_matchcol = col; } else { if (rex.reg_match->endp[0] < rex.reg_match->startp[0]) { rex.reg_match->endp[0] = rex.reg_match->startp[0]; } + + // startpos[0] may be set by "\zs", also return the column where + // the whole pattern matched. + rex.reg_match->rm_matchcol = col; } } diff --git a/src/nvim/search.c b/src/nvim/search.c index cb31da3e87..3e64549ec5 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -655,6 +655,8 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, // match (this is vi compatible) or on the next char. if (dir == FORWARD && at_first_line) { match_ok = true; + matchcol = col; + // When the match starts in a next line it's certainly // past the start position. // When match lands on a NUL the cursor will be put @@ -679,20 +681,21 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, break; } matchcol = endpos.col; - // for empty match (matchcol == matchpos.col): advance one char + // for empty match: advance one char + if (matchcol == matchpos.col && ptr[matchcol] != NUL) { + matchcol += utfc_ptr2len(ptr + matchcol); + } } else { - // Prepare to start after first matched character. - matchcol = matchpos.col; - } - - if (matchcol == matchpos.col && ptr[matchcol] != NUL) { - matchcol += utfc_ptr2len(ptr + matchcol); + // Advance "matchcol" to the next character. + // This does not use matchpos.col, because + // "\zs" may have have set it. + if (ptr[matchcol] != NUL) { + matchcol += utfc_ptr2len(ptr + matchcol); + } } - if (matchcol == 0 && (options & SEARCH_START)) { break; } - if (ptr[matchcol] == NUL || (nmatched = vim_regexec_multi(®match, win, buf, lnum, matchcol, tm, diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 1ebf72ce41..5ffddb7925 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -288,7 +288,7 @@ let s:filename_checks = { \ 'jess': ['file.clp'], \ 'jgraph': ['file.jgr'], \ 'jovial': ['file.jov', 'file.j73', 'file.jovial'], - \ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'], + \ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file', 'org.eclipse.xyz.prefs'], \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', '.babelrc', '.eslintrc', '.prettierrc', '.firebaserc', 'file.slnf'], \ 'json5': ['file.json5'], \ 'jsonc': ['file.jsonc'], diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 23ed3817dd..2215166cd6 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -1192,7 +1192,7 @@ endfunc " Test for merging two recursive folds when an intermediate line with no fold " is removed -func Test_fold_merge_recrusive() +func Test_fold_merge_recursive() new call setline(1, [' one', ' two', 'xxxx', ' three', \ ' four', "\tfive"]) diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim index d618637d63..8a102f2e65 100644 --- a/src/nvim/testdir/test_highlight.vim +++ b/src/nvim/testdir/test_highlight.vim @@ -819,11 +819,11 @@ func Test_highlight_clear_restores_context() let patContextDefault = fnamemodify(scriptContextDefault, ':t') .. ' line 1' let patContextRelink = fnamemodify(scriptContextRelink, ':t') .. ' line 2' - exec "source" scriptContextDefault + exec 'source ' .. scriptContextDefault let hlContextDefault = execute("verbose hi Context") call assert_match(patContextDefault, hlContextDefault) - exec "source" scriptContextRelink + exec 'source ' .. scriptContextRelink let hlContextRelink = execute("verbose hi Context") call assert_match(patContextRelink, hlContextRelink) diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 96ed35718f..0702e89ebb 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -1816,7 +1816,7 @@ func Test_search_smartcase_utf8() set ignorecase& smartcase& let &encoding = save_enc - close! + bwipe! endfunc " Test searching past the end of a file @@ -1825,7 +1825,29 @@ func Test_search_past_eof() call setline(1, ['Line']) exe "normal /\\n\\zs\<CR>" call assert_equal([1, 4], [line('.'), col('.')]) - close! + bwipe! +endfunc + +" Test setting the start of the match and still finding a next match in the +" same line. +func Test_search_set_start_same_line() + new + set cpo-=c + + call setline(1, ['1', '2', '3 .', '4', '5']) + exe "normal /\\_s\\zs\\S\<CR>" + call assert_equal([2, 1], [line('.'), col('.')]) + exe 'normal n' + call assert_equal([3, 1], [line('.'), col('.')]) + exe 'normal n' + call assert_equal([3, 3], [line('.'), col('.')]) + exe 'normal n' + call assert_equal([4, 1], [line('.'), col('.')]) + exe 'normal n' + call assert_equal([5, 1], [line('.'), col('.')]) + + set cpo+=c + bwipe! endfunc " Test for various search offsets diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index bab339e253..41596f5416 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -12,6 +12,7 @@ local eval = helpers.eval local exec_lua = helpers.exec_lua local feed = helpers.feed local funcs = helpers.funcs +local pesc = helpers.pesc local mkdir = helpers.mkdir local mkdir_p = helpers.mkdir_p local nvim_prog = helpers.nvim_prog @@ -576,7 +577,66 @@ describe('user config init', function() eq(funcs.fnamemodify(init_lua_path, ':p'), eval('$MYVIMRC')) end) - describe 'with explicitly provided config'(function() + describe('with existing .exrc in cwd', function() + local exrc_path = '.exrc' + local xstate = 'Xstate' + + before_each(function() + write_file(init_lua_path, [[ + vim.o.exrc = true + vim.g.from_exrc = 0 + ]]) + mkdir_p(xstate .. pathsep .. (is_os('win') and 'nvim-data' or 'nvim')) + write_file(exrc_path, [[ + let g:from_exrc = 1 + ]]) + end) + + after_each(function() + os.remove(exrc_path) + rmdir(xstate) + end) + + it('loads .exrc #13501', function() + clear{ args_rm = {'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_STATE_HOME=xstate } } + -- The .exrc file is not trusted, and the prompt is skipped because there is no UI. + eq(0, eval('g:from_exrc')) + + local screen = Screen.new(50, 8) + screen:attach() + funcs.termopen({nvim_prog}) + screen:expect({ any = pesc('[i]gnore, (v)iew, (d)eny, (a)llow:') }) + -- `i` to enter Terminal mode, `a` to allow + feed('ia') + screen:expect([[ + | + ~ | + ~ | + ~ | + ~ | + [No Name] 0,0-1 All| + | + -- TERMINAL -- | + ]]) + feed(':echo g:from_exrc<CR>') + screen:expect([[ + | + ~ | + ~ | + ~ | + ~ | + [No Name] 0,0-1 All| + 1 | + -- TERMINAL -- | + ]]) + + clear{ args_rm = {'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_STATE_HOME=xstate } } + -- The .exrc file is now trusted. + eq(1, eval('g:from_exrc')) + end) + end) + + describe('with explicitly provided config', function() local custom_lua_path = table.concat({xhome, 'custom.lua'}, pathsep) before_each(function() write_file(custom_lua_path, [[ @@ -591,7 +651,7 @@ describe('user config init', function() end) end) - describe 'VIMRC also exists'(function() + describe('VIMRC also exists', function() before_each(function() write_file(table.concat({xconfig, 'nvim', 'init.vim'}, pathsep), [[ let g:vim_rc = 1 diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua index 425790dbf9..5b43edbad4 100644 --- a/test/functional/ui/spell_spec.lua +++ b/test/functional/ui/spell_spec.lua @@ -70,7 +70,7 @@ describe("'spell'", function() "with missing caps here.", | ^ | | - ]]) + ]]) end) it('"noplainbuffer" and syntax #20385', function() |