From d35d7b75384841f47f9293ad10136d7ae4d192f7 Mon Sep 17 00:00:00 2001 From: glepnir Date: Tue, 16 Jul 2024 19:41:15 +0800 Subject: [PATCH] fix(float): close preview float window when no selected Problem: Float preview window still exist when back at origianl. Or no info item in this selected. Solution: if selected is -1 or no info in this selected if float preview window exist close it first. --- src/nvim/popupmenu.c | 21 ++-- test/functional/ui/popupmenu_spec.lua | 141 +++++++++++++++++++------- 2 files changed, 113 insertions(+), 49 deletions(-) diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 64db351dfa..3090deaf19 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -894,16 +894,18 @@ static bool pum_set_selected(int n, int repeat) int context = pum_height / 2; int prev_selected = pum_selected; + // Close the floating preview window when 'selected' is -1, meaning we are back to the original. + // Or no info item in this selected. + if (n < 0 || (n >= 0 && pum_array[n].pum_info == NULL)) { + win_T *wp = win_float_find_preview(); + if (wp) { + win_close(wp, true, true); + } + } + pum_selected = n; unsigned cur_cot_flags = get_cot_flags(); bool use_float = (cur_cot_flags & COT_POPUP) != 0; - // when new leader add and info window is shown and no selected we still - // need use the first index item to update the info float window position. - bool force_select = use_float && pum_selected < 0 && win_float_find_preview(); - if (force_select) { - pum_selected = 0; - } - if ((pum_selected >= 0) && (pum_selected < pum_size)) { if (pum_first > pum_selected - 4) { // scroll down; when we did a jump it's probably a PageUp then @@ -1120,11 +1122,6 @@ static bool pum_set_selected(int n, int repeat) } } - // restore before selected value - if (force_select) { - pum_selected = n; - } - return resized; } diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index e005cfd2e6..7823b72c87 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1674,25 +1674,26 @@ describe('builtin popupmenu', function() } end - -- info window position should be adjusted when new leader add - feed('o') + -- delete one character make the pum width smaller than before + -- info window position should be adjusted when popupmenu width changed + feed('') if multigrid then - screen:expect { + screen:expect({ grid = [[ - ## grid 1 - [2:----------------------------------------]|*10 - [3:----------------------------------------]| - ## grid 2 - o^ | - {1:~ }|*9 - ## grid 3 - {2:-- }{8:Back at original} | - ## grid 4 - {n:1info}| - {n: }| - ## grid 5 - {n:one }| - ]], + ## grid 1 + [2:----------------------------------------]|*10 + [3:----------------------------------------]| + ## grid 2 + on^ | + {1:~ }|*9 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {n:1info}| + {n: }| + ## grid 5 + {s:one }| + ]], float_pos = { [5] = { -1, 'NW', 2, 1, 0, false, 100 }, [4] = { 1001, 'NW', 1, 1, 15, false, 50 }, @@ -1703,7 +1704,7 @@ describe('builtin popupmenu', function() topline = 0, botline = 2, curline = 0, - curcol = 1, + curcol = 2, linecount = 1, sum_scroll_delta = 0, }, @@ -1717,22 +1718,88 @@ describe('builtin popupmenu', function() sum_scroll_delta = 0, }, }, - } + win_viewport_margins = { + [2] = { + bottom = 0, + left = 0, + right = 0, + top = 0, + win = 1000, + }, + [4] = { + bottom = 0, + left = 0, + right = 0, + top = 0, + win = 1001, + }, + }, + }) else - screen:expect { + screen:expect({ grid = [[ - o^ | - {n:one 1info}{1: }| - {1:~ }{n: }{1: }| - {1:~ }|*7 - {2:-- }{8:Back at original} | - ]], - } + on^ | + {s:one }{n:1info}{1: }| + {1:~ }{n: }{1: }| + {1:~ }|*7 + {2:-- }{5:match 1 of 3} | + ]], + }) + end + + -- when back to original the preview float should be closed. + feed('') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:----------------------------------------]|*10 + [3:----------------------------------------]| + ## grid 2 + on^ | + {1:~ }|*9 + ## grid 3 + {2:-- }{8:Back at original} | + ## grid 5 + {n:one }| + ]], + float_pos = { + [5] = { -1, 'NW', 2, 1, 0, false, 100 }, + }, + win_viewport = { + [2] = { + win = 1000, + topline = 0, + botline = 2, + curline = 0, + curcol = 2, + linecount = 1, + sum_scroll_delta = 0, + }, + }, + win_viewport_margins = { + [2] = { + bottom = 0, + left = 0, + right = 0, + top = 0, + win = 1000, + }, + }, + }) + else + screen:expect({ + grid = [[ + on^ | + {n:one }{1: }| + {1:~ }|*8 + {2:-- }{8:Back at original} | + ]], + }) end -- test nvim__complete_set_info - feed('cc') - vim.uv.sleep(10) + feed('S') if multigrid then screen:expect { grid = [[ @@ -1748,13 +1815,13 @@ describe('builtin popupmenu', function() {n:one }| {n:two }| {s:looooooooooooooong }| - ## grid 6 + ## grid 7 {n:3info}| {n: }| ]], float_pos = { [5] = { -1, 'NW', 2, 1, 0, false, 100 }, - [6] = { 1002, 'NW', 1, 1, 19, false, 50 }, + [7] = { 1003, 'NW', 1, 1, 19, false, 50 }, }, win_viewport = { [2] = { @@ -1766,8 +1833,8 @@ describe('builtin popupmenu', function() linecount = 1, sum_scroll_delta = 0, }, - [6] = { - win = 1002, + [7] = { + win = 1003, topline = 0, botline = 2, curline = 0, @@ -1809,12 +1876,12 @@ describe('builtin popupmenu', function() {s: one }| {n: two }| {n: looooooooooooooong }| - ## grid 7 + ## grid 8 {n:1info}| {n: }| ]], float_pos = { - [7] = { 1003, 'NW', 1, 1, 14, false, 50 }, + [8] = { 1004, 'NW', 1, 1, 14, false, 50 }, [5] = { -1, 'NW', 2, 1, 19, false, 100 }, }, win_viewport = { @@ -1827,8 +1894,8 @@ describe('builtin popupmenu', function() linecount = 1, sum_scroll_delta = 0, }, - [7] = { - win = 1003, + [8] = { + win = 1004, topline = 0, botline = 2, curline = 0,