mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	Merge pull request #9607 from bfredl/wildpum
UI: deprecate redundant ext_wildmenu events and allow TUI popupmenu for cmdline
This commit is contained in:
		| @@ -6599,12 +6599,13 @@ A jump table for the options with a short description can be found at |Q_op|. | ||||
| 'wildoptions' 'wop'	string	(default "") | ||||
| 			global | ||||
| 	A list of words that change how command line completion is done. | ||||
| 	Currently only one word is allowed: | ||||
| 	  tagfile	When using CTRL-D to list matching tags, the kind of | ||||
| 			tag and the file of the tag is listed.	Only one match | ||||
| 			is displayed per line.  Often used tag kinds are: | ||||
| 				d	#define | ||||
| 				f	function | ||||
| 	  pum		Display the completion matches using the popupmenu | ||||
| 			in the same style as the |ins-completion-menu|. | ||||
| 	Also see |cmdline-completion|. | ||||
|  | ||||
| 						*'winaltkeys'* *'wak'* | ||||
|   | ||||
| @@ -31,7 +31,7 @@ a dictionary with these (optional) keys: | ||||
| 	`ext_popupmenu`		Externalize the popupmenu. |ui-popupmenu| | ||||
| 	`ext_tabline`		Externalize the tabline. |ui-tabline| | ||||
| 	`ext_cmdline`		Externalize the cmdline. |ui-cmdline| | ||||
| 	`ext_wildmenu`		Externalize the wildmenu. |ui-wildmenu| | ||||
| 	`ext_wildmenu`		Externalize the wildmenu (deprecated). |ui-wildmenu| | ||||
| 	`ext_messages`		Externalize messages. |ui-messages| | ||||
| 	`ext_linegrid`		Use new revision of the grid events. |ui-linegrid| | ||||
| 	`ext_multigrid`		Use per-window grid based events. |ui-multigrid| | ||||
| @@ -554,7 +554,7 @@ See |nvim_input_mouse| for sending mouse events to Nvim. | ||||
| ============================================================================== | ||||
| Popupmenu Events						 *ui-popupmenu* | ||||
|  | ||||
| Only sent if `ext_popupmenu` option is set in |ui-options| | ||||
| Only sent if `ext_popupmenu` option is set in |ui-options|. | ||||
|  | ||||
| ["popupmenu_show", items, selected, row, col, grid] | ||||
| 	Show |popupmenu-completion|. `items` is an array of completion items | ||||
| @@ -564,7 +564,9 @@ Only sent if `ext_popupmenu` option is set in |ui-options| | ||||
| 	index into the array of items (-1 if no item is selected). `row` and | ||||
| 	`col` give the anchor position, where the first character of the | ||||
| 	completed word will be. When |ui-multigrid| is used, `grid` is the | ||||
| 	grid for the anchor position. | ||||
| 	grid for the anchor position. When `ext_cmdline` is active, `grid` is | ||||
| 	set to -1 to indicate the popupmenu should be anchored to the external | ||||
| 	cmdline. Then `col` will be a byte position in the cmdline text. | ||||
|  | ||||
| ["popupmenu_select", selected] | ||||
| 	Select an item in the current popupmenu. `selected` is a zero-based | ||||
| @@ -588,7 +590,10 @@ Only sent if `ext_tabline` option is set in |ui-options| | ||||
| ============================================================================== | ||||
| Cmdline Events							   *ui-cmdline* | ||||
|  | ||||
| Only sent if `ext_cmdline` option is set in |ui-options|. | ||||
| Only sent if `ext_cmdline` option is set in |ui-options|. To handle | ||||
| command-line completion (wildmenu), use |ui-popupmenu| events activated by | ||||
| |ext_popupmenu| option. (The `ext_wildmenu` option only exists for backwards | ||||
| compatibility). | ||||
|  | ||||
| ["cmdline_show", content, pos, firstc, prompt, indent, level] | ||||
|         content: List of [attrs, string] | ||||
| @@ -648,6 +653,11 @@ Wildmenu Events							   *ui-wildmenu* | ||||
|  | ||||
| Only sent if `ext_wildmenu` option is set in |ui-options| | ||||
|  | ||||
| Deprecated. When `ext_cmdline` and `ext_popupmenu` are both set, | ||||
| |ui-popupmenu| events will be used for command-line completion. But if | ||||
| `ext_wildmenu` is also set, these events are still used for backwards | ||||
| compatibility. New clients should use `ext_popupmenu` instead. | ||||
|  | ||||
| ["wildmenu_show", items] | ||||
| 	Activate the wildmenu (command-line completion). `items` is an array | ||||
| 	with the completion items. | ||||
|   | ||||
| @@ -195,6 +195,7 @@ Options: | ||||
|   'scrollback' | ||||
|   'statusline' supports unlimited alignment sections | ||||
|   'tabline' %@Func@foo%X can call any function on mouse-click | ||||
|   'wildoptions' `pum` flag to use popupmenu for wildmode completion | ||||
|   'winhighlight' window-local highlights | ||||
|  | ||||
| Variables: | ||||
|   | ||||
| @@ -34,6 +34,7 @@ typedef struct { | ||||
|  | ||||
|   // Position of legacy cursor, used both for drawing and visible user cursor. | ||||
|   Integer client_row, client_col; | ||||
|   bool wildmenu_active; | ||||
| } UIData; | ||||
|  | ||||
| static PMap(uint64_t) *connected_uis = NULL; | ||||
| @@ -146,6 +147,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, | ||||
|   data->buffer = (Array)ARRAY_DICT_INIT; | ||||
|   data->hl_id = 0; | ||||
|   data->client_col = -1; | ||||
|   data->wildmenu_active = false; | ||||
|   ui->data = data; | ||||
|  | ||||
|   pmap_put(uint64_t)(connected_uis, channel_id, ui); | ||||
| @@ -586,6 +588,7 @@ static Array translate_firstarg(UI *ui, Array args) | ||||
|  | ||||
| static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) | ||||
| { | ||||
|   UIData *data = ui->data; | ||||
|   if (!ui->ui_ext[kUILinegrid]) { | ||||
|     // the representation of highlights in cmdline changed, translate back | ||||
|     // never consumes args | ||||
| @@ -611,6 +614,39 @@ static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Back-compat: translate popupmenu_xx to legacy wildmenu_xx. | ||||
|   if (ui->ui_ext[kUIWildmenu]) { | ||||
|     if (strequal(name, "popupmenu_show")) { | ||||
|       data->wildmenu_active = (args.items[4].data.integer == -1) | ||||
|                             || !ui->ui_ext[kUIPopupmenu]; | ||||
|       if (data->wildmenu_active) { | ||||
|         Array new_args = ARRAY_DICT_INIT; | ||||
|         Array items = args.items[0].data.array; | ||||
|         Array new_items = ARRAY_DICT_INIT; | ||||
|         for (size_t i = 0; i < items.size; i++) { | ||||
|           ADD(new_items, copy_object(items.items[i].data.array.items[0])); | ||||
|         } | ||||
|         ADD(new_args, ARRAY_OBJ(new_items)); | ||||
|         push_call(ui, "wildmenu_show", new_args); | ||||
|         if (args.items[1].data.integer != -1) { | ||||
|           Array new_args2 = ARRAY_DICT_INIT; | ||||
|           ADD(new_args2, args.items[1]); | ||||
|           push_call(ui, "wildmenu_select", new_args); | ||||
|         } | ||||
|         return; | ||||
|       } | ||||
|     } else if (strequal(name, "popupmenu_select")) { | ||||
|       if (data->wildmenu_active) { | ||||
|         name = "wildmenu_select"; | ||||
|       } | ||||
|     } else if (strequal(name, "popupmenu_hide")) { | ||||
|       if (data->wildmenu_active) { | ||||
|         name = "wildmenu_hide"; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
|   Array my_args = ARRAY_DICT_INIT; | ||||
|   // Objects are currently single-reference | ||||
|   // make a copy, but only if necessary | ||||
|   | ||||
| @@ -143,11 +143,11 @@ void cmdline_block_hide(void) | ||||
|   FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; | ||||
|  | ||||
| void wildmenu_show(Array items) | ||||
|   FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; | ||||
|   FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL; | ||||
| void wildmenu_select(Integer selected) | ||||
|   FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; | ||||
|   FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL; | ||||
| void wildmenu_hide(void) | ||||
|   FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; | ||||
|   FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL; | ||||
|  | ||||
| void msg_show(String kind, Array content, Boolean replace_last) | ||||
|   FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; | ||||
|   | ||||
| @@ -2656,7 +2656,7 @@ void ins_compl_show_pum(void) | ||||
|   col = curwin->w_cursor.col; | ||||
|   curwin->w_cursor.col = compl_col; | ||||
|   pum_selected_item = cur; | ||||
|   pum_display(compl_match_array, compl_match_arraysize, cur, array_changed); | ||||
|   pum_display(compl_match_array, compl_match_arraysize, cur, array_changed, 0); | ||||
|   curwin->w_cursor.col = col; | ||||
|  | ||||
|   if (!has_event(EVENT_MENUPOPUPCHANGED)) { | ||||
|   | ||||
| @@ -3235,7 +3235,7 @@ const char * set_one_cmd_context( | ||||
|   case CMD_tjump: | ||||
|   case CMD_stjump: | ||||
|   case CMD_ptjump: | ||||
|     if (*p_wop != NUL) { | ||||
|     if (wop_flags & WOP_TAGFILE) { | ||||
|       xp->xp_context = EXPAND_TAGS_LISTFILES; | ||||
|     } else { | ||||
|       xp->xp_context = EXPAND_TAGS; | ||||
|   | ||||
| @@ -214,6 +214,15 @@ static int hislen = 0;                  /* actual length of history tables */ | ||||
| /// user interrupting highlight function to not interrupt command-line. | ||||
| static bool getln_interrupted_highlight = false; | ||||
|  | ||||
| // "compl_match_array" points the currently displayed list of entries in the | ||||
| // popup menu.  It is NULL when there is no popup menu. | ||||
| static pumitem_T *compl_match_array = NULL; | ||||
| static int compl_match_arraysize; | ||||
| // First column in cmdline of the matched item for completion. | ||||
| static int compl_startcol; | ||||
| static int compl_selected; | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifdef INCLUDE_GENERATED_DECLARATIONS | ||||
| # include "ex_getln.c.generated.h" | ||||
| @@ -600,6 +609,13 @@ static int command_line_execute(VimState *state, int key) | ||||
|     } else if (s->c == K_RIGHT) { | ||||
|       s->c = Ctrl_N; | ||||
|     } | ||||
|     if (compl_match_array) { | ||||
|       if (s->c == K_UP) { | ||||
|         s->c = Ctrl_P; | ||||
|       } else if (s->c == K_DOWN) { | ||||
|         s->c = Ctrl_N; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Hitting CR after "emenu Name.": complete submenu | ||||
| @@ -615,8 +631,10 @@ static int command_line_execute(VimState *state, int key) | ||||
|   if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm | ||||
|       && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A | ||||
|       && s->c != Ctrl_L) { | ||||
|     if (ui_has(kUIWildmenu)) { | ||||
|       ui_call_wildmenu_hide(); | ||||
|     if (compl_match_array) { | ||||
|       pum_undisplay(true); | ||||
|       xfree(compl_match_array); | ||||
|       compl_match_array = NULL; | ||||
|     } | ||||
|     if (s->xpc.xp_numfiles != -1) { | ||||
|       (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE); | ||||
| @@ -3746,14 +3764,13 @@ ExpandOne ( | ||||
|         else | ||||
|           findex = -1; | ||||
|       } | ||||
|       if (p_wmnu) { | ||||
|         if (ui_has(kUIWildmenu)) { | ||||
|           ui_call_wildmenu_select(findex); | ||||
|         } else { | ||||
|       if (compl_match_array) { | ||||
|         compl_selected = findex; | ||||
|         cmdline_pum_display(false); | ||||
|       } else if (p_wmnu) { | ||||
|         win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files, | ||||
|                                 findex, cmd_showtail); | ||||
|       } | ||||
|       } | ||||
|       if (findex == -1) { | ||||
|         return vim_strsave(orig_save); | ||||
|       } | ||||
| @@ -4069,6 +4086,12 @@ void tilde_replace(char_u *orig_pat, int num_files, char_u **files) | ||||
|   } | ||||
| } | ||||
|  | ||||
| void cmdline_pum_display(bool changed_array) | ||||
| { | ||||
|   pum_display(compl_match_array, compl_match_arraysize, compl_selected, | ||||
|               changed_array, compl_startcol); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Show all matches for completion on the command line. | ||||
|  * Returns EXPAND_NOTHING when the character that triggered expansion should | ||||
| @@ -4102,12 +4125,28 @@ static int showmatches(expand_T *xp, int wildmenu) | ||||
|     showtail = cmd_showtail; | ||||
|   } | ||||
|  | ||||
|   if (ui_has(kUIWildmenu)) { | ||||
|     Array args = ARRAY_DICT_INIT; | ||||
|   bool compl_use_pum = (ui_has(kUICmdline) | ||||
|                         ? ui_has(kUIPopupmenu) | ||||
|                         : wildmenu && (wop_flags & WOP_PUM)) | ||||
|                        || ui_has(kUIWildmenu); | ||||
|  | ||||
|   if (compl_use_pum) { | ||||
|     compl_match_arraysize = num_files; | ||||
|     compl_match_array = xcalloc(compl_match_arraysize, sizeof(pumitem_T)); | ||||
|     for (i = 0; i < num_files; i++) { | ||||
|       ADD(args, STRING_OBJ(cstr_to_string((char *)files_found[i]))); | ||||
|       compl_match_array[i].pum_text = L_SHOWFILE(i); | ||||
|     } | ||||
|     ui_call_wildmenu_show(args); | ||||
|     ssize_t offset = showtail ? sm_gettail(xp->xp_pattern)-xp->xp_pattern : 0; | ||||
|     if (ui_has(kUICmdline)) { | ||||
|       compl_startcol = ccline.cmdpos - strnlen((char *)xp->xp_pattern+offset, | ||||
|                                                xp->xp_pattern_len-offset); | ||||
|     } else { | ||||
|       compl_startcol = ccline.cmdspos | ||||
|                        - mb_string2cells_len(xp->xp_pattern+offset, | ||||
|                                              xp->xp_pattern_len-offset); | ||||
|     } | ||||
|     compl_selected = -1; | ||||
|     cmdline_pum_display(true); | ||||
|     return EXPAND_OK; | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -555,6 +555,24 @@ size_t mb_string2cells(const char_u *str) | ||||
|   return clen; | ||||
| } | ||||
|  | ||||
| /// Get the number of cells occupied by string `str` with maximum length `size` | ||||
| /// | ||||
| /// @param str The source string, may not be NULL, must be a NUL-terminated | ||||
| ///            string. | ||||
| /// @param size maximum length of string. It will terminate on earlier NUL. | ||||
| /// @return The number of cells occupied by string `str` | ||||
| size_t mb_string2cells_len(const char_u *str, size_t size) | ||||
| { | ||||
|   size_t clen = 0; | ||||
|  | ||||
|   for (const char_u *p = str; *p != NUL && p < str+size; | ||||
|        p += utf_ptr2len_len(p, size+(p-str))) { | ||||
|     clen += utf_ptr2cells(p); | ||||
|   } | ||||
|  | ||||
|   return clen; | ||||
| } | ||||
|  | ||||
| /// Convert a UTF-8 byte sequence to a wide character | ||||
| /// | ||||
| /// If the sequence is illegal or truncated by a NUL then the first byte is | ||||
|   | ||||
| @@ -284,7 +284,6 @@ static char *(p_ambw_values[]) =      { "single", "double", NULL }; | ||||
| static char *(p_bg_values[]) =        { "light", "dark", NULL }; | ||||
| static char *(p_nf_values[]) =        { "bin", "octal", "hex", "alpha", NULL }; | ||||
| static char *(p_ff_values[]) =        { FF_UNIX, FF_DOS, FF_MAC, NULL }; | ||||
| static char *(p_wop_values[]) =       { "tagfile", NULL }; | ||||
| static char *(p_wak_values[]) =       { "yes", "menu", "no", NULL }; | ||||
| static char *(p_mousem_values[]) =    { "extend", "popup", "popup_setpos", | ||||
|                                         "mac", NULL }; | ||||
| @@ -2608,12 +2607,12 @@ ambw_end: | ||||
|   else if (varp == &p_wim) { | ||||
|     if (check_opt_wim() == FAIL) | ||||
|       errmsg = e_invarg; | ||||
|   } | ||||
|   /* 'wildoptions' */ | ||||
|   else if (varp == &p_wop) { | ||||
|     if (check_opt_strings(p_wop, p_wop_values, TRUE) != OK) | ||||
|   // 'wildoptions' | ||||
|   } else if (varp == &p_wop) { | ||||
|     if (opt_strings_flags(p_wop, p_wop_values, &wop_flags, true) != OK) { | ||||
|       errmsg = e_invarg; | ||||
|     } | ||||
|   } | ||||
|   /* 'winaltkeys' */ | ||||
|   else if (varp == &p_wak) { | ||||
|     if (*p_wak == NUL | ||||
|   | ||||
| @@ -659,6 +659,12 @@ extern char_u   *p_vfile;       /* 'verbosefile' */ | ||||
| #endif | ||||
| EXTERN int p_warn;              // 'warn' | ||||
| EXTERN char_u   *p_wop;         // 'wildoptions' | ||||
| EXTERN unsigned wop_flags; | ||||
| # ifdef IN_OPTION_C | ||||
| static char *(p_wop_values[]) =  { "tagfile", "pum", NULL }; | ||||
| #endif | ||||
| #define WOP_TAGFILE             0x01 | ||||
| #define WOP_PUM                 0x02 | ||||
| EXTERN long p_window;           // 'window' | ||||
| EXTERN char_u   *p_wak;         // 'winaltkeys' | ||||
| EXTERN char_u   *p_wig;         // 'wildignore' | ||||
|   | ||||
| @@ -2699,7 +2699,7 @@ return { | ||||
|     }, | ||||
|     { | ||||
|       full_name='wildoptions', abbreviation='wop', | ||||
|       type='string', scope={'global'}, | ||||
|       type='string', list='onecomma', scope={'global'}, | ||||
|       vi_def=true, | ||||
|       varname='p_wop', | ||||
|       defaults={if_true={vi=""}} | ||||
|   | ||||
| @@ -66,7 +66,9 @@ static bool pum_invalid = false;  // the screen was just cleared | ||||
| /// @param array_changed if true, array contains different items since last call | ||||
| ///                      if false, a new item is selected, but the array | ||||
| ///                      is the same | ||||
| void pum_display(pumitem_T *array, int size, int selected, bool array_changed) | ||||
| /// @param cmd_startcol only for cmdline mode: column of completed match | ||||
| void pum_display(pumitem_T *array, int size, int selected, bool array_changed, | ||||
|                  int cmd_startcol) | ||||
| { | ||||
|   int w; | ||||
|   int def_width; | ||||
| @@ -84,7 +86,8 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) | ||||
|   if (!pum_is_visible) { | ||||
|     // To keep the code simple, we only allow changing the | ||||
|     // draw mode when the popup menu is not being displayed | ||||
|     pum_external = ui_has(kUIPopupmenu); | ||||
|     pum_external = ui_has(kUIPopupmenu) | ||||
|                    || (State == CMDLINE && ui_has(kUIWildmenu)); | ||||
|   } | ||||
|  | ||||
|   do { | ||||
| @@ -96,6 +99,12 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) | ||||
|     above_row = 0; | ||||
|     below_row = cmdline_row; | ||||
|  | ||||
|     // wildoptions=pum | ||||
|     if (State == CMDLINE) { | ||||
|       row = ui_has(kUICmdline) ? 0 : cmdline_row; | ||||
|       col = cmd_startcol; | ||||
|       pum_anchor_grid = ui_has(kUICmdline) ? -1 : DEFAULT_GRID_HANDLE; | ||||
|     } else { | ||||
|       // anchor position: the start of the completed word | ||||
|       row = curwin->w_wrow; | ||||
|       if (curwin->w_p_rl) { | ||||
| @@ -110,6 +119,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) | ||||
|         row += curwin->w_winrow; | ||||
|         col += curwin->w_wincol; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (pum_external) { | ||||
|       if (array_changed) { | ||||
|   | ||||
| @@ -7151,8 +7151,12 @@ void screen_resize(int width, int height) | ||||
|       if (curwin->w_p_scb) | ||||
|         do_check_scrollbind(TRUE); | ||||
|       if (State & CMDLINE) { | ||||
|         redraw_popupmenu = false; | ||||
|         update_screen(NOT_VALID); | ||||
|         redrawcmdline(); | ||||
|         if (pum_drawn()) { | ||||
|           cmdline_pum_display(false); | ||||
|         } | ||||
|       } else { | ||||
|         update_topline(); | ||||
|         if (pum_drawn()) { | ||||
|   | ||||
| @@ -600,6 +600,137 @@ local function test_cmdline(linegrid) | ||||
|       pos = 12, | ||||
|     }}} | ||||
|   end) | ||||
|  | ||||
|   it('works together with ext_popupmenu', function() | ||||
|     local expected = { | ||||
|         {'define', '', '', ''}, | ||||
|         {'jump', '', '', ''}, | ||||
|         {'list', '', '', ''}, | ||||
|         {'place', '', '', ''}, | ||||
|         {'undefine', '', '', ''}, | ||||
|         {'unplace', '', '', ''}, | ||||
|     } | ||||
|  | ||||
|     command('set wildmode=full') | ||||
|     command('set wildmenu') | ||||
|     screen:set_option('ext_popupmenu', true) | ||||
|     feed(':sign <tab>') | ||||
|  | ||||
|     screen:expect{grid=[[ | ||||
|       ^                         | | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|                                | | ||||
|     ]], cmdline={{ | ||||
|       firstc = ":", | ||||
|       content = {{"sign define"}}, | ||||
|       pos = 11, | ||||
|     }}, popupmenu={items=expected, pos=0, anchor={-1, 0, 5}}} | ||||
|  | ||||
|     feed('<tab>') | ||||
|     screen:expect{grid=[[ | ||||
|       ^                         | | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|                                | | ||||
|     ]], cmdline={{ | ||||
|       firstc = ":", | ||||
|       content = {{"sign jump"}}, | ||||
|       pos = 9, | ||||
|     }}, popupmenu={items=expected, pos=1, anchor={-1, 0, 5}}} | ||||
|  | ||||
|     feed('<left><left>') | ||||
|     screen:expect{grid=[[ | ||||
|       ^                         | | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|                                | | ||||
|     ]], cmdline={{ | ||||
|       firstc = ":", | ||||
|       content = {{"sign "}}, | ||||
|       pos = 5, | ||||
|     }}, popupmenu={items=expected, pos=-1, anchor={-1, 0, 5}}} | ||||
|  | ||||
|     feed('<right>') | ||||
|     screen:expect{grid=[[ | ||||
|       ^                         | | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|                                | | ||||
|     ]], cmdline={{ | ||||
|       firstc = ":", | ||||
|       content = {{"sign define"}}, | ||||
|       pos = 11, | ||||
|     }}, popupmenu={items=expected, pos=0, anchor={-1, 0, 5}}} | ||||
|  | ||||
|     feed('a') | ||||
|     screen:expect{grid=[[ | ||||
|       ^                         | | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|                                | | ||||
|     ]], cmdline={{ | ||||
|       firstc = ":", | ||||
|       content = {{"sign definea"}}, | ||||
|       pos = 12, | ||||
|     }}} | ||||
|     feed('<esc>') | ||||
|  | ||||
|     -- check positioning with multibyte char in pattern | ||||
|     command("e långfile1") | ||||
|     command("sp långfile2") | ||||
|     feed(':b lå<tab>') | ||||
|     screen:expect{grid=[[ | ||||
|       ^                         | | ||||
|       {3:långfile2                }| | ||||
|                                | | ||||
|       {2:långfile1                }| | ||||
|                                | | ||||
|     ]], popupmenu={ | ||||
|       anchor = { -1, 0, 2 }, | ||||
|       items = {{ "långfile1", "", "", "" }, { "långfile2", "", "", "" }}, | ||||
|       pos = 0 | ||||
|     }, cmdline={{ | ||||
|       content = {{ "b långfile1" }}, | ||||
|       firstc = ":", | ||||
|       pos = 12 | ||||
|     }}} | ||||
|   end) | ||||
|  | ||||
|   it('ext_wildmenu takes precedence over ext_popupmenu', function() | ||||
|     local expected = { | ||||
|       'define', | ||||
|       'jump', | ||||
|       'list', | ||||
|       'place', | ||||
|       'undefine', | ||||
|       'unplace', | ||||
|     } | ||||
|  | ||||
|     command('set wildmode=full') | ||||
|     command('set wildmenu') | ||||
|     screen:set_option('ext_wildmenu', true) | ||||
|     screen:set_option('ext_popupmenu', true) | ||||
|     feed(':sign <tab>') | ||||
|  | ||||
|     screen:expect{grid=[[ | ||||
|       ^                         | | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|                                | | ||||
|     ]], cmdline={{ | ||||
|       firstc = ":", | ||||
|       content = {{"sign define"}}, | ||||
|       pos = 11, | ||||
|     }}, wildmenu_items=expected, wildmenu_pos=0} | ||||
|   end) | ||||
|  | ||||
| end | ||||
|  | ||||
| -- the representation of cmdline and cmdline_block contents changed with ext_linegrid | ||||
|   | ||||
| @@ -1341,7 +1341,7 @@ describe('floating windows', function() | ||||
|           ]], float_pos={ | ||||
|             [3] = {{ id = 1001 }, "NW", 1, 2, 5, true}, | ||||
|           }, popupmenu={ | ||||
|             anchor = {0, 2, 3}, items = items, pos = 0 | ||||
|             anchor = {3, 0, 2}, items = items, pos = 0 | ||||
|           }} | ||||
|         else | ||||
|           screen:expect{grid=[[ | ||||
| @@ -1353,7 +1353,7 @@ describe('floating windows', function() | ||||
|             {0:~    }{12:~           }{0:                       }| | ||||
|             {3:-- INSERT --}                            | | ||||
|           ]], popupmenu={ | ||||
|             anchor = {2, 7}, items = items, pos = 0 | ||||
|             anchor = {1, 2, 7}, items = items, pos = 0 | ||||
|           }} | ||||
|         end | ||||
|  | ||||
| @@ -1423,7 +1423,7 @@ describe('floating windows', function() | ||||
|           ]], float_pos={ | ||||
|             [3] = {{ id = 1001 }, "NW", 1, 2, 5, true}, | ||||
|           }, popupmenu={ | ||||
|             anchor = {0, 0, 2}, items = items, pos = 0 | ||||
|             anchor = {2, 0, 0}, items = items, pos = 0 | ||||
|           }} | ||||
|         else | ||||
|           screen:expect{grid=[[ | ||||
| @@ -1435,7 +1435,7 @@ describe('floating windows', function() | ||||
|             {0:~    }{12:~           }{0:                       }| | ||||
|             {3:-- INSERT --}                            | | ||||
|           ]], popupmenu={ | ||||
|             anchor = {0, 0}, items = items, pos = 0 | ||||
|             anchor = {1, 0, 0}, items = items, pos = 0 | ||||
|           }} | ||||
|         end | ||||
|  | ||||
|   | ||||
| @@ -179,7 +179,7 @@ describe('ui/ext_messages', function() | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|     ]], popupmenu={ | ||||
|       anchor = { 2, 0 }, | ||||
|       anchor = { 1, 2, 0 }, | ||||
|       items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, | ||||
|       pos = 1 | ||||
|     }, showmode={ { "-- Keyword Local completion (^N^P) ", 3 }, { "match 1 of 2", 4 } }} | ||||
| @@ -194,7 +194,7 @@ describe('ui/ext_messages', function() | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|     ]], popupmenu={ | ||||
|       anchor = { 2, 0 }, | ||||
|       anchor = { 1, 2, 0 }, | ||||
|       items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, | ||||
|       pos = 1 | ||||
|     }, messages={ { | ||||
| @@ -210,7 +210,7 @@ describe('ui/ext_messages', function() | ||||
|       {1:~                        }| | ||||
|       {1:~                        }| | ||||
|     ]], popupmenu={ | ||||
|       anchor = { 2, 0 }, | ||||
|       anchor = { 1, 2, 0 }, | ||||
|       items = { { "alphpabet", "", "", "" }, { "alphanum", "", "", "" } }, | ||||
|       pos = 0 | ||||
|     }, messages={ { | ||||
|   | ||||
| @@ -50,7 +50,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=0, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     feed('<c-p>') | ||||
| @@ -66,7 +66,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=-1, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     -- down moves the selection in the menu, but does not insert anything | ||||
| @@ -83,7 +83,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=1, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     feed('<cr>') | ||||
| @@ -113,7 +113,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=0, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     meths.select_popupmenu_item(1,false,false,{}) | ||||
| @@ -129,7 +129,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=1, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     meths.select_popupmenu_item(2,true,false,{}) | ||||
| @@ -145,7 +145,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=2, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     meths.select_popupmenu_item(0,true,true,{}) | ||||
| @@ -174,7 +174,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=0, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     meths.select_popupmenu_item(-1,false,false,{}) | ||||
| @@ -190,7 +190,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=-1, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     meths.select_popupmenu_item(1,true,false,{}) | ||||
| @@ -206,7 +206,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=1, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     meths.select_popupmenu_item(-1,true,false,{}) | ||||
| @@ -222,7 +222,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=-1, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     meths.select_popupmenu_item(0,true,false,{}) | ||||
| @@ -238,7 +238,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=0, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     meths.select_popupmenu_item(-1,true,true,{}) | ||||
| @@ -269,7 +269,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=0, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     feed('<f1>') | ||||
| @@ -285,7 +285,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=2, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     feed('<f2>') | ||||
| @@ -301,7 +301,7 @@ describe('ui/ext_popupmenu', function() | ||||
|     ]], popupmenu={ | ||||
|       items=expected, | ||||
|       pos=-1, | ||||
|       anchor={1,0}, | ||||
|       anchor={1,1,0}, | ||||
|     }} | ||||
|  | ||||
|     feed('<f3>') | ||||
| @@ -366,6 +366,113 @@ describe('ui/ext_popupmenu', function() | ||||
|       {2:-- INSERT --}                                                | | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it('works with wildoptions=pum', function() | ||||
|     screen:try_resize(32,10) | ||||
|     command('set wildmenu') | ||||
|     command('set wildoptions=pum') | ||||
|  | ||||
|     local wild_expected = { | ||||
|         {'define', '', '', ''}, | ||||
|         {'jump', '', '', ''}, | ||||
|         {'list', '', '', ''}, | ||||
|         {'place', '', '', ''}, | ||||
|         {'undefine', '', '', ''}, | ||||
|         {'unplace', '', '', ''}, | ||||
|     } | ||||
|  | ||||
|     feed(':sign ') | ||||
|     screen:expect([[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       :sign ^                          | | ||||
|     ]]) | ||||
|  | ||||
|     feed('<tab>') | ||||
|     screen:expect{grid=[[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       :sign define^                    | | ||||
|     ]], popupmenu={items=wild_expected, pos=0, anchor={1, 9, 6}}} | ||||
|  | ||||
|     feed('<left>') | ||||
|     screen:expect{grid=[[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       :sign ^                          | | ||||
|     ]], popupmenu={items=wild_expected, pos=-1, anchor={1, 9, 6}}} | ||||
|  | ||||
|     feed('<left>') | ||||
|     screen:expect{grid=[[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       :sign unplace^                   | | ||||
|     ]], popupmenu={items=wild_expected, pos=5, anchor={1, 9, 6}}} | ||||
|  | ||||
|     feed('x') | ||||
|     screen:expect([[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       :sign unplacex^                  | | ||||
|     ]]) | ||||
|     feed('<esc>') | ||||
|  | ||||
|     -- check positioning with multibyte char in pattern | ||||
|     command("e långfile1") | ||||
|     command("sp långfile2") | ||||
|     feed(':b lå<tab>') | ||||
|     screen:expect{grid=[[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {4:långfile2                       }| | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {3:långfile1                       }| | ||||
|       :b långfile1^                    | | ||||
|     ]], popupmenu={ | ||||
|       anchor = {1, 9, 3}, | ||||
|       items = {{"långfile1", "", "", "" }, {"långfile2", "", "", ""}}, | ||||
|       pos = 0, | ||||
|     }} | ||||
|   end) | ||||
| end) | ||||
|  | ||||
|  | ||||
| @@ -1209,7 +1316,7 @@ describe('builtin popupmenu', function() | ||||
|     ]]) | ||||
|  | ||||
|     meths.input_mouse('wheel', 'down', '', 0, 6, 15) | ||||
|     screen:expect([[ | ||||
|     screen:expect{grid=[[ | ||||
|       choice^                                  | | ||||
|       {1:~                                       }| | ||||
|       {n:word           }{1:                         }| | ||||
| @@ -1218,7 +1325,7 @@ describe('builtin popupmenu', function() | ||||
|       {n:thing          }{1:                         }| | ||||
|       {3:[No Name] [+]                           }| | ||||
|       {2:-- INSERT --}                            | | ||||
|     ]]) | ||||
|     ]], unchanged=true} | ||||
|   end) | ||||
|  | ||||
|   it('works with kind, menu and abbr attributes', function() | ||||
| @@ -1273,6 +1380,131 @@ describe('builtin popupmenu', function() | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it('works with wildoptions=pum', function() | ||||
|     screen:try_resize(32,10) | ||||
|     command('set wildmenu') | ||||
|     command('set wildoptions=pum') | ||||
|  | ||||
|     feed(':sign ') | ||||
|     screen:expect([[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       :sign ^                          | | ||||
|     ]]) | ||||
|  | ||||
|     feed('<tab>') | ||||
|     screen:expect([[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~    }{s: define         }{1:           }| | ||||
|       {1:~    }{n: jump           }{1:           }| | ||||
|       {1:~    }{n: list           }{1:           }| | ||||
|       {1:~    }{n: place          }{1:           }| | ||||
|       {1:~    }{n: undefine       }{1:           }| | ||||
|       {1:~    }{n: unplace        }{1:           }| | ||||
|       :sign define^                    | | ||||
|     ]]) | ||||
|  | ||||
|     feed('<left>') | ||||
|     screen:expect([[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~    }{n: define         }{1:           }| | ||||
|       {1:~    }{n: jump           }{1:           }| | ||||
|       {1:~    }{n: list           }{1:           }| | ||||
|       {1:~    }{n: place          }{1:           }| | ||||
|       {1:~    }{n: undefine       }{1:           }| | ||||
|       {1:~    }{n: unplace        }{1:           }| | ||||
|       :sign ^                          | | ||||
|     ]]) | ||||
|  | ||||
|     feed('<left>') | ||||
|     screen:expect([[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~    }{n: define         }{1:           }| | ||||
|       {1:~    }{n: jump           }{1:           }| | ||||
|       {1:~    }{n: list           }{1:           }| | ||||
|       {1:~    }{n: place          }{1:           }| | ||||
|       {1:~    }{n: undefine       }{1:           }| | ||||
|       {1:~    }{s: unplace        }{1:           }| | ||||
|       :sign unplace^                   | | ||||
|     ]]) | ||||
|  | ||||
|     feed('x') | ||||
|     screen:expect([[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       :sign unplacex^                  | | ||||
|     ]]) | ||||
|  | ||||
|     feed('<esc>') | ||||
|  | ||||
|     -- check positioning with multibyte char in pattern | ||||
|     command("e långfile1") | ||||
|     command("sp långfile2") | ||||
|     feed(':b lå<tab>') | ||||
|     screen:expect([[ | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {1:~                               }| | ||||
|       {4:långfile2                       }| | ||||
|                                       | | ||||
|       {1:~                               }| | ||||
|       {1:~ }{s: långfile1      }{1:              }| | ||||
|       {3:lå}{n: långfile2      }{3:              }| | ||||
|       :b långfile1^                    | | ||||
|     ]]) | ||||
|  | ||||
|     -- check doesn't crash on screen resize | ||||
|     screen:try_resize(20,6) | ||||
|     screen:expect([[ | ||||
|                           | | ||||
|       {1:~                   }| | ||||
|       {4:långfile2           }| | ||||
|         {s: långfile1      }  | | ||||
|       {3:lå}{n: långfile2      }{3:  }| | ||||
|       :b långfile1^        | | ||||
|     ]]) | ||||
|  | ||||
|     screen:try_resize(50,15) | ||||
|     screen:expect([[ | ||||
|                                                         | | ||||
|       {1:~                                                 }| | ||||
|       {4:långfile2                                         }| | ||||
|                                                         | | ||||
|       {1:~                                                 }| | ||||
|       {1:~                                                 }| | ||||
|       {1:~                                                 }| | ||||
|       {1:~                                                 }| | ||||
|       {1:~                                                 }| | ||||
|       {1:~                                                 }| | ||||
|       {1:~                                                 }| | ||||
|       {1:~                                                 }| | ||||
|       {1:~ }{s: långfile1      }{1:                                }| | ||||
|       {3:lå}{n: långfile2      }{3:                                }| | ||||
|       :b långfile1^                                      | | ||||
|     ]]) | ||||
|   end) | ||||
|  | ||||
|   it("'pumblend' RGB-color", function() | ||||
|     screen:try_resize(60,14) | ||||
|     screen:set_default_attr_ids({ | ||||
|   | ||||
| @@ -937,10 +937,7 @@ function Screen:_handle_option_set(name, value) | ||||
| end | ||||
|  | ||||
| function Screen:_handle_popupmenu_show(items, selected, row, col, grid) | ||||
|   if (not self._options.ext_multigrid) and grid == 1 then | ||||
|     grid = nil | ||||
|   end | ||||
|   self.popupmenu = {items=items, pos=selected, anchor={row, col, grid}} | ||||
|   self.popupmenu = {items=items, pos=selected, anchor={grid, row, col}} | ||||
| end | ||||
|  | ||||
| function Screen:_handle_popupmenu_select(selected) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Björn Linse
					Björn Linse