]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1850: completion: not triggered after i_Ctrl-W/i_Ctrl-U v9.1.1850
authorGirish Palya <girishji@gmail.com>
Sun, 12 Oct 2025 14:37:02 +0000 (14:37 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 12 Oct 2025 14:37:02 +0000 (14:37 +0000)
Problem:  completion: not triggered after i_Ctrl-W/i_Ctrl-U
Solution: Trigger autocomplete when entering Insert mode
          (Girish Palya).

fixes: #18535
closes: #18543

Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/insert.txt
src/edit.c
src/testdir/test_ins_complete.vim
src/version.c

index 914e9fc83a55eb6c24371ee8c559d7d64d59076a..5ed3e803a7a623aa5f76a9812df4dbcb9c0b4774 100644 (file)
@@ -1,4 +1,4 @@
-*insert.txt*    For Vim version 9.1.  Last change: 2025 Sep 16
+*insert.txt*    For Vim version 9.1.  Last change: 2025 Oct 12
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -80,10 +80,11 @@ CTRL-W              Delete the word before the cursor (see |i_backspacing| about
                joining lines).  See the section "word motions",
                |word-motions|, for the definition of a word.
                                                *i_CTRL-U*
-CTRL-U         Delete all entered characters before the cursor in the current
-               line.  If there are no newly entered characters and
-               'backspace' is not empty, delete all characters before the
-               cursor in the current line.
+CTRL-U         Delete all characters that were entered after starting Insert
+               mode and before the cursor in the current line.
+               If there are no newly entered characters and 'backspace' is
+               not empty, delete all characters before the cursor in the
+               current line.
                If C-indenting is enabled the indent will be adjusted if the
                line becomes blank.
                See |i_backspacing| about joining lines.
index 2a765467d648ddd673d48727b915d7d0fc1348a7..891d51cf951b13b49d991cc885f81c2ec891acc9 100644 (file)
@@ -100,6 +100,25 @@ static int ins_need_undo;          // call u_save() before inserting a
 static int     dont_sync_undo = FALSE; // CTRL-G U prevents syncing undo for
                                        // the next left/right cursor key
 
+#define TRIGGER_AUTOCOMPLETE()                 \
+    do {                                       \
+       update_screen(UPD_VALID);  /* Show char (deletion) immediately */ \
+       out_flush();                            \
+       ins_compl_enable_autocomplete();        \
+       goto docomplete;                        \
+    } while (0)
+
+#define MAY_TRIGGER_AUTOCOMPLETE(c)                            \
+    do {                                                       \
+       if (ins_compl_has_autocomplete() && !char_avail()       \
+               && curwin->w_cursor.col > 0)                    \
+       {                                                       \
+           (c) = char_before_cursor();                         \
+           if (vim_isprintc(c))                                \
+               TRIGGER_AUTOCOMPLETE();                         \
+       }                                                       \
+    } while (0)
+
 /*
  * edit(): Start inserting text.
  *
@@ -146,6 +165,7 @@ edit(
 #ifdef FEAT_CONCEAL
     int                cursor_line_was_concealed;
 #endif
+    int                ins_just_started = TRUE;
 
     // Remember whether editing was restarted after CTRL-O.
     did_restart_edit = restart_edit;
@@ -593,6 +613,30 @@ edit(
            // Got here from normal mode when bracketed paste started.
            c = K_PS;
        else
+       {
+           // Trigger autocomplete when entering Insert mode, either directly
+           // or via change commands like 'ciw', 'cw', etc., before the first
+           // character is typed.
+           if (ins_just_started)
+           {
+               ins_just_started = FALSE;
+               if (ins_compl_has_autocomplete() && !char_avail()
+                       && curwin->w_cursor.col > 0)
+               {
+                   c = char_before_cursor();
+                   if (vim_isprintc(c))
+                   {
+                       ins_compl_enable_autocomplete();
+                       ins_compl_init_get_longest();
+#ifdef FEAT_RIGHTLEFT
+                       if (p_hkmap)
+                           c = hkmap(c);               // Hebrew mode mapping
+#endif
+                       goto docomplete;
+                   }
+               }
+           }
+
            do
            {
                c = safe_vgetc();
@@ -622,6 +666,7 @@ edit(
                    goto doESCkey;
                }
            } while (c == K_IGNORE || c == K_NOP);
+       }
 
        // Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V.
        did_cursorhold = TRUE;
@@ -991,18 +1036,8 @@ doESCkey:
        case Ctrl_H:
            did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space);
            auto_format(FALSE, TRUE);
-           if (did_backspace && ins_compl_has_autocomplete() && !char_avail()
-                   && curwin->w_cursor.col > 0)
-           {
-               c = char_before_cursor();
-               if (vim_isprintc(c))
-               {
-                   update_screen(UPD_VALID); // Show char deletion immediately
-                   out_flush();
-                   ins_compl_enable_autocomplete();
-                   goto docomplete; // Trigger autocompletion
-               }
-           }
+           if (did_backspace)
+               MAY_TRIGGER_AUTOCOMPLETE(c);
            break;
 
        case Ctrl_W:    // delete word before the cursor
@@ -1020,6 +1055,8 @@ doESCkey:
 #endif
            did_backspace = ins_bs(c, BACKSPACE_WORD, &inserted_space);
            auto_format(FALSE, TRUE);
+           if (did_backspace)
+               MAY_TRIGGER_AUTOCOMPLETE(c);
            break;
 
        case Ctrl_U:    // delete all inserted text in current line
@@ -1031,6 +1068,8 @@ doESCkey:
            did_backspace = ins_bs(c, BACKSPACE_LINE, &inserted_space);
            auto_format(FALSE, TRUE);
            inserted_space = FALSE;
+           if (did_backspace)
+               MAY_TRIGGER_AUTOCOMPLETE(c);
            break;
 
        case K_LEFTMOUSE:   // mouse keys
@@ -1424,12 +1463,7 @@ normalchar:
            // Trigger autocompletion
            if (ins_compl_has_autocomplete() && !char_avail()
                    && vim_isprintc(c))
-           {
-               update_screen(UPD_VALID); // Show character immediately
-               out_flush();
-               ins_compl_enable_autocomplete();
-               goto docomplete;
-           }
+               TRIGGER_AUTOCOMPLETE();
 
            break;
        }   // end of switch (c)
index 23c84b28b1f5d5bdc50f12da39153696c7736ac7..6d492373c4c320abec83842a8123e6b594314b00 100644 (file)
@@ -5416,10 +5416,33 @@ func Test_autocomplete_trigger()
   call assert_equal(['fodabc', 'fodxyz'], b:matches->mapnew('v:val.word'))
   call assert_equal(-1, b:selected)
 
+  " Test 8: Ctrl_W / Ctrl_U (delete word/line) should restart autocompletion
+  func! TestComplete(findstart, base)
+    if a:findstart
+      return col('.') - 1
+    endif
+    return ['fooze', 'faberge']
+  endfunc
+  set omnifunc=TestComplete
+  set complete+=o
+  call feedkeys("Sprefix->fo\<F2>\<Esc>0", 'tx!')
+  call assert_equal(['fodabc', 'fodxyz', 'foobar', 'fooze'], b:matches->mapnew('v:val.word'))
+  call feedkeys("Sprefix->fo\<C-W>\<F2>\<Esc>0", 'tx!')
+  call assert_equal(['fooze', 'faberge'], b:matches->mapnew('v:val.word'))
+  call feedkeys("Sprefix->\<Esc>afo\<C-U>\<F2>\<Esc>0", 'tx!')
+  call assert_equal(['fooze', 'faberge'], b:matches->mapnew('v:val.word'))
+
+  " Test 9: Trigger autocomplete immediately upon entering Insert mode
+  call feedkeys("Sprefix->foo\<Esc>a\<F2>\<Esc>0", 'tx!')
+  call assert_equal(['foobar', 'fooze', 'faberge'], b:matches->mapnew('v:val.word'))
+  call feedkeys("Sprefix->fooxx\<Esc>hcw\<F2>\<Esc>0", 'tx!')
+  call assert_equal(['foobar', 'fooze', 'faberge'], b:matches->mapnew('v:val.word'))
+
   bw!
   call test_override("char_avail", 0)
   delfunc NonKeywordComplete
-  set autocomplete&
+  delfunc TestComplete
+  set autocomplete& omnifunc& complete&
   unlet g:CallCount
 endfunc
 
index c28ce040a6b7b770ece8741e86c318bef64f179e..3f6baf6bb22cb67fda6db2aac9ff2f822b985b9a 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1850,
 /**/
     1849,
 /**/