mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
vim-patch:9.1.1424: PMenu selection broken with multi-line selection and limits
Problem: PMenu selection broken with multi-line selection and limits
(Maxim Kim)
Solution: update completion match index when limiting the completion
sources (Girish Palya)
fixes: vim/vim#17394
closes: vim/vim#17401
6c40df09e0
Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
@@ -1369,8 +1369,12 @@ static void trigger_complete_changed_event(int cur)
|
||||
/// becomes inconsistent with compl_first_match (list) after former is sorted by
|
||||
/// fuzzy score. The two structures end up in different orders.
|
||||
/// Ideally, compl_first_match list should have been sorted instead.
|
||||
static void trim_compl_match_array(void)
|
||||
///
|
||||
/// Returns recalculated index of shown match.
|
||||
static int trim_compl_match_array(int shown_match_idx)
|
||||
{
|
||||
int remove_count = 0;
|
||||
|
||||
// Count current matches per source.
|
||||
int *match_counts = xcalloc((size_t)cpt_sources_count, sizeof(int));
|
||||
for (int i = 0; i < compl_match_arraysize; i++) {
|
||||
@@ -1402,6 +1406,8 @@ static void trim_compl_match_array(void)
|
||||
if (limit <= 0 || match_counts[src_idx] < limit) {
|
||||
trimmed[trimmed_idx++] = compl_match_array[i];
|
||||
match_counts[src_idx]++;
|
||||
} else if (i < shown_match_idx) {
|
||||
remove_count++;
|
||||
}
|
||||
} else {
|
||||
trimmed[trimmed_idx++] = compl_match_array[i];
|
||||
@@ -1413,6 +1419,7 @@ static void trim_compl_match_array(void)
|
||||
|
||||
theend:
|
||||
xfree(match_counts);
|
||||
return shown_match_idx - remove_count;
|
||||
}
|
||||
|
||||
/// pumitem qsort compare func
|
||||
@@ -1607,8 +1614,8 @@ static int ins_compl_build_pum(void)
|
||||
shown_match_ok = true;
|
||||
}
|
||||
|
||||
if (is_forward && fuzzy_sort && cpt_sources_array != NULL) {
|
||||
trim_compl_match_array(); // Truncate by max_matches in 'cpt'
|
||||
if (fuzzy_sort && cpt_sources_array != NULL) {
|
||||
cur = trim_compl_match_array(cur); // Truncate by max_matches in 'cpt'
|
||||
}
|
||||
if (!shown_match_ok) { // no displayed match at all
|
||||
cur = -1;
|
||||
|
@@ -4319,7 +4319,33 @@ func Test_complete_match_count()
|
||||
call assert_equal('abac', getline(4))
|
||||
bw!
|
||||
|
||||
set completeopt& complete&
|
||||
" Items with '\n' that cause menu to shift, with no leader (issue #17394)
|
||||
func! ComplFunc(findstart, base)
|
||||
if a:findstart == 1
|
||||
return col('.') - 1
|
||||
endif
|
||||
return ["one\ntwo\nthree", "four five six", "hello\nworld\nhere"]
|
||||
endfunc
|
||||
set completeopt=menuone,popup,noselect,fuzzy infercase
|
||||
set complete=.^1,FComplFunc^5
|
||||
new
|
||||
call setline(1, ["foo", "bar", "baz"])
|
||||
execute "normal Go\<c-n>\<c-n>\<c-n>"
|
||||
call assert_equal(['one', 'two', 'three'], getline(4, 6))
|
||||
%d
|
||||
call setline(1, ["foo", "bar", "baz"])
|
||||
execute "normal Go\<c-n>\<c-n>\<c-n>\<c-p>"
|
||||
call assert_equal('foo', getline(4))
|
||||
execute "normal S\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>"
|
||||
call assert_equal('foo', getline(4))
|
||||
set complete=.^1,FComplFunc^2
|
||||
execute "normal S\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>"
|
||||
call assert_equal('foo', getline(4))
|
||||
execute "normal S\<c-n>\<c-p>\<c-p>\<c-p>\<c-n>\<c-n>"
|
||||
call assert_equal('four five six', getline(4))
|
||||
bw!
|
||||
|
||||
set completeopt& complete& infercase&
|
||||
delfunc PrintMenuWords
|
||||
delfunc ComplFunc
|
||||
delfunc CompleteItemsSelect
|
||||
|
Reference in New Issue
Block a user