summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-10-20 18:17:57 +0200
committerBram Moolenaar <Bram@vim.org>2019-10-20 18:17:57 +0200
commitdca7abe79cc4f0933473c3e4bcc75b46cc2c48fd (patch)
tree577964fff695a536bc2d957889e74a2f9f087290
parent88d3d09e07dbe0e3ea450bc554e2aadc451450d2 (diff)
downloadvim-git-dca7abe79cc4f0933473c3e4bcc75b46cc2c48fd.tar.gz
patch 8.1.2192: cannot easily fill the info popup asynchronouslyv8.1.2192
Problem: Cannot easily fill the info popup asynchronously. Solution: Add the "popuphidden" value to 'completeopt'. (closes #4924)
-rw-r--r--runtime/doc/insert.txt23
-rw-r--r--runtime/doc/options.txt9
-rw-r--r--src/ex_cmds.c17
-rw-r--r--src/optionstr.c2
-rw-r--r--src/popupmenu.c52
-rw-r--r--src/popupwin.c6
-rw-r--r--src/proto/ex_cmds.pro2
-rw-r--r--src/proto/popupmenu.pro1
-rw-r--r--src/proto/popupwin.pro1
-rw-r--r--src/testdir/dumps/Test_popupwin_infopopup_hidden_1.dump14
-rw-r--r--src/testdir/dumps/Test_popupwin_infopopup_hidden_2.dump14
-rw-r--r--src/testdir/dumps/Test_popupwin_infopopup_hidden_3.dump14
-rw-r--r--src/testdir/test_popupwin.vim59
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h7
15 files changed, 195 insertions, 28 deletions
diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt
index dfc3541f5..d28bf5998 100644
--- a/runtime/doc/insert.txt
+++ b/runtime/doc/insert.txt
@@ -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
@@ -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
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
may be used to show the completion differently (different color or icon).
Currently these types can be used:
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 8436c8a0d..e62ee8974 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -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
@@ -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.
{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
a match from the menu. Only works in combination with
"menu" or "menuone". No effect if "longest" is present.
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index fc70e2cfe..bcff7ee71 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -4919,13 +4919,14 @@ free_old_sub(void)
#if defined(FEAT_QUICKFIX) || defined(PROTO)
/*
* Set up for a tagpreview.
+ * Makes the preview window the current window.
* Return TRUE when it was created.
*/
int
prepare_tagpreview(
int undo_sync, // sync undo when leaving the window
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;
@@ -4945,11 +4946,16 @@ prepare_tagpreview(
if (wp != NULL)
popup_set_wantpos_cursor(wp, wp->w_minwidth);
}
- else if (use_popup)
+ else if (use_popup != USEPOPUP_NONE)
{
wp = popup_find_info_window();
if (wp != NULL)
- popup_show(wp);
+ {
+ if (use_popup == USEPOPUP_NORMAL)
+ popup_show(wp);
+ else
+ popup_hide(wp);
+ }
}
else
# endif
@@ -4966,8 +4972,9 @@ prepare_tagpreview(
* There is no preview window open yet. Create one.
*/
# ifdef FEAT_TEXT_PROP
- if ((use_previewpopup && *p_pvp != NUL) || use_popup)
- return popup_create_preview_window(use_popup);
+ if ((use_previewpopup && *p_pvp != NUL)
+ || use_popup != USEPOPUP_NONE)
+ return popup_create_preview_window(use_popup != USEPOPUP_NONE);
# endif
if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0) == FAIL)
return FALSE;
diff --git a/src/optionstr.c b/src/optionstr.c
index 7b83aed25..bcc737eb1 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -76,7 +76,7 @@ static char *(p_fdm_values[]) = {"manual", "expr", "marker", "indent", "syntax",
NULL};
static char *(p_fcl_values[]) = {"all", NULL};
#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
static char *(p_csl_values[]) = {"slash", "backslash", NULL};
#endif
diff --git a/src/popupmenu.c b/src/popupmenu.c
index b88c6531c..005adb20b 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -622,33 +622,36 @@ pum_redraw(void)
}
#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 row = pum_row;
int botpos = POPPOS_BOTLEFT;
- curwin->w_popup_pos = POPPOS_TOPLEFT;
+ wp->w_popup_pos = POPPOS_TOPLEFT;
if (Columns - col < 20 && Columns - col < pum_col)
{
col = pum_col - 1;
- curwin->w_popup_pos = POPPOS_TOPRIGHT;
+ wp->w_popup_pos = POPPOS_TOPRIGHT;
botpos = POPPOS_BOTRIGHT;
- curwin->w_maxwidth = pum_col - 1;
+ wp->w_maxwidth = pum_col - 1;
}
else
- curwin->w_maxwidth = Columns - col + 1;
- curwin->w_maxwidth -= popup_extra_width(curwin);
+ wp->w_maxwidth = Columns - col + 1;
+ wp->w_maxwidth -= popup_extra_width(wp);
- row -= popup_top_extra(curwin);
- if (curwin->w_popup_flags & POPF_INFO_MENU)
+ row -= popup_top_extra(wp);
+ if (wp->w_popup_flags & POPF_INFO_MENU)
{
if (pum_row < pum_win_row)
{
// menu above cursor line, align with bottom
row += pum_height;
- curwin->w_popup_pos = botpos;
+ wp->w_popup_pos = botpos;
}
else
// menu below cursor line, align with top
@@ -658,7 +661,7 @@ pum_position_info_popup(void)
// align with the selected item
row += pum_selected - pum_first + 1;
- popup_set_wantpos_rowcol(curwin, row, col);
+ popup_set_wantpos_rowcol(wp, row, col);
}
#endif
@@ -756,15 +759,21 @@ pum_set_selected(int n, int repeat UNUSED)
tabpage_T *curtab_save = curtab;
int res = OK;
# ifdef FEAT_TEXT_PROP
- int use_popup = strstr((char *)p_cot, "popup") != NULL;
+ use_popup_T use_popup;
# else
-# define use_popup 0
+# define use_popup POPUP_NONE
# endif
# ifdef FEAT_TEXT_PROP
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
- // Open a preview window. 3 lines by default. Prefer
- // 'previewheight' if set and smaller.
+ // Open a preview window and set "curwin" to it.
+ // 3 lines by default, prefer 'previewheight' if set and smaller.
g_do_tagpreview = 3;
if (p_pvh > 0 && p_pvh < g_do_tagpreview)
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
* text, but no more than 'previewheight' lines. */
- if (repeat == 0 && !use_popup)
+ if (repeat == 0 && use_popup == USEPOPUP_NONE)
{
if (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.col = 0;
# 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))
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))
{
+# ifdef FEAT_TEXT_PROP
+ win_T *wp = curwin;
+# endif
++no_u_sync;
win_enter(curwin_save, TRUE);
--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
diff --git a/src/popupwin.c b/src/popupwin.c
index f9c127a6c..95435f8fe 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -2225,7 +2225,7 @@ f_popup_close(typval_T *argvars, typval_T *rettv UNUSED)
popup_close_and_callback(wp, &argvars[1]);
}
- static void
+ void
popup_hide(win_T *wp)
{
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);
if (wp != NULL)
+ {
popup_show(wp);
+ if (wp->w_popup_flags & POPF_INFO)
+ pum_position_info_popup(wp);
+ }
}
/*
diff --git a/src/proto/ex_cmds.pro b/src/proto/ex_cmds.pro
index a4d60ba16..3693cf426 100644
--- a/src/proto/ex_cmds.pro
+++ b/src/proto/ex_cmds.pro
@@ -35,7 +35,7 @@ void global_exe(char_u *cmd);
char_u *get_old_sub(void);
void set_old_sub(char_u *val);
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_helpclose(exarg_T *eap);
char_u *check_help_lang(char_u *arg);
diff --git a/src/proto/popupmenu.pro b/src/proto/popupmenu.pro
index f5b6c0c90..c6527b859 100644
--- a/src/proto/popupmenu.pro
+++ b/src/proto/popupmenu.pro
@@ -3,6 +3,7 @@ void pum_display(pumitem_T *array, int size, int selected);
void pum_call_update_screen(void);
int pum_under_menu(int row, int col);
void pum_redraw(void);
+void pum_position_info_popup(win_T *wp);
void pum_undisplay(void);
void pum_clear(void);
int pum_visible(void);
diff --git a/src/proto/popupwin.pro b/src/proto/popupwin.pro
index d6ba3e7f8..4ec4a748d 100644
--- a/src/proto/popupwin.pro
+++ b/src/proto/popupwin.pro
@@ -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_notification(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 popup_show(win_T *wp);
void f_popup_show(typval_T *argvars, typval_T *rettv);
diff --git a/src/testdir/dumps/Test_popupwin_infopopup_hidden_1.dump b/src/testdir/dumps/Test_popupwin_infopopup_hidden_1.dump
new file mode 100644
index 000000000..f56ebc447
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_infopopup_hidden_1.dump
@@ -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
diff --git a/src/testdir/dumps/Test_popupwin_infopopup_hidden_2.dump b/src/testdir/dumps/Test_popupwin_infopopup_hidden_2.dump
new file mode 100644
index 000000000..d834e579b
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_infopopup_hidden_2.dump
@@ -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
diff --git a/src/testdir/dumps/Test_popupwin_infopopup_hidden_3.dump b/src/testdir/dumps/Test_popupwin_infopopup_hidden_3.dump
new file mode 100644
index 000000000..410c39340
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_infopopup_hidden_3.dump
@@ -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
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index e84527bf7..2e2d1df80 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -2498,6 +2498,41 @@ func Get_popupmenu_lines()
let id = popup_findinfo()
eval id->popup_setoptions(#{highlight: 'InfoPopup'})
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
return lines
endfunc
@@ -2580,6 +2615,30 @@ func Test_popupmenu_info_align_menu()
call delete('XtestInfoPopupNb')
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()
let bufnr = popup_notification('nothing wrong', {})->winbufnr()
call popup_clear()
diff --git a/src/version.c b/src/version.c
index c9c0943e1..76b4c1cf5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2192,
+/**/
2191,
/**/
2190,
diff --git a/src/vim.h b/src/vim.h
index e92352c65..43eecf090 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2112,6 +2112,13 @@ typedef enum {
FLUSH_INPUT // flush typebuf and inchar() input
} 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 "spell.h" // spell checking stuff