aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_getln.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_getln.c')
-rw-r--r--src/nvim/ex_getln.c85
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]);
}
}