]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1424: PMenu selection broken with multi-line selection and limits v9.1.1424
authorGirish Palya <girishji@gmail.com>
Sun, 1 Jun 2025 18:11:59 +0000 (20:11 +0200)
committerChristian Brabandt <cb@256bit.org>
Sun, 1 Jun 2025 18:11:59 +0000 (20:11 +0200)
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 <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/insexpand.c
src/testdir/test_ins_complete.vim
src/version.c

index 66db022c19ff67fbaa0c7dbf5a3978c7f6307e66..51dd675b1379f7e28477afc4dfece18fe9c4dce0 100644 (file)
@@ -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;
index dfc2189bc481198883a728c05a525edfbf6abc3c..f3c29d1e76fc7ec60ac4144fed6f17796935e98f 100644 (file)
@@ -4238,7 +4238,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
index e7cabf84a119a3ec12d787734ea240c94754150c..7bc3a495dbbb2ef48b9c9e6229735b6b4d962051 100644 (file)
@@ -709,6 +709,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1424,
 /**/
     1423,
 /**/