patch 9.1.0810: cannot easily adjust the |:find| command
Problem: cannot easily adjust the |:find| command
Solution: Add support for the 'findexpr' option (Yegappan Lakshmanan)
closes: #15901
closes: #15905
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/test_findfile.vim b/src/testdir/test_findfile.vim
index a5e18b9..f8be713 100644
--- a/src/testdir/test_findfile.vim
+++ b/src/testdir/test_findfile.vim
@@ -1,5 +1,7 @@
" Test findfile() and finddir()
+source check.vim
+
let s:files = [ 'Xfinddir1/foo',
\ 'Xfinddir1/bar',
\ 'Xfinddir1/Xdir2/foo',
@@ -281,4 +283,170 @@
let &path = save_path
endfunc
+" Test for 'findexpr'
+func Test_findexpr()
+ CheckUnix
+ call assert_equal('', &findexpr)
+ call writefile(['aFile'], 'Xfindexpr1.c', 'D')
+ call writefile(['bFile'], 'Xfindexpr2.c', 'D')
+ call writefile(['cFile'], 'Xfindexpr3.c', 'D')
+
+ " basic tests
+ func FindExpr1()
+ let fnames = ['Xfindexpr1.c', 'Xfindexpr2.c', 'Xfindexpr3.c']
+ "return fnames->copy()->filter('v:val =~? v:fname')->join("\n")
+ return fnames->copy()->filter('v:val =~? v:fname')
+ endfunc
+
+ set findexpr=FindExpr1()
+ find Xfindexpr3
+ call assert_match('Xfindexpr3.c', @%)
+ bw!
+ 2find Xfind
+ call assert_match('Xfindexpr2.c', @%)
+ bw!
+ call assert_fails('4find Xfind', 'E347: No more file "Xfind" found in path')
+ call assert_fails('find foobar', 'E345: Can''t find file "foobar" in path')
+
+ sfind Xfindexpr2.c
+ call assert_match('Xfindexpr2.c', @%)
+ call assert_equal(2, winnr('$'))
+ %bw!
+ call assert_fails('sfind foobar', 'E345: Can''t find file "foobar" in path')
+
+ tabfind Xfindexpr3.c
+ call assert_match('Xfindexpr3.c', @%)
+ call assert_equal(2, tabpagenr())
+ %bw!
+ call assert_fails('tabfind foobar', 'E345: Can''t find file "foobar" in path')
+
+ " Buffer-local option
+ set findexpr=['abc']
+ new
+ setlocal findexpr=['def']
+ find xxxx
+ call assert_equal('def', @%)
+ wincmd w
+ find xxxx
+ call assert_equal('abc', @%)
+ aboveleft new
+ call assert_equal("['abc']", &findexpr)
+ wincmd k
+ aboveleft new
+ call assert_equal("['abc']", &findexpr)
+ %bw!
+
+ " Empty list
+ set findexpr=[]
+ call assert_fails('find xxxx', 'E345: Can''t find file "xxxx" in path')
+
+ " Error cases
+
+ " Syntax error in the expression
+ set findexpr=FindExpr1{}
+ call assert_fails('find Xfindexpr1.c', 'E15: Invalid expression')
+
+ " Find expression throws an error
+ func FindExpr2()
+ throw 'find error'
+ endfunc
+ set findexpr=FindExpr2()
+ call assert_fails('find Xfindexpr1.c', 'find error')
+
+ " Try using a null string as the expression
+ set findexpr=test_null_string()
+ call assert_fails('find Xfindexpr1.c', 'E345: Can''t find file "Xfindexpr1.c" in path')
+
+ " Try to create a new window from the find expression
+ func FindExpr3()
+ new
+ return ["foo"]
+ endfunc
+ set findexpr=FindExpr3()
+ call assert_fails('find Xfindexpr1.c', 'E565: Not allowed to change text or change window')
+
+ " Try to modify the current buffer from the find expression
+ func FindExpr4()
+ call setline(1, ['abc'])
+ return ["foo"]
+ endfunc
+ set findexpr=FindExpr4()
+ call assert_fails('find Xfindexpr1.c', 'E565: Not allowed to change text or change window')
+
+ set findexpr&
+ delfunc! FindExpr1
+ delfunc! FindExpr2
+ delfunc! FindExpr3
+ delfunc! FindExpr4
+endfunc
+
+" Test for using a script-local function for 'findexpr'
+func Test_findexpr_scriptlocal_func()
+ func! s:FindExprScript()
+ let g:FindExprArg = v:fname
+ return ['xxx']
+ endfunc
+
+ set findexpr=s:FindExprScript()
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &findexpr)
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr)
+ new | only
+ let g:FindExprArg = ''
+ find abc
+ call assert_equal('abc', g:FindExprArg)
+ bw!
+
+ set findexpr=<SID>FindExprScript()
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &findexpr)
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr)
+ new | only
+ let g:FindExprArg = ''
+ find abc
+ call assert_equal('abc', g:FindExprArg)
+ bw!
+
+ let &findexpr = 's:FindExprScript()'
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr)
+ new | only
+ let g:FindExprArg = ''
+ find abc
+ call assert_equal('abc', g:FindExprArg)
+ bw!
+
+ let &findexpr = '<SID>FindExprScript()'
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr)
+ new | only
+ let g:FindExprArg = ''
+ find abc
+ call assert_equal('abc', g:FindExprArg)
+ bw!
+
+ set findexpr=
+ setglobal findexpr=s:FindExprScript()
+ setlocal findexpr=
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &findexpr)
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &g:findexpr)
+ call assert_equal('', &l:findexpr)
+ new | only
+ let g:FindExprArg = ''
+ find abc
+ call assert_equal('abc', g:FindExprArg)
+ bw!
+
+ new | only
+ set findexpr=
+ setglobal findexpr=
+ setlocal findexpr=s:FindExprScript()
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &findexpr)
+ call assert_equal(expand('<SID>') .. 'FindExprScript()', &l:findexpr)
+ call assert_equal('', &g:findexpr)
+ let g:FindExprArg = ''
+ find abc
+ call assert_equal('abc', g:FindExprArg)
+ bw!
+
+ set findexpr=
+ delfunc s:FindExprScript
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_modeline.vim b/src/testdir/test_modeline.vim
index 0a7240b..bb5bc6b 100644
--- a/src/testdir/test_modeline.vim
+++ b/src/testdir/test_modeline.vim
@@ -208,6 +208,7 @@
call s:modeline_fails('equalprg', 'equalprg=Something()', 'E520:')
call s:modeline_fails('errorfile', 'errorfile=Something()', 'E520:')
call s:modeline_fails('exrc', 'exrc=Something()', 'E520:')
+ call s:modeline_fails('findexpr', 'findexpr=Something()', 'E520:')
call s:modeline_fails('formatprg', 'formatprg=Something()', 'E520:')
call s:modeline_fails('fsync', 'fsync=Something()', 'E520:')
call s:modeline_fails('grepprg', 'grepprg=Something()', 'E520:')
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index 73e6d85..35b7d48 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -1570,7 +1570,7 @@
" Test for changing options in a sandbox
func Test_opt_sandbox()
- for opt in ['backupdir', 'cdpath', 'exrc']
+ for opt in ['backupdir', 'cdpath', 'exrc', 'findexpr']
call assert_fails('sandbox set ' .. opt .. '?', 'E48:')
call assert_fails('sandbox let &' .. opt .. ' = 1', 'E48:')
endfor