mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
autocmd: add MenuPopupChanged autocmd
Update src/nvim/auevents.lua Co-Authored-By: chemzqm <chemzqm@gmail.com>
This commit is contained in:
parent
7e6fce0698
commit
6c375d71c3
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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,33 +4113,39 @@ static void ins_compl_insert(int in_compl_func)
|
||||
else
|
||||
compl_used_match = TRUE;
|
||||
|
||||
// Set completed item.
|
||||
// { 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));
|
||||
tv_dict_add_str(
|
||||
dict, S_LEN("abbr"),
|
||||
(const char *)EMPTY_IF_NULL(compl_shown_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]));
|
||||
tv_dict_add_str(
|
||||
dict, S_LEN("kind"),
|
||||
(const char *)EMPTY_IF_NULL(compl_shown_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]));
|
||||
tv_dict_add_str(
|
||||
dict, S_LEN("user_data"),
|
||||
(const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_USER_DATA]));
|
||||
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(match->cp_str));
|
||||
tv_dict_add_str(
|
||||
dict, S_LEN("abbr"),
|
||||
(const char *)EMPTY_IF_NULL(match->cp_text[CPT_ABBR]));
|
||||
tv_dict_add_str(
|
||||
dict, S_LEN("menu"),
|
||||
(const char *)EMPTY_IF_NULL(match->cp_text[CPT_MENU]));
|
||||
tv_dict_add_str(
|
||||
dict, S_LEN("kind"),
|
||||
(const char *)EMPTY_IF_NULL(match->cp_text[CPT_KIND]));
|
||||
tv_dict_add_str(
|
||||
dict, S_LEN("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(match->cp_text[CPT_USER_DATA]));
|
||||
return dict;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the next completion in the current direction.
|
||||
* If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user