summaryrefslogtreecommitdiff
path: root/src/edit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/edit.c')
-rw-r--r--src/edit.c112
1 files changed, 86 insertions, 26 deletions
diff --git a/src/edit.c b/src/edit.c
index ff09f09c8..53eabe667 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -121,7 +121,9 @@ static buf_T *ins_compl_next_buf __ARGS((buf_T *buf, int flag));
static int ins_compl_get_exp __ARGS((pos_T *ini, int dir));
static void ins_compl_delete __ARGS((void));
static void ins_compl_insert __ARGS((void));
-static int ins_compl_next __ARGS((int allow_get_expansion));
+static int ins_compl_next __ARGS((int allow_get_expansion, int count));
+static int ins_compl_key2dir __ARGS((int c));
+static int ins_compl_key2count __ARGS((int c));
static int ins_complete __ARGS((int c));
static int quote_meta __ARGS((char_u *dest, char_u *str, int len));
#endif /* FEAT_INS_EXPAND */
@@ -1043,6 +1045,8 @@ doESCkey:
case K_S_UP: /* <S-Up> */
case K_PAGEUP:
case K_KPAGEUP:
+ if (pum_visible())
+ goto docomplete;
ins_pageup();
break;
@@ -1056,6 +1060,8 @@ doESCkey:
case K_S_DOWN: /* <S-Down> */
case K_PAGEDOWN:
case K_KPAGEDOWN:
+ if (pum_visible())
+ goto docomplete;
ins_pagedown();
break;
@@ -1819,6 +1825,11 @@ vim_is_ctrl_x_key(c)
if (c == Ctrl_R)
return TRUE;
+ /* Accept <PageUp> and <PageDown> if the popup menu is visible. */
+ if (pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
+ || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN))
+ return TRUE;
+
switch (ctrl_x_mode)
{
case 0: /* Not in any CTRL-X mode */
@@ -3272,11 +3283,14 @@ ins_compl_insert()
* calls this function with "allow_get_expansion" FALSE.
*/
static int
-ins_compl_next(allow_get_expansion)
+ins_compl_next(allow_get_expansion, count)
int allow_get_expansion;
+ int count; /* repeat completion this many times; should
+ be at least 1 */
{
int num_matches = -1;
int i;
+ int todo = count;
if (allow_get_expansion)
{
@@ -3284,24 +3298,41 @@ ins_compl_next(allow_get_expansion)
ins_compl_delete();
}
compl_pending = FALSE;
- if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL)
- compl_shown_match = compl_shown_match->cp_next;
- else if (compl_shows_dir == BACKWARD && compl_shown_match->cp_prev != NULL)
- compl_shown_match = compl_shown_match->cp_prev;
- else
+
+ /* Repeat this for when <PageUp> or <PageDown> is typed. But don't wrap
+ * around. */
+ while (--todo >= 0)
{
- compl_pending = TRUE;
- if (allow_get_expansion)
+ if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL)
{
- num_matches = ins_compl_get_exp(&compl_startpos, compl_direction);
- if (compl_pending)
+ compl_shown_match = compl_shown_match->cp_next;
+ if (compl_shown_match->cp_next != NULL
+ && compl_shown_match->cp_next == compl_first_match)
+ break;
+ }
+ else if (compl_shows_dir == BACKWARD
+ && compl_shown_match->cp_prev != NULL)
+ {
+ compl_shown_match = compl_shown_match->cp_prev;
+ if (compl_shown_match == compl_first_match)
+ break;
+ }
+ else
+ {
+ compl_pending = TRUE;
+ if (allow_get_expansion)
{
- if (compl_direction == compl_shows_dir)
- compl_shown_match = compl_curr_match;
+ num_matches = ins_compl_get_exp(&compl_startpos,
+ compl_direction);
+ if (compl_pending)
+ {
+ if (compl_direction == compl_shows_dir)
+ compl_shown_match = compl_curr_match;
+ }
}
+ else
+ return -1;
}
- else
- return -1;
}
/* Insert the text of the new completion */
@@ -3376,17 +3407,49 @@ ins_compl_check_keys(frequency)
if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R)
{
c = safe_vgetc(); /* Eat the character */
- if (c == Ctrl_P || c == Ctrl_L)
- compl_shows_dir = BACKWARD;
- else
- compl_shows_dir = FORWARD;
- (void)ins_compl_next(FALSE);
+ compl_shows_dir = ins_compl_key2dir(c);
+ (void)ins_compl_next(FALSE, ins_compl_key2count(c));
}
else if (c != Ctrl_R)
compl_interrupted = TRUE;
}
if (compl_pending && !got_int)
- (void)ins_compl_next(FALSE);
+ (void)ins_compl_next(FALSE, 1);
+}
+
+/*
+ * Decide the direction of Insert mode complete from the key typed.
+ * Returns BACKWARD or FORWARD.
+ */
+ static int
+ins_compl_key2dir(c)
+ int c;
+{
+ if (c == Ctrl_P || c == Ctrl_L || (pum_visible()
+ && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP)))
+ return BACKWARD;
+ return FORWARD;
+}
+
+/*
+ * Decide the number of completions to move forward.
+ * Returns 1 for most keys, height of the popup menu for page-up/down keys.
+ */
+ static int
+ins_compl_key2count(c)
+ int c;
+{
+ int h;
+
+ if (pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
+ || c == K_PAGEDOWN || c == K_KPAGEDOWN || c == K_S_DOWN))
+ {
+ h = pum_get_height();
+ if (h > 3)
+ h -= 2; /* keep some context */
+ return h;
+ }
+ return 1;
}
/*
@@ -3403,10 +3466,7 @@ ins_complete(c)
colnr_T curs_col; /* cursor column */
int n;
- if (c == Ctrl_P || c == Ctrl_L)
- compl_direction = BACKWARD;
- else
- compl_direction = FORWARD;
+ compl_direction = ins_compl_key2dir(c);
if (!compl_started)
{
/* First time we hit ^N or ^P (in a row, I mean) */
@@ -3783,7 +3843,7 @@ ins_complete(c)
/*
* Find next match.
*/
- n = ins_compl_next(TRUE);
+ n = ins_compl_next(TRUE, ins_compl_key2count(c));
/* may undisplay the popup menu */
ins_compl_upd_pum();