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.c93
1 files changed, 58 insertions, 35 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 93c5d24c0d..62586598bf 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1225,6 +1225,8 @@ static int command_line_execute(VimState *state, int key)
}
if (cmdline_pum_active() || s->did_wild_list) {
+ // 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;
(void)nextwild(&s->xpc, wild_type, WILD_NO_BEEP, s->firstc != '@');
@@ -1232,10 +1234,20 @@ static int command_line_execute(VimState *state, int key)
}
}
+ // The wildmenu is cleared if the pressed key is not used for
+ // navigating the wild menu (i.e. the key is not 'wildchar' or
+ // '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
+ && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
+ && s->c != Ctrl_L);
+ end_wildmenu = end_wildmenu && (!cmdline_pum_active()
+ || (s->c != K_PAGEDOWN && s->c != K_PAGEUP
+ && s->c != K_KPAGEDOWN && s->c != K_KPAGEUP));
+
// free expanded names when finished walking through matches
- if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm && s->c != Ctrl_Z
- && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
- && s->c != Ctrl_L) {
+ if (end_wildmenu) {
command_line_end_wildmenu(s);
}
@@ -1466,27 +1478,27 @@ static int command_line_erase_chars(CommandLineState *s)
}
if (ccline.cmdpos > 0) {
- char_u *p;
+ char *p;
int j = ccline.cmdpos;
- p = mb_prevptr((char_u *)ccline.cmdbuff, (char_u *)ccline.cmdbuff + j);
+ p = mb_prevptr(ccline.cmdbuff, ccline.cmdbuff + j);
if (s->c == Ctrl_W) {
- while (p > (char_u *)ccline.cmdbuff && ascii_isspace(*p)) {
- p = mb_prevptr((char_u *)ccline.cmdbuff, p);
+ while (p > ccline.cmdbuff && ascii_isspace(*p)) {
+ p = mb_prevptr(ccline.cmdbuff, p);
}
int i = mb_get_class(p);
- while (p > (char_u *)ccline.cmdbuff && mb_get_class(p) == i) {
- p = mb_prevptr((char_u *)ccline.cmdbuff, p);
+ while (p > ccline.cmdbuff && mb_get_class(p) == i) {
+ p = mb_prevptr(ccline.cmdbuff, p);
}
if (mb_get_class(p) != i) {
- p += utfc_ptr2len((char *)p);
+ p += utfc_ptr2len(p);
}
}
- ccline.cmdpos = (int)(p - (char_u *)ccline.cmdbuff);
+ ccline.cmdpos = (int)(p - ccline.cmdbuff);
ccline.cmdlen -= j - ccline.cmdpos;
int i = ccline.cmdpos;
@@ -1998,8 +2010,8 @@ static int command_line_handle_key(CommandLineState *s)
case Ctrl_N: // next match
case Ctrl_P: // previous match
if (s->xpc.xp_numfiles > 0) {
- if (nextwild(&s->xpc, (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT,
- 0, s->firstc != '@') == FAIL) {
+ const int wild_type = (s->c == Ctrl_P) ? WILD_PREV : WILD_NEXT;
+ if (nextwild(&s->xpc, wild_type, 0, s->firstc != '@') == FAIL) {
break;
}
return command_line_not_changed(s);
@@ -2014,13 +2026,26 @@ static int command_line_handle_key(CommandLineState *s)
case K_KPAGEUP:
case K_PAGEDOWN:
case K_KPAGEDOWN:
- switch (command_line_browse_history(s)) {
- case CMDLINE_CHANGED:
- return command_line_changed(s);
- case GOTO_NORMAL_MODE:
- return 0;
- default:
+ if (cmdline_pum_active()
+ && (s->c == K_PAGEUP || s->c == K_PAGEDOWN
+ || s->c == K_KPAGEUP || s->c == K_KPAGEDOWN)) {
+ // If the popup menu is displayed, then PageUp and PageDown
+ // are used to scroll the menu.
+ const int wild_type =
+ (s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN) ? WILD_PAGEDOWN : WILD_PAGEUP;
+ if (nextwild(&s->xpc, wild_type, 0, s->firstc != '@') == FAIL) {
+ break;
+ }
return command_line_not_changed(s);
+ } else {
+ switch (command_line_browse_history(s)) {
+ case CMDLINE_CHANGED:
+ return command_line_changed(s);
+ case GOTO_NORMAL_MODE:
+ return 0;
+ default:
+ return command_line_not_changed(s);
+ }
}
case Ctrl_G: // next match
@@ -2097,11 +2122,11 @@ static int command_line_handle_key(CommandLineState *s)
// put the character in the command line
if (IS_SPECIAL(s->c) || mod_mask != 0) {
- put_on_cmdline(get_special_key_name(s->c, mod_mask), -1, true);
+ put_on_cmdline((char *)get_special_key_name(s->c, mod_mask), -1, true);
} else {
int j = utf_char2bytes(s->c, IObuff);
IObuff[j] = NUL; // exclude composing chars
- put_on_cmdline((char_u *)IObuff, j, true);
+ put_on_cmdline(IObuff, j, true);
}
return command_line_changed(s);
}
@@ -3509,14 +3534,14 @@ void unputcmdline(void)
// part will be redrawn, otherwise it will not. If this function is called
// twice in a row, then 'redraw' should be false and redrawcmd() should be
// called afterwards.
-void put_on_cmdline(char_u *str, int len, int redraw)
+void put_on_cmdline(char *str, int len, int redraw)
{
int i;
int m;
int c;
if (len < 0) {
- len = (int)strlen((char *)str);
+ len = (int)strlen(str);
}
realloc_cmdbuff(ccline.cmdlen + len + 1);
@@ -3529,7 +3554,7 @@ void put_on_cmdline(char_u *str, int len, int redraw)
} else {
// Count nr of characters in the new string.
m = 0;
- for (i = 0; i < len; i += utfc_ptr2len((char *)str + i)) {
+ for (i = 0; i < len; i += utfc_ptr2len(str + i)) {
m++;
}
// Count nr of bytes in cmdline that are overwritten by these
@@ -3725,7 +3750,7 @@ void cmdline_paste_str(char_u *s, int literally)
int c, cv;
if (literally) {
- put_on_cmdline(s, -1, true);
+ put_on_cmdline((char *)s, -1, true);
} else {
while (*s != NUL) {
cv = *s;
@@ -3964,18 +3989,16 @@ char *vim_strsave_fnameescape(const char *const fname, const int what)
char *p = (char *)vim_strsave_escaped((const char_u *)fname,
(const char_u *)buf);
#else
-# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
-# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
-# define BUFFER_ESC_CHARS ((char_u *)" \t\n*?[`$\\%#'\"|!<")
- char *p =
- (char *)vim_strsave_escaped((const char_u *)fname,
- what == VSE_SHELL ? SHELL_ESC_CHARS
- : what == VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS);
+# define PATH_ESC_CHARS " \t\n*?[{`$\\%#'\"|!<"
+# define SHELL_ESC_CHARS " \t\n*?[{`$\\%#'\"|!<>();&"
+# define BUFFER_ESC_CHARS " \t\n*?[`$\\%#'\"|!<"
+ char *p = vim_strsave_escaped(fname,
+ what == VSE_SHELL ? SHELL_ESC_CHARS : what ==
+ VSE_BUFFER ? BUFFER_ESC_CHARS : PATH_ESC_CHARS);
if (what == VSE_SHELL && csh_like_shell()) {
// For csh and similar shells need to put two backslashes before '!'.
// One is taken by Vim, one by the shell.
- char *s = (char *)vim_strsave_escaped((const char_u *)p,
- (const char_u *)"!");
+ char *s = vim_strsave_escaped(p, "!");
xfree(p);
p = s;
}
@@ -4002,7 +4025,7 @@ void escape_fname(char **pp)
/// For each file name in files[num_files]:
/// If 'orig_pat' starts with "~/", replace the home directory with "~".
-void tilde_replace(char_u *orig_pat, int num_files, char **files)
+void tilde_replace(char *orig_pat, int num_files, char **files)
{
char *p;