diff options
author | chemzqm <chemzqm@gmail.com> | 2019-02-16 04:54:10 +0800 |
---|---|---|
committer | chemzqm <chemzqm@gmail.com> | 2019-03-15 04:24:41 +0800 |
commit | 6c375d71c3a92b0f83f1756799520ae61d11e64e (patch) | |
tree | f59a5c7d4f9e5ad461e603626715d05e86305724 | |
parent | 7e6fce0698f52fb189a78bf7388a4bdb238dcde7 (diff) | |
download | rneovim-6c375d71c3a92b0f83f1756799520ae61d11e64e.tar.gz rneovim-6c375d71c3a92b0f83f1756799520ae61d11e64e.tar.bz2 rneovim-6c375d71c3a92b0f83f1756799520ae61d11e64e.zip |
autocmd: add MenuPopupChanged autocmd
Update src/nvim/auevents.lua
Co-Authored-By: chemzqm <chemzqm@gmail.com>
-rw-r--r-- | runtime/doc/autocmd.txt | 17 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 13 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 1 | ||||
-rw-r--r-- | src/nvim/edit.c | 45 | ||||
-rw-r--r-- | src/nvim/popupmnu.c | 15 | ||||
-rw-r--r-- | src/nvim/popupmnu.h | 1 | ||||
-rw-r--r-- | test/functional/viml/completion_spec.lua | 79 |
7 files changed, 160 insertions, 11 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 6423939b83..89d9e45e0d 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -350,6 +350,7 @@ Name triggered by ~ |SessionLoadPost| after loading a session file |MenuPopup| just before showing the popup menu +|MenuPopupChanged| after popup menu changed, not fired on popup menu hide |CompleteDone| after Insert mode completion is done |User| to be used in combination with ":doautocmd" @@ -843,6 +844,22 @@ MenuPopup Just before showing the popup menu (under the o Operator-pending i Insert c Command line +MenuPopupChanged *MenuPopupChanged* + After each time popup menu changed, not fired + on popup menu hide, use |CompleteDone| for popup + menu hide. + + Sets these |v:event| keys: + completed_item + height + width + row + col + size + scrollbar + + It is not allowed to change the text |textlock|. + *OptionSet* OptionSet After setting an option. The pattern is matched against the long option name. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 3efe651dfe..2610b2683e 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1552,6 +1552,19 @@ v:event Dictionary of event data for the current |autocommand|. Valid operation. regtype Type of register as returned by |getregtype()|. + completed_item Current selected complete item on + |MenuPopupChanged|, Is `{}` when no complete + item selected. + height Height of popup menu on |MenuPopupChanged| + width width of popup menu on |MenuPopupChanged| + row Row count of popup menu on |MenuPopupChanged|, + relative to screen. + col Col count of popup menu on |MenuPopupChanged|, + relative to screen. + size Total number of completion items on + |MenuPopupChanged|. + scrollbar Is |v:true| if popup menu have scrollbar, or + |v:false| if not. *v:exception* *exception-variable* v:exception The value of the exception most recently caught and not diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index cc0ed0f587..345bf67c0e 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -66,6 +66,7 @@ return { 'InsertLeave', -- when leaving Insert mode 'JobActivity', -- when job sent some data 'MenuPopup', -- just before popup menu is displayed + 'MenuPopupChanged', -- after popup menu changed 'OptionSet', -- after setting any option 'QuickFixCmdPost', -- after :make, :grep etc. 'QuickFixCmdPre', -- before :make, :grep etc. diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 6b31406b0c..6f0468dbea 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2658,6 +2658,23 @@ void ins_compl_show_pum(void) pum_selected_item = cur; pum_display(compl_match_array, compl_match_arraysize, cur, array_changed); curwin->w_cursor.col = col; + + if (!has_event(EVENT_MENUPOPUPCHANGED)) { + return; + } + dict_T *dict = get_vim_var_dict(VV_EVENT); + if (cur < 0) { + tv_dict_add_dict(dict, S_LEN("completed_item"), tv_dict_alloc()); + } else { + dict_T *item = ins_compl_dict_alloc(compl_curr_match); + tv_dict_add_dict(dict, S_LEN("completed_item"), item); + } + pum_set_boundings(dict); + tv_dict_set_keys_readonly(dict); + textlock++; + apply_autocmds(EVENT_MENUPOPUPCHANGED, NULL, NULL, false, curbuf); + textlock--; + tv_dict_clear(dict); } #define DICT_FIRST (1) /* use just first element in "dict" */ @@ -4096,31 +4113,37 @@ static void ins_compl_insert(int in_compl_func) else compl_used_match = TRUE; - // Set completed item. + dict_T *dict = ins_compl_dict_alloc(compl_shown_match); + set_vim_var_dict(VV_COMPLETED_ITEM, dict); + if (!in_compl_func) { + compl_curr_match = compl_shown_match; + } +} + +// Convert to complete item dict +static dict_T *ins_compl_dict_alloc(compl_T *match) +{ // { word, abbr, menu, kind, info } dict_T *dict = tv_dict_alloc(); tv_dict_add_str( dict, S_LEN("word"), - (const char *)EMPTY_IF_NULL(compl_shown_match->cp_str)); + (const char *)EMPTY_IF_NULL(match->cp_str)); tv_dict_add_str( dict, S_LEN("abbr"), - (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_ABBR])); + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_ABBR])); tv_dict_add_str( dict, S_LEN("menu"), - (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_MENU])); + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_MENU])); tv_dict_add_str( dict, S_LEN("kind"), - (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_KIND])); + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_KIND])); tv_dict_add_str( dict, S_LEN("info"), - (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_INFO])); + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_INFO])); tv_dict_add_str( dict, S_LEN("user_data"), - (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_USER_DATA])); - set_vim_var_dict(VV_COMPLETED_ITEM, dict); - if (!in_compl_func) { - compl_curr_match = compl_shown_match; - } + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_USER_DATA])); + return dict; } /* diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 499ee11cad..e9b3f04454 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -12,6 +12,7 @@ #include "nvim/vim.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" +#include "nvim/eval/typval.h" #include "nvim/popupmnu.h" #include "nvim/charset.h" #include "nvim/ex_cmds.h" @@ -841,3 +842,17 @@ int pum_get_height(void) { return pum_height; } + +void pum_set_boundings(dict_T *dict) +{ + if (!pum_visible()) { + return; + } + tv_dict_add_nr(dict, S_LEN("height"), pum_height); + tv_dict_add_nr(dict, S_LEN("width"), pum_width); + tv_dict_add_nr(dict, S_LEN("row"), pum_row); + tv_dict_add_nr(dict, S_LEN("col"), pum_col); + tv_dict_add_nr(dict, S_LEN("size"), pum_size); + tv_dict_add_special(dict, S_LEN("scrollbar"), + pum_scrollbar ? kSpecialVarTrue : kSpecialVarFalse); +} diff --git a/src/nvim/popupmnu.h b/src/nvim/popupmnu.h index 42e6ef5653..7956e50a93 100644 --- a/src/nvim/popupmnu.h +++ b/src/nvim/popupmnu.h @@ -1,6 +1,7 @@ #ifndef NVIM_POPUPMNU_H #define NVIM_POPUPMNU_H +#include "nvim/vim.h" #include "nvim/macros.h" #include "nvim/grid_defs.h" #include "nvim/types.h" diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua index cd1b312265..c84b2c1087 100644 --- a/test/functional/viml/completion_spec.lua +++ b/test/functional/viml/completion_spec.lua @@ -1072,4 +1072,83 @@ describe('completion', function() set complete&vim completeopt&vim ]]) end) + + it('MenuPopupChanged autocommand', function() + curbufmeths.set_lines(0, 1, false, { 'foo', 'bar', 'foobar', ''}) + source([[ + set complete=. completeopt=noinsert,noselect,menuone + function! OnPumChange() + let g:event = copy(v:event) + let g:item = get(v:event, 'completed_item', {}) + let g:word = get(g:item, 'word', v:null) + endfunction + autocmd! MenuPopupChanged * :call OnPumChange() + call cursor(4, 1) + ]]) + + feed('Sf<C-N>') + screen:expect([[ + foo | + bar | + foobar | + f^ | + {1:foo }{0: }| + {1:foobar }{0: }| + {0:~ }| + {3:-- Keyword completion (^N^P) }{5:Back at original} | + ]]) + eq({completed_item = {}, width = 15, + height = 2, size = 2, + col = 0, row = 4, scrollbar = false}, + eval('g:event')) + feed('<C-N>') + screen:expect([[ + foo | + bar | + foobar | + foo^ | + {2:foo }{0: }| + {1:foobar }{0: }| + {0:~ }| + {3:-- Keyword completion (^N^P) }{4:match 1 of 2} | + ]]) + eq('foo', eval('g:word')) + feed('<C-N>') + screen:expect([[ + foo | + bar | + foobar | + foobar^ | + {1:foo }{0: }| + {2:foobar }{0: }| + {0:~ }| + {3:-- Keyword completion (^N^P) }{4:match 2 of 2} | + ]]) + eq('foobar', eval('g:word')) + feed('<up>') + screen:expect([[ + foo | + bar | + foobar | + foobar^ | + {2:foo }{0: }| + {1:foobar }{0: }| + {0:~ }| + {3:-- Keyword completion (^N^P) }{4:match 1 of 2} | + ]]) + eq('foo', eval('g:word')) + feed('<down>') + screen:expect([[ + foo | + bar | + foobar | + foobar^ | + {1:foo }{0: }| + {2:foobar }{0: }| + {0:~ }| + {3:-- Keyword completion (^N^P) }{4:match 2 of 2} | + ]]) + eq('foobar', eval('g:word')) + feed('<esc>') + end) end) |