# HG changeset patch # User Bram Moolenaar # Date 1566135006 -7200 # Node ID c75da1064e33f53635127514cdeff6544b5ceb21 # Parent be00d5dad3f5daf267c3d27c161c6b2ad7df8655 patch 8.1.1880: cannot show extra info for completion in a popup window commit https://github.com/vim/vim/commit/576a4a6ff14da876d7c4418e5f27e926fcfa8d2a Author: Bram Moolenaar Date: Sun Aug 18 15:25:17 2019 +0200 patch 8.1.1880: cannot show extra info for completion in a popup window Problem: Cannot show extra info for completion in a popup window. Solution: Add the "popup" entry in 'completeopt'. diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 8.1. Last change: 2019 Jul 31 +*options.txt* For Vim version 8.1. Last change: 2019 Aug 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1915,6 +1915,11 @@ A jump table for the options with a shor completion in the preview window. Only works in combination with "menu" or "menuone". + popup Show extra information about the currently selected + completion in a popup window. Only works in combination + with "menu" or "menuone". Overrides "preview". + {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. @@ -5650,6 +5655,8 @@ A jump table for the options with a shor |+textprop| or |+quickfix| feature} When not empty a popup window is used for commands that would open a preview window. See |preview-popup|. + Not used for the insert completion info, add "popup" to + 'completeopt' for that. *'previewwindow'* *'nopreviewwindow'* *'pvw'* *'nopvw'* *E590* diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -5131,7 +5131,9 @@ free_old_sub(void) */ int 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_popup) // use other popup window { win_T *wp; @@ -5145,11 +5147,16 @@ prepare_tagpreview( if (!curwin->w_p_pvw) { # ifdef FEAT_TEXT_PROP - if (*p_pvp != NUL) + if (use_previewpopup && *p_pvp != NUL) { wp = popup_find_preview_window(); if (wp != NULL) - popup_set_wantpos(wp, wp->w_minwidth); + popup_set_wantpos_cursor(wp, wp->w_minwidth); + } + else if (use_popup) + { + wp = popup_find_info_window(); + // TODO: set position } else # endif @@ -5166,8 +5173,8 @@ prepare_tagpreview( * There is no preview window open yet. Create one. */ # ifdef FEAT_TEXT_PROP - if (*p_pvp != NUL) - return popup_create_preview_window(); + if ((use_previewpopup && *p_pvp != NUL) || use_popup) + return popup_create_preview_window(use_popup); # endif if (win_split(g_do_tagpreview > 0 ? g_do_tagpreview : 0, 0) == FAIL) return FALSE; diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -5825,7 +5825,7 @@ ex_pclose(exarg_T *eap) } # ifdef FEAT_TEXT_PROP // Also when 'previewpopup' is empty, it might have been cleared. - popup_close_preview(); + popup_close_preview(FALSE); # endif } #endif @@ -8614,7 +8614,7 @@ ex_pedit(exarg_T *eap) // Open the preview window or popup and make it the current window. g_do_tagpreview = p_pvh; - prepare_tagpreview(TRUE); + prepare_tagpreview(TRUE, TRUE, FALSE); // Edit the file. do_exedit(eap, NULL); diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -3247,7 +3247,7 @@ static char *(p_fdm_values[]) = {"manual static char *(p_fcl_values[]) = {"all", NULL}; #endif #ifdef FEAT_INS_EXPAND -static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "noinsert", "noselect", NULL}; +static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "popup", "noinsert", "noselect", NULL}; # ifdef BACKSLASH_IN_FILENAME static char *(p_csl_values[]) = {"slash", "backslash", NULL}; # endif diff --git a/src/popupmnu.c b/src/popupmnu.c --- a/src/popupmnu.c +++ b/src/popupmnu.c @@ -638,6 +638,9 @@ pum_set_selected(int n, int repeat) { int resized = FALSE; int context = pum_height / 2; +#ifdef FEAT_TEXT_PROP + int has_info = FALSE; +#endif pum_selected = n; @@ -690,11 +693,14 @@ pum_set_selected(int n, int repeat) pum_first = pum_selected + context - pum_height + 1; } } + // adjust for the number of lines displayed + if (pum_first > pum_size - pum_height) + pum_first = pum_size - pum_height; #if defined(FEAT_QUICKFIX) /* * Show extra info in the preview window if there is something and - * 'completeopt' contains "preview". + * 'completeopt' contains "preview" or "popup". * Skip this when tried twice already. * Skip this also when there is not much room. * NOTE: Be very careful not to sync undo! @@ -707,43 +713,71 @@ pum_set_selected(int n, int repeat) win_T *curwin_save = curwin; tabpage_T *curtab_save = curtab; int res = OK; +# ifdef FEAT_TEXT_PROP + int use_popup = strstr((char *)p_cot, "popup") != NULL; +# else +# define use_popup 0 +# endif + has_info = TRUE; - /* Open a preview window. 3 lines by default. Prefer - * 'previewheight' if set and smaller. */ + // Open a preview window. 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; ++RedrawingDisabled; - /* Prevent undo sync here, if an autocommand syncs undo weird - * things can happen to the undo tree. */ + // Prevent undo sync here, if an autocommand syncs undo weird + // things can happen to the undo tree. ++no_u_sync; - resized = prepare_tagpreview(FALSE); + resized = prepare_tagpreview(FALSE, FALSE, use_popup); --no_u_sync; --RedrawingDisabled; g_do_tagpreview = 0; - if (curwin->w_p_pvw) + if (curwin->w_p_pvw +# ifdef FEAT_TEXT_PROP + || (curwin->w_popup_flags & POPF_INFO) +# endif + ) { +# ifdef FEAT_TEXT_PROP + if (use_popup) + { + int col = pum_col + pum_width + 1; + + if (Columns - col < 20 && Columns - col < pum_col) + { + col = pum_col - 1; + curwin->w_popup_pos = POPPOS_TOPRIGHT; + curwin->w_maxwidth = pum_col - 1; + } + else + curwin->w_maxwidth = Columns - col + 1; + curwin->w_maxwidth -= popup_extra_width(curwin); + popup_set_wantpos_rowcol(curwin, + pum_row + pum_selected - pum_first, col); + } +# endif if (!resized && curbuf->b_nwindows == 1 && curbuf->b_fname == NULL && bt_nofile(curbuf) && curbuf->b_p_bh[0] == 'w') { - /* Already a "wipeout" buffer, make it empty. */ + // Already a "wipeout" buffer, make it empty. while (!BUFEMPTY()) ml_delete((linenr_T)1, FALSE); } else { - /* Don't want to sync undo in the current buffer. */ + // Don't want to sync undo in the current buffer. ++no_u_sync; res = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, 0, NULL); --no_u_sync; if (res == OK) { - /* Edit a new, empty buffer. Set options for a "wipeout" - * buffer. */ + // Edit a new, empty buffer. Set options for a "wipeout" + // buffer. set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL); set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL); @@ -774,10 +808,12 @@ pum_set_selected(int n, int repeat) p = e + 1; } } + // delete the empty last line + ml_delete(curbuf->b_ml.ml_line_count, FALSE); /* Increase the height of the preview window to show the * text, but no more than 'previewheight' lines. */ - if (repeat == 0) + if (repeat == 0 && !use_popup) { if (lnum > p_pvh) lnum = p_pvh; @@ -792,6 +828,8 @@ pum_set_selected(int n, int repeat) curbuf->b_p_ma = FALSE; curwin->w_cursor.lnum = 1; curwin->w_cursor.col = 0; + if (use_popup && win_valid(curwin_save)) + redraw_win_later(curwin_save, SOME_VALID); if ((curwin != curwin_save && win_valid(curwin_save)) || (curtab != curtab_save @@ -852,6 +890,11 @@ pum_set_selected(int n, int repeat) } #endif } +# ifdef FEAT_TEXT_PROP + if (!has_info) + // close any popup info window + popup_close_preview(TRUE); +# endif if (!resized) pum_redraw(); @@ -869,6 +912,10 @@ pum_undisplay(void) redraw_all_later(NOT_VALID); redraw_tabline = TRUE; status_redraw_all(); +#ifdef FEAT_TEXT_PROP + // close any popup info window + popup_close_preview(TRUE); +#endif } /* diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -951,8 +951,8 @@ popup_top_extra(win_T *wp) popup_height(win_T *wp) { return wp->w_height - + popup_top_extra(wp) - + wp->w_popup_padding[2] + wp->w_popup_border[2]; + + popup_top_extra(wp) + + wp->w_popup_padding[2] + wp->w_popup_border[2]; } /* @@ -965,10 +965,19 @@ popup_width(win_T *wp) // w_leftcol is how many columns of the core are left of the screen // w_popup_rightoff is how many columns of the core are right of the screen return wp->w_width + wp->w_leftcol - + wp->w_popup_padding[3] + wp->w_popup_border[3] - + wp->w_popup_padding[1] + wp->w_popup_border[1] - + wp->w_has_scrollbar - + wp->w_popup_rightoff; + + popup_extra_width(wp) + + wp->w_popup_rightoff; +} + +/* + * Return the extra width of popup window "wp": border, padding and scrollbar. + */ + int +popup_extra_width(win_T *wp) +{ + return wp->w_popup_padding[3] + wp->w_popup_border[3] + + wp->w_popup_padding[1] + wp->w_popup_border[1] + + wp->w_has_scrollbar; } /* @@ -1230,7 +1239,8 @@ typedef enum TYPE_NOTIFICATION, TYPE_DIALOG, TYPE_MENU, - TYPE_PREVIEW + TYPE_PREVIEW, // preview window + TYPE_INFO // popup menu info } create_type_T; /* @@ -1330,7 +1340,7 @@ parse_previewpopup(win_T *wp) * Keep at least "width" columns from the right of the screen. */ void -popup_set_wantpos(win_T *wp, int width) +popup_set_wantpos_cursor(win_T *wp, int width) { setcursor_mayforce(TRUE); wp->w_wantline = curwin->w_winrow + curwin->w_wrow; @@ -1351,10 +1361,37 @@ popup_set_wantpos(win_T *wp, int width) } /* + * Set w_wantline and w_wantcol for the a given screen position. + * Caller must take care of running into the window border. + */ + void +popup_set_wantpos_rowcol(win_T *wp, int row, int col) +{ + wp->w_wantline = row; + wp->w_wantcol = col; + popup_adjust_position(wp); +} + +/* + * Add a border and lef&right padding. + */ + static void +add_border_left_right_padding(win_T *wp) +{ + int i; + + for (i = 0; i < 4; ++i) + { + wp->w_popup_border[i] = 1; + wp->w_popup_padding[i] = (i & 1) ? 1 : 0; + } +} + +/* * popup_create({text}, {options}) * popup_atcursor({text}, {options}) * etc. - * When creating a preview window popup "argvars" and "rettv" are NULL. + * When creating a preview or info popup "argvars" and "rettv" are NULL. */ static win_T * popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) @@ -1495,7 +1532,7 @@ popup_create(typval_T *argvars, typval_T } if (type == TYPE_ATCURSOR) { - popup_set_wantpos(wp, 0); + popup_set_wantpos_cursor(wp, 0); set_moved_values(wp); set_moved_columns(wp, FIND_STRING); } @@ -1571,11 +1608,7 @@ popup_create(typval_T *argvars, typval_T wp->w_zindex = POPUPWIN_DIALOG_ZINDEX; wp->w_popup_flags |= POPF_DRAG; wp->w_popup_flags &= ~POPF_MAPPING; - for (i = 0; i < 4; ++i) - { - wp->w_popup_border[i] = 1; - wp->w_popup_padding[i] = (i & 1) ? 1 : 0; - } + add_border_left_right_padding(wp); } if (type == TYPE_MENU) @@ -1600,7 +1633,14 @@ popup_create(typval_T *argvars, typval_T for (i = 0; i < 4; ++i) wp->w_popup_border[i] = 1; parse_previewpopup(wp); - popup_set_wantpos(wp, wp->w_minwidth); + popup_set_wantpos_cursor(wp, wp->w_minwidth); + } + if (type == TYPE_INFO) + { + wp->w_popup_pos = POPPOS_TOPLEFT; + wp->w_popup_flags |= POPF_DRAG | POPF_RESIZE; + wp->w_popup_close = POPCLOSE_BUTTON; + add_border_left_right_padding(wp); } for (i = 0; i < 4; ++i) @@ -3171,6 +3211,28 @@ popup_find_preview_window(void) return NULL; } + int +popup_is_popup(win_T *wp) +{ + return wp->w_popup_flags != 0; +} + +/* + * Find an existing popup used as the info window, in the current tab page. + * Return NULL if not found. + */ + win_T * +popup_find_info_window(void) +{ + win_T *wp; + + // info window popup is always local to tab page. + for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next) + if (wp->w_popup_flags & POPF_INFO) + return wp; + return NULL; +} + void f_popup_getpreview(typval_T *argvars UNUSED, typval_T *rettv) { @@ -3179,26 +3241,23 @@ f_popup_getpreview(typval_T *argvars UNU rettv->vval.v_number = wp == NULL ? 0 : wp->w_id; } - int -popup_is_popup(win_T *wp) -{ - return wp->w_popup_flags != 0; -} - /* - * Create a popup to be used as the preview window. + * Create a popup to be used as the preview or info window. * NOTE: this makes the popup the current window, so that the file can be * edited. However, it must not remain to be the current window, the caller * must make sure of that. */ int -popup_create_preview_window(void) +popup_create_preview_window(int info) { - win_T *wp = popup_create(NULL, NULL, TYPE_PREVIEW); + win_T *wp = popup_create(NULL, NULL, info ? TYPE_INFO : TYPE_PREVIEW); if (wp == NULL) return FAIL; - wp->w_p_pvw = TRUE; + if (info) + wp->w_popup_flags |= POPF_INFO; + else + wp->w_p_pvw = TRUE; // Set the width to a reasonable value, so that w_topline can be computed. if (wp->w_minwidth > 0) @@ -3216,9 +3275,9 @@ popup_create_preview_window(void) } void -popup_close_preview() +popup_close_preview(int info) { - win_T *wp = popup_find_preview_window(); + win_T *wp = info ? popup_find_info_window() : popup_find_preview_window(); if (wp != NULL) { diff --git a/src/proto/ex_cmds.pro b/src/proto/ex_cmds.pro --- a/src/proto/ex_cmds.pro +++ b/src/proto/ex_cmds.pro @@ -37,7 +37,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 prepare_tagpreview(int undo_sync, int use_previewpopup, int 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/popupwin.pro b/src/proto/popupwin.pro --- a/src/proto/popupwin.pro +++ b/src/proto/popupwin.pro @@ -8,9 +8,11 @@ int popup_is_in_scrollbar(win_T *wp, int void popup_handle_scrollbar_click(win_T *wp, int row, int col); int popup_height(win_T *wp); int popup_width(win_T *wp); +int popup_extra_width(win_T *wp); void popup_adjust_position(win_T *wp); int parse_previewpopup(win_T *wp); -void popup_set_wantpos(win_T *wp, int width); +void popup_set_wantpos_cursor(win_T *wp, int width); +void popup_set_wantpos_rowcol(win_T *wp, int row, int col); void f_popup_clear(typval_T *argvars, typval_T *rettv); void f_popup_create(typval_T *argvars, typval_T *rettv); void f_popup_atcursor(typval_T *argvars, typval_T *rettv); @@ -44,10 +46,11 @@ void may_update_popup_mask(int type); void update_popups(void (*win_update)(win_T *wp)); int set_ref_in_popups(int copyID); win_T *popup_find_preview_window(void); +int popup_is_popup(win_T *wp); +win_T *popup_find_info_window(void); void f_popup_getpreview(typval_T *argvars, typval_T *rettv); -int popup_is_popup(win_T *wp); -int popup_create_preview_window(void); -void popup_close_preview(void); +int popup_create_preview_window(int info); +void popup_close_preview(int info); void popup_set_title(win_T *wp); void popup_update_preview_title(void); /* vim: set ft=c : */ diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -5578,7 +5578,7 @@ search_line: if (g_do_tagpreview != 0) { curwin_save = curwin; - prepare_tagpreview(TRUE); + prepare_tagpreview(TRUE, TRUE, FALSE); } #endif if (action == ACTION_SPLIT) diff --git a/src/tag.c b/src/tag.c --- a/src/tag.c +++ b/src/tag.c @@ -3439,7 +3439,7 @@ jumpto_tag( * Make the preview window the current window. * Open a preview window when needed. */ - prepare_tagpreview(TRUE); + prepare_tagpreview(TRUE, TRUE, FALSE); } } diff --git a/src/testdir/dumps/Test_popupwin_infopopup_1.dump b/src/testdir/dumps/Test_popupwin_infopopup_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_infopopup_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> @15|╔+0#0000001#ffd7ff255|═@15|X| +0#0000000#ffffff0@9 +|~+0#4040ff13&| @23| +0#0000001#e0e0e08|w|r|d| @4|W| |e|x|t|r|a| |t|e|x|t| |║+0&#ffd7ff255| |w|o|r|d|s| |a|r|e| |c|o@1|l| |║| +0#4040ff13#ffffff0@9 +|~| @23| +0#0000001#ffd7ff255|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| |╚|═@15|⇲| +0#4040ff13#ffffff0@9 +|~| @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_2.dump b/src/testdir/dumps/Test_popupwin_infopopup_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_infopopup_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| |╔|═@25|X +|~+0#4040ff13#ffffff0| @23| +0#0000001#e0e0e08|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| |║+0&#ffd7ff255| |o|t|h|e|r| |w|o|r|d|s| |a|r|e| @9|║ +|~+0#4040ff13#ffffff0| @23| +0#0000001#ffd7ff255|n|o|a|w|r|d| @1|W| |e|x|t|r|a| |t|e|x|t| |║| |c|o@1|l|e|r| |t|h|a|n| |t|h|i|s| |a|n|d| |s|o|m| |║ +|~+0#4040ff13#ffffff0| @23| +0#0000001#ffd7ff255|t|h|a|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| |║| |e| |m|o|r|e| |t|e|x|t| @13|║ +|~+0#4040ff13#ffffff0| @45|║+0#0000001#ffd7ff255| |t|o| |m|a|k|e| |w|r|a|p| @12|║ +|~+0#4040ff13#ffffff0| @45|╚+0#0000001#ffd7ff255|═@25|⇲ +|~+0#4040ff13#ffffff0| @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_3.dump b/src/testdir/dumps/Test_popupwin_infopopup_3.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_infopopup_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#4040ff13#ffffff0@27 +|~| @23| +0#0000001#ffd7ff255|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| |╔|═@14|X| +0#4040ff13#ffffff0@10 +|~| @23| +0#0000001#e0e0e08|n|o|a|w|r|d| @1|W| |e|x|t|r|a| |t|e|x|t| |║+0&#ffd7ff255| |n|o| |w|o|r|d|s| |h|e|r|e| |║| +0#4040ff13#ffffff0@10 +|~| @23| +0#0000001#ffd7ff255|t|h|a|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| |╚|═@14|⇲| +0#4040ff13#ffffff0@10 +|~| @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/dumps/Test_popupwin_infopopup_4.dump b/src/testdir/dumps/Test_popupwin_infopopup_4.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_infopopup_4.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|e|x|t| |t|e|x|t| > @39 +|~+0#4040ff13&| @23| +0#0000001#ffd7ff255|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|)| |B+0#e000002&|a|c|k| |a|t| |o|r|i|g|i|n|a|l| +0#0000000&@22 diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -2193,4 +2193,76 @@ func Test_previewpopup() call delete('Xheader.h') endfunc +func Test_popupmenu_info() + let lines =<< trim END + set completeopt+=preview,popup + set completefunc=CompleteFuncDict + + func CompleteFuncDict(findstart, base) + if a:findstart + if col('.') > 10 + return col('.') - 10 + endif + return 0 + endif + + return { + \ 'words': [ + \ { + \ 'word': 'aword', + \ 'abbr': 'wrd', + \ 'menu': 'extra text', + \ 'info': 'words are cool', + \ 'kind': 'W', + \ 'user_data': 'test' + \ }, + \ { + \ 'word': 'anotherword', + \ 'abbr': 'anotwrd', + \ 'menu': 'extra text', + \ 'info': "other words are\ncooler than this and some more text\nto make wrap", + \ 'kind': 'W', + \ 'user_data': 'notest' + \ }, + \ { + \ 'word': 'noinfo', + \ 'abbr': 'noawrd', + \ 'menu': 'extra text', + \ 'info': 'no words here', + \ 'kind': 'W', + \ 'user_data': 'notest' + \ }, + \ { + \ 'word': 'thatword', + \ 'abbr': 'thatwrd', + \ 'menu': 'extra text', + \ 'info': 'that word is cool', + \ 'kind': 'W', + \ 'user_data': 'notest' + \ }, + \ ] + \ } + endfunc + call setline(1, 'text text text text text text text ') + END + call writefile(lines, 'XtestInfoPopup') + let buf = RunVimInTerminal('-S XtestInfoPopup', #{rows: 14}) + call term_wait(buf, 50) + + call term_sendkeys(buf, "A\\") + call VerifyScreenDump(buf, 'Test_popupwin_infopopup_1', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_popupwin_infopopup_2', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_popupwin_infopopup_3', {}) + + call term_sendkeys(buf, "\\") + call VerifyScreenDump(buf, 'Test_popupwin_infopopup_4', {}) + + call StopVimInTerminal(buf) + call delete('XtestInfoPopup') +endfunc + " vim: shiftwidth=2 sts=2 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1880, +/**/ 1879, /**/ 1878, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -622,6 +622,7 @@ extern int (*dyn_libintl_wputenv)(const #define POPF_DRAG 0x20 // popup can be moved by dragging #define POPF_RESIZE 0x40 // popup can be resized by dragging #define POPF_MAPPING 0x80 // mapping keys +#define POPF_INFO 0x100 // used for info of popup menu #ifdef FEAT_TEXT_PROP # define WIN_IS_POPUP(wp) ((wp)->w_popup_flags != 0)