aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-12-03 08:17:38 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-12-03 08:35:13 +0800
commit9671908c682dc3fc4e939f44a636457db6f3e5a4 (patch)
treecc8180e5890f33950be616471ec521b0f08dc5a4 /src
parent2ae0d32a72c3ee207b6f9cd48c4beffa6e7c774f (diff)
downloadrneovim-9671908c682dc3fc4e939f44a636457db6f3e5a4.tar.gz
rneovim-9671908c682dc3fc4e939f44a636457db6f3e5a4.tar.bz2
rneovim-9671908c682dc3fc4e939f44a636457db6f3e5a4.zip
vim-patch:8.2.3900: it is not easy to use a script-local function for an option
Problem: It is not easy to use a script-local function for an option. Solution: recognize s: and <SID> at the start of the expression. (Yegappan Lakshmanan, closes vim/vim#9401) https://github.com/vim/vim/commit/8bb65f230d3025037f34021a72616038da0601ee Omit duplicate docs in fold.txt: removed in a later runtime update. Cherry-pick test_diffmode.vim changes from patch 8.2.1432. Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/option_defs.h2
-rw-r--r--src/nvim/optionstr.c50
-rw-r--r--src/nvim/testdir/test_diffmode.vim26
-rw-r--r--src/nvim/testdir/test_edit.vim10
-rw-r--r--src/nvim/testdir/test_fold.vim26
-rw-r--r--src/nvim/testdir/test_gf.vim26
-rw-r--r--src/nvim/testdir/test_hardcopy.vim8
-rw-r--r--src/nvim/testdir/test_normal.vim39
9 files changed, 180 insertions, 9 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index fdb379a682..554771d9c9 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -711,7 +711,7 @@ void eval_patch(const char *const origfile, const char *const difffile, const ch
set_vim_var_string(VV_FNAME_IN, origfile, -1);
set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
set_vim_var_string(VV_FNAME_OUT, outfile, -1);
- (void)eval_to_bool((char *)p_pex, &err, NULL, false);
+ (void)eval_to_bool(p_pex, &err, NULL, false);
set_vim_var_string(VV_FNAME_IN, NULL, -1);
set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
set_vim_var_string(VV_FNAME_OUT, NULL, -1);
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 40ce022bea..de07327416 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -622,7 +622,7 @@ EXTERN char *p_opfunc; // 'operatorfunc'
EXTERN char_u *p_para; // 'paragraphs'
EXTERN int p_paste; // 'paste'
EXTERN char *p_pt; // 'pastetoggle'
-EXTERN char_u *p_pex; // 'patchexpr'
+EXTERN char *p_pex; // 'patchexpr'
EXTERN char *p_pm; // 'patchmode'
EXTERN char_u *p_path; // 'path'
EXTERN char_u *p_cdpath; // 'cdpath'
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 61a51532a4..b5dce7ff2a 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -17,6 +17,7 @@
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
+#include "nvim/eval/userfunc.h"
#include "nvim/eval/vars.h"
#include "nvim/ex_getln.h"
#include "nvim/fold.h"
@@ -1341,10 +1342,6 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
newFoldLevel();
}
}
- } else if (varp == &curwin->w_p_fde) { // 'foldexpr'
- if (foldmethodIsExpr(curwin)) {
- foldUpdateAll(curwin);
- }
} else if (gvarp == &curwin->w_allbuf_opt.wo_fmr) { // 'foldmarker'
p = vim_strchr(*varp, ',');
if (p == NULL) {
@@ -1484,6 +1481,51 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
}
}
}
+ } else if (varp == &p_dex
+ || varp == &curwin->w_p_fde
+ || gvarp == &p_fex
+ || gvarp == &p_inex
+ || gvarp == &p_inde
+ || varp == &p_pex
+ || varp == &p_pexpr) { // '*expr' options
+ char **p_opt = NULL;
+
+ // If the option value starts with <SID> or s:, then replace that with
+ // the script identifier.
+
+ if (varp == &p_dex) { // 'diffexpr'
+ p_opt = &p_dex;
+ }
+ if (varp == &curwin->w_p_fde) { // 'foldexpr'
+ p_opt = &curwin->w_p_fde;
+ }
+ if (gvarp == &p_fex) { // 'formatexpr'
+ p_opt = &curbuf->b_p_fex;
+ }
+ if (gvarp == &p_inex) { // 'includeexpr'
+ p_opt = &curbuf->b_p_inex;
+ }
+ if (gvarp == &p_inde) { // 'indentexpr'
+ p_opt = &curbuf->b_p_inde;
+ }
+ if (varp == &p_pex) { // 'patchexpr'
+ p_opt = &p_pex;
+ }
+ if (varp == &p_pexpr) { // 'printexpr'
+ p_opt = &p_pexpr;
+ }
+
+ if (p_opt != NULL) {
+ char *name = get_scriptlocal_funcname(*p_opt);
+ if (name != NULL) {
+ free_string_option(*p_opt);
+ *p_opt = name;
+ }
+ }
+
+ if (varp == &curwin->w_p_fde && foldmethodIsExpr(curwin)) {
+ foldUpdateAll(curwin);
+ }
} else if (gvarp == &p_cfu) { // 'completefunc'
if (set_completefunc_option() == FAIL) {
errmsg = e_invarg;
diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim
index d83cd505a6..0049398776 100644
--- a/src/nvim/testdir/test_diffmode.vim
+++ b/src/nvim/testdir/test_diffmode.vim
@@ -1,4 +1,5 @@
" Tests for diff mode
+
source shared.vim
source screendump.vim
source check.vim
@@ -681,15 +682,25 @@ func Test_diffexpr()
set diffexpr=NewDiffFunc()
call assert_fails('windo diffthis', ['E117:', 'E97:'])
diffoff!
+
+ " Using a script-local function
+ func s:NewDiffExpr()
+ endfunc
+ set diffexpr=s:NewDiffExpr()
+ call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr)
+ set diffexpr=<SID>NewDiffExpr()
+ call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr)
+
%bwipe!
set diffexpr& diffopt&
+ delfunc DiffExpr
+ delfunc s:NewDiffExpr
endfunc
func Test_diffpatch()
" The patch program on MS-Windows may fail or hang.
- if !executable('patch') || !has('unix')
- return
- endif
+ CheckExecutable patch
+ CheckUnix
new
insert
***************
@@ -1250,10 +1261,19 @@ func Test_patchexpr()
call assert_equal(2, winnr('$'))
call assert_true(&diff)
+ " Using a script-local function
+ func s:NewPatchExpr()
+ endfunc
+ set patchexpr=s:NewPatchExpr()
+ call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
+ set patchexpr=<SID>NewPatchExpr()
+ call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
+
call delete('Xinput')
call delete('Xdiff')
set patchexpr&
delfunc TPatch
+ delfunc s:NewPatchExpr
%bwipe!
endfunc
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index 89e597f401..fd54f77ccb 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -330,6 +330,16 @@ func Test_edit_11_indentexpr()
set cinkeys&vim indentkeys&vim
set nocindent indentexpr=
delfu Do_Indent
+
+ " Using a script-local function
+ func s:NewIndentExpr()
+ endfunc
+ set indentexpr=s:NewIndentExpr()
+ call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
+ set indentexpr=<SID>NewIndentExpr()
+ call assert_equal(expand('<SID>') .. 'NewIndentExpr()', &indentexpr)
+ set indentexpr&
+
bw!
endfunc
diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim
index 2215166cd6..bc8364a80e 100644
--- a/src/nvim/testdir/test_fold.vim
+++ b/src/nvim/testdir/test_fold.vim
@@ -1273,6 +1273,32 @@ func Test_fold_jump()
bw!
endfunc
+" Test for using a script-local function for 'foldexpr'
+func Test_foldexpr_scriptlocal_func()
+ func! s:FoldFunc()
+ let g:FoldLnum = v:lnum
+ endfunc
+ new | only
+ call setline(1, 'abc')
+ let g:FoldLnum = 0
+ set foldmethod=expr foldexpr=s:FoldFunc()
+ redraw!
+ call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
+ call assert_equal(1, g:FoldLnum)
+ set foldmethod& foldexpr=
+ bw!
+ new | only
+ call setline(1, 'abc')
+ let g:FoldLnum = 0
+ set foldmethod=expr foldexpr=<SID>FoldFunc()
+ redraw!
+ call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
+ call assert_equal(1, g:FoldLnum)
+ set foldmethod& foldexpr=
+ delfunc s:FoldFunc
+ bw!
+endfunc
+
" Make sure a fold containing a nested fold is split correctly when using
" foldmethod=indent
func Test_fold_split()
diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim
index b2bb189688..e369645328 100644
--- a/src/nvim/testdir/test_gf.vim
+++ b/src/nvim/testdir/test_gf.vim
@@ -226,6 +226,32 @@ func Test_gf_includeexpr()
delfunc IncFunc
endfunc
+" Test for using a script-local function for 'includeexpr'
+func Test_includeexpr_scriptlocal_func()
+ func! s:IncludeFunc()
+ let g:IncludeFname = v:fname
+ return ''
+ endfunc
+ set includeexpr=s:IncludeFunc()
+ call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
+ new | only
+ call setline(1, 'TestFile1')
+ let g:IncludeFname = ''
+ call assert_fails('normal! gf', 'E447:')
+ call assert_equal('TestFile1', g:IncludeFname)
+ bw!
+ set includeexpr=<SID>IncludeFunc()
+ call assert_equal(expand('<SID>') .. 'IncludeFunc()', &includeexpr)
+ new | only
+ call setline(1, 'TestFile2')
+ let g:IncludeFname = ''
+ call assert_fails('normal! gf', 'E447:')
+ call assert_equal('TestFile2', g:IncludeFname)
+ set includeexpr&
+ delfunc s:IncludeFunc
+ bw!
+endfunc
+
" Check that expanding directories can handle more than 255 entries.
func Test_gf_subdirs_wildcard()
let cwd = getcwd()
diff --git a/src/nvim/testdir/test_hardcopy.vim b/src/nvim/testdir/test_hardcopy.vim
index e390bd5cc8..be83728b4f 100644
--- a/src/nvim/testdir/test_hardcopy.vim
+++ b/src/nvim/testdir/test_hardcopy.vim
@@ -125,6 +125,14 @@ func Test_printexpr()
set printexpr=PrintFails(v:fname_in)
call assert_fails('hardcopy', 'E365:')
+ " Using a script-local function
+ func s:NewPrintExpr()
+ endfunc
+ set printexpr=s:NewPrintExpr()
+ call assert_equal(expand('<SID>') .. 'NewPrintExpr()', &printexpr)
+ set printexpr=<SID>NewPrintExpr()
+ call assert_equal(expand('<SID>') .. 'NewPrintExpr()', &printexpr)
+
set printexpr&
bwipe
endfunc
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
index 9c5cc51f79..7e8b8c5eef 100644
--- a/src/nvim/testdir/test_normal.vim
+++ b/src/nvim/testdir/test_normal.vim
@@ -255,6 +255,45 @@ func Test_normal_formatexpr_returns_nonzero()
close!
endfunc
+" Test for using a script-local function for 'formatexpr'
+func Test_formatexpr_scriptlocal_func()
+ func! s:Format()
+ let g:FormatArgs = [v:lnum, v:count]
+ endfunc
+ set formatexpr=s:Format()
+ call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+ new | only
+ call setline(1, range(1, 40))
+ let g:FormatArgs = []
+ normal! 2GVjgq
+ call assert_equal([2, 2], g:FormatArgs)
+ bw!
+ set formatexpr=<SID>Format()
+ call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
+ new | only
+ call setline(1, range(1, 40))
+ let g:FormatArgs = []
+ normal! 4GVjgq
+ call assert_equal([4, 2], g:FormatArgs)
+ bw!
+ let &formatexpr = 's:Format()'
+ new | only
+ call setline(1, range(1, 40))
+ let g:FormatArgs = []
+ normal! 6GVjgq
+ call assert_equal([6, 2], g:FormatArgs)
+ bw!
+ let &formatexpr = '<SID>Format()'
+ new | only
+ call setline(1, range(1, 40))
+ let g:FormatArgs = []
+ normal! 8GVjgq
+ call assert_equal([8, 2], g:FormatArgs)
+ setlocal formatexpr=
+ delfunc s:Format
+ bw!
+endfunc
+
" basic test for formatprg
func Test_normal06_formatprg()
" only test on non windows platform