vim-patch:8.0.1148: gN doesn't work on last match with 'wrapscan' off

Problem:    "gN" doesn't work on last match with 'wrapscan' off. (fcpg)
Solution:   Adjust for searching backward. (Christian Brabandt)
22ab547dc2
This commit is contained in:
Jan Edmund Lazo 2018-08-19 08:39:21 -04:00
parent 098e1f9dfd
commit ff1d111120
3 changed files with 25 additions and 10 deletions

View File

@ -521,7 +521,7 @@ int searchit(
buffer without a window! */ buffer without a window! */
buf_T *buf, buf_T *buf,
pos_T *pos, pos_T *pos,
int dir, Direction dir,
char_u *pat, char_u *pat,
long count, long count,
int options, int options,
@ -3968,8 +3968,9 @@ current_search(
orig_pos = pos = curwin->w_cursor; orig_pos = pos = curwin->w_cursor;
} }
// Is the pattern is zero-width? // Is the pattern is zero-width?, this time, don't care about the direction
int one_char = is_one_char(spats[last_idx].pat, true, &curwin->w_cursor); int one_char = is_one_char(spats[last_idx].pat, true, &curwin->w_cursor,
FORWARD);
if (one_char == -1) { if (one_char == -1) {
p_ws = old_p_ws; p_ws = old_p_ws;
return FAIL; /* pattern not found */ return FAIL; /* pattern not found */
@ -4014,12 +4015,13 @@ current_search(
p_ws = old_p_ws; p_ws = old_p_ws;
} }
int flags = forward ? SEARCH_END : 0; const int flags = forward ? SEARCH_END : SEARCH_START;
pos_T start_pos = pos; pos_T start_pos = pos;
const Direction direction = forward ? FORWARD : BACKWARD;
// Check again from the current cursor position, // Check again from the current cursor position,
// since the next match might actually be only one char wide // since the next match might actually be only one char wide
one_char = is_one_char(spats[last_idx].pat, false, &pos); one_char = is_one_char(spats[last_idx].pat, false, &pos, direction);
if (one_char < 0) { if (one_char < 0) {
// search failed, abort // search failed, abort
return FAIL; return FAIL;
@ -4028,7 +4030,7 @@ current_search(
/* move to match, except for zero-width matches, in which case, we are /* move to match, except for zero-width matches, in which case, we are
* already on the next match */ * already on the next match */
if (!one_char) if (!one_char)
searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD), searchit(curwin, curbuf, &pos, direction,
spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL); spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL);
if (!VIsual_active) if (!VIsual_active)
@ -4063,8 +4065,10 @@ current_search(
/// Check if the pattern is one character long or zero-width. /// Check if the pattern is one character long or zero-width.
/// If move is true, check from the beginning of the buffer, /// If move is true, check from the beginning of the buffer,
/// else from position "cur". /// else from position "cur".
/// "direction" is FORWARD or BACKWARD.
/// Returns TRUE, FALSE or -1 for failure. /// Returns TRUE, FALSE or -1 for failure.
static int is_one_char(char_u *pattern, bool move, pos_T *cur) static int is_one_char(char_u *pattern, bool move, pos_T *cur,
Direction direction)
{ {
regmmatch_T regmatch; regmmatch_T regmatch;
int nmatched = 0; int nmatched = 0;
@ -4091,7 +4095,7 @@ static int is_one_char(char_u *pattern, bool move, pos_T *cur)
// accept a match at the cursor position // accept a match at the cursor position
flag = SEARCH_START; flag = SEARCH_START;
} }
if (searchit(curwin, curbuf, &pos, FORWARD, pattern, 1, if (searchit(curwin, curbuf, &pos, direction, pattern, 1,
SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL) { SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL) {
// Zero-width pattern should match somewhere, then we can check if // Zero-width pattern should match somewhere, then we can check if
// start and end are in the same position. // start and end are in the same position.
@ -4103,7 +4107,9 @@ static int is_one_char(char_u *pattern, bool move, pos_T *cur)
if (!nmatched) { if (!nmatched) {
break; break;
} }
} while (regmatch.startpos[0].col < pos.col); } while (direction == FORWARD
? regmatch.startpos[0].col < pos.col
: regmatch.startpos[0].col > pos.col);
if (!called_emsg) { if (!called_emsg) {
result = (nmatched != 0 result = (nmatched != 0

View File

@ -4,7 +4,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "nvim/types.h" #include "nvim/vim.h"
#include "nvim/buffer_defs.h" #include "nvim/buffer_defs.h"
#include "nvim/eval/typval.h" #include "nvim/eval/typval.h"
#include "nvim/normal.h" #include "nvim/normal.h"

View File

@ -111,6 +111,15 @@ func Test_gn_command()
call assert_equal(['foo baz'], getline(1,'$')) call assert_equal(['foo baz'], getline(1,'$'))
sil! %d_ sil! %d_
" search upwards with nowrapscan set
call setline('.', ['foo', 'bar', 'foo', 'baz'])
set nowrapscan
let @/='foo'
$
norm! dgN
call assert_equal(['foo', 'bar', '', 'baz'], getline(1,'$'))
sil! %d_
set wrapscan&vim set wrapscan&vim
set belloff&vim set belloff&vim
endfu endfu