1
0
forked from aniani/vim

patch 8.1.2192: cannot easily fill the info popup asynchronously

Problem:    Cannot easily fill the info popup asynchronously.
Solution:   Add the "popuphidden" value to 'completeopt'. (closes #4924)
This commit is contained in:
Bram Moolenaar 2019-10-20 18:17:57 +02:00
parent 88d3d09e07
commit dca7abe79c
15 changed files with 195 additions and 28 deletions

View File

@ -1,4 +1,4 @@
*insert.txt* For Vim version 8.1. Last change: 2019 Sep 27 *insert.txt* For Vim version 8.1. Last change: 2019 Oct 20
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -1138,6 +1138,27 @@ below the text, and the bottom of the menu otherwise.
After the info popup is created it can be found with |popup_findinfo()| and After the info popup is created it can be found with |popup_findinfo()| and
properties can be changed with |popup_setoptions()|. properties can be changed with |popup_setoptions()|.
*complete-popuphidden*
If the information for the popup is obtained asynchronously, use "popuphidden"
in 'completeopt'. The info popup will then be initally hidden and
|popup_show()| must be called once it has been filled with the info. This can
be done with a |CompleteChanged| autocommand, something like this: >
set completeopt+=popuphidden
au CompleteChanged * call UpdateCompleteInfo()
func UpdateCompleteInfo()
" Cancel any pending info fetch
let item = v:event.completed_item
" Start fetching info for the item then call ShowCompleteInfo(info)
endfunc
func ShowCompleteInfo(info)
let id = popup_findinfo()
if id
call popup_settext(id, 'async info: ' .. a:info)
call popup_show(id)
endif
endfunc
< *complete-item-kind*
The "kind" item uses a single letter to indicate the kind of completion. This The "kind" item uses a single letter to indicate the kind of completion. This
may be used to show the completion differently (different color or icon). may be used to show the completion differently (different color or icon).
Currently these types can be used: Currently these types can be used:

View File

@ -1,4 +1,4 @@
*options.txt* For Vim version 8.1. Last change: 2019 Sep 28 *options.txt* For Vim version 8.1. Last change: 2019 Oct 20
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -1919,6 +1919,13 @@ A jump table for the options with a short description can be found at |Q_op|.
See |'completepopup'| for specifying properties. See |'completepopup'| for specifying properties.
{only works when compiled with the |+textprop| feature} {only works when compiled with the |+textprop| feature}
popuphidden
Just like "popup" but initially hide the popup. Use a
|CompleteChanged| autocommand to fetch the info and call
|popup_show()| once the popup has been filled.
See the example at |complete-popuphidden|.
{only works when compiled with the |+textprop| feature}
noinsert Do not insert any text for a match until the user selects noinsert Do not insert any text for a match until the user selects
a match from the menu. Only works in combination with a match from the menu. Only works in combination with
"menu" or "menuone". No effect if "longest" is present. "menu" or "menuone". No effect if "longest" is present.

View File

@ -4919,13 +4919,14 @@ free_old_sub(void)
#if defined(FEAT_QUICKFIX) || defined(PROTO) #if defined(FEAT_QUICKFIX) || defined(PROTO)
/* /*
* Set up for a tagpreview. * Set up for a tagpreview.
* Makes the preview window the current window.
* Return TRUE when it was created. * Return TRUE when it was created.
*/ */
int int
prepare_tagpreview( prepare_tagpreview(
int undo_sync, // sync undo when leaving the window int undo_sync, // sync undo when leaving the window
int use_previewpopup, // use popup if 'previewpopup' set int use_previewpopup, // use popup if 'previewpopup' set
int use_popup) // use other popup window use_popup_T use_popup) // use other popup window
{ {
win_T *wp; win_T *wp;
@ -4945,11 +4946,16 @@ prepare_tagpreview(
if (wp != NULL) if (wp != NULL)
popup_set_wantpos_cursor(wp, wp->w_minwidth); popup_set_wantpos_cursor(wp, wp->w_minwidth);
} }
else if (use_popup) else if (use_popup != USEPOPUP_NONE)
{ {
wp = popup_find_info_window(); wp = popup_find_info_window();
if (wp != NULL) if (wp != NULL)
{
if (use_popup == USEPOPUP_NORMAL)
popup_show(wp); popup_show(wp);
else
popup_hide(wp);
}
} }
else else
# endif # endif
@ -4966,8 +4972,9 @@ prepare_tagpreview(
* There is no preview window open yet. Create one. * There is no preview window open yet. Create one.
*/ */
# ifdef FEAT_TEXT_PROP # ifdef FEAT_TEXT_PROP
if ((use_previewpopup && *p_pvp != NUL) || use_popup) if ((use_previewpopup && *p_pvp != NUL)
return popup_create_preview_window(use_popup); || use_popup != USEPOPUP_NONE)
return popup_create_preview_window(use_popup != USEPOPUP_NONE);
# endif # endif
if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0) == FAIL) if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0) == FAIL)
return FALSE; return FALSE;

View File

@ -76,7 +76,7 @@ static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax",
NULL}; NULL};
static char *(p_fcl_values[]) = {"all", NULL}; static char *(p_fcl_values[]) = {"all", NULL};
#endif #endif
static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "popup", "noinsert", "noselect", NULL}; static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "popup", "popuphidden", "noinsert", "noselect", NULL};
#ifdef BACKSLASH_IN_FILENAME #ifdef BACKSLASH_IN_FILENAME
static char *(p_csl_values[]) = {"slash", "backslash", NULL}; static char *(p_csl_values[]) = {"slash", "backslash", NULL};
#endif #endif

View File

@ -622,33 +622,36 @@ pum_redraw(void)
} }
#if defined(FEAT_TEXT_PROP) && defined(FEAT_QUICKFIX) #if defined(FEAT_TEXT_PROP) && defined(FEAT_QUICKFIX)
static void /*
pum_position_info_popup(void) * Position the info popup relative to the popup menu item.
*/
void
pum_position_info_popup(win_T *wp)
{ {
int col = pum_col + pum_width + 1; int col = pum_col + pum_width + 1;
int row = pum_row; int row = pum_row;
int botpos = POPPOS_BOTLEFT; int botpos = POPPOS_BOTLEFT;
curwin->w_popup_pos = POPPOS_TOPLEFT; wp->w_popup_pos = POPPOS_TOPLEFT;
if (Columns - col < 20 && Columns - col < pum_col) if (Columns - col < 20 && Columns - col < pum_col)
{ {
col = pum_col - 1; col = pum_col - 1;
curwin->w_popup_pos = POPPOS_TOPRIGHT; wp->w_popup_pos = POPPOS_TOPRIGHT;
botpos = POPPOS_BOTRIGHT; botpos = POPPOS_BOTRIGHT;
curwin->w_maxwidth = pum_col - 1; wp->w_maxwidth = pum_col - 1;
} }
else else
curwin->w_maxwidth = Columns - col + 1; wp->w_maxwidth = Columns - col + 1;
curwin->w_maxwidth -= popup_extra_width(curwin); wp->w_maxwidth -= popup_extra_width(wp);
row -= popup_top_extra(curwin); row -= popup_top_extra(wp);
if (curwin->w_popup_flags & POPF_INFO_MENU) if (wp->w_popup_flags & POPF_INFO_MENU)
{ {
if (pum_row < pum_win_row) if (pum_row < pum_win_row)
{ {
// menu above cursor line, align with bottom // menu above cursor line, align with bottom
row += pum_height; row += pum_height;
curwin->w_popup_pos = botpos; wp->w_popup_pos = botpos;
} }
else else
// menu below cursor line, align with top // menu below cursor line, align with top
@ -658,7 +661,7 @@ pum_position_info_popup(void)
// align with the selected item // align with the selected item
row += pum_selected - pum_first + 1; row += pum_selected - pum_first + 1;
popup_set_wantpos_rowcol(curwin, row, col); popup_set_wantpos_rowcol(wp, row, col);
} }
#endif #endif
@ -756,15 +759,21 @@ pum_set_selected(int n, int repeat UNUSED)
tabpage_T *curtab_save = curtab; tabpage_T *curtab_save = curtab;
int res = OK; int res = OK;
# ifdef FEAT_TEXT_PROP # ifdef FEAT_TEXT_PROP
int use_popup = strstr((char *)p_cot, "popup") != NULL; use_popup_T use_popup;
# else # else
# define use_popup 0 # define use_popup POPUP_NONE
# endif # endif
# ifdef FEAT_TEXT_PROP # ifdef FEAT_TEXT_PROP
has_info = TRUE; has_info = TRUE;
if (strstr((char *)p_cot, "popuphidden") != NULL)
use_popup = USEPOPUP_HIDDEN;
else if (strstr((char *)p_cot, "popup") != NULL)
use_popup = USEPOPUP_NORMAL;
else
use_popup = USEPOPUP_NONE;
# endif # endif
// Open a preview window. 3 lines by default. Prefer // Open a preview window and set "curwin" to it.
// 'previewheight' if set and smaller. // 3 lines by default, prefer 'previewheight' if set and smaller.
g_do_tagpreview = 3; g_do_tagpreview = 3;
if (p_pvh > 0 && p_pvh < g_do_tagpreview) if (p_pvh > 0 && p_pvh < g_do_tagpreview)
g_do_tagpreview = p_pvh; g_do_tagpreview = p_pvh;
@ -838,7 +847,7 @@ pum_set_selected(int n, int repeat UNUSED)
/* Increase the height of the preview window to show the /* Increase the height of the preview window to show the
* text, but no more than 'previewheight' lines. */ * text, but no more than 'previewheight' lines. */
if (repeat == 0 && !use_popup) if (repeat == 0 && use_popup == USEPOPUP_NONE)
{ {
if (lnum > p_pvh) if (lnum > p_pvh)
lnum = p_pvh; lnum = p_pvh;
@ -863,9 +872,9 @@ pum_set_selected(int n, int repeat UNUSED)
curwin->w_cursor.lnum = curwin->w_topline; curwin->w_cursor.lnum = curwin->w_topline;
curwin->w_cursor.col = 0; curwin->w_cursor.col = 0;
# ifdef FEAT_TEXT_PROP # ifdef FEAT_TEXT_PROP
if (use_popup) if (use_popup != USEPOPUP_NONE)
{ {
pum_position_info_popup(); pum_position_info_popup(curwin);
if (win_valid(curwin_save)) if (win_valid(curwin_save))
redraw_win_later(curwin_save, SOME_VALID); redraw_win_later(curwin_save, SOME_VALID);
} }
@ -907,9 +916,16 @@ pum_set_selected(int n, int repeat UNUSED)
if (!resized && win_valid(curwin_save)) if (!resized && win_valid(curwin_save))
{ {
# ifdef FEAT_TEXT_PROP
win_T *wp = curwin;
# endif
++no_u_sync; ++no_u_sync;
win_enter(curwin_save, TRUE); win_enter(curwin_save, TRUE);
--no_u_sync; --no_u_sync;
# ifdef FEAT_TEXT_PROP
if (use_popup == USEPOPUP_HIDDEN && win_valid(wp))
popup_hide(wp);
# endif
} }
/* May need to update the screen again when there are /* May need to update the screen again when there are

View File

@ -2225,7 +2225,7 @@ f_popup_close(typval_T *argvars, typval_T *rettv UNUSED)
popup_close_and_callback(wp, &argvars[1]); popup_close_and_callback(wp, &argvars[1]);
} }
static void void
popup_hide(win_T *wp) popup_hide(win_T *wp)
{ {
if ((wp->w_popup_flags & POPF_HIDDEN) == 0) if ((wp->w_popup_flags & POPF_HIDDEN) == 0)
@ -2272,7 +2272,11 @@ f_popup_show(typval_T *argvars, typval_T *rettv UNUSED)
win_T *wp = find_popup_win(id); win_T *wp = find_popup_win(id);
if (wp != NULL) if (wp != NULL)
{
popup_show(wp); popup_show(wp);
if (wp->w_popup_flags & POPF_INFO)
pum_position_info_popup(wp);
}
} }
/* /*

View File

@ -35,7 +35,7 @@ void global_exe(char_u *cmd);
char_u *get_old_sub(void); char_u *get_old_sub(void);
void set_old_sub(char_u *val); void set_old_sub(char_u *val);
void free_old_sub(void); void free_old_sub(void);
int prepare_tagpreview(int undo_sync, int use_previewpopup, int use_popup); int prepare_tagpreview(int undo_sync, int use_previewpopup, use_popup_T use_popup);
void ex_help(exarg_T *eap); void ex_help(exarg_T *eap);
void ex_helpclose(exarg_T *eap); void ex_helpclose(exarg_T *eap);
char_u *check_help_lang(char_u *arg); char_u *check_help_lang(char_u *arg);

View File

@ -3,6 +3,7 @@ void pum_display(pumitem_T *array, int size, int selected);
void pum_call_update_screen(void); void pum_call_update_screen(void);
int pum_under_menu(int row, int col); int pum_under_menu(int row, int col);
void pum_redraw(void); void pum_redraw(void);
void pum_position_info_popup(win_T *wp);
void pum_undisplay(void); void pum_undisplay(void);
void pum_clear(void); void pum_clear(void);
int pum_visible(void); int pum_visible(void);

View File

@ -26,6 +26,7 @@ void f_popup_dialog(typval_T *argvars, typval_T *rettv);
void f_popup_menu(typval_T *argvars, typval_T *rettv); void f_popup_menu(typval_T *argvars, typval_T *rettv);
void f_popup_notification(typval_T *argvars, typval_T *rettv); void f_popup_notification(typval_T *argvars, typval_T *rettv);
void f_popup_close(typval_T *argvars, typval_T *rettv); void f_popup_close(typval_T *argvars, typval_T *rettv);
void popup_hide(win_T *wp);
void f_popup_hide(typval_T *argvars, typval_T *rettv); void f_popup_hide(typval_T *argvars, typval_T *rettv);
void popup_show(win_T *wp); void popup_show(win_T *wp);
void f_popup_show(typval_T *argvars, typval_T *rettv); void f_popup_show(typval_T *argvars, typval_T *rettv);

View File

@ -0,0 +1,14 @@
|t+0&#ffffff0|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|a|w|o|r|d> @43
|~+0#4040ff13&| @23| +0#0000001#e0e0e08|w|r|d| @4|W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @23| +0#0000001#ffd7ff255|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @23| +0#0000001#ffd7ff255|n|o|a|w|r|d| @1|W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @23| +0#0000001#ffd7ff255|t|h|a|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@26

View File

@ -0,0 +1,14 @@
|t+0&#ffffff0|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|a|n|o|t|h|e|r|w|o|r|d> @37
|~+0#4040ff13&| @23| +0#0000001#ffd7ff255|w|r|d| @4|W| |e|x|t|r|a| |t|e|x|t| | +0&#e0e0e08|i|m@1|e|d|i|a|t|e| |i|n|f|o| |3| | +0#4040ff13#ffffff0@9
|~| @23| +0#0000001#e0e0e08|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @23| +0#0000001#ffd7ff255|n|o|a|w|r|d| @1|W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @23| +0#0000001#ffd7ff255|t|h|a|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |4| +0#0000000&@26

View File

@ -0,0 +1,14 @@
|t+0&#ffffff0|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|e|x|t| |t|n|o|i|n|f|o> @42
|~+0#4040ff13&| @23| +0#0000001#ffd7ff255|w|r|d| @4|W| |e|x|t|r|a| |t|e|x|t| | +0&#e0e0e08|a|s|y|n|c| |i|n|f|o| |4| | +0#4040ff13#ffffff0@13
|~| @23| +0#0000001#ffd7ff255|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @23| +0#0000001#e0e0e08|n|o|a|w|r|d| @1|W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @23| +0#0000001#ffd7ff255|t|h|a|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| | +0#4040ff13#ffffff0@27
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |3| |o|f| |4| +0#0000000&@26

View File

@ -2498,6 +2498,41 @@ func Get_popupmenu_lines()
let id = popup_findinfo() let id = popup_findinfo()
eval id->popup_setoptions(#{highlight: 'InfoPopup'}) eval id->popup_setoptions(#{highlight: 'InfoPopup'})
endfunc endfunc
func InfoHidden()
set completepopup=height:4,border:off,align:menu
set completeopt-=popup completeopt+=popuphidden
au CompleteChanged * call HandleChange()
endfunc
let s:counter = 0
func HandleChange()
let s:counter += 1
let selected = complete_info(['selected']).selected
if selected <= 0
" First time: do nothing, info remains hidden
return
endif
if selected == 1
" Second time: show info right away
let id = popup_findinfo()
if id
call popup_settext(id, 'immediate info ' .. s:counter)
call popup_show(id)
endif
else
" Third time: show info after a short delay
call timer_start(100, 'ShowInfo')
endif
endfunc
func ShowInfo(...)
let id = popup_findinfo()
if id
call popup_settext(id, 'async info ' .. s:counter)
call popup_show(id)
endif
endfunc
END END
return lines return lines
endfunc endfunc
@ -2580,6 +2615,30 @@ func Test_popupmenu_info_align_menu()
call delete('XtestInfoPopupNb') call delete('XtestInfoPopupNb')
endfunc endfunc
func Test_popupmenu_info_hidden()
CheckScreendump
let lines = Get_popupmenu_lines()
call add(lines, 'call InfoHidden()')
call writefile(lines, 'XtestInfoPopupHidden')
let buf = RunVimInTerminal('-S XtestInfoPopupHidden', #{rows: 14})
call term_wait(buf, 50)
call term_sendkeys(buf, "A\<C-X>\<C-U>")
call VerifyScreenDump(buf, 'Test_popupwin_infopopup_hidden_1', {})
call term_sendkeys(buf, "\<C-N>")
call VerifyScreenDump(buf, 'Test_popupwin_infopopup_hidden_2', {})
call term_sendkeys(buf, "\<C-N>")
call VerifyScreenDump(buf, 'Test_popupwin_infopopup_hidden_3', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
call delete('XtestInfoPopupHidden')
endfunc
func Test_popupwin_recycle_bnr() func Test_popupwin_recycle_bnr()
let bufnr = popup_notification('nothing wrong', {})->winbufnr() let bufnr = popup_notification('nothing wrong', {})->winbufnr()
call popup_clear() call popup_clear()

View File

@ -741,6 +741,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 */
/**/
2192,
/**/ /**/
2191, 2191,
/**/ /**/

View File

@ -2112,6 +2112,13 @@ typedef enum {
FLUSH_INPUT // flush typebuf and inchar() input FLUSH_INPUT // flush typebuf and inchar() input
} flush_buffers_T; } flush_buffers_T;
// Argument for prepare_tagpreview()
typedef enum {
USEPOPUP_NONE,
USEPOPUP_NORMAL, // use info popup
USEPOPUP_HIDDEN // use info popup initially hidden
} use_popup_T;
#include "ex_cmds.h" // Ex command defines #include "ex_cmds.h" // Ex command defines
#include "spell.h" // spell checking stuff #include "spell.h" // spell checking stuff