aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/search.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 21:52:58 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 21:52:58 +0000
commit931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch)
treed8c1843a95da5ea0bb4acc09f7e37843d9995c86 /src/nvim/search.c
parent142d9041391780ac15b89886a54015fdc5c73995 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-userreg.tar.gz
rneovim-userreg.tar.bz2
rneovim-userreg.zip
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'src/nvim/search.c')
-rw-r--r--src/nvim/search.c352
1 files changed, 169 insertions, 183 deletions
diff --git a/src/nvim/search.c b/src/nvim/search.c
index b24b6ad27c..642219c1e0 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
// search.c: code for normal mode searching commands
#include <assert.h>
@@ -11,7 +8,7 @@
#include <stdlib.h>
#include <string.h>
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
@@ -27,13 +24,14 @@
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/func_attr.h"
#include "nvim/getchar.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
-#include "nvim/highlight_defs.h"
+#include "nvim/highlight.h"
#include "nvim/indent_c.h"
#include "nvim/insexpand.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
@@ -43,23 +41,31 @@
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/option_vars.h"
#include "nvim/os/fs.h"
#include "nvim/os/input.h"
#include "nvim/os/time.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/profile.h"
#include "nvim/regexp.h"
-#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/state_defs.h"
#include "nvim/strings.h"
+#include "nvim/tag.h"
#include "nvim/ui.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#include "nvim/window.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "search.c.generated.h"
#endif
+static const char e_search_hit_top_without_match_for_str[]
+ = N_("E384: Search hit TOP without match for: %s");
+static const char e_search_hit_bottom_without_match_for_str[]
+ = N_("E385: Search hit BOTTOM without match for: %s");
+
// This file contains various searching-related routines. These fall into
// three groups:
// 1. string searches (for /, ?, n, and N)
@@ -88,14 +94,14 @@
static struct spat spats[2] = {
// Last used search pattern
- [0] = { NULL, true, false, 0, { '/', false, false, 0L }, NULL },
+ [0] = { NULL, true, false, 0, { '/', false, false, 0 }, NULL },
// Last used substitute pattern
- [1] = { NULL, true, false, 0, { '/', false, false, 0L }, NULL }
+ [1] = { NULL, true, false, 0, { '/', false, false, 0 }, NULL }
};
static int last_idx = 0; // index in spats[] for RE_LAST
-static char_u lastc[2] = { NUL, NUL }; // last character searched for
+static uint8_t lastc[2] = { NUL, NUL }; // last character searched for
static Direction lastcdir = FORWARD; // last direction of character search
static int last_t_cmd = true; // last search t_cmd
static char lastc_bytes[MB_MAXBYTES + 1];
@@ -136,14 +142,12 @@ typedef struct SearchedFile {
int search_regcomp(char *pat, char **used_pat, int pat_save, int pat_use, int options,
regmmatch_T *regmatch)
{
- int magic;
- int i;
-
rc_did_emsg = false;
- magic = magic_isset();
+ int magic = magic_isset();
// If no pattern given, use a previously defined pattern.
if (pat == NULL || *pat == NUL) {
+ int i;
if (pat_use == RE_LAST) {
i = last_idx;
} else {
@@ -343,13 +347,13 @@ void restore_last_search_pattern(void)
static void save_incsearch_state(void)
{
saved_search_match_endcol = search_match_endcol;
- saved_search_match_lines = search_match_lines;
+ saved_search_match_lines = search_match_lines;
}
static void restore_incsearch_state(void)
{
search_match_endcol = saved_search_match_endcol;
- search_match_lines = saved_search_match_lines;
+ search_match_lines = saved_search_match_lines;
}
char *last_search_pattern(void)
@@ -439,7 +443,7 @@ int last_csearch_until(void)
void set_last_csearch(int c, char *s, int len)
{
- *lastc = (char_u)c;
+ *lastc = (uint8_t)c;
lastc_bytelen = len;
if (len) {
memcpy(lastc_bytes, s, (size_t)len);
@@ -547,7 +551,7 @@ void last_pat_prog(regmmatch_T *regmatch)
/// the index of the first matching
/// subpattern plus one; one if there was none.
int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, char *pat,
- long count, int options, int pat_use, searchit_arg_T *extra_arg)
+ int count, int options, int pat_use, searchit_arg_T *extra_arg)
{
int found;
linenr_T lnum; // no init to shut up Apollo cc
@@ -557,12 +561,10 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
lpos_T endpos;
lpos_T matchpos;
int loop;
- pos_T start_pos;
- int at_first_line;
int extra_col;
int start_char_len;
bool match_ok;
- long nmatched;
+ int nmatched;
int submatch = 0;
bool first_match = true;
const int called_emsg_before = called_emsg;
@@ -596,7 +598,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
&& pos->lnum <= buf->b_ml.ml_line_count
&& pos->col < MAXCOL - 2) {
// Watch out for the "col" being MAXCOL - 2, used in a closed fold.
- ptr = ml_get_buf(buf, pos->lnum, false);
+ ptr = ml_get_buf(buf, pos->lnum);
if ((int)strlen(ptr) <= pos->col) {
start_char_len = 1;
} else {
@@ -611,9 +613,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
extra_col = (options & SEARCH_START) ? start_char_len : 0;
}
- start_pos = *pos; // remember start pos for detecting no match
+ pos_T start_pos = *pos; // remember start pos for detecting no match
found = 0; // default: not found
- at_first_line = true; // default: start in first line
+ int at_first_line = true; // default: start in first line
if (pos->lnum == 0) { // correct lnum for when starting in line 0
pos->lnum = 1;
pos->col = 0;
@@ -667,7 +669,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
if (lnum + matchpos.lnum > buf->b_ml.ml_line_count) {
ptr = "";
} else {
- ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
+ ptr = ml_get_buf(buf, lnum + matchpos.lnum);
}
// Forward search in the first line: match should be after
@@ -683,9 +685,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
// otherwise "/$" will get stuck on end of line.
while (matchpos.lnum == 0
&& (((options & SEARCH_END) && first_match)
- ? (nmatched == 1
- && (int)endpos.col - 1
- < (int)start_pos.col + extra_col)
+ ? (nmatched == 1
+ && (int)endpos.col - 1
+ < (int)start_pos.col + extra_col)
: ((int)matchpos.col
- (ptr[matchpos.col] == NUL)
< (int)start_pos.col + extra_col))) {
@@ -739,7 +741,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
}
// Need to get the line pointer again, a multi-line search may
// have made it invalid.
- ptr = ml_get_buf(buf, lnum, false);
+ ptr = ml_get_buf(buf, lnum);
}
if (!match_ok) {
continue;
@@ -752,7 +754,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
// When putting the new cursor at the end, compare
// relative to the end of the match.
match_ok = false;
- for (;;) {
+ while (true) {
// Remember a position that is before the start
// position, we use it if it's the last match in
// the line. Always accept a position after
@@ -821,7 +823,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
}
// Need to get the line pointer again, a
// multi-line search may have made it invalid.
- ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
+ ptr = ml_get_buf(buf, lnum + matchpos.lnum);
}
// If there is only a match after the cursor, skip
@@ -844,12 +846,12 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
if (endpos.col == 0) {
if (pos->lnum > 1) { // just in case
pos->lnum--;
- pos->col = (colnr_T)strlen(ml_get_buf(buf, pos->lnum, false));
+ pos->col = (colnr_T)strlen(ml_get_buf(buf, pos->lnum));
}
} else {
pos->col--;
if (pos->lnum <= buf->b_ml.ml_line_count) {
- ptr = ml_get_buf(buf, pos->lnum, false);
+ ptr = ml_get_buf(buf, pos->lnum);
pos->col -= utf_head_off(ptr, ptr + pos->col);
}
}
@@ -913,19 +915,22 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
|| found || loop) {
break;
}
- //
+
// If 'wrapscan' is set we continue at the other end of the file.
- // If 'shortmess' does not contain 's', we give a message.
+ // If 'shortmess' does not contain 's', we give a message, but
+ // only, if we won't show the search stat later anyhow,
+ // (so SEARCH_COUNT must be absent).
// This message is also remembered in keep_msg for when the screen
// is redrawn. The keep_msg is cleared whenever another message is
// written.
- //
if (dir == BACKWARD) { // start second loop at the other end
lnum = buf->b_ml.ml_line_count;
} else {
lnum = 1;
}
- if (!shortmess(SHM_SEARCH) && (options & SEARCH_MSG)) {
+ if (!shortmess(SHM_SEARCH)
+ && shortmess(SHM_SEARCHCOUNT)
+ && (options & SEARCH_MSG)) {
give_warning(_(dir == BACKWARD ? top_bot_msg : bot_top_msg), true);
}
if (extra_arg != NULL) {
@@ -948,11 +953,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
if (p_ws) {
semsg(_(e_patnotf2), mr_pattern);
} else if (lnum == 0) {
- semsg(_("E384: search hit TOP without match for: %s"),
- mr_pattern);
+ semsg(_(e_search_hit_top_without_match_for_str), mr_pattern);
} else {
- semsg(_("E385: search hit BOTTOM without match for: %s"),
- mr_pattern);
+ semsg(_(e_search_hit_bottom_without_match_for_str), mr_pattern);
}
}
return FAIL;
@@ -961,7 +964,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
// A pattern like "\n\zs" may go past the last line.
if (pos->lnum > buf->b_ml.ml_line_count) {
pos->lnum = buf->b_ml.ml_line_count;
- pos->col = (int)strlen(ml_get_buf(buf, pos->lnum, false));
+ pos->col = (int)strlen(ml_get_buf(buf, pos->lnum));
if (pos->col > 0) {
pos->col--;
}
@@ -977,7 +980,7 @@ void set_search_direction(int cdir)
static void set_vv_searchforward(void)
{
- set_vim_var_nr(VV_SEARCHFORWARD, (long)(spats[0].off.dir == '/'));
+ set_vim_var_nr(VV_SEARCHFORWARD, spats[0].off.dir == '/');
}
// Return the number of the first subpat that matched.
@@ -1023,15 +1026,14 @@ static int first_submatch(regmmatch_T *rp)
/// @param sia optional arguments or NULL
///
/// @return 0 for failure, 1 for found, 2 for found and line offset added.
-int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, int options,
+int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, int count, int options,
searchit_arg_T *sia)
{
pos_T pos; // position of the last match
char *searchstr;
- struct soffset old_off;
int retval; // Return value
char *p;
- long c;
+ int64_t c;
char *dircp;
char *strcopy = NULL;
char *ps;
@@ -1047,13 +1049,13 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i
// Save the values for when (options & SEARCH_KEEP) is used.
// (there is no "if ()" around this because gcc wants them initialized)
- old_off = spats[0].off;
+ struct soffset old_off = spats[0].off;
pos = curwin->w_cursor; // start searching at the cursor position
// Find out the direction of the search.
if (dirc == 0) {
- dirc = (char_u)spats[0].off.dir;
+ dirc = (uint8_t)spats[0].off.dir;
} else {
spats[0].off.dir = (char)dirc;
set_vv_searchforward();
@@ -1085,7 +1087,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i
}
// Repeat the search when pattern followed by ';', e.g. "/foo/;?bar".
- for (;;) {
+ while (true) {
bool show_top_bot_msg = false;
searchstr = pat;
@@ -1169,7 +1171,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i
// Get the offset, so we know how long it is.
if (!cmd_silent
&& (spats[0].off.line || spats[0].off.end || spats[0].off.off)) {
- p = off_buf; // -V507
+ p = off_buf;
*p++ = (char)dirc;
if (spats[0].off.end) {
*p++ = 'e';
@@ -1262,7 +1264,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, i
memset(msgbuf + pat_len, ' ', (size_t)(r - msgbuf));
}
}
- msg_outtrans(msgbuf);
+ msg_outtrans(msgbuf, 0);
msg_clr_eos();
msg_check();
@@ -1434,13 +1436,11 @@ end_do_search:
int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char *pat)
{
linenr_T start = 0;
- char *ptr;
- char *p;
if (buf->b_ml.ml_line_count == 0) {
return FAIL;
}
- for (;;) {
+ while (true) {
pos->lnum += dir;
if (pos->lnum < 1) {
if (p_ws) {
@@ -1469,21 +1469,21 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char *pat)
if (start == 0) {
start = pos->lnum;
}
- ptr = ml_get_buf(buf, pos->lnum, false);
- p = skipwhite(ptr);
+ char *ptr = ml_get_buf(buf, pos->lnum);
+ char *p = skipwhite(ptr);
pos->col = (colnr_T)(p - ptr);
// when adding lines the matching line may be empty but it is not
// ignored because we are interested in the next line -- Acevedo
if (compl_status_adding() && !compl_status_sol()) {
- if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) {
+ if (mb_strcmp_ic((bool)p_ic, p, pat) == 0) {
return OK;
}
} else if (*p != NUL) { // Ignore empty lines.
// Expanding lines or words.
assert(ins_compl_len() >= 0);
if ((p_ic ? mb_strnicmp(p, pat, (size_t)ins_compl_len())
- : strncmp(p, pat, (size_t)ins_compl_len())) == 0) {
+ : strncmp(p, pat, (size_t)ins_compl_len())) == 0) {
return OK;
}
}
@@ -1502,15 +1502,12 @@ int searchc(cmdarg_T *cap, int t_cmd)
{
int c = cap->nchar; // char to search for
int dir = cap->arg; // true for searching forward
- long count = cap->count1; // repeat count
- int col;
- char *p;
- int len;
+ int count = cap->count1; // repeat count
bool stop = true;
if (c != NUL) { // normal search: remember args for repeat
if (!KeyStuffed) { // don't remember when redoing
- *lastc = (char_u)c;
+ *lastc = (uint8_t)c;
set_csearch_direction(dir);
set_csearch_until(t_cmd);
lastc_bytelen = utf_char2bytes(c, lastc_bytes);
@@ -1524,7 +1521,7 @@ int searchc(cmdarg_T *cap, int t_cmd)
}
}
} else { // repeat previous search
- if (*lastc == NUL && lastc_bytelen == 1) {
+ if (*lastc == NUL && lastc_bytelen <= 1) {
return FAIL;
}
if (dir) { // repeat in opposite direction
@@ -1550,12 +1547,12 @@ int searchc(cmdarg_T *cap, int t_cmd)
cap->oap->inclusive = true;
}
- p = get_cursor_line_ptr();
- col = curwin->w_cursor.col;
- len = (int)strlen(p);
+ char *p = get_cursor_line_ptr();
+ int col = curwin->w_cursor.col;
+ int len = (int)strlen(p);
while (count--) {
- for (;;) {
+ while (true) {
if (dir > 0) {
col += utfc_ptr2len(p + col);
if (col >= len) {
@@ -1567,7 +1564,7 @@ int searchc(cmdarg_T *cap, int t_cmd)
}
col -= utf_head_off(p, p + col - 1) + 1;
}
- if (lastc_bytelen == 1) {
+ if (lastc_bytelen <= 1) {
if (p[col] == c && stop) {
break;
}
@@ -1632,7 +1629,7 @@ static bool find_rawstring_end(char *linep, pos_T *startpos, pos_T *endpos)
for (p = linep + startpos->col + 1; *p && *p != '('; p++) {}
size_t delim_len = (size_t)((p - linep) - startpos->col - 1);
- char *delim_copy = xstrnsave(linep + startpos->col + 1, delim_len);
+ char *delim_copy = xmemdupz(linep + startpos->col + 1, delim_len);
bool found = false;
for (lnum = startpos->lnum; lnum <= endpos->lnum; lnum++) {
char *line = ml_get(lnum);
@@ -1821,7 +1818,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
if (linep[pos.col] == NUL && pos.col) {
pos.col--;
}
- for (;;) {
+ while (true) {
initc = utf_ptr2char(linep + pos.col);
if (initc == NUL) {
break;
@@ -1841,11 +1838,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
return NULL;
}
} else if (!cpo_bsl) {
- int col, bslcnt = 0;
+ int bslcnt = 0;
// Set "match_escaped" if there are an odd number of
// backslashes.
- for (col = pos.col; check_prevcol(linep, col, '\\', &col);) {
+ for (int col = pos.col; check_prevcol(linep, col, '\\', &col);) {
bslcnt++;
}
match_escaped = (bslcnt & 1);
@@ -2207,10 +2204,10 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
// quotes when the start is also inside of quotes.
if ((!inquote || start_in_quotes == kTrue)
&& (c == initc || c == findc)) {
- int col, bslcnt = 0;
+ int bslcnt = 0;
if (!cpo_bsl) {
- for (col = pos.col; check_prevcol(linep, col, '\\', &col);) {
+ for (int col = pos.col; check_prevcol(linep, col, '\\', &col);) {
bslcnt++;
}
}
@@ -2244,10 +2241,10 @@ int check_linecomment(const char *line)
const char *p = line; // scan from start
// skip Lispish one-line comments
if (curbuf->b_p_lisp) {
- if (vim_strchr((char *)p, ';') != NULL) { // there may be comments
+ if (vim_strchr(p, ';') != NULL) { // there may be comments
bool in_str = false; // inside of string
- while ((p = strpbrk((char *)p, "\";")) != NULL) {
+ while ((p = strpbrk(p, "\";")) != NULL) {
if (*p == '"') {
if (in_str) {
if (*(p - 1) != '\\') { // skip escaped quote
@@ -2269,7 +2266,7 @@ int check_linecomment(const char *line)
p = NULL;
}
} else {
- while ((p = vim_strchr((char *)p, '/')) != NULL) {
+ while ((p = vim_strchr(p, '/')) != NULL) {
// Accept a double /, unless it's preceded with * and followed by *,
// because * / / * is an end and start of a C comment. Only
// accept the position if it is not inside a string.
@@ -2295,15 +2292,10 @@ int check_linecomment(const char *line)
/// @param c char to show match for
void showmatch(int c)
{
- pos_T *lpos, save_cursor;
- pos_T mpos;
+ pos_T *lpos;
colnr_T vcol;
- long *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
- long *siso = curwin->w_p_siso >= 0 ? &curwin->w_p_siso : &p_siso;
- long save_so;
- long save_siso;
- int save_state;
- colnr_T save_dollar_vcol;
+ OptInt *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
+ OptInt *siso = curwin->w_p_siso >= 0 ? &curwin->w_p_siso : &p_siso;
char *p;
// Only show match for chars in the 'matchpairs' option.
@@ -2345,26 +2337,26 @@ void showmatch(int c)
return;
}
- mpos = *lpos; // save the pos, update_screen() may change it
- save_cursor = curwin->w_cursor;
- save_so = *so;
- save_siso = *siso;
+ pos_T mpos = *lpos; // save the pos, update_screen() may change it
+ pos_T save_cursor = curwin->w_cursor;
+ OptInt save_so = *so;
+ OptInt save_siso = *siso;
// Handle "$" in 'cpo': If the ')' is typed on top of the "$",
// stop displaying the "$".
if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol) {
dollar_vcol = -1;
}
curwin->w_virtcol++; // do display ')' just before "$"
- update_screen(); // show the new char first
- save_dollar_vcol = dollar_vcol;
- save_state = State;
+ colnr_T save_dollar_vcol = dollar_vcol;
+ int save_state = State;
State = MODE_SHOWMATCH;
ui_cursor_shape(); // may show different cursor shape
curwin->w_cursor = mpos; // move to matching char
*so = 0; // don't use 'scrolloff' here
*siso = 0; // don't use 'sidescrolloff' here
- show_cursor_info(false);
+ show_cursor_info_later(false);
+ update_screen(); // show the new char
setcursor();
ui_flush();
// Restore dollar_vcol(), because setcursor() may call curs_rows()
@@ -2375,9 +2367,9 @@ void showmatch(int c)
// brief pause, unless 'm' is present in 'cpo' and a character is
// available.
if (vim_strchr(p_cpo, CPO_SHOWMATCH) != NULL) {
- os_delay((uint64_t)p_mat * 100L + 8, true);
+ os_delay((uint64_t)p_mat * 100 + 8, true);
} else if (!char_avail()) {
- os_delay((uint64_t)p_mat * 100L + 9, false);
+ os_delay((uint64_t)p_mat * 100 + 9, false);
}
curwin->w_cursor = save_cursor; // restore cursor position
*so = save_so;
@@ -2390,7 +2382,7 @@ void showmatch(int c)
/// Used while an operator is pending, and in Visual mode.
///
/// @param forward true for forward, false for backward
-int current_search(long count, bool forward)
+int current_search(int count, bool forward)
{
bool old_p_ws = p_ws;
pos_T save_VIsual = VIsual;
@@ -2475,7 +2467,7 @@ int current_search(long count, bool forward)
} 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));
+ pos.col = (colnr_T)strlen(ml_get(curwin->w_buffer->b_ml.ml_line_count));
}
}
}
@@ -2531,7 +2523,6 @@ int current_search(long count, bool forward)
static int is_zero_width(char *pattern, int move, pos_T *cur, Direction direction)
{
regmmatch_T regmatch;
- int nmatched = 0;
int result = -1;
pos_T pos;
const int called_emsg_before = called_emsg;
@@ -2558,13 +2549,14 @@ static int is_zero_width(char *pattern, int move, pos_T *cur, Direction directio
}
if (searchit(curwin, curbuf, &pos, NULL, direction, pattern, 1,
SEARCH_KEEP + flag, RE_SEARCH, NULL) != FAIL) {
+ int nmatched = 0;
// Zero-width pattern should match somewhere, then we can check if
// start and end are in the same position.
do {
regmatch.startpos[0].col++;
- nmatched = (int)vim_regexec_multi(&regmatch, curwin, curbuf,
- pos.lnum, regmatch.startpos[0].col,
- NULL, NULL);
+ nmatched = vim_regexec_multi(&regmatch, curwin, curbuf,
+ pos.lnum, regmatch.startpos[0].col,
+ NULL, NULL);
if (nmatched != 0) {
break;
}
@@ -2587,16 +2579,14 @@ static int is_zero_width(char *pattern, int move, pos_T *cur, Direction directio
/// return true if line 'lnum' is empty or has white chars only.
int linewhite(linenr_T lnum)
{
- char *p;
-
- p = skipwhite(ml_get(lnum));
+ char *p = skipwhite(ml_get(lnum));
return *p == NUL;
}
/// Add the search count "[3/19]" to "msgbuf".
/// See update_search_stat() for other arguments.
static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool show_top_bot_msg,
- char *msgbuf, bool recompute, int maxcount, long timeout)
+ char *msgbuf, bool recompute, int maxcount, int timeout)
{
searchstat_T stat;
@@ -2644,7 +2634,12 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
len += 2;
}
- memmove(msgbuf + strlen(msgbuf) - len, t, len);
+ size_t msgbuf_len = strlen(msgbuf);
+ if (len > msgbuf_len) {
+ len = msgbuf_len;
+ }
+ memmove(msgbuf + msgbuf_len - len, t, len);
+
if (dirc == '?' && stat.cur == maxcount + 1) {
stat.cur = -1;
}
@@ -2663,7 +2658,7 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
// dirc == '/': find the next match
// dirc == '?': find the previous match
static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchstat_T *stat,
- bool recompute, int maxcount, long timeout)
+ bool recompute, int maxcount, int timeout)
{
int save_ws = p_ws;
bool wraparound = false;
@@ -2677,7 +2672,6 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
static int chgtick = 0;
static char *lastpat = NULL;
static buf_T *lbuf = NULL;
- proftime_T start;
CLEAR_POINTER(stat);
@@ -2713,15 +2707,18 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
lbuf = curbuf;
}
+ // when searching backwards and having jumped to the first occurrence,
+ // cur must remain greater than 1
if (equalpos(lastpos, *cursor_pos) && !wraparound
- && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 0)) {
+ && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 1)) {
cur += dirc == 0 ? 0 : dirc == '/' ? 1 : -1;
} else {
+ proftime_T start;
bool done_search = false;
pos_T endpos = { 0, 0, 0 };
p_ws = false;
if (timeout > 0) {
- start = profile_setlimit(timeout);
+ start = profile_setlimit(timeout);
}
while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos,
FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST,
@@ -2770,7 +2767,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
pos_T pos = curwin->w_cursor;
char *pattern = NULL;
int maxcount = SEARCH_STAT_DEF_MAX_COUNT;
- long timeout = SEARCH_STAT_DEF_TIMEOUT;
+ int timeout = SEARCH_STAT_DEF_TIMEOUT;
bool recompute = true;
searchstat_T stat;
@@ -2783,29 +2780,27 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
if (argvars[0].v_type != VAR_UNKNOWN) {
dict_T *dict;
dictitem_T *di;
- listitem_T *li;
bool error = false;
- if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) {
- emsg(_(e_dictreq));
+ if (tv_check_for_nonnull_dict_arg(argvars, 0) == FAIL) {
return;
}
dict = argvars[0].vval.v_dict;
- di = tv_dict_find(dict, (const char *)"timeout", -1);
+ di = tv_dict_find(dict, "timeout", -1);
if (di != NULL) {
- timeout = (long)tv_get_number_chk(&di->di_tv, &error);
+ timeout = (int)tv_get_number_chk(&di->di_tv, &error);
if (error) {
return;
}
}
- di = tv_dict_find(dict, (const char *)"maxcount", -1);
+ di = tv_dict_find(dict, "maxcount", -1);
if (di != NULL) {
maxcount = (int)tv_get_number_chk(&di->di_tv, &error);
if (error) {
return;
}
}
- di = tv_dict_find(dict, (const char *)"recompute", -1);
+ di = tv_dict_find(dict, "recompute", -1);
if (di != NULL) {
recompute = tv_get_number_chk(&di->di_tv, &error);
if (error) {
@@ -2819,7 +2814,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
return;
}
}
- di = tv_dict_find(dict, (const char *)"pos", -1);
+ di = tv_dict_find(dict, "pos", -1);
if (di != NULL) {
if (di->di_tv.v_type != VAR_LIST) {
semsg(_(e_invarg2), "pos");
@@ -2829,21 +2824,21 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
semsg(_(e_invarg2), "List format should be [lnum, col, off]");
return;
}
- li = tv_list_find(di->di_tv.vval.v_list, 0L);
+ listitem_T *li = tv_list_find(di->di_tv.vval.v_list, 0);
if (li != NULL) {
pos.lnum = (linenr_T)tv_get_number_chk(TV_LIST_ITEM_TV(li), &error);
if (error) {
return;
}
}
- li = tv_list_find(di->di_tv.vval.v_list, 1L);
+ li = tv_list_find(di->di_tv.vval.v_list, 1);
if (li != NULL) {
pos.col = (colnr_T)tv_get_number_chk(TV_LIST_ITEM_TV(li), &error) - 1;
if (error) {
return;
}
}
- li = tv_list_find(di->di_tv.vval.v_list, 2L);
+ li = tv_list_find(di->di_tv.vval.v_list, 2);
if (li != NULL) {
pos.coladd = (colnr_T)tv_get_number_chk(TV_LIST_ITEM_TV(li), &error);
if (error) {
@@ -3050,8 +3045,8 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s
// Loop through fuzpat and str looking for a match
bool first_match = true;
while (*fuzpat != NUL && *str != NUL) {
- const int c1 = utf_ptr2char((char *)fuzpat);
- const int c2 = utf_ptr2char((char *)str);
+ const int c1 = utf_ptr2char(fuzpat);
+ const int c2 = utf_ptr2char(str);
// Found match
if (mb_tolower(c1) == mb_tolower(c2)) {
@@ -3060,6 +3055,10 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s
return 0;
}
+ int recursiveScore = 0;
+ uint32_t recursiveMatches[MAX_FUZZY_MATCHES];
+ CLEAR_FIELD(recursiveMatches);
+
// "Copy-on-Write" srcMatches into matches
if (first_match && srcMatches != NULL) {
memcpy(matches, srcMatches, (size_t)nextMatch * sizeof(srcMatches[0]));
@@ -3067,9 +3066,7 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s
}
// Recursive call that "skips" this match
- uint32_t recursiveMatches[MAX_FUZZY_MATCHES];
- int recursiveScore = 0;
- const char *const next_char = (char *)str + utfc_ptr2len((char *)str);
+ const char *const next_char = str + utfc_ptr2len(str);
if (fuzzy_match_recursive(fuzpat, next_char, strIdx + 1, &recursiveScore, strBegin, strLen,
matches, recursiveMatches,
sizeof(recursiveMatches) / sizeof(recursiveMatches[0]), nextMatch,
@@ -3120,8 +3117,7 @@ static int fuzzy_match_recursive(const char *fuzpat, const char *str, uint32_t s
/// normalized and varies with pattern.
/// Recursion is limited internally (default=10) to prevent degenerate cases
/// (pat_arg="aaaaaa" str="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").
-/// Uses char_u for match indices. Therefore patterns are limited to
-/// MAX_FUZZY_MATCHES characters.
+/// Patterns are limited to MAX_FUZZY_MATCHES characters.
///
/// @return true if "pat_arg" matches "str". Also returns the match score in
/// "outScore" and the matching character positions in "matches".
@@ -3211,10 +3207,10 @@ static int fuzzy_match_item_compare(const void *const s1, const void *const s2)
static void fuzzy_match_in_list(list_T *const l, char *const str, const bool matchseq,
const char *const key, Callback *const item_cb,
const bool retmatchpos, list_T *const fmatchlist,
- const long max_matches)
+ const int max_matches)
FUNC_ATTR_NONNULL_ARG(2, 5, 7)
{
- long len = tv_list_len(l);
+ int len = tv_list_len(l);
if (len == 0) {
return;
}
@@ -3223,7 +3219,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat
}
fuzzyItem_T *const items = xcalloc((size_t)len, sizeof(fuzzyItem_T));
- long match_count = 0;
+ int match_count = 0;
uint32_t matches[MAX_FUZZY_MATCHES];
// For all the string items in items, get the fuzzy matching score
@@ -3242,7 +3238,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat
// For a dict, either use the specified key to lookup the string or
// use the specified callback function to get the string.
if (key != NULL) {
- itemstr = tv_dict_get_string(tv->vval.v_dict, (const char *)key, false);
+ itemstr = tv_dict_get_string(tv->vval.v_dict, key, false);
} else {
typval_T argv[2];
@@ -3272,7 +3268,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat
if (retmatchpos) {
items[match_count].lmatchpos = tv_list_alloc(kListLenMayKnow);
int j = 0;
- const char *p = (char *)str;
+ const char *p = str;
while (*p != NUL) {
if (!ascii_iswhite(utf_ptr2char(p)) || matchseq) {
tv_list_append_number(items[match_count].lmatchpos, matches[j]);
@@ -3307,7 +3303,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat
}
// Copy the matching strings with a valid score to the return list
- for (long i = 0; i < match_count; i++) {
+ for (int i = 0; i < match_count; i++) {
if (items[i].score == SCORE_NONE) {
break;
}
@@ -3320,7 +3316,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat
assert(li != NULL && TV_LIST_ITEM_TV(li)->vval.v_list != NULL);
retlist = TV_LIST_ITEM_TV(li)->vval.v_list;
- for (long i = 0; i < match_count; i++) {
+ for (int i = 0; i < match_count; i++) {
if (items[i].score == SCORE_NONE) {
break;
}
@@ -3331,7 +3327,7 @@ static void fuzzy_match_in_list(list_T *const l, char *const str, const bool mat
li = tv_list_find(fmatchlist, -1);
assert(li != NULL && TV_LIST_ITEM_TV(li)->vval.v_list != NULL);
retlist = TV_LIST_ITEM_TV(li)->vval.v_list;
- for (long i = 0; i < match_count; i++) {
+ for (int i = 0; i < match_count; i++) {
if (items[i].score == SCORE_NONE) {
break;
}
@@ -3361,10 +3357,9 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv,
Callback cb = CALLBACK_NONE;
const char *key = NULL;
bool matchseq = false;
- long max_matches = 0;
+ int max_matches = 0;
if (argvars[2].v_type != VAR_UNKNOWN) {
- if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL) {
- emsg(_(e_dictreq));
+ if (tv_check_for_nonnull_dict_arg(argvars, 2) == FAIL) {
return;
}
@@ -3389,7 +3384,7 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv,
semsg(_(e_invarg2), tv_get_string(&di->di_tv));
return;
}
- max_matches = (long)tv_get_number_chk(&di->di_tv, NULL);
+ max_matches = (int)tv_get_number_chk(&di->di_tv, NULL);
}
if (tv_dict_find(d, "matchseq", -1) != NULL) {
@@ -3553,26 +3548,19 @@ static char *get_line_and_copy(linenr_T lnum, char *buf)
/// @param start_lnum first line to start searching
/// @param end_lnum last line for searching
void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool skip_comments,
- int type, long count, int action, linenr_T start_lnum, linenr_T end_lnum)
+ int type, int count, int action, linenr_T start_lnum, linenr_T end_lnum)
{
SearchedFile *files; // Stack of included files
SearchedFile *bigger; // When we need more space
int max_path_depth = 50;
- long match_count = 1;
+ int match_count = 1;
- char *pat;
char *new_fname;
char *curr_fname = curbuf->b_fname;
char *prev_fname = NULL;
- linenr_T lnum;
- int depth;
int depth_displayed; // For type==CHECK_PATH
- int old_files;
int already_searched;
- char *file_line;
- char *line;
char *p;
- char save_char;
bool define_matched;
regmatch_T regmatch;
regmatch_T incl_regmatch;
@@ -3590,14 +3578,14 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
incl_regmatch.regprog = NULL;
def_regmatch.regprog = NULL;
- file_line = xmalloc(LSIZE);
+ char *file_line = xmalloc(LSIZE);
if (type != CHECK_PATH && type != FIND_DEFINE
// when CONT_SOL is set compare "ptr" with the beginning of the
// line is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo
&& !compl_status_sol()) {
size_t patlen = len + 5;
- pat = xmalloc(patlen);
+ char *pat = xmalloc(patlen);
assert(len <= INT_MAX);
snprintf(pat, patlen, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr);
// ignore case according to p_ic, p_scs and pat
@@ -3626,23 +3614,23 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
def_regmatch.rm_ic = false; // don't ignore case in define pat.
}
files = xcalloc((size_t)max_path_depth, sizeof(SearchedFile));
- old_files = max_path_depth;
- depth = depth_displayed = -1;
+ int old_files = max_path_depth;
+ int depth = depth_displayed = -1;
- lnum = start_lnum;
+ linenr_T lnum = start_lnum;
if (end_lnum > curbuf->b_ml.ml_line_count) {
end_lnum = curbuf->b_ml.ml_line_count;
}
if (lnum > end_lnum) { // do at least one line
lnum = end_lnum;
}
- line = get_line_and_copy(lnum, file_line);
+ char *line = get_line_and_copy(lnum, file_line);
- for (;;) {
+ while (true) {
if (incl_regmatch.regprog != NULL
- && vim_regexec(&incl_regmatch, line, (colnr_T)0)) {
+ && vim_regexec(&incl_regmatch, line, 0)) {
char *p_fname = (curr_fname == curbuf->b_fname)
- ? curbuf->b_ffname : curr_fname;
+ ? curbuf->b_ffname : curr_fname;
if (inc_opt != NULL && strstr(inc_opt, "\\zs") != NULL) {
// Use text from '\zs' to '\ze' (or end) of 'include'.
@@ -3650,11 +3638,11 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
(size_t)(incl_regmatch.endp[0]
- incl_regmatch.startp[0]),
FNAME_EXP|FNAME_INCL|FNAME_REL,
- 1L, p_fname);
+ 1, p_fname);
} else {
// Use text after match with 'include'.
new_fname = file_name_in_line(incl_regmatch.endp[0], 0,
- FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname,
+ FNAME_EXP|FNAME_INCL|FNAME_REL, 1, p_fname,
NULL);
}
already_searched = false;
@@ -3715,7 +3703,7 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
if (new_fname != NULL) {
// using "new_fname" is more reliable, e.g., when
// 'includeexpr' is set.
- msg_outtrans_attr(new_fname, HL_ATTR(HLF_D));
+ msg_outtrans(new_fname, HL_ATTR(HLF_D));
} else {
// Isolate the file name.
// Include the surrounding "" or <> if present.
@@ -3747,9 +3735,9 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
i++;
}
}
- save_char = p[i];
+ char save_char = p[i];
p[i] = NUL;
- msg_outtrans_attr(p, HL_ATTR(HLF_D));
+ msg_outtrans(p, HL_ATTR(HLF_D));
p[i] = save_char;
}
@@ -3797,14 +3785,14 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
files[depth].lnum = 0;
files[depth].matched = false;
if (action == ACTION_EXPAND) {
- msg_hist_off = true; // reset in msg_trunc_attr()
+ msg_hist_off = true; // reset in msg_trunc()
vim_snprintf(IObuff, IOSIZE,
_("Scanning included file: %s"),
new_fname);
- msg_trunc_attr(IObuff, true, HL_ATTR(HLF_R));
+ msg_trunc(IObuff, true, HL_ATTR(HLF_R));
} else if (p_verbose >= 5) {
verbose_enter();
- smsg(_("Searching included file %s"), new_fname);
+ smsg(0, _("Searching included file %s"), new_fname);
verbose_leave();
}
}
@@ -3815,7 +3803,7 @@ void find_pattern_in_path(char *ptr, Direction dir, size_t len, bool whole, bool
search_line:
define_matched = false;
if (def_regmatch.regprog != NULL
- && vim_regexec(&def_regmatch, line, (colnr_T)0)) {
+ && vim_regexec(&def_regmatch, line, 0)) {
// Pattern must be first identifier after 'define', so skip
// to that position before checking for match of pattern. Also
// don't let it match beyond the end of this identifier.
@@ -4000,7 +3988,7 @@ search_line:
} else if (action == ACTION_SHOW) {
show_pat_in_path(line, type, did_show, action,
(depth == -1) ? NULL : files[depth].fp,
- (depth == -1) ? &lnum : &files[depth].lnum, 1L);
+ (depth == -1) ? &lnum : &files[depth].lnum, 1);
did_show = true;
} else {
// ":psearch" uses the preview window
@@ -4030,7 +4018,7 @@ search_line:
curwin->w_cursor.lnum = lnum;
check_cursor();
} else {
- if (!GETFILE_SUCCESS(getfile(0, (char *)files[depth].name, NULL, true,
+ if (!GETFILE_SUCCESS(getfile(0, files[depth].name, NULL, true,
files[depth].lnum, false))) {
break; // failed to jump to file
}
@@ -4107,7 +4095,7 @@ exit_matched:
}
already = NULL;
}
- // End of big for (;;) loop.
+ // End of big while (true) loop.
// Close any files that are still open.
for (i = 0; i <= depth; i++) {
@@ -4122,9 +4110,9 @@ exit_matched:
if (type == CHECK_PATH) {
if (!did_show) {
if (action != ACTION_SHOW_ALL) {
- msg(_("All included files were found"));
+ msg(_("All included files were found"), 0);
} else {
- msg(_("No included files"));
+ msg(_("No included files"), 0);
}
}
} else if (!found
@@ -4149,11 +4137,9 @@ fpip_end:
}
static void show_pat_in_path(char *line, int type, bool did_show, int action, FILE *fp,
- linenr_T *lnum, long count)
+ linenr_T *lnum, int count)
FUNC_ATTR_NONNULL_ARG(1, 6)
{
- char *p;
-
if (did_show) {
msg_putchar('\n'); // cursor below last one
} else if (!msg_silent) {
@@ -4162,8 +4148,8 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI
if (got_int) { // 'q' typed at "--more--" message
return;
}
- for (;;) {
- p = line + strlen(line) - 1;
+ while (true) {
+ char *p = line + strlen(line) - 1;
if (fp != NULL) {
// We used fgets(), so get rid of newline at end
if (p >= line && *p == '\n') {
@@ -4175,11 +4161,11 @@ static void show_pat_in_path(char *line, int type, bool did_show, int action, FI
*(p + 1) = NUL;
}
if (action == ACTION_SHOW_ALL) {
- snprintf(IObuff, IOSIZE, "%3ld: ", count); // Show match nr.
- msg_puts((const char *)IObuff);
+ snprintf(IObuff, IOSIZE, "%3d: ", count); // Show match nr.
+ msg_puts(IObuff);
snprintf(IObuff, IOSIZE, "%4" PRIdLINENR, *lnum); // Show line nr.
// Highlight line numbers.
- msg_puts_attr((const char *)IObuff, HL_ATTR(HLF_N));
+ msg_puts_attr(IObuff, HL_ATTR(HLF_N));
msg_puts(" ");
}
msg_prt_line(line, false);