commit d01b2611a6d54ec20640ddab4149932bd9213b7b
parent d9353bd44285a9a3abbe97410730fbf9a252aee3
Author: Luuk van Baal <luukvbaal@gmail.com>
Date: Thu, 24 Apr 2025 16:05:40 +0200
fix(ui): exclude unfocusable windows from 'complete' "w" completion
Problem: As in f85bc41, assume unfocusable windows to be UI windows
whose buffer content is unexpectedly included in 'complete'
"w" completion.
Solution: Exclude unfocusable windows when looping over windows.
Diffstat:
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
@@ -69,8 +69,9 @@ If a window is focusable, it is part of the "navigation stack", that is,
editor commands such as :windo, |CTRL-W|, etc., will consider the window as
one that can be made the "current window". A non-focusable window will be
skipped by such commands (though it can be explicitly focused by
-|nvim_set_current_win()|). Non-focusable windows are not listed by |:tabs|, and
-are not counted by the default 'tabline'.
+|nvim_set_current_win()|). Non-focusable windows are not listed by |:tabs|,
+or counted by the default 'tabline'. Their buffer content is not included
+in 'complete' "w" completion.
Windows (especially floating windows) can have many other |api-win_config|
properties such as "hide" and "fixed" which also affect behavior.
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
@@ -2613,8 +2613,8 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag)
while (true) {
// Move to next window (wrap to first window if at the end)
wp = (wp->w_next != NULL) ? wp->w_next : firstwin;
- // Break if we're back at start or found an unscanned buffer
- if (wp == curwin || !wp->w_buffer->b_scanned) {
+ // Break if we're back at start or found an unscanned buffer (in a focusable window)
+ if (wp == curwin || (!wp->w_buffer->b_scanned && wp->w_config.focusable)) {
break;
}
}
diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua
@@ -1351,4 +1351,26 @@ describe('completion', function()
eq('completeopt option does not include popup', api.nvim_get_var('err_msg'))
end)
end)
+
+ it([[does not include buffer from non-focusable window for 'complete' "w"]], function()
+ local buf = api.nvim_create_buf(false, true)
+ local cfg = { focusable = false, relative = 'win', bufpos = { 1, 0 }, width = 1, height = 1 }
+ local win = api.nvim_open_win(buf, false, cfg)
+ api.nvim_buf_set_lines(buf, 0, -1, false, { 'foo' })
+ feed('i<C-N>')
+ screen:expect([[
+ ^ |
+ {4:f}{1: }|
+ {1:~ }|*5
+ {5:-- Keyword completion (^N^P) }{9:Pattern not found} |
+ ]])
+ api.nvim_win_set_config(win, { focusable = true })
+ feed('<Esc>i<C-N>')
+ screen:expect([[
+ foo^ |
+ {4:f}{1: }|
+ {1:~ }|*5
+ {5:-- Keyword completion (^N^P) The only match} |
+ ]])
+ end)
end)