Commit: patch 9.1.1424: PMenu selection broken with multi-line selection and limits

4 views
Skip to first unread message

Christian Brabandt

unread,
Jun 1, 2025, 2:30:13 PM6/1/25
to vim...@googlegroups.com
patch 9.1.1424: PMenu selection broken with multi-line selection and limits

Commit: https://github.com/vim/vim/commit/6c40df09e07dced75010be2d7a8e4831f6b9f796
Author: Girish Palya <giri...@gmail.com>
Date: Sun Jun 1 20:11:59 2025 +0200

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: #17394
closes: #17401

Signed-off-by: Girish Palya <giri...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/insexpand.c b/src/insexpand.c
index 66db022c1..51dd675b1 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -1446,18 +1446,20 @@ 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.
+ *
+ * Returns recalculated index of shown match.
*/
- static void
-trim_compl_match_array(void)
+ static int
+trim_compl_match_array(int shown_match_idx)
{
int i, src_idx, limit, new_size = 0, *match_counts = NULL;
pumitem_T *trimmed = NULL;
- int trimmed_idx = 0;
+ int trimmed_idx = 0, remove_count = 0;

// Count current matches per source.
match_counts = ALLOC_CLEAR_MULT(int, cpt_sources_count);
if (match_counts == NULL)
- return;
+ return shown_match_idx;
for (i = 0; i < compl_match_arraysize; i++)
{
src_idx = compl_match_array[i].pum_cpt_source_idx;
@@ -1492,6 +1494,8 @@ trim_compl_match_array(void)
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];
@@ -1502,6 +1506,7 @@ trim_compl_match_array(void)

theend:
vim_free(match_counts);
+ return shown_match_idx - remove_count;
}

/*
@@ -1713,8 +1718,8 @@ 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;
diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim
index dfc2189bc..f3c29d1e7 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -4238,7 +4238,33 @@ func Test_complete_match_count()
call assert_equal('abac', getline(4))
bw!

- set completeopt& complete&
+ " Items with '
' that cause menu to shift, with no leader (issue #17394)
+ func! ComplFunc(findstart, base)
+ if a:findstart == 1
+ return col('.') - 1
+ endif
+ return ["one
two
three", "four five six", "hello
world
here"]
+ 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
diff --git a/src/version.c b/src/version.c
index e7cabf84a..7bc3a495d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -709,6 +709,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1424,
/**/
1423,
/**/
Reply all
Reply to author
Forward
0 new messages