]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0905: Missing information in CompleteDone event v9.1.0905
authorglepnir <glephunter@gmail.com>
Wed, 4 Dec 2024 19:27:34 +0000 (20:27 +0100)
committerChristian Brabandt <cb@256bit.org>
Wed, 4 Dec 2024 19:31:43 +0000 (20:31 +0100)
Problem:  Missing information in CompleteDone event
Solution: add complete_word and complete_type to v:event dict
          (glepnir)

closes: #16153

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/autocmd.txt
runtime/doc/todo.txt
src/insexpand.c
src/testdir/test_ins_complete.vim
src/version.c

index 6ca00a6e1efa4cb289ffe68aca497139875e689c..8a653f2be7ebc51cfe500e9d59141f0518a90e44 100644 (file)
@@ -1,4 +1,4 @@
-*autocmd.txt*   For Vim version 9.1.  Last change: 2024 Oct 27
+*autocmd.txt*   For Vim version 9.1.  Last change: 2024 Dec 04
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -702,6 +702,12 @@ CompleteDone                       After Insert mode completion is done.  Either
                                The |v:completed_item| variable contains
                                information about the completed item.
 
+                               Sets these |v:event| keys:
+                                   complete_word       The word that was
+                                                       selected, empty if
+                                                       abandoned complete.
+                                   complete_type       |complete_info_mode|
+
                                                        *CursorHold*
 CursorHold                     When the user doesn't press a key for the time
                                specified with 'updatetime'.  Not triggered
index e73d2f1fe2c994bb732949025843845990adf805..b1318cf9e139001b2a67db8c01d340d2b44af472 100644 (file)
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 9.1.  Last change: 2024 Dec 02
+*todo.txt*      For Vim version 9.1.  Last change: 2024 Dec 04
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -4752,9 +4752,6 @@ Insert mode completion/expansion:
 -   When complete() first argument is before where insert started and
     'backspace' is Vi compatible, the completion fails.
     (Hirohito Higashi, 2015 Feb 19)
--   The CompleteDone autocommand needs some info passed to it:
-    - The word that was selected (empty if abandoned complete)
-    - Type of completion: tag, omnifunc, user func.
 -   When a:base in 'completefunc' starts with a number it's passed as a
     number, not a string. (Sean Ma)  Need to add flag to call_func_retlist()
     to force a string value.
index 75403f1b3b386dab84a9fc1beee9ec5673381629..305511cd8ccc4a831fe741ad3ff64b376ee641c1 100644 (file)
@@ -2296,6 +2296,35 @@ set_ctrl_x_mode(int c)
     return retval;
 }
 
+/*
+ * Trigger CompleteDone event and adds relevant information to v:event
+ */
+    static void
+trigger_complete_done_event(int mode UNUSED, char_u *word UNUSED)
+{
+#if defined(FEAT_EVAL)
+    save_v_event_T     save_v_event;
+    dict_T             *v_event = get_v_event(&save_v_event);
+    char_u             *mode_str = NULL;
+
+    mode = mode & ~CTRL_X_WANT_IDENT;
+    if (ctrl_x_mode_names[mode])
+       mode_str = (char_u *)ctrl_x_mode_names[mode];
+
+    (void)dict_add_string(v_event, "complete_word",
+                               word == NULL ? (char_u *)"" : word);
+    (void)dict_add_string(v_event, "complete_type",
+                               mode_str != NULL ? mode_str : (char_u *)"");
+
+    dict_set_items_ro(v_event);
+#endif
+    ins_apply_autocmds(EVENT_COMPLETEDONE);
+
+#if defined(FEAT_EVAL)
+    restore_v_event(v_event, &save_v_event);
+#endif
+}
+
 /*
  * Stop insert completion mode
  */
@@ -2303,6 +2332,7 @@ set_ctrl_x_mode(int c)
 ins_compl_stop(int c, int prev_mode, int retval)
 {
     int                want_cindent;
+    char_u     *word = NULL;
 
     // Get here when we have finished typing a sequence of ^N and
     // ^P or other completion characters in CTRL-X mode.  Free up
@@ -2358,7 +2388,10 @@ ins_compl_stop(int c, int prev_mode, int retval)
     if ((c == Ctrl_Y || (compl_enter_selects
                    && (c == CAR || c == K_KENTER || c == NL)))
            && pum_visible())
+    {
+       word = vim_strsave(compl_shown_match->cp_str.string);
        retval = TRUE;
+    }
 
     // CTRL-E means completion is Ended, go back to the typed text.
     // but only do this, if the Popup is still visible
@@ -2418,7 +2451,8 @@ ins_compl_stop(int c, int prev_mode, int retval)
        do_c_expr_indent();
     // Trigger the CompleteDone event to give scripts a chance to act
     // upon the end of completion.
-    ins_apply_autocmds(EVENT_COMPLETEDONE);
+    trigger_complete_done_event(prev_mode, word);
+    vim_free(word);
 
     return retval;
 }
@@ -2538,7 +2572,7 @@ ins_compl_prep(int c)
     else if (ctrl_x_mode == CTRL_X_LOCAL_MSG)
        // Trigger the CompleteDone event to give scripts a chance to act
        // upon the (possibly failed) completion.
-       ins_apply_autocmds(EVENT_COMPLETEDONE);
+       trigger_complete_done_event(ctrl_x_mode, NULL);
 
     may_trigger_modechanged();
 
index 7829f79fbba01c91cdd3a993d82aaf6f48572a65..ad2d421676e6d7310c8589f8b37f34b7b8858422 100644 (file)
@@ -277,6 +277,91 @@ func Test_CompleteDoneNone()
   au! CompleteDone
 endfunc
 
+func Test_CompleteDone_vevent_keys()
+  func OnDone()
+    let g:complete_word = get(v:event, 'complete_word', v:null)
+    let g:complete_type = get(v:event, 'complete_type', v:null)
+  endfunction
+
+  autocmd CompleteDone * :call OnDone()
+
+  func CompleteFunc(findstart, base)
+    if a:findstart
+      return col(".")
+    endif
+    return [#{word: "foo"}, #{word: "bar"}]
+  endfunc
+  set omnifunc=CompleteFunc
+  set completefunc=CompleteFunc
+  set completeopt+=menuone
+
+  new
+  call feedkeys("A\<C-X>\<C-O>\<Esc>", 'tx')
+  call assert_equal('', g:complete_word)
+  call assert_equal('omni', g:complete_type)
+
+  call feedkeys("S\<C-X>\<C-O>\<C-Y>\<Esc>", 'tx')
+  call assert_equal('foo', g:complete_word)
+  call assert_equal('omni', g:complete_type)
+
+  call feedkeys("S\<C-X>\<C-O>\<C-N>\<C-Y>\<Esc>0", 'tx')
+  call assert_equal('bar', g:complete_word)
+  call assert_equal('omni', g:complete_type)
+
+  call feedkeys("Shello vim visual v\<C-X>\<C-N>\<ESC>", 'tx')
+  call assert_equal('', g:complete_word)
+  call assert_equal('keyword', g:complete_type)
+
+  call feedkeys("Shello vim visual v\<C-X>\<C-N>\<C-Y>", 'tx')
+  call assert_equal('vim', g:complete_word)
+  call assert_equal('keyword', g:complete_type)
+
+  call feedkeys("Shello vim visual v\<C-X>\<C-N>\<C-Y>", 'tx')
+  call assert_equal('vim', g:complete_word)
+  call assert_equal('keyword', g:complete_type)
+
+  call feedkeys("Shello vim\<CR>completion test\<CR>\<C-X>\<C-l>\<C-Y>", 'tx')
+  call assert_equal('completion test', g:complete_word)
+  call assert_equal('whole_line', g:complete_type)
+
+  call feedkeys("S\<C-X>\<C-U>\<C-Y>", 'tx')
+  call assert_equal('foo', g:complete_word)
+  call assert_equal('function', g:complete_type)
+
+  inoremap <buffer> <f3> <cmd>call complete(1, ["red", "blue"])<cr>
+  call feedkeys("S\<f3>\<C-Y>", 'tx')
+  call assert_equal('red', g:complete_word)
+  call assert_equal('eval', g:complete_type)
+
+  call feedkeys("S\<C-X>\<C-V>\<C-Y>", 'tx')
+  call assert_equal('!', g:complete_word)
+  call assert_equal('cmdline', g:complete_type)
+
+  call writefile([''], 'foo_test', 'D')
+  call feedkeys("Sfoo\<C-X>\<C-F>\<C-Y>\<Esc>", 'tx')
+  call assert_equal('foo_test', g:complete_word)
+  call assert_equal('files', g:complete_type)
+
+  call writefile(['hello help'], 'test_case.txt', 'D')
+  set dictionary=test_case.txt
+  call feedkeys("ggdGSh\<C-X>\<C-K>\<C-Y>\<Esc>", 'tx')
+  call assert_equal('hello', g:complete_word)
+  call assert_equal('dictionary', g:complete_type)
+
+  set spell spelllang=en_us
+  call feedkeys("STheatre\<C-X>s\<C-Y>\<Esc>", 'tx')
+  call assert_equal('Theater', g:complete_word)
+  call assert_equal('spell', g:complete_type)
+
+  bwipe!
+  set completeopt& omnifunc& completefunc& spell& spelllang& dictionary&
+  autocmd! CompleteDone
+  delfunc OnDone
+  delfunc CompleteFunc
+  unlet g:complete_word
+  unlet g:complete_type
+endfunc
+
 func Test_CompleteDoneDict()
   au CompleteDonePre * :call <SID>CompleteDone_CheckCompletedItemDict(1)
   au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDict(0)
index 42d8e1182ba3dce431327f1fc23921737c3d8ce0..4cf68620cb27ae548c8fa6e0a7247a257982564b 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    905,
 /**/
     904,
 /**/