]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1305: completion menu active after switching windows/tabs v9.1.1305
authorglepnir <glephunter@gmail.com>
Tue, 15 Apr 2025 17:02:00 +0000 (19:02 +0200)
committerChristian Brabandt <cb@256bit.org>
Tue, 15 Apr 2025 17:02:00 +0000 (19:02 +0200)
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 <zeertzjq@outlook.com>
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/edit.c
src/insexpand.c
src/proto/insexpand.pro
src/testdir/dumps/Test_switchwin_clear_pum_01.dump [new file with mode: 0644]
src/testdir/dumps/Test_switchwin_clear_pum_02.dump [new file with mode: 0644]
src/testdir/dumps/Test_tabnext_clear_pum_01.dump [new file with mode: 0644]
src/testdir/dumps/Test_tabnext_clear_pum_02.dump [new file with mode: 0644]
src/testdir/test_popup.vim
src/version.c

index ab67fdc68b49cc58b1dcf2a369af3c910de45281..3c98bb8bb1613ca28420c5e2d0df5ac4e045862d 100644 (file)
@@ -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;
index c0762da9081fdca00b1571e61a5494c8e84a4ed2..8c15adeee4fc7d4309d333a7bbe3b010a286aebe 100644 (file)
@@ -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;
 
index a9ca289db11879a2f92d2e275de57a1beef7f665..8529b7b6c16484bd42991c66d0e2e53507592933 100644 (file)
@@ -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 (file)
index 0000000..9005f8d
--- /dev/null
@@ -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 (file)
index 0000000..39013c0
--- /dev/null
@@ -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 (file)
index 0000000..6eb86e6
--- /dev/null
@@ -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 (file)
index 0000000..347767c
--- /dev/null
@@ -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| 
index b2952fdc35e4d725115d580a5cf1d1687a67ebd1..ac879d24fffb93473f194573bf9e5a9810cf1bb1 100644 (file)
@@ -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
index 30904d7c06000d8a57e9859faa4170c66ed73146..7bd2bb6b7b29ad13529bf31d6a5ce15e66df15d5 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1305,
 /**/
     1304,
 /**/