vim-patch:9.1.0835: :setglobal doesn't work properly for 'ffu' and 'tsrfu'

Problem:  :setglobal doesn't work properly for 'ffu' and 'tsrfu' when
          the local value is set (after v9.1.0831)
Solution: Check os_flags instead of buffer option variable (zeertzjq).

closes: vim/vim#15980

6eda269600
This commit is contained in:
zeertzjq
2024-11-03 16:54:25 +08:00
parent 981fa11c91
commit fe565ca382
4 changed files with 94 additions and 9 deletions

View File

@@ -5173,7 +5173,7 @@ static Callback *get_findfunc_callback(void)
return *curbuf->b_p_ffu != NUL ? &curbuf->b_ffu_cb : &ffu_cb; return *curbuf->b_p_ffu != NUL ? &curbuf->b_ffu_cb : &ffu_cb;
} }
/// Call 'findfunc' to obtain the list of file names. /// Call 'findfunc' to obtain a list of file names.
static list_T *call_findfunc(char *pat, BoolVarValue cmdcomplete) static list_T *call_findfunc(char *pat, BoolVarValue cmdcomplete)
{ {
const sctx_T saved_sctx = current_sctx; const sctx_T saved_sctx = current_sctx;
@@ -5294,12 +5294,16 @@ const char *did_set_findfunc(optset_T *args)
buf_T *buf = (buf_T *)args->os_buf; buf_T *buf = (buf_T *)args->os_buf;
int retval; int retval;
if (*buf->b_p_ffu != NUL) { if (args->os_flags & OPT_LOCAL) {
// buffer-local option set // buffer-local option set
retval = option_set_callback_func(buf->b_p_ffu, &buf->b_ffu_cb); retval = option_set_callback_func(buf->b_p_ffu, &buf->b_ffu_cb);
} else { } else {
// global option set // global option set
retval = option_set_callback_func(p_ffu, &ffu_cb); retval = option_set_callback_func(p_ffu, &ffu_cb);
// when using :set, free the local callback
if (!(args->os_flags & OPT_GLOBAL)) {
callback_free(&buf->b_ffu_cb);
}
} }
if (retval == FAIL) { if (retval == FAIL) {

View File

@@ -2368,13 +2368,13 @@ static void copy_global_to_buflocal_cb(Callback *globcb, Callback *bufcb)
/// Invoked when the 'completefunc' option is set. The option value can be a /// Invoked when the 'completefunc' option is set. The option value can be a
/// name of a function (string), or function(<name>) or funcref(<name>) or a /// name of a function (string), or function(<name>) or funcref(<name>) or a
/// lambda expression. /// lambda expression.
const char *did_set_completefunc(optset_T *args FUNC_ATTR_UNUSED) const char *did_set_completefunc(optset_T *args)
{ {
if (option_set_callback_func(curbuf->b_p_cfu, &cfu_cb) == FAIL) { buf_T *buf = (buf_T *)args->os_buf;
if (option_set_callback_func(buf->b_p_cfu, &cfu_cb) == FAIL) {
return e_invarg; return e_invarg;
} }
set_buflocal_cfu_callback(buf);
set_buflocal_cfu_callback(curbuf);
return NULL; return NULL;
} }
@@ -2412,14 +2412,19 @@ void set_buflocal_ofu_callback(buf_T *buf)
/// lambda expression. /// lambda expression.
const char *did_set_thesaurusfunc(optset_T *args FUNC_ATTR_UNUSED) const char *did_set_thesaurusfunc(optset_T *args FUNC_ATTR_UNUSED)
{ {
buf_T *buf = (buf_T *)args->os_buf;
int retval; int retval;
if (*curbuf->b_p_tsrfu != NUL) { if (args->os_flags & OPT_LOCAL) {
// buffer-local option set // buffer-local option set
retval = option_set_callback_func(curbuf->b_p_tsrfu, &curbuf->b_tsrfu_cb); retval = option_set_callback_func(buf->b_p_tsrfu, &buf->b_tsrfu_cb);
} else { } else {
// global option set // global option set
retval = option_set_callback_func(p_tsrfu, &tsrfu_cb); retval = option_set_callback_func(p_tsrfu, &tsrfu_cb);
// when using :set, free the local callback
if (!(args->os_flags & OPT_GLOBAL)) {
callback_free(&buf->b_tsrfu_cb);
}
} }
return retval == FAIL ? e_invarg : NULL; return retval == FAIL ? e_invarg : NULL;

View File

@@ -364,7 +364,7 @@ func Test_findfunc()
" Error cases " Error cases
" Function that doesn't any argument " Function that doesn't take any arguments
func FindFuncNoArg() func FindFuncNoArg()
endfunc endfunc
set findfunc=FindFuncNoArg set findfunc=FindFuncNoArg
@@ -484,6 +484,41 @@ func Test_findfunc_scriptlocal_func()
call assert_equal('abc', g:FindFuncArg) call assert_equal('abc', g:FindFuncArg)
bw! bw!
new | only
set findfunc=
setlocal findfunc=NoSuchFunc
setglobal findfunc=s:FindFuncScript
call assert_equal('NoSuchFunc', &findfunc)
call assert_equal('NoSuchFunc', &l:findfunc)
call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
new | only
call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
call assert_equal('', &l:findfunc)
let g:FindFuncArg = ''
find abc
call assert_equal('abc', g:FindFuncArg)
bw!
new | only
set findfunc=
setlocal findfunc=NoSuchFunc
set findfunc=s:FindFuncScript
call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
call assert_equal('', &l:findfunc)
let g:FindFuncArg = ''
find abc
call assert_equal('abc', g:FindFuncArg)
new | only
call assert_equal(expand('<SID>') .. 'FindFuncScript', &findfunc)
call assert_equal(expand('<SID>') .. 'FindFuncScript', &g:findfunc)
call assert_equal('', &l:findfunc)
let g:FindFuncArg = ''
find abc
call assert_equal('abc', g:FindFuncArg)
bw!
set findfunc= set findfunc=
delfunc s:FindFuncScript delfunc s:FindFuncScript
endfunc endfunc

View File

@@ -2268,6 +2268,7 @@ func Test_thesaurusfunc_callback()
call add(g:TsrFunc3Args, [a:findstart, a:base]) call add(g:TsrFunc3Args, [a:findstart, a:base])
return a:findstart ? 0 : [] return a:findstart ? 0 : []
endfunc endfunc
set tsrfu=s:TsrFunc3 set tsrfu=s:TsrFunc3
new new
call setline(1, 'script1') call setline(1, 'script1')
@@ -2283,6 +2284,46 @@ func Test_thesaurusfunc_callback()
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x') call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
call assert_equal([[1, ''], [0, 'script2']], g:TsrFunc3Args) call assert_equal([[1, ''], [0, 'script2']], g:TsrFunc3Args)
bw! bw!
new | only
set thesaurusfunc=
setlocal thesaurusfunc=NoSuchFunc
setglobal thesaurusfunc=s:TsrFunc3
call assert_equal('NoSuchFunc', &thesaurusfunc)
call assert_equal('NoSuchFunc', &l:thesaurusfunc)
call assert_equal('s:TsrFunc3', &g:thesaurusfunc)
new | only
call assert_equal('s:TsrFunc3', &thesaurusfunc)
call assert_equal('s:TsrFunc3', &g:thesaurusfunc)
call assert_equal('', &l:thesaurusfunc)
call setline(1, 'script1')
let g:TsrFunc3Args = []
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
call assert_equal([[1, ''], [0, 'script1']], g:TsrFunc3Args)
bw!
new | only
set thesaurusfunc=
setlocal thesaurusfunc=NoSuchFunc
set thesaurusfunc=s:TsrFunc3
call assert_equal('s:TsrFunc3', &thesaurusfunc)
call assert_equal('s:TsrFunc3', &g:thesaurusfunc)
call assert_equal('', &l:thesaurusfunc)
call setline(1, 'script1')
let g:TsrFunc3Args = []
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
call assert_equal([[1, ''], [0, 'script1']], g:TsrFunc3Args)
setlocal bufhidden=wipe
new | only!
call assert_equal('s:TsrFunc3', &thesaurusfunc)
call assert_equal('s:TsrFunc3', &g:thesaurusfunc)
call assert_equal('', &l:thesaurusfunc)
call setline(1, 'script1')
let g:TsrFunc3Args = []
call feedkeys("A\<C-X>\<C-T>\<Esc>", 'x')
call assert_equal([[1, ''], [0, 'script1']], g:TsrFunc3Args)
bw!
delfunc s:TsrFunc3 delfunc s:TsrFunc3
" invalid return value " invalid return value