1
0
forked from aniani/vim

patch 9.1.0905: Missing information in CompleteDone event

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>
This commit is contained in:
glepnir
2024-12-04 20:27:34 +01:00
committed by Christian Brabandt
parent 215c82d061
commit 1c5a120a70
5 changed files with 131 additions and 7 deletions

View 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 VIM REFERENCE MANUAL by Bram Moolenaar
@@ -702,6 +702,12 @@ CompleteDone After Insert mode completion is done. Either
The |v:completed_item| variable contains The |v:completed_item| variable contains
information about the completed item. 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*
CursorHold When the user doesn't press a key for the time CursorHold When the user doesn't press a key for the time
specified with 'updatetime'. Not triggered specified with 'updatetime'. Not triggered

View 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 VIM REFERENCE MANUAL by Bram Moolenaar
@@ -4752,9 +4752,6 @@ Insert mode completion/expansion:
- When complete() first argument is before where insert started and - When complete() first argument is before where insert started and
'backspace' is Vi compatible, the completion fails. 'backspace' is Vi compatible, the completion fails.
(Hirohito Higashi, 2015 Feb 19) (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 - 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() number, not a string. (Sean Ma) Need to add flag to call_func_retlist()
to force a string value. to force a string value.

View File

@@ -2296,6 +2296,35 @@ set_ctrl_x_mode(int c)
return retval; 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 * Stop insert completion mode
*/ */
@@ -2303,6 +2332,7 @@ set_ctrl_x_mode(int c)
ins_compl_stop(int c, int prev_mode, int retval) ins_compl_stop(int c, int prev_mode, int retval)
{ {
int want_cindent; int want_cindent;
char_u *word = NULL;
// Get here when we have finished typing a sequence of ^N and // Get here when we have finished typing a sequence of ^N and
// ^P or other completion characters in CTRL-X mode. Free up // ^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 if ((c == Ctrl_Y || (compl_enter_selects
&& (c == CAR || c == K_KENTER || c == NL))) && (c == CAR || c == K_KENTER || c == NL)))
&& pum_visible()) && pum_visible())
{
word = vim_strsave(compl_shown_match->cp_str.string);
retval = TRUE; retval = TRUE;
}
// CTRL-E means completion is Ended, go back to the typed text. // CTRL-E means completion is Ended, go back to the typed text.
// but only do this, if the Popup is still visible // 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(); do_c_expr_indent();
// Trigger the CompleteDone event to give scripts a chance to act // Trigger the CompleteDone event to give scripts a chance to act
// upon the end of completion. // upon the end of completion.
ins_apply_autocmds(EVENT_COMPLETEDONE); trigger_complete_done_event(prev_mode, word);
vim_free(word);
return retval; return retval;
} }
@@ -2538,7 +2572,7 @@ ins_compl_prep(int c)
else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) else if (ctrl_x_mode == CTRL_X_LOCAL_MSG)
// Trigger the CompleteDone event to give scripts a chance to act // Trigger the CompleteDone event to give scripts a chance to act
// upon the (possibly failed) completion. // upon the (possibly failed) completion.
ins_apply_autocmds(EVENT_COMPLETEDONE); trigger_complete_done_event(ctrl_x_mode, NULL);
may_trigger_modechanged(); may_trigger_modechanged();

View File

@@ -277,6 +277,91 @@ func Test_CompleteDoneNone()
au! CompleteDone au! CompleteDone
endfunc 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() func Test_CompleteDoneDict()
au CompleteDonePre * :call <SID>CompleteDone_CheckCompletedItemDict(1) au CompleteDonePre * :call <SID>CompleteDone_CheckCompletedItemDict(1)
au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDict(0) au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDict(0)

View File

@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
905,
/**/ /**/
904, 904,
/**/ /**/