diff options
Diffstat (limited to 'src/nvim/ex_getln.c')
| -rw-r--r-- | src/nvim/ex_getln.c | 85 |
1 files changed, 63 insertions, 22 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 8e6fc5ad4f..b16023b0ec 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -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" @@ -357,7 +366,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) // redraw the statusline for statuslines that display the current mode // using the mode() function. - if (KeyTyped && msg_scrolled == 0) { + if (!cmd_silent && msg_scrolled == 0) { curwin->w_redr_status = true; redraw_statuslines(); } @@ -615,8 +624,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); @@ -1378,6 +1389,7 @@ static int command_line_handle_key(CommandLineState *s) } } } + ccline.special_char = NUL; redrawcmd(); return command_line_changed(s); @@ -1436,6 +1448,9 @@ static int command_line_handle_key(CommandLineState *s) && ccline.cmdbuff[ccline.cmdpos - 1] != ' '); set_cmdspos_cursor(); + if (ccline.special_char != NUL) { + putcmdline(ccline.special_char, ccline.special_shift); + } return command_line_not_changed(s); @@ -1693,6 +1708,7 @@ static int command_line_handle_key(CommandLineState *s) putcmdline('^', true); s->c = get_literal(); // get next (two) character(s) s->do_abbr = false; // don't do abbreviation now + ccline.special_char = NUL; // may need to remove ^ when composing char was typed if (enc_utf8 && utf_iscomposing(s->c) && !cmd_silent) { if (ui_has(kUICmdline)) { @@ -1710,6 +1726,7 @@ static int command_line_handle_key(CommandLineState *s) s->ignore_drag_release = true; putcmdline('?', true); s->c = get_digraph(true); + ccline.special_char = NUL; if (s->c != NUL) { break; @@ -3071,15 +3088,13 @@ void putcmdline(int c, int shift) draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos); } msg_no_more = false; - } else { - ccline.special_char = c; - ccline.special_shift = shift; - if (ccline.redraw_state != kCmdRedrawAll) { + } else if (ccline.redraw_state != kCmdRedrawAll) { ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift, ccline.level); - } } cursorcmd(); + ccline.special_char = c; + ccline.special_shift = shift; ui_cursor_shape(); } @@ -3097,6 +3112,7 @@ void unputcmdline(void) } msg_no_more = false; cursorcmd(); + ccline.special_char = NUL; ui_cursor_shape(); } @@ -3457,6 +3473,10 @@ void redrawcmd(void) set_cmdspos_cursor(); + if (ccline.special_char != NUL) { + putcmdline(ccline.special_char, ccline.special_shift); + } + /* * An emsg() before may have set msg_scroll. This is used in normal mode, * in cmdline mode we can reset them now. @@ -3746,13 +3766,12 @@ ExpandOne ( else findex = -1; } - if (p_wmnu) { - if (ui_has(kUIWildmenu)) { - ui_call_wildmenu_select(findex); - } else { - win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files, - findex, cmd_showtail); - } + 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 +4088,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 +4127,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; } @@ -6069,9 +6110,9 @@ static int open_cmdwin(void) do { if (++i == hislen) i = 0; - if (history[histtype][i].hisstr != NULL) - ml_append(lnum++, history[histtype][i].hisstr, - (colnr_T)0, FALSE); + if (history[histtype][i].hisstr != NULL) { + ml_append(lnum++, history[histtype][i].hisstr, (colnr_T)0, false); + } } while (i != hisidx[histtype]); } } |