patch 9.1.1305: completion menu active after switching windows/tabs

Commit: 
https://github.com/vim/vim/commit/cf7f01252f00061876f7eb14dbf74342a55a13a1
Author: glepnir <glephun...@gmail.com>
Date:   Tue Apr 15 19:02:00 2025 +0200

    patch 9.1.1305: completion menu active after switching windows/tabs
    
    Problem:  When switching to another window or tab page while the
              completion menu is active, the menu stays visible, although it
              belongs to the previous window/tab page context (Evgeni
              Chasnovski).
    Solution: Track the window and tab page where completion started. Detect
              changes in the main editing loop and cancel completion mode if
              the current window or tab page differs from where completion
              started.
    
    fixes: #17090
    closes: #17101
    
    Co-authored-by: zeertzjq <zeert...@outlook.com>
    Signed-off-by: glepnir <glephun...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/edit.c b/src/edit.c
index ab67fdc68..3c98bb8bb 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1411,6 +1411,11 @@ normalchar:
               )
            did_cursorhold = FALSE;
 
+       // Check if we need to cancel completion mode because the window
+       // or tab page was changed
+       if (ins_compl_active() && !ins_compl_win_active(curwin))
+           ins_compl_cancel();
+
        // If the cursor was moved we didn't just insert a space
        if (arrow_used)
            inserted_space = FALSE;
diff --git a/src/insexpand.c b/src/insexpand.c
index c0762da90..8c15adeee 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -192,6 +192,9 @@ static string_T       compl_orig_text = {NULL, 0};  // text 
as it was before
 static int       compl_cont_mode = 0;
 static expand_T          compl_xp;
 
+static win_T     *compl_curr_win = NULL;  // win where completion is active
+static buf_T     *compl_curr_buf = NULL;  // buf where completion is active
+
 // List of flags for method of completion.
 static int       compl_cont_status = 0;
 # define CONT_ADDING   1       // "normal" or "adding" expansion
@@ -2014,6 +2017,8 @@ ins_compl_clear(void)
     compl_matches = 0;
     compl_selected_item = -1;
     compl_ins_end_col = 0;
+    compl_curr_win = NULL;
+    compl_curr_buf = NULL;
     VIM_CLEAR_STRING(compl_pattern);
     VIM_CLEAR_STRING(compl_leader);
     edit_submode_extra = NULL;
@@ -2039,17 +2044,10 @@ ins_compl_active(void)
  * Return True when wp is the actual completion window
  */
     int
-ins_compl_win_active(win_T *wp UNUSED)
+ins_compl_win_active(win_T *wp)
 {
-    return ins_compl_active()
-#if defined(FEAT_QUICKFIX)
-        && (!wp->w_p_pvw
-# ifdef FEAT_PROP_POPUP
-            && !(wp->w_popup_flags & POPF_INFO)
-# endif
-        )
-#endif
-    ;
+    return ins_compl_active() && wp == compl_curr_win
+       && wp->w_buffer == compl_curr_buf;
 }
 
 /*
@@ -2706,6 +2704,15 @@ ins_compl_stop(int c, int prev_mode, int retval)
     return retval;
 }
 
+/*
+ * Cancel completion.
+ */
+    int
+ins_compl_cancel(void)
+{
+    return ins_compl_stop(' ', ctrl_x_mode, TRUE);
+}
+
 /*
  * Prepare for Insert mode completion, or stop it.
  * Called just after typing a character in Insert mode.
@@ -6080,6 +6087,8 @@ ins_complete(int c, int enable_pum)
     else if (insert_match && stop_arrow() == FAIL)
        return FAIL;
 
+    compl_curr_win = curwin;
+    compl_curr_buf = curwin->w_buffer;
     compl_shown_match = compl_curr_match;
     compl_shows_dir = compl_direction;
 
diff --git a/src/proto/insexpand.pro b/src/proto/insexpand.pro
index a9ca289db..8529b7b6c 100644
--- a/src/proto/insexpand.pro
+++ b/src/proto/insexpand.pro
@@ -66,4 +66,5 @@ void ins_compl_insert(int in_compl_func, int move_cursor);
 void ins_compl_check_keys(int frequency, int in_compl_func);
 int ins_complete(int c, int enable_pum);
 void free_insexpand_stuff(void);
+int ins_compl_cancel(void);
 /* vim: set ft=c : */
diff --git a/src/testdir/dumps/Test_switchwin_clear_pum_01.dump 
b/src/testdir/dumps/Test_switchwin_clear_pum_01.dump
new file mode 100644
index 000000000..9005f8d85
--- /dev/null
+++ b/src/testdir/dumps/Test_switchwin_clear_pum_01.dump
@@ -0,0 +1,20 @@
+|b+0&#ffffff0@1| |b@2| |b@1> @27||+1&&|a+0&&@1| |a@2| |a@1| @27
+|~+0#4040ff13&| @4| +0#0000001#e0e0e08|b@1| @12| 
+0#4040ff13#ffffff0@14||+1#0000000&|~+0#4040ff13&| @35
+|~| @4| +0#0000001#ffd7ff255|b@2| @11| 
+0#4040ff13#ffffff0@14||+1#0000000&|~+0#4040ff13&| @35
+|~| @4| +0#0000001#ffd7ff255|a@1| @12| 
+0#4040ff13#ffffff0@14||+1#0000000&|~+0#4040ff13&| @35
+|~| @4| +0#0000001#ffd7ff255|a@2| @11| 
+0#4040ff13#ffffff0@14||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|w+3#0000000&|i|n|_|b| |[|+|]| @9|1|,|1|0| @10|A|l@1| |[+1&&|N|o| |N|a|m|e|]| 
|[|+|]| @5|1|,|9| @11|A|l@1
+|-+2&&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| 
|m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@33
diff --git a/src/testdir/dumps/Test_switchwin_clear_pum_02.dump 
b/src/testdir/dumps/Test_switchwin_clear_pum_02.dump
new file mode 100644
index 000000000..39013c09f
--- /dev/null
+++ b/src/testdir/dumps/Test_switchwin_clear_pum_02.dump
@@ -0,0 +1,20 @@
+|b+0&#ffffff0@1| |b@2| |b@1| @27||+1&&|a+0&&@1| |a@2| |a>a| @27
+|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|~| @35||+1#0000000&|~+0#4040ff13&| @35
+|w+1#0000000&|i|n|_|b| |[|+|]| @9|1|,|1|0| @10|A|l@1| |[+3&&|N|o| |N|a|m|e|]| 
|[|+|]| @5|1|,|9| @11|A|l@1
+|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@62
diff --git a/src/testdir/dumps/Test_tabnext_clear_pum_01.dump 
b/src/testdir/dumps/Test_tabnext_clear_pum_01.dump
new file mode 100644
index 000000000..6eb86e6c7
--- /dev/null
+++ b/src/testdir/dumps/Test_tabnext_clear_pum_01.dump
@@ -0,0 +1,20 @@
+| +8#0000001#e0e0e08|[|N|o| |N|a|m|e|]| | +2#0000000#ffffff0|+| |[|N|o| 
|N|a|m|e|]| | +1&&@49|X+8#0000001#e0e0e08
+|a+0#0000000#ffffff0@1| |a@2| |a@1> @65
+|~+0#4040ff13&| @4| +0#0000001#e0e0e08|a@1| @12| +0#4040ff13#ffffff0@52
+|~| @4| +0#0000001#ffd7ff255|a@2| @11| +0#4040ff13#ffffff0@52
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| 
|m+0#00e0003&|a|t|c|h| |1| |o|f| |2| +0#0000000&@33
diff --git a/src/testdir/dumps/Test_tabnext_clear_pum_02.dump 
b/src/testdir/dumps/Test_tabnext_clear_pum_02.dump
new file mode 100644
index 000000000..347767c66
--- /dev/null
+++ b/src/testdir/dumps/Test_tabnext_clear_pum_02.dump
@@ -0,0 +1,20 @@
+| +2&#ffffff0|[|N|o| |N|a|m|e|]| | +8#0000001#e0e0e08|+| |[|N|o| |N|a|m|e|]| | 
+1#0000000#ffffff0@49|X+8#0000001#e0e0e08
+> +0#0000000#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|0|,|1| @10|A|l@1| 
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index b2952fdc3..ac879d24f 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -2157,4 +2157,36 @@ func Test_pum_maxwidth_multibyte()
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_pum_clear_when_switch_tab_or_win()
+  CheckScreendump
+
+  let lines =<< trim END
+    inoremap <F4> <Cmd>wincmd w<CR>
+    inoremap <F5> <Cmd>tabnext<CR>
+  END
+
+  call writefile(lines, 'Xtest', 'D')
+  let buf = RunVimInTerminal('-S Xtest', {})
+
+  call term_sendkeys(buf, ":tabe\<CR>")
+  call TermWait(buf, 50)
+  call term_sendkeys(buf, "Aaa aaa \<C-N>")
+  call VerifyScreenDump(buf, 'Test_tabnext_clear_pum_01', {})
+  call term_sendkeys(buf, "\<F5>")
+  call TermWait(buf, 50)
+  call VerifyScreenDump(buf, 'Test_tabnext_clear_pum_02', {})
+  call term_sendkeys(buf, "\<ESC>:tabclose!\<CR>")
+
+  call term_sendkeys(buf, ":vnew win_b\<CR>")
+  call TermWait(buf, 50)
+  call term_sendkeys(buf, "Abb bbb \<C-N>")
+  call VerifyScreenDump(buf, 'Test_switchwin_clear_pum_01', {})
+  call term_sendkeys(buf, "\<F4>")
+  call TermWait(buf, 50)
+  call VerifyScreenDump(buf, 'Test_switchwin_clear_pum_02', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 30904d7c0..7bd2bb6b7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1305,
 /**/
     1304,
 /**/

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1u4jsF-004rQk-JF%40256bit.org.

Raspunde prin e-mail lui