diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c index 05bd31061c..0714269a67 100644 --- a/src/nvim/insexpand.c +++ b/src/nvim/insexpand.c @@ -2929,11 +2929,18 @@ static void copy_global_to_buflocal_cb(Callback *globcb, Callback *bufcb) const char *did_set_completefunc(optset_T *args) { buf_T *buf = (buf_T *)args->os_buf; - if (option_set_callback_func(buf->b_p_cfu, &cfu_cb) == FAIL) { - return e_invarg; + int retval; + + if (args->os_flags & OPT_LOCAL) { + retval = option_set_callback_func(args->os_newval.string.data, &buf->b_cfu_cb); + } else { + retval = option_set_callback_func(args->os_newval.string.data, &cfu_cb); + if (retval == OK && !(args->os_flags & OPT_GLOBAL)) { + set_buflocal_cfu_callback(buf); + } } - set_buflocal_cfu_callback(buf); - return NULL; + + return retval == FAIL ? e_invarg : NULL; } /// Copy the global 'completefunc' callback function to the buffer-local @@ -2950,11 +2957,18 @@ void set_buflocal_cfu_callback(buf_T *buf) const char *did_set_omnifunc(optset_T *args) { buf_T *buf = (buf_T *)args->os_buf; - if (option_set_callback_func(buf->b_p_ofu, &ofu_cb) == FAIL) { - return e_invarg; + int retval; + + if (args->os_flags & OPT_LOCAL) { + retval = option_set_callback_func(args->os_newval.string.data, &buf->b_ofu_cb); + } else { + retval = option_set_callback_func(args->os_newval.string.data, &ofu_cb); + if (retval == OK && !(args->os_flags & OPT_GLOBAL)) { + set_buflocal_ofu_callback(buf); + } } - set_buflocal_ofu_callback(buf); - return NULL; + + return retval == FAIL ? e_invarg : NULL; } /// Copy the global 'omnifunc' callback function to the buffer-local 'omnifunc' diff --git a/src/nvim/tag.c b/src/nvim/tag.c index e3a6f87335..d07ba9c475 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -228,20 +228,18 @@ static Callback tfu_cb; // 'tagfunc' callback function const char *did_set_tagfunc(optset_T *args) { buf_T *buf = (buf_T *)args->os_buf; + int retval; - callback_free(&tfu_cb); - callback_free(&buf->b_tfu_cb); - - if (*buf->b_p_tfu == NUL) { - return NULL; + if (args->os_flags & OPT_LOCAL) { + retval = option_set_callback_func(args->os_newval.string.data, &buf->b_tfu_cb); + } else { + retval = option_set_callback_func(args->os_newval.string.data, &tfu_cb); + if (retval == OK && !(args->os_flags & OPT_GLOBAL)) { + set_buflocal_tfu_callback(buf); + } } - if (option_set_callback_func(buf->b_p_tfu, &tfu_cb) == FAIL) { - return e_invarg; - } - - callback_copy(&buf->b_tfu_cb, &tfu_cb); - return NULL; + return retval == FAIL ? e_invarg : NULL; } #if defined(EXITFREE) diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index c6f64840a5..250559cc4a 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -2535,6 +2535,35 @@ func Test_completefunc_callback() call feedkeys("A\\\", 'x') call assert_equal([[1, ''], [0, 'five']], g:CompleteFunc2Args) bw! + + #" :setlocal and :setglobal + set completefunc& + setlocal completefunc=function('g:CompleteFunc1',\ [22]) + call setline(1, 'sun') + LET g:CompleteFunc1Args = [] + call feedkeys("A\\\", 'x') + call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:CompleteFunc1Args) + new + call setline(1, 'sun') + LET g:CompleteFunc1Args = [] + call assert_fails('call feedkeys("A\\\", "x")', 'E764:') + call assert_equal([], g:CompleteFunc1Args) + bw! + setglobal completefunc=function('g:CompleteFunc1',\ [23]) + call setline(1, 'sun') + call feedkeys("A\\\", 'x') + call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:CompleteFunc1Args) + new + call setline(1, 'sun') + LET g:CompleteFunc1Args = [] + call feedkeys("A\\\", 'x') + call assert_equal([[23, 1, ''], [23, 0, 'sun']], g:CompleteFunc1Args) + setlocal completefunc& + call setline(1, 'sun') + LET g:CompleteFunc1Args = [] + call assert_fails('call feedkeys("A\\\", "x")', 'E764:') + call assert_equal([], g:CompleteFunc1Args) + :%bw! END call CheckLegacyAndVim9Success(lines) @@ -2809,6 +2838,35 @@ func Test_omnifunc_callback() call feedkeys("A\\\", 'x') call assert_equal([[1, ''], [0, 'nine']], g:OmniFunc2Args) bw! + + #" :setlocal and :setglobal + set omnifunc& + setlocal omnifunc=function('g:OmniFunc1',\ [22]) + call setline(1, 'sun') + LET g:OmniFunc1Args = [] + call feedkeys("A\\\", 'x') + call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:OmniFunc1Args) + new + call setline(1, 'sun') + LET g:OmniFunc1Args = [] + call assert_fails('call feedkeys("A\\\", "x")', 'E764:') + call assert_equal([], g:OmniFunc1Args) + bw! + setglobal omnifunc=function('g:OmniFunc1',\ [23]) + call setline(1, 'sun') + call feedkeys("A\\\", 'x') + call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:OmniFunc1Args) + new + call setline(1, 'sun') + LET g:OmniFunc1Args = [] + call feedkeys("A\\\", 'x') + call assert_equal([[23, 1, ''], [23, 0, 'sun']], g:OmniFunc1Args) + setlocal omnifunc& + call setline(1, 'sun') + LET g:OmniFunc1Args = [] + call assert_fails('call feedkeys("A\\\", "x")', 'E764:') + call assert_equal([], g:OmniFunc1Args) + :%bw! END call CheckLegacyAndVim9Success(lines) diff --git a/test/old/testdir/test_tagfunc.vim b/test/old/testdir/test_tagfunc.vim index 19fc8de8dd..052b685a18 100644 --- a/test/old/testdir/test_tagfunc.vim +++ b/test/old/testdir/test_tagfunc.vim @@ -257,13 +257,37 @@ func Test_tagfunc_callback() call assert_fails("set tagfunc=funcref('abc')", "E700:") #" set 'tagfunc' to a non-existing function - LET &tagfunc = function('g:TagFunc2', [21]) + LET &tagfunc = function('g:TagFunc2') LET g:TagFunc2Args = [] call assert_fails("set tagfunc=function('NonExistingFunc')", 'E700:') call assert_fails("LET &tagfunc = function('NonExistingFunc')", 'E700:') - call assert_fails("tag axb123", 'E426:') - call assert_equal([], g:TagFunc2Args) + call assert_fails("tag axb123", 'E433:') + call assert_equal(['axb123', '', {}], g:TagFunc2Args) bw! + + #" :setlocal and :setglobal + set tagfunc& + setlocal tagfunc=function('g:TagFunc1',\ [22]) + LET g:TagFunc1Args = [] + call assert_fails("tag a22", 'E433:') + call assert_equal([22, 'a22', '', {}], g:TagFunc1Args) + new + LET g:TagFunc1Args = [] + call assert_fails("tag a22", 'E433:') + call assert_equal([], g:TagFunc1Args) + bw! + setglobal tagfunc=function('g:TagFunc1',\ [23]) + call assert_fails("tag a22", 'E433:') + call assert_equal([22, 'a22', '', {}], g:TagFunc1Args) + new + LET g:TagFunc1Args = [] + call assert_fails("tag a23", 'E433:') + call assert_equal([23, 'a23', '', {}], g:TagFunc1Args) + setlocal tagfunc& + LET g:TagFunc1Args = [] + call assert_fails("tag a23", 'E433:') + call assert_equal([], g:TagFunc1Args) + :%bw! END call CheckLegacyAndVim9Success(lines)