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 */
case K_S_UP: /* <S-Up> */
case K_PAGEUP:
case K_KPAGEUP:
+ if (pum_visible())
+ goto docomplete;
ins_pageup();
break;
case K_S_DOWN: /* <S-Down> */
case K_PAGEDOWN:
case K_KPAGEDOWN:
+ if (pum_visible())
+ goto docomplete;
ins_pagedown();
break;
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 */
* 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)
{
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 */
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;
}
/*
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) */
/*
* 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();
/* misc1.c */
-extern int get_indent __ARGS((void));
-extern int get_indent_lnum __ARGS((linenr_T lnum));
-extern int get_indent_buf __ARGS((buf_T *buf, linenr_T lnum));
-extern int get_indent_str __ARGS((char_u *ptr, int ts));
-extern int set_indent __ARGS((int size, int flags));
-extern int get_number_indent __ARGS((linenr_T lnum));
-extern int open_line __ARGS((int dir, int flags, int old_indent));
-extern int get_leader_len __ARGS((char_u *line, char_u **flags, int backward));
-extern int plines __ARGS((linenr_T lnum));
-extern int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight));
-extern int plines_nofill __ARGS((linenr_T lnum));
-extern int plines_win_nofill __ARGS((win_T *wp, linenr_T lnum, int winheight));
-extern int plines_win_nofold __ARGS((win_T *wp, linenr_T lnum));
-extern int plines_win_col __ARGS((win_T *wp, linenr_T lnum, long column));
-extern int plines_m_win __ARGS((win_T *wp, linenr_T first, linenr_T last));
-extern void ins_bytes __ARGS((char_u *p));
-extern void ins_bytes_len __ARGS((char_u *p, int len));
-extern void ins_char __ARGS((int c));
-extern void ins_char_bytes __ARGS((char_u *buf, int charlen));
-extern void ins_str __ARGS((char_u *s));
-extern int del_char __ARGS((int fixpos));
-extern int del_chars __ARGS((long count, int fixpos));
-extern int del_bytes __ARGS((long count, int fixpos));
-extern int truncate_line __ARGS((int fixpos));
-extern void del_lines __ARGS((long nlines, int undo));
-extern int gchar_pos __ARGS((pos_T *pos));
-extern int gchar_cursor __ARGS((void));
-extern void pchar_cursor __ARGS((int c));
-extern int inindent __ARGS((int extra));
-extern char_u *skip_to_option_part __ARGS((char_u *p));
-extern void changed __ARGS((void));
-extern void changed_bytes __ARGS((linenr_T lnum, colnr_T col));
-extern void appended_lines __ARGS((linenr_T lnum, long count));
-extern void appended_lines_mark __ARGS((linenr_T lnum, long count));
-extern void deleted_lines __ARGS((linenr_T lnum, long count));
-extern void deleted_lines_mark __ARGS((linenr_T lnum, long count));
-extern void changed_lines __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume, long xtra));
-extern void unchanged __ARGS((buf_T *buf, int ff));
-extern void check_status __ARGS((buf_T *buf));
-extern void change_warning __ARGS((int col));
-extern int ask_yesno __ARGS((char_u *str, int direct));
-extern int get_keystroke __ARGS((void));
-extern int get_number __ARGS((int colon, int *mouse_used));
-extern int prompt_for_number __ARGS((int *mouse_used));
-extern void msgmore __ARGS((long n));
-extern void beep_flush __ARGS((void));
-extern void vim_beep __ARGS((void));
-extern void init_homedir __ARGS((void));
-extern void free_homedir __ARGS((void));
-extern void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
-extern void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, char_u *startstr));
-extern char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
-extern char_u *expand_env_save __ARGS((char_u *src));
-extern void vim_setenv __ARGS((char_u *name, char_u *val));
-extern char_u *get_env_name __ARGS((expand_T *xp, int idx));
-extern void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one));
-extern char_u *home_replace_save __ARGS((buf_T *buf, char_u *src));
-extern int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname));
-extern char_u *gettail __ARGS((char_u *fname));
-extern char_u *gettail_sep __ARGS((char_u *fname));
-extern char_u *getnextcomp __ARGS((char_u *fname));
-extern char_u *get_past_head __ARGS((char_u *path));
-extern int vim_ispathsep __ARGS((int c));
-extern int vim_ispathlistsep __ARGS((int c));
-extern int dir_of_file_exists __ARGS((char_u *fname));
-extern int vim_fnamecmp __ARGS((char_u *x, char_u *y));
-extern int vim_fnamencmp __ARGS((char_u *x, char_u *y, size_t len));
-extern char_u *concat_fnames __ARGS((char_u *fname1, char_u *fname2, int sep));
-extern char_u *concat_str __ARGS((char_u *str1, char_u *str2));
-extern void add_pathsep __ARGS((char_u *p));
-extern char_u *FullName_save __ARGS((char_u *fname, int force));
-extern pos_T *find_start_comment __ARGS((int ind_maxcomment));
-extern void do_c_expr_indent __ARGS((void));
-extern int cin_islabel __ARGS((int ind_maxcomment));
-extern int cin_iscase __ARGS((char_u *s));
-extern int cin_isscopedecl __ARGS((char_u *s));
-extern int get_c_indent __ARGS((void));
-extern int get_expr_indent __ARGS((void));
-extern int get_lisp_indent __ARGS((void));
-extern void prepare_to_exit __ARGS((void));
-extern void preserve_exit __ARGS((void));
-extern int vim_fexists __ARGS((char_u *fname));
-extern void line_breakcheck __ARGS((void));
-extern void fast_breakcheck __ARGS((void));
-extern int expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags));
-extern int match_suffix __ARGS((char_u *fname));
-extern int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags, int didstar));
-extern int gen_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags));
-extern void addfile __ARGS((garray_T *gap, char_u *f, int flags));
-extern char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags));
-extern void FreeWild __ARGS((int count, char_u **files));
-extern int goto_im __ARGS((void));
+int get_indent __ARGS((void));
+int get_indent_lnum __ARGS((linenr_T lnum));
+int get_indent_buf __ARGS((buf_T *buf, linenr_T lnum));
+int get_indent_str __ARGS((char_u *ptr, int ts));
+int set_indent __ARGS((int size, int flags));
+int get_number_indent __ARGS((linenr_T lnum));
+int open_line __ARGS((int dir, int flags, int old_indent));
+int get_leader_len __ARGS((char_u *line, char_u **flags, int backward));
+int plines __ARGS((linenr_T lnum));
+int plines_win __ARGS((win_T *wp, linenr_T lnum, int winheight));
+int plines_nofill __ARGS((linenr_T lnum));
+int plines_win_nofill __ARGS((win_T *wp, linenr_T lnum, int winheight));
+int plines_win_nofold __ARGS((win_T *wp, linenr_T lnum));
+int plines_win_col __ARGS((win_T *wp, linenr_T lnum, long column));
+int plines_m_win __ARGS((win_T *wp, linenr_T first, linenr_T last));
+void ins_bytes __ARGS((char_u *p));
+void ins_bytes_len __ARGS((char_u *p, int len));
+void ins_char __ARGS((int c));
+void ins_char_bytes __ARGS((char_u *buf, int charlen));
+void ins_str __ARGS((char_u *s));
+int del_char __ARGS((int fixpos));
+int del_chars __ARGS((long count, int fixpos));
+int del_bytes __ARGS((long count, int fixpos, int use_delcombine));
+int truncate_line __ARGS((int fixpos));
+void del_lines __ARGS((long nlines, int undo));
+int gchar_pos __ARGS((pos_T *pos));
+int gchar_cursor __ARGS((void));
+void pchar_cursor __ARGS((int c));
+int inindent __ARGS((int extra));
+char_u *skip_to_option_part __ARGS((char_u *p));
+void changed __ARGS((void));
+void changed_bytes __ARGS((linenr_T lnum, colnr_T col));
+void appended_lines __ARGS((linenr_T lnum, long count));
+void appended_lines_mark __ARGS((linenr_T lnum, long count));
+void deleted_lines __ARGS((linenr_T lnum, long count));
+void deleted_lines_mark __ARGS((linenr_T lnum, long count));
+void changed_lines __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume, long xtra));
+void unchanged __ARGS((buf_T *buf, int ff));
+void check_status __ARGS((buf_T *buf));
+void change_warning __ARGS((int col));
+int ask_yesno __ARGS((char_u *str, int direct));
+int get_keystroke __ARGS((void));
+int get_number __ARGS((int colon, int *mouse_used));
+int prompt_for_number __ARGS((int *mouse_used));
+void msgmore __ARGS((long n));
+void beep_flush __ARGS((void));
+void vim_beep __ARGS((void));
+void init_homedir __ARGS((void));
+void free_homedir __ARGS((void));
+void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
+void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, char_u *startstr));
+char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
+char_u *expand_env_save __ARGS((char_u *src));
+void vim_setenv __ARGS((char_u *name, char_u *val));
+char_u *get_env_name __ARGS((expand_T *xp, int idx));
+void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one));
+char_u *home_replace_save __ARGS((buf_T *buf, char_u *src));
+int fullpathcmp __ARGS((char_u *s1, char_u *s2, int checkname));
+char_u *gettail __ARGS((char_u *fname));
+char_u *gettail_sep __ARGS((char_u *fname));
+char_u *getnextcomp __ARGS((char_u *fname));
+char_u *get_past_head __ARGS((char_u *path));
+int vim_ispathsep __ARGS((int c));
+int vim_ispathlistsep __ARGS((int c));
+int dir_of_file_exists __ARGS((char_u *fname));
+int vim_fnamecmp __ARGS((char_u *x, char_u *y));
+int vim_fnamencmp __ARGS((char_u *x, char_u *y, size_t len));
+char_u *concat_fnames __ARGS((char_u *fname1, char_u *fname2, int sep));
+char_u *concat_str __ARGS((char_u *str1, char_u *str2));
+void add_pathsep __ARGS((char_u *p));
+char_u *FullName_save __ARGS((char_u *fname, int force));
+pos_T *find_start_comment __ARGS((int ind_maxcomment));
+void do_c_expr_indent __ARGS((void));
+int cin_islabel __ARGS((int ind_maxcomment));
+int cin_iscase __ARGS((char_u *s));
+int cin_isscopedecl __ARGS((char_u *s));
+int get_c_indent __ARGS((void));
+int get_expr_indent __ARGS((void));
+int get_lisp_indent __ARGS((void));
+void prepare_to_exit __ARGS((void));
+void preserve_exit __ARGS((void));
+int vim_fexists __ARGS((char_u *fname));
+void line_breakcheck __ARGS((void));
+void fast_breakcheck __ARGS((void));
+int expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags));
+int match_suffix __ARGS((char_u *fname));
+int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags, int didstar));
+int gen_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags));
+void addfile __ARGS((garray_T *gap, char_u *f, int flags));
+char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags));
+void FreeWild __ARGS((int count, char_u **files));
+int goto_im __ARGS((void));
/* vim: set ft=c : */