diff options
-rw-r--r-- | src/nvim/cmdexpand.c | 84 |
1 files changed, 44 insertions, 40 deletions
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 3a9eeb73c8..5d28a481c8 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -645,6 +645,7 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m /// in "xp->xp_selected" static char *get_next_or_prev_match(int mode, expand_T *xp) { + // When no files found, return NULL if (xp->xp_numfiles <= 0) { return NULL; } @@ -652,45 +653,42 @@ static char *get_next_or_prev_match(int mode, expand_T *xp) int findex = xp->xp_selected; if (mode == WILD_PREV) { + // Select last file if at start if (findex == -1) { findex = xp->xp_numfiles; } findex--; } else if (mode == WILD_NEXT) { - findex++; - } else if (mode == WILD_PAGEUP) { - if (findex == 0) { - // at the first entry, don't select any entries - findex = -1; - } else if (findex == -1) { - // no entry is selected. select the last entry - findex = xp->xp_numfiles - 1; - } else { - // go up by the pum height - int ht = pum_get_height(); - if (ht > 3) { - ht -= 2; - } - findex -= ht; - findex = MAX(findex, 0); // few entries left, select the first entry - } - } else if (mode == WILD_PAGEDOWN) { - if (findex == xp->xp_numfiles - 1) { - // at the last entry, don't select any entries - findex = -1; - } else if (findex == -1) { - // no entry is selected. select the first entry - findex = 0; - } else { - // go down by the pum height - int ht = pum_get_height(); - if (ht > 3) { - ht -= 2; - } - findex += ht; - if (findex >= xp->xp_numfiles) { - // few entries left, select the last entry + // Select next file + findex = findex + 1; + } else if (mode == WILD_PAGEUP || mode == WILD_PAGEDOWN) { + // Get the height of popup menu (used for both PAGEUP and PAGEDOWN) + int ht = pum_get_height(); + if (ht > 3) { + ht -= 2; + } + + if (mode == WILD_PAGEUP) { + if (findex == 0) { + // at the first entry, don't select any entries + findex = -1; + } else if (findex == -1) { + // no entry is selected. select the last entry findex = xp->xp_numfiles - 1; + } else { + // go up by the pum height + findex = MAX(findex - ht, 0); + } + } else { // mode == WILD_PAGEDOWN + if (findex < 0) { + // no entry is selected. select the first entry + findex = 0; + } else if (findex == xp->xp_numfiles - 1) { + // at the last entry, don't select any entries + findex = -1; + } else { + // go down by the pum height + findex = MIN(findex + ht, xp->xp_numfiles - 1); } } } else { // mode == WILD_PUM_WANT @@ -698,21 +696,27 @@ static char *get_next_or_prev_match(int mode, expand_T *xp) findex = pum_want.item; } - // When wrapping around, return the original string, set findex to -1. - if (findex < 0) { - findex = xp->xp_orig == NULL ? xp->xp_numfiles - 1 : -1; - } - if (findex >= xp->xp_numfiles) { - findex = xp->xp_orig == NULL ? 0 : -1; + // Handle wrapping around + if (findex < 0 || findex >= xp->xp_numfiles) { + // If original string exists, return to it when wrapping around + if (xp->xp_orig != NULL) { + findex = -1; + } else { + // Wrap around to opposite end + findex = (findex < 0) ? xp->xp_numfiles - 1 : 0; + } } + + // Display matches on screen if (compl_match_array) { compl_selected = findex; cmdline_pum_display(false); } else if (p_wmnu) { redraw_wildmenu(xp, xp->xp_numfiles, xp->xp_files, findex, cmd_showtail); } - xp->xp_selected = findex; + xp->xp_selected = findex; + // Return the original string or the selected match return xstrdup(findex == -1 ? xp->xp_orig : xp->xp_files[findex]); } |