diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/edit.c | 8 | ||||
| -rw-r--r-- | src/nvim/eval.c | 4 | ||||
| -rw-r--r-- | src/nvim/ex_docmd.c | 6 | ||||
| -rw-r--r-- | src/nvim/ex_getln.c | 2 | ||||
| -rw-r--r-- | src/nvim/normal.c | 2 | ||||
| -rw-r--r-- | src/nvim/search.c | 92 | ||||
| -rw-r--r-- | src/nvim/testdir/test_gn.vim | 19 | 
7 files changed, 70 insertions, 63 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 5ac95b64e7..9af003f140 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -4045,13 +4045,15 @@ static int ins_compl_get_exp(pos_T *ini)          if (CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)              || (compl_cont_status & CONT_SOL)) {            found_new_match = search_for_exact_line(ins_buf, pos, -              compl_direction, compl_pattern); -        } else -          found_new_match = searchit(NULL, ins_buf, pos, +                                                  compl_direction, +                                                  compl_pattern); +        } else { +          found_new_match = searchit(NULL, ins_buf, pos, NULL,                                       compl_direction,                                       compl_pattern, 1L,                                       SEARCH_KEEP + SEARCH_NFMSG,                                       RE_LAST, (linenr_T)0, NULL, NULL); +        }          msg_silent--;          if (!compl_started || set_match_pos) {            /* set "compl_started" even on fail */ diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a4606f76f3..49ebf8cef0 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14139,7 +14139,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)    }    pos = save_cursor = curwin->w_cursor; -  subpatnum = searchit(curwin, curbuf, &pos, dir, (char_u *)pat, 1, +  subpatnum = searchit(curwin, curbuf, &pos, NULL, dir, (char_u *)pat, 1,                         options, RE_SEARCH, (linenr_T)lnum_stop, &tm, NULL);    if (subpatnum != FAIL) {      if (flags & SP_SUBPAT) @@ -14657,7 +14657,7 @@ do_searchpair(    clearpos(&foundpos);    pat = pat3;    for (;; ) { -    n = searchit(curwin, curbuf, &pos, dir, pat, 1L, +    n = searchit(curwin, curbuf, &pos, NULL, dir, pat, 1L,                   options, RE_SEARCH, lnum_stop, &tm, NULL);      if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) {        // didn't find it or found the first match again: FAIL diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index ec4b16fbb0..16118d642b 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -3750,12 +3750,12 @@ static linenr_T get_address(exarg_T *eap,          // Start the search just like for the above do_search().          pos.col = (*cmd != '?') ? MAXCOL : 0;          pos.coladd = 0; -        if (searchit(curwin, curbuf, &pos, +        if (searchit(curwin, curbuf, &pos, NULL,                       *cmd == '?' ? BACKWARD : FORWARD,                       (char_u *)"", 1L, SEARCH_MSG, -                     i, (linenr_T)0, NULL, NULL) != FAIL) +                     i, (linenr_T)0, NULL, NULL) != FAIL) {            lnum = pos.lnum; -        else { +        } else {            cmd = NULL;            goto error;          } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 3bfda1f9f0..479d195966 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1069,7 +1069,7 @@ static void command_line_next_incsearch(CommandLineState *s, bool next_match)      search_flags += SEARCH_KEEP;    }    emsg_off++; -  s->i = searchit(curwin, curbuf, &t, +  s->i = searchit(curwin, curbuf, &t, NULL,                    next_match ? FORWARD : BACKWARD,                    pat, s->count, search_flags,                    RE_SEARCH, 0, NULL, NULL); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index db2da6a807..c59de4f4e3 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -3782,7 +3782,7 @@ find_decl (    for (;; ) {      valid = false;      (void)valid;  // Avoid "dead assignment" warning. -    t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD, +    t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,                   pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL, NULL);      if (curwin->w_cursor.lnum >= old_pos.lnum) {        t = false;         // match after start is failure too diff --git a/src/nvim/search.c b/src/nvim/search.c index e64233985b..5661c41129 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -497,8 +497,8 @@ void last_pat_prog(regmmatch_T *regmatch)  }  /// lowest level search function. -/// Search for 'count'th occurrence of pattern 'pat' in direction 'dir'. -/// Start at position 'pos' and return the found position in 'pos'. +/// Search for 'count'th occurrence of pattern "pat" in direction "dir". +/// Start at position "pos" and return the found position in "pos".  ///  /// if (options & SEARCH_MSG) == 0 don't give any messages  /// if (options & SEARCH_MSG) == SEARCH_NFMSG don't give 'notfound' messages @@ -519,6 +519,7 @@ int searchit(                                         buffer without a window! */      buf_T       *buf,      pos_T       *pos, +    pos_T       *end_pos,  // set to end of the match, unless NULL      Direction dir,      char_u      *pat,      long count, @@ -819,11 +820,22 @@ int searchit(                  pos->col -= utf_head_off(ptr, ptr + pos->col);                }              } +            if (end_pos != NULL) { +              end_pos->lnum = lnum + matchpos.lnum; +              end_pos->col = matchpos.col; +            }            } else {              pos->lnum = lnum + matchpos.lnum;              pos->col = matchpos.col; +            if (end_pos != NULL) { +              end_pos->lnum = lnum + endpos.lnum; +              end_pos->col = endpos.col; +            }            }            pos->coladd = 0; +          if (end_pos != NULL) { +            end_pos->coladd = 0; +          }            found = 1;            first_match = false; @@ -1196,7 +1208,7 @@ int do_search(        }      } -    c = searchit(curwin, curbuf, &pos, dirc == '/' ? FORWARD : BACKWARD, +    c = searchit(curwin, curbuf, &pos, NULL, dirc == '/' ? FORWARD : BACKWARD,                   searchstr, count,                   (spats[0].off.end * SEARCH_END                    + (options @@ -3933,7 +3945,7 @@ abort_search:  int  current_search(      long count, -    int forward                    /* move forward or backwards */ +    int forward  // true for forward, false for backward  )  {    bool old_p_ws = p_ws; @@ -3946,8 +3958,8 @@ current_search(    if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))      dec_cursor(); +  pos_T end_pos;                // end position of the pattern match    pos_T orig_pos;               // position of the cursor at beginning -  pos_T first_match;            // position of first match    pos_T pos;                    // position after the pattern    int result;                   // result of various function calls @@ -3981,78 +3993,52 @@ current_search(      int dir = forward ? i : !i;      int flags = 0; -    if (!dir && !one_char) +    if (!dir && !one_char) {        flags = SEARCH_END; +    } +    end_pos = pos; -    result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), +    result = searchit(curwin, curbuf, &pos, &end_pos, +                      (dir ? FORWARD : BACKWARD),                        spats[last_idx].pat, i ? count : 1,                        SEARCH_KEEP | flags, RE_SEARCH, 0, NULL, NULL); -    /* First search may fail, but then start searching from the -     * beginning of the file (cursor might be on the search match) -     * except when Visual mode is active, so that extending the visual -     * selection works. */ -    if (!result && i) {   /* not found, abort */ +    // First search may fail, but then start searching from the +    // beginning of the file (cursor might be on the search match) +    // except when Visual mode is active, so that extending the visual +    // selection works. +    if (i == 1 && !result) {  // not found, abort */        curwin->w_cursor = orig_pos;        if (VIsual_active)          VIsual = save_VIsual;        p_ws = old_p_ws;        return FAIL; -    } else if (!i && !result) { -      if (forward) {     /* try again from start of buffer */ +    } else if (i == 0 && !result) { +      if (forward) {  // try again from start of buffer          clearpos(&pos); -      } else { /* try again from end of buffer */ -                 /* searching backwards, so set pos to last line and col */ +      } else {  // try again from end of buffer +                // searching backwards, so set pos to last line and col          pos.lnum = curwin->w_buffer->b_ml.ml_line_count;          pos.col  = (colnr_T)STRLEN(              ml_get(curwin->w_buffer->b_ml.ml_line_count));        }      } -    if (i == 0) { -      first_match = pos; -    }      p_ws = old_p_ws;    } -  const int flags = forward ? SEARCH_END : SEARCH_START;    pos_T start_pos = pos; -  const Direction direction = forward ? FORWARD : BACKWARD; - -  // Check again from the current cursor position, -  // since the next match might actually be only one char wide -  one_char = is_one_char(spats[last_idx].pat, false, &pos, direction); -  if (one_char < 0) { -    // search failed, abort -    return FAIL; -  } - -  /* move to match, except for zero-width matches, in which case, we are -   * already on the next match */ -  if (!one_char) { -    p_ws = false; -    for (int i = 0; i < 2; i++) { -      result = searchit(curwin, curbuf, &pos, direction, -                        spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, -                        0, NULL, NULL); -      // Search successfull, break out from the loop -      if (result) { -        break; -      } -      // search failed, try again from the last search position match -      pos = first_match; -    } -  }    p_ws = old_p_ws; -  // not found -  if (!result) { -    return FAIL; -  } -  if (!VIsual_active) +  if (!VIsual_active) {      VIsual = start_pos; +  } -  curwin->w_cursor = pos; +  // put cursor on last character of match +  curwin->w_cursor = end_pos; +  if (lt(VIsual, end_pos)) { +    dec_cursor(); +  }    VIsual_active = true;    VIsual_mode = 'v'; @@ -4111,7 +4097,7 @@ static int is_one_char(char_u *pattern, bool move, pos_T *cur,      // accept a match at the cursor position      flag = SEARCH_START;    } -  if (searchit(curwin, curbuf, &pos, direction, pattern, 1, +  if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, 1,                 SEARCH_KEEP + flag, RE_SEARCH, 0, NULL, NULL) != FAIL) {      // Zero-width pattern should match somewhere, then we can check if      // start and end are in the same position. diff --git a/src/nvim/testdir/test_gn.vim b/src/nvim/testdir/test_gn.vim index 405425a42b..5e74289b00 100644 --- a/src/nvim/testdir/test_gn.vim +++ b/src/nvim/testdir/test_gn.vim @@ -133,4 +133,23 @@ func Test_gn_command()    set belloff&vim  endfu +func Test_gn_multi_line() +  new +  call setline(1, [ +        \ 'func Tm1()', +        \ ' echo "one"', +        \ 'endfunc', +        \ 'func Tm2()', +        \ ' echo "two"', +        \ 'endfunc', +        \ 'func Tm3()', +        \ ' echo "three"', +        \ 'endfunc', +        \]) +  /\v^func Tm\d\(\)\n.*\zs".*"\ze$ +  normal jgnrx +  call assert_equal(' echo xxxxx', getline(5)) +  bwipe! +endfunc +  " vim: shiftwidth=2 sts=2 expandtab  | 
