aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/cmdexpand.c84
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]);
}