aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/cmdexpand.c2
-rw-r--r--src/nvim/ex_docmd.c3
-rw-r--r--src/nvim/ex_getln.c25
3 files changed, 24 insertions, 6 deletions
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c
index 3cc9515fef..496c047a4a 100644
--- a/src/nvim/cmdexpand.c
+++ b/src/nvim/cmdexpand.c
@@ -267,7 +267,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
char *p1;
if (cmdline_fuzzy_completion_supported(xp)) {
// If fuzzy matching, don't modify the search string
- p1 = xstrdup(xp->xp_pattern);
+ p1 = xstrnsave(xp->xp_pattern, xp->xp_pattern_len);
} else {
p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index c52937b6c1..98da044bb4 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -4241,7 +4241,8 @@ int expand_argopt(char *pat, expand_T *xp, regmatch_T *rmp, char ***matches, int
// Special handling of "ff" which acts as a short form of
// "fileformat", as "ff" is not a substring of it.
- if (strcmp(xp->xp_pattern, "ff") == 0) {
+ if (xp->xp_pattern_len == 2
+ && strncmp(xp->xp_pattern, "ff", xp->xp_pattern_len) == 0) {
*matches = xmalloc(sizeof(char *));
*numMatches = 1;
(*matches)[0] = xstrdup("fileformat=");
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 2759dc9bb5..9d0e3d542a 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -861,6 +861,16 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
cmdmsg_rl = false;
+ // We could have reached here without having a chance to clean up wild menu
+ // if certain special keys like <Esc> or <C-\> were used as wildchar. Make
+ // sure to still clean up to avoid memory corruption.
+ if (cmdline_pum_active()) {
+ cmdline_pum_remove();
+ }
+ wildmenu_cleanup(&ccline);
+ s->did_wild_list = false;
+ s->wim_index = 0;
+
ExpandCleanup(&s->xpc);
ccline.xpc = NULL;
@@ -1247,13 +1257,14 @@ static int command_line_execute(VimState *state, int key)
s->c = wildmenu_translate_key(&ccline, s->c, &s->xpc, s->did_wild_list);
}
- if (cmdline_pum_active() || s->did_wild_list) {
+ int wild_type = 0;
+ const bool key_is_wc = (s->c == p_wc && KeyTyped) || s->c == p_wcm;
+ if ((cmdline_pum_active() || s->did_wild_list) && !key_is_wc) {
// Ctrl-Y: Accept the current selection and close the popup menu.
// Ctrl-E: cancel the cmdline popup menu and return the original text.
if (s->c == Ctrl_E || s->c == Ctrl_Y) {
- const int wild_type = (s->c == Ctrl_E) ? WILD_CANCEL : WILD_APPLY;
+ wild_type = (s->c == Ctrl_E) ? WILD_CANCEL : WILD_APPLY;
(void)nextwild(&s->xpc, wild_type, WILD_NO_BEEP, s->firstc != '@');
- s->c = Ctrl_E;
}
}
@@ -1262,7 +1273,7 @@ static int command_line_execute(VimState *state, int key)
// 'wildcharm' or Ctrl-N or Ctrl-P or Ctrl-A or Ctrl-L).
// If the popup menu is displayed, then PageDown and PageUp keys are
// also used to navigate the menu.
- bool end_wildmenu = (!(s->c == p_wc && KeyTyped) && s->c != p_wcm && s->c != Ctrl_Z
+ bool end_wildmenu = (!key_is_wc && s->c != Ctrl_Z
&& s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
&& s->c != Ctrl_L);
end_wildmenu = end_wildmenu && (!cmdline_pum_active()
@@ -1366,6 +1377,12 @@ static int command_line_execute(VimState *state, int key)
}
s->do_abbr = true; // default: check for abbreviation
+
+ // If already used to cancel/accept wildmenu, don't process the key further.
+ if (wild_type == WILD_CANCEL || wild_type == WILD_APPLY) {
+ return command_line_not_changed(s);
+ }
+
return command_line_handle_key(s);
}