patch 9.1.1991: :setlocal changes effective global 'omnifunc'

Commit: 
https://github.com/vim/vim/commit/3e82b0ebfe7fe2d87bc7bc843291f13183aac828
Author: zeertzjq <[email protected]>
Date:   Wed Dec 17 21:34:23 2025 +0100

    patch 9.1.1991: :setlocal changes effective global 'omnifunc'
    
    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 <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/insexpand.c b/src/insexpand.c
index b44f77d53..30a89df96 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -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;
 }
 
 /*
diff --git a/src/tag.c b/src/tag.c
index 78d290277..796fd12a9 100644
--- 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
 
diff --git a/src/testdir/test_ins_complete.vim 
b/src/testdir/test_ins_complete.vim
index c2b8c67bc..315b81e49 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -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)
 
diff --git a/src/testdir/test_tagfunc.vim b/src/testdir/test_tagfunc.vim
index 11a105b63..286a54a3c 100644
--- a/src/testdir/test_tagfunc.vim
+++ b/src/testdir/test_tagfunc.vim
@@ -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)
 
diff --git a/src/version.c b/src/version.c
index a36890701..b18869873 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1991,
 /**/
     1990,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vVyON-002bZI-KR%40256bit.org.

Raspunde prin e-mail lui