]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1991: :setlocal changes effective global 'omnifunc' v9.1.1991
authorzeertzjq <zeertzjq@outlook.com>
Wed, 17 Dec 2025 20:34:23 +0000 (21:34 +0100)
committerChristian Brabandt <cb@256bit.org>
Wed, 17 Dec 2025 20:34:23 +0000 (21:34 +0100)
Problem:  :setlocal changes effective global 'omnifunc' (Maxim Kim)
Solution: Don't change global callback when using :setlocal (zeertzjq).

fixes:  #18948
closes: #18951

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/insexpand.c
src/tag.c
src/testdir/test_ins_complete.vim
src/testdir/test_tagfunc.vim
src/version.c

index b44f77d5316c022ff00b52302b954bac90c3472c..30a89df96c820ed7e3dad89112d1e865dbdd9c90 100644 (file)
@@ -3319,14 +3319,21 @@ copy_global_to_buflocal_cb(callback_T *globcb, callback_T *bufcb)
  * lambda expression.
  */
     char *
-did_set_completefunc(optset_T *args UNUSED)
+did_set_completefunc(optset_T *args)
 {
-    if (option_set_callback_func(curbuf->b_p_cfu, &cfu_cb) == FAIL)
-       return e_invalid_argument;
+    int        retval;
 
-    set_buflocal_cfu_callback(curbuf);
+    if (args->os_flags & OPT_LOCAL)
+       retval = option_set_callback_func(args->os_newval.string,
+                                                           &curbuf->b_cfu_cb);
+    else
+    {
+       retval = option_set_callback_func(args->os_newval.string, &cfu_cb);
+       if (retval == OK && !(args->os_flags & OPT_GLOBAL))
+           set_buflocal_cfu_callback(curbuf);
+    }
 
-    return NULL;
+    return retval == FAIL ? e_invalid_argument : NULL;
 }
 
 /*
@@ -3348,13 +3355,21 @@ set_buflocal_cfu_callback(buf_T *buf UNUSED)
  * lambda expression.
  */
     char *
-did_set_omnifunc(optset_T *args UNUSED)
+did_set_omnifunc(optset_T *args)
 {
-    if (option_set_callback_func(curbuf->b_p_ofu, &ofu_cb) == FAIL)
-       return e_invalid_argument;
+    int        retval;
 
-    set_buflocal_ofu_callback(curbuf);
-    return NULL;
+    if (args->os_flags & OPT_LOCAL)
+       retval = option_set_callback_func(args->os_newval.string,
+                                                           &curbuf->b_ofu_cb);
+    else
+    {
+       retval = option_set_callback_func(args->os_newval.string, &ofu_cb);
+       if (retval == OK && !(args->os_flags & OPT_GLOBAL))
+           set_buflocal_ofu_callback(curbuf);
+    }
+
+    return retval == FAIL ? e_invalid_argument : NULL;
 }
 
 /*
index 78d2902770aa52d85fc2e14e71a734db2b612c08..796fd12a9b250b3aa044565575cb0e787f6bbe47 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
@@ -170,22 +170,21 @@ static callback_T tfu_cb;     // 'tagfunc' callback function
  * a function (string), or function(<name>) or funcref(<name>) or a lambda.
  */
     char *
-did_set_tagfunc(optset_T *args UNUSED)
+did_set_tagfunc(optset_T *args)
 {
-#ifdef FEAT_EVAL
-    free_callback(&tfu_cb);
-    free_callback(&curbuf->b_tfu_cb);
-
-    if (*curbuf->b_p_tfu == NUL)
-       return NULL;
-
-    if (option_set_callback_func(curbuf->b_p_tfu, &tfu_cb) == FAIL)
-       return e_invalid_argument;
+    int        retval;
 
-    copy_callback(&curbuf->b_tfu_cb, &tfu_cb);
-#endif
+    if (args->os_flags & OPT_LOCAL)
+       retval = option_set_callback_func(args->os_newval.string,
+                                                           &curbuf->b_tfu_cb);
+    else
+    {
+       retval = option_set_callback_func(args->os_newval.string, &tfu_cb);
+       if (retval == OK && !(args->os_flags & OPT_GLOBAL))
+           set_buflocal_tfu_callback(curbuf);
+    }
 
-    return NULL;
+    return retval == FAIL ? e_invalid_argument : NULL;
 }
 #endif
 
index c2b8c67bc37efd58831fc734158355ca6e5c6633..315b81e49e25ef4d1c5e4424a8d518326bc67e94 100644 (file)
@@ -2426,6 +2426,35 @@ func Test_completefunc_callback()
     call feedkeys("A\<C-X>\<C-U>\<Esc>", '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\<C-X>\<C-U>\<Esc>", '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\<C-X>\<C-U>\<Esc>", "x")', 'E764:')
+    call assert_equal([], g:CompleteFunc1Args)
+    bw!
+    setglobal completefunc=function('g:CompleteFunc1',\ [23])
+    call setline(1, 'sun')
+    call feedkeys("A\<C-X>\<C-U>\<Esc>", 'x')
+    call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:CompleteFunc1Args)
+    new
+    call setline(1, 'sun')
+    LET g:CompleteFunc1Args = []
+    call feedkeys("A\<C-X>\<C-U>\<Esc>", '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\<C-X>\<C-U>\<Esc>", "x")', 'E764:')
+    call assert_equal([], g:CompleteFunc1Args)
+    :%bw!
   END
   call v9.CheckLegacyAndVim9Success(lines)
 
@@ -2700,6 +2729,35 @@ func Test_omnifunc_callback()
     call feedkeys("A\<C-X>\<C-O>\<Esc>", '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\<C-X>\<C-O>\<Esc>", '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\<C-X>\<C-O>\<Esc>", "x")', 'E764:')
+    call assert_equal([], g:OmniFunc1Args)
+    bw!
+    setglobal omnifunc=function('g:OmniFunc1',\ [23])
+    call setline(1, 'sun')
+    call feedkeys("A\<C-X>\<C-O>\<Esc>", 'x')
+    call assert_equal([[22, 1, ''], [22, 0, 'sun']], g:OmniFunc1Args)
+    new
+    call setline(1, 'sun')
+    LET g:OmniFunc1Args = []
+    call feedkeys("A\<C-X>\<C-O>\<Esc>", '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\<C-X>\<C-O>\<Esc>", "x")', 'E764:')
+    call assert_equal([], g:OmniFunc1Args)
+    :%bw!
   END
   call v9.CheckLegacyAndVim9Success(lines)
 
index 11a105b63fd0193e81e77081501fd6dfaa75dafc..286a54a3c5266855afa5550f775541cdac53ac75 100644 (file)
@@ -255,13 +255,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 v9.CheckLegacyAndVim9Success(lines)
 
index a368907018adc378cd6d25771e3536702316b345..b18869873204976b63cce04166a591959aa70c9e 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1991,
 /**/
     1990,
 /**/