mirror of
https://github.com/neovim/neovim.git
synced 2026-04-18 21:40:45 +00:00
Merge pull request #33589 from zeertzjq/backport
vim-patch:9.1.1305: completion menu active after switching windows/tabs (#33488)
This commit is contained in:
@@ -381,6 +381,12 @@ static int insert_check(VimState *state)
|
||||
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) {
|
||||
s->inserted_space = false;
|
||||
|
||||
@@ -265,6 +265,9 @@ static extmark_undo_vec_t compl_orig_extmarks;
|
||||
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
|
||||
@@ -1753,6 +1756,8 @@ void ins_compl_clear(void)
|
||||
compl_matches = 0;
|
||||
compl_selected_item = -1;
|
||||
compl_ins_end_col = 0;
|
||||
compl_curr_win = NULL;
|
||||
compl_curr_buf = NULL;
|
||||
API_CLEAR_STRING(compl_pattern);
|
||||
API_CLEAR_STRING(compl_leader);
|
||||
edit_submode_extra = NULL;
|
||||
@@ -1773,7 +1778,7 @@ bool ins_compl_active(void)
|
||||
/// Return true when wp is the actual completion window
|
||||
bool ins_compl_win_active(win_T *wp)
|
||||
{
|
||||
return ins_compl_active() && !(wp->w_p_pvw || wp->w_float_is_info);
|
||||
return ins_compl_active() && wp == compl_curr_win && wp->w_buffer == compl_curr_buf;
|
||||
}
|
||||
|
||||
/// Selected one of the matches. When false the match was edited or using the
|
||||
@@ -2300,6 +2305,12 @@ static bool ins_compl_stop(const int c, const int prev_mode, bool retval)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/// Cancel completion.
|
||||
bool 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.
|
||||
///
|
||||
@@ -4851,6 +4862,8 @@ int ins_complete(int c, bool enable_pum)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
compl_curr_win = curwin;
|
||||
compl_curr_buf = curwin->w_buffer;
|
||||
compl_shown_match = compl_curr_match;
|
||||
compl_shows_dir = compl_direction;
|
||||
|
||||
|
||||
@@ -1164,6 +1164,7 @@ describe('builtin popupmenu', function()
|
||||
[8] = { foreground = Screen.colors.Red },
|
||||
[9] = { foreground = Screen.colors.Yellow, background = Screen.colors.Green },
|
||||
[10] = { foreground = Screen.colors.White, background = Screen.colors.Green },
|
||||
[11] = { background = Screen.colors.LightGrey, underline = true },
|
||||
ks = { foreground = Screen.colors.Red, background = Screen.colors.Grey },
|
||||
kn = { foreground = Screen.colors.Red, background = Screen.colors.Plum1 },
|
||||
xs = { foreground = Screen.colors.Black, background = Screen.colors.Grey },
|
||||
@@ -4343,12 +4344,32 @@ describe('builtin popupmenu', function()
|
||||
end
|
||||
end)
|
||||
|
||||
if not multigrid then
|
||||
it('with multiline messages', function()
|
||||
screen:try_resize(40, 8)
|
||||
feed('ixx<cr>')
|
||||
command('imap <f2> <cmd>echoerr "very"\\|echoerr "much"\\|echoerr "error"<cr>')
|
||||
fn.complete(1, { 'word', 'choice', 'text', 'thing' })
|
||||
it('with multiline messages', function()
|
||||
screen:try_resize(40, 8)
|
||||
feed('ixx<cr>')
|
||||
command('imap <f2> <cmd>echoerr "very"\\|echoerr "much"\\|echoerr "error"<cr>')
|
||||
fn.complete(1, { 'word', 'choice', 'text', 'thing' })
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
[2:----------------------------------------]|*7
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
xx |
|
||||
word^ |
|
||||
{1:~ }|*5
|
||||
## grid 3
|
||||
{2:-- INSERT --} |
|
||||
## grid 4
|
||||
{s:word }|
|
||||
{n:choice }|
|
||||
{n:text }|
|
||||
{n:thing }|
|
||||
]],
|
||||
float_pos = { [4] = { -1, 'NW', 2, 2, 0, false, 100 } },
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
xx |
|
||||
word^ |
|
||||
@@ -4359,8 +4380,33 @@ describe('builtin popupmenu', function()
|
||||
{1:~ }|
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
end
|
||||
|
||||
feed('<f2>')
|
||||
feed('<f2>')
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
[2:----------------------------------------]|*4
|
||||
[3:----------------------------------------]|*4
|
||||
## grid 2
|
||||
xx |
|
||||
word |
|
||||
{1:~ }|*5
|
||||
## grid 3
|
||||
{6:very} |
|
||||
{6:much} |
|
||||
{6:error} |
|
||||
{5:Press ENTER or type command to continue}^ |
|
||||
## grid 4
|
||||
{s:word }|
|
||||
{n:choice }|
|
||||
{n:text }|
|
||||
{n:thing }|
|
||||
]],
|
||||
float_pos = { [4] = { -1, 'NW', 2, 2, 0, false, 100 } },
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
xx |
|
||||
word |
|
||||
@@ -4371,8 +4417,30 @@ describe('builtin popupmenu', function()
|
||||
{6:error} |
|
||||
{5:Press ENTER or type command to continue}^ |
|
||||
]])
|
||||
end
|
||||
|
||||
feed('<cr>')
|
||||
feed('<cr>')
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
[2:----------------------------------------]|*7
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
xx |
|
||||
word^ |
|
||||
{1:~ }|*5
|
||||
## grid 3
|
||||
{2:-- INSERT --} |
|
||||
## grid 4
|
||||
{s:word }|
|
||||
{n:choice }|
|
||||
{n:text }|
|
||||
{n:thing }|
|
||||
]],
|
||||
float_pos = { [4] = { -1, 'NW', 2, 2, 0, false, 100 } },
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
xx |
|
||||
word^ |
|
||||
@@ -4383,8 +4451,30 @@ describe('builtin popupmenu', function()
|
||||
{1:~ }|
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
end
|
||||
|
||||
feed('<c-n>')
|
||||
feed('<c-n>')
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
[2:----------------------------------------]|*7
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
xx |
|
||||
choice^ |
|
||||
{1:~ }|*5
|
||||
## grid 3
|
||||
{2:-- INSERT --} |
|
||||
## grid 4
|
||||
{n:word }|
|
||||
{s:choice }|
|
||||
{n:text }|
|
||||
{n:thing }|
|
||||
]],
|
||||
float_pos = { [4] = { -1, 'NW', 2, 2, 0, false, 100 } },
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
xx |
|
||||
choice^ |
|
||||
@@ -4395,35 +4485,92 @@ describe('builtin popupmenu', function()
|
||||
{1:~ }|
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
end
|
||||
|
||||
command('split')
|
||||
command('split')
|
||||
feed('<c-u>')
|
||||
fn.complete(1, { 'word', 'choice', 'text', 'thing' })
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
[5:----------------------------------------]|*3
|
||||
{4:[No Name] [+] }|
|
||||
[2:----------------------------------------]|*2
|
||||
{3:[No Name] [+] }|
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
xx |
|
||||
word |
|
||||
## grid 3
|
||||
{2:-- INSERT --} |
|
||||
## grid 4
|
||||
{s:word }|
|
||||
{n:choice }|
|
||||
{n:text }|
|
||||
{n:thing }|
|
||||
## grid 5
|
||||
xx |
|
||||
word^ |
|
||||
{1:~ }|
|
||||
]],
|
||||
float_pos = { [4] = { -1, 'NW', 5, 2, 0, false, 100 } },
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
xx |
|
||||
choice^ |
|
||||
{n:word }{1: }|
|
||||
{s:choice }{4: }|
|
||||
word^ |
|
||||
{s:word }{1: }|
|
||||
{n:choice }{4: }|
|
||||
{n:text } |
|
||||
{n:thing } |
|
||||
{3:[No Name] [+] }|
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
end
|
||||
|
||||
api.nvim_input_mouse('wheel', 'down', '', 0, 6, 15)
|
||||
screen:expect {
|
||||
api.nvim_input_mouse('wheel', 'down', '', 0, 6, 15)
|
||||
if multigrid then
|
||||
screen:expect({
|
||||
grid = [[
|
||||
## grid 1
|
||||
[5:----------------------------------------]|*3
|
||||
{4:[No Name] [+] }|
|
||||
[2:----------------------------------------]|*2
|
||||
{3:[No Name] [+] }|
|
||||
[3:----------------------------------------]|
|
||||
## grid 2
|
||||
word |
|
||||
{1:~ }|
|
||||
## grid 3
|
||||
{2:-- INSERT --} |
|
||||
## grid 4
|
||||
{s:word }|
|
||||
{n:choice }|
|
||||
{n:text }|
|
||||
{n:thing }|
|
||||
## grid 5
|
||||
xx |
|
||||
choice^ |
|
||||
{n:word }{1: }|
|
||||
{s:choice }{4: }|
|
||||
word^ |
|
||||
{1:~ }|
|
||||
]],
|
||||
float_pos = { [4] = { -1, 'NW', 5, 2, 0, false, 100 } },
|
||||
})
|
||||
else
|
||||
screen:expect([[
|
||||
xx |
|
||||
word^ |
|
||||
{s:word }{1: }|
|
||||
{n:choice }{4: }|
|
||||
{n:text } |
|
||||
{n:thing }{1: }|
|
||||
{3:[No Name] [+] }|
|
||||
{2:-- INSERT --} |
|
||||
]],
|
||||
unchanged = true,
|
||||
}
|
||||
end)
|
||||
]])
|
||||
end
|
||||
end)
|
||||
|
||||
if not multigrid then
|
||||
it('with kind, menu and abbr attributes', function()
|
||||
screen:try_resize(40, 8)
|
||||
feed('ixx ')
|
||||
@@ -7839,6 +7986,53 @@ describe('builtin popupmenu', function()
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
-- oldtest: Test_pum_clear_when_switch_tab_or_win()
|
||||
it('is cleared when switching tab or win', function()
|
||||
screen:try_resize(55, 20)
|
||||
exec([[
|
||||
inoremap <F4> <Cmd>wincmd w<CR>
|
||||
inoremap <F5> <Cmd>tabnext<CR>
|
||||
]])
|
||||
|
||||
command('tabe')
|
||||
feed('Aaa aaa <C-X><C-N>')
|
||||
screen:expect([[
|
||||
{11: [No Name] }{2: + [No Name] }{3: }{11:X}|
|
||||
aa aaa aa^ |
|
||||
{1:~ }{s: aa }{1: }|
|
||||
{1:~ }{n: aaa }{1: }|
|
||||
{1:~ }|*15
|
||||
{2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
|
||||
]])
|
||||
feed('<F5>')
|
||||
screen:expect([[
|
||||
{2: [No Name] }{11: + [No Name] }{3: }{11:X}|
|
||||
^ |
|
||||
{1:~ }|*17
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
command('tabclose!')
|
||||
|
||||
command('vnew win_b')
|
||||
feed('Abb bbb <C-X><C-N>')
|
||||
screen:expect([[
|
||||
bb bbb bb^ │aa aaa aa |
|
||||
{1:~ }{s: bb }{1: }│{1:~ }|
|
||||
{1:~ }{n: bbb }{1: }│{1:~ }|
|
||||
{1:~ }│{1:~ }|*15
|
||||
{4:win_b [+] }{3:[No Name] [+] }|
|
||||
{2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} |
|
||||
]])
|
||||
feed('<F4>')
|
||||
screen:expect([[
|
||||
bb bbb bb │aa aaa a^a |
|
||||
{1:~ }│{1:~ }|*17
|
||||
{3:win_b [+] }{4:[No Name] [+] }|
|
||||
{2:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1966,4 +1966,36 @@ func Test_pum_complete_with_special_characters()
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user