diff options
author | Josh Rahm <rahm@google.com> | 2022-10-11 19:00:52 +0000 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-10-11 19:00:52 +0000 |
commit | 21e2e46242033c7aaa6ccfb23e256680816c063c (patch) | |
tree | f089522cfb145d6e9c8a86a01d8e454ce5501e20 /src/nvim/search.c | |
parent | 179d3ed87b17988f5fe00d8b99f2611a28212be7 (diff) | |
parent | 760b399f6c0c6470daa0663752bd22886997f9e6 (diff) | |
download | rneovim-floattitle.tar.gz rneovim-floattitle.tar.bz2 rneovim-floattitle.zip |
Merge remote-tracking branch 'upstream/master' into floattitlefloattitle
Diffstat (limited to 'src/nvim/search.c')
-rw-r--r-- | src/nvim/search.c | 2523 |
1 files changed, 302 insertions, 2221 deletions
diff --git a/src/nvim/search.c b/src/nvim/search.c index c53d955974..ed0f25cba0 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -1,9 +1,7 @@ // 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 - */ +// search.c: code for normal mode searching commands #include <assert.h> #include <inttypes.h> @@ -106,10 +104,8 @@ static bool saved_spats_no_hlsearch = false; static char_u *mr_pattern = NULL; // pattern used by search_regcomp() static bool mr_pattern_alloced = false; // mr_pattern was allocated -/* - * Type used by find_pattern_in_path() to remember which included files have - * been searched already. - */ +// Type used by find_pattern_in_path() to remember which included files have +// been searched already. typedef struct SearchedFile { FILE *fp; // File pointer char_u *name; // Full name of file @@ -139,9 +135,7 @@ int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatc rc_did_emsg = false; magic = p_magic; - /* - * If no pattern given, use a previously defined pattern. - */ + // If no pattern given, use a previously defined pattern. if (pat == NULL || *pat == NUL) { if (pat_use == RE_LAST) { i = last_idx; @@ -161,7 +155,7 @@ int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatc magic = spats[i].magic; no_smartcase = spats[i].no_scs; } else if (options & SEARCH_HIS) { // put new pattern in history - add_to_history(HIST_SEARCH, pat, true, NUL); + add_to_history(HIST_SEARCH, (char *)pat, true, NUL); } if (mr_pattern_alloced) { @@ -170,24 +164,22 @@ int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatc } if (curwin->w_p_rl && *curwin->w_p_rlc == 's') { - mr_pattern = reverse_text(pat); + mr_pattern = (char_u *)reverse_text((char *)pat); mr_pattern_alloced = true; } else { mr_pattern = pat; } - /* - * Save the currently used pattern in the appropriate place, - * unless the pattern should not be remembered. - */ + // Save the currently used pattern in the appropriate place, + // unless the pattern should not be remembered. if (!(options & SEARCH_KEEP) && (cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) { // search or global command if (pat_save == RE_SEARCH || pat_save == RE_BOTH) { - save_re_pat(RE_SEARCH, pat, magic); + save_re_pat(RE_SEARCH, (char *)pat, magic); } // substitute or global command if (pat_save == RE_SUBST || pat_save == RE_BOTH) { - save_re_pat(RE_SUBST, pat, magic); + save_re_pat(RE_SUBST, (char *)pat, magic); } } @@ -200,19 +192,17 @@ int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatc return OK; } -/* - * Get search pattern used by search_regcomp(). - */ +// Get search pattern used by search_regcomp(). char_u *get_search_pat(void) { return mr_pattern; } -void save_re_pat(int idx, char_u *pat, int magic) +void save_re_pat(int idx, char *pat, int magic) { - if (spats[idx].pat != pat) { + if (spats[idx].pat != (char_u *)pat) { free_spat(&spats[idx]); - spats[idx].pat = vim_strsave(pat); + spats[idx].pat = (char_u *)xstrdup(pat); spats[idx].magic = magic; spats[idx].no_scs = no_smartcase; spats[idx].timestamp = os_time(); @@ -220,16 +210,14 @@ void save_re_pat(int idx, char_u *pat, int magic) last_idx = idx; // If 'hlsearch' set and search pat changed: need redraw. if (p_hls) { - redraw_all_later(SOME_VALID); + redraw_all_later(UPD_SOME_VALID); } set_no_hlsearch(false); } } -/* - * Save the search patterns, so they can be restored later. - * Used before/after executing autocommands and user functions. - */ +// Save the search patterns, so they can be restored later. +// Used before/after executing autocommands and user functions. static int save_level = 0; void save_search_patterns(void) @@ -237,11 +225,11 @@ void save_search_patterns(void) if (save_level++ == 0) { saved_spats[0] = spats[0]; if (spats[0].pat != NULL) { - saved_spats[0].pat = vim_strsave(spats[0].pat); + saved_spats[0].pat = (char_u *)xstrdup((char *)spats[0].pat); } saved_spats[1] = spats[1]; if (spats[1].pat != NULL) { - saved_spats[1].pat = vim_strsave(spats[1].pat); + saved_spats[1].pat = (char_u *)xstrdup((char *)spats[1].pat); } saved_spats_last_idx = last_idx; saved_spats_no_hlsearch = no_hlsearch; @@ -308,7 +296,7 @@ void save_last_search_pattern(void) saved_last_search_spat = spats[RE_SEARCH]; if (spats[RE_SEARCH].pat != NULL) { - saved_last_search_spat.pat = vim_strsave(spats[RE_SEARCH].pat); + saved_last_search_spat.pat = (char_u *)xstrdup((char *)spats[RE_SEARCH].pat); } saved_last_idx = last_idx; saved_no_hlsearch = no_hlsearch; @@ -354,10 +342,8 @@ char_u *last_search_pattern(void) return spats[RE_SEARCH].pat; } -/* - * Return TRUE when case should be ignored for search pattern "pat". - * Uses the 'ignorecase' and 'smartcase' options. - */ +/// Return true when case should be ignored for search pattern "pat". +/// Uses the 'ignorecase' and 'smartcase' options. int ignorecase(char_u *pat) { return ignorecase_opt(pat, p_ic, p_scs); @@ -423,7 +409,7 @@ int last_csearch_forward(void) int last_csearch_until(void) { - return last_t_cmd == TRUE; + return last_t_cmd == true; } void set_last_csearch(int c, char_u *s, int len) @@ -452,19 +438,15 @@ char_u *last_search_pat(void) return spats[last_idx].pat; } -/* - * Reset search direction to forward. For "gd" and "gD" commands. - */ +// Reset search direction to forward. For "gd" and "gD" commands. void reset_search_dir(void) { spats[0].off.dir = '/'; set_vv_searchforward(); } -/* - * Set the last search pattern. For ":let @/ =" and ShaDa file. - * Also set the saved search pattern, so that this works in an autocommand. - */ +// Set the last search pattern. For ":let @/ =" and ShaDa file. +// Also set the saved search pattern, so that this works in an autocommand. void set_last_search_pat(const char_u *s, int idx, int magic, int setlast) { free_spat(&spats[idx]); @@ -480,8 +462,8 @@ void set_last_search_pat(const char_u *s, int idx, int magic, int setlast) spats[idx].no_scs = false; spats[idx].off.dir = '/'; set_vv_searchforward(); - spats[idx].off.line = FALSE; - spats[idx].off.end = FALSE; + spats[idx].off.line = false; + spats[idx].off.end = false; spats[idx].off.off = 0; if (setlast) { last_idx = idx; @@ -492,28 +474,26 @@ void set_last_search_pat(const char_u *s, int idx, int magic, int setlast) if (spats[idx].pat == NULL) { saved_spats[idx].pat = NULL; } else { - saved_spats[idx].pat = vim_strsave(spats[idx].pat); + saved_spats[idx].pat = (char_u *)xstrdup((char *)spats[idx].pat); } saved_spats_last_idx = last_idx; } // If 'hlsearch' set and search pat changed: need redraw. if (p_hls && idx == last_idx && !no_hlsearch) { - redraw_all_later(SOME_VALID); + redraw_all_later(UPD_SOME_VALID); } } -/* - * Get a regexp program for the last used search pattern. - * This is used for highlighting all matches in a window. - * Values returned in regmatch->regprog and regmatch->rmm_ic. - */ +// Get a regexp program for the last used search pattern. +// This is used for highlighting all matches in a window. +// Values returned in regmatch->regprog and regmatch->rmm_ic. void last_pat_prog(regmmatch_T *regmatch) { if (spats[last_idx].pat == NULL) { regmatch->regprog = NULL; return; } - ++emsg_off; // So it doesn't beep if bad expr + emsg_off++; // So it doesn't beep if bad expr (void)search_regcomp((char_u *)"", 0, last_idx, SEARCH_KEEP, regmatch); emsg_off--; } @@ -580,9 +560,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, return FAIL; } - /* - * find the string - */ + // find the string do { // loop for count // When not accepting a match at the start position set "extra_col" to a // non-zero value. Don't do that when starting at MAXCOL, since MAXCOL + 1 @@ -593,7 +571,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 = (char_u *)ml_get_buf(buf, pos->lnum, false); if ((int)STRLEN(ptr) <= pos->col) { start_char_len = 1; } else { @@ -610,31 +588,29 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, start_pos = *pos; // remember start pos for detecting no match found = 0; // default: not found - at_first_line = TRUE; // default: start in first line + 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; - at_first_line = FALSE; // not in first line now + at_first_line = false; // not in first line now } - /* - * Start searching in current line, unless searching backwards and - * we're in column 0. - * If we are searching backwards, in column 0, and not including the - * current position, gain some efficiency by skipping back a line. - * Otherwise begin the search in the current line. - */ + // Start searching in current line, unless searching backwards and + // we're in column 0. + // If we are searching backwards, in column 0, and not including the + // current position, gain some efficiency by skipping back a line. + // Otherwise begin the search in the current line. if (dir == BACKWARD && start_pos.col == 0 && (options & SEARCH_START) == 0) { lnum = pos->lnum - 1; - at_first_line = FALSE; + at_first_line = false; } else { lnum = pos->lnum; } - for (loop = 0; loop <= 1; ++loop) { // loop twice if 'wrapscan' set + for (loop = 0; loop <= 1; loop++) { // loop twice if 'wrapscan' set for (; lnum > 0 && lnum <= buf->b_ml.ml_line_count; - lnum += dir, at_first_line = FALSE) { + lnum += dir, at_first_line = false) { // Stop after checking "stop_lnum", if it's set. if (stop_lnum != 0 && (dir == FORWARD ? lnum > stop_lnum : lnum < stop_lnum)) { @@ -666,14 +642,12 @@ 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 = (char_u *)""; } else { - ptr = ml_get_buf(buf, lnum + matchpos.lnum, false); + ptr = (char_u *)ml_get_buf(buf, lnum + matchpos.lnum, false); } - /* - * Forward search in the first line: match should be after - * the start position. If not, continue at the end of the - * match (this is vi compatible) or on the next char. - */ + // Forward search in the first line: match should be after + // the start position. If not, continue at the end of the + // match (this is vi compatible) or on the next char. if (dir == FORWARD && at_first_line) { match_ok = true; // When the match starts in a next line it's certainly @@ -689,11 +663,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, : ((int)matchpos.col - (ptr[matchpos.col] == NUL) < (int)start_pos.col + extra_col))) { - /* - * If vi-compatible searching, continue at the end - * of the match, otherwise continue one position - * forward. - */ + // If vi-compatible searching, continue at the end + // of the match, otherwise continue one position + // forward. if (vim_strchr(p_cpo, CPO_SEARCH) != NULL) { if (nmatched > 1) { // end is in next line, thus no match in @@ -739,20 +711,18 @@ 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 = (char_u *)ml_get_buf(buf, lnum, false); } if (!match_ok) { continue; } } if (dir == BACKWARD) { - /* - * Now, if there are multiple matches on this line, - * we have to get the last one. Or the last one before - * the cursor, if we're on that line. - * When putting the new cursor at the end, compare - * relative to the end of the match. - */ + // Now, if there are multiple matches on this line, + // we have to get the last one. Or the last one before + // the cursor, if we're on that line. + // When putting the new cursor at the end, compare + // relative to the end of the match. match_ok = false; for (;;) { // Remember a position that is before the start @@ -824,13 +794,11 @@ 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 = (char_u *)ml_get_buf(buf, lnum + matchpos.lnum, false); } - /* - * If there is only a match after the cursor, skip - * this match. - */ + // If there is only a match after the cursor, skip + // this match. if (!match_ok) { continue; } @@ -849,13 +817,13 @@ 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, false)); } } else { pos->col--; if (pos->lnum <= buf->b_ml.ml_line_count) { - ptr = ml_get_buf(buf, pos->lnum, false); - pos->col -= utf_head_off(ptr, ptr + pos->col); + ptr = (char_u *)ml_get_buf(buf, pos->lnum, false); + pos->col -= utf_head_off((char *)ptr, (char *)ptr + pos->col); } } if (end_pos != NULL) { @@ -901,7 +869,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, break; // if second loop, stop where started } } - at_first_line = FALSE; + at_first_line = false; // vim_regexec_multi() may clear "regprog" if (regmatch.regprog == NULL) { @@ -966,7 +934,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, false)); if (pos->col > 0) { pos->col--; } @@ -991,7 +959,7 @@ static int first_submatch(regmmatch_T *rp) { int submatch; - for (submatch = 1;; ++submatch) { + for (submatch = 1;; submatch++) { if (rp->startpos[submatch].lnum >= 0) { break; } @@ -1006,22 +974,22 @@ static int first_submatch(regmmatch_T *rp) /// Highest level string search function. /// Search for the 'count'th occurrence of pattern 'pat' in direction 'dirc' /// -/// Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this +/// Careful: If spats[0].off.line == true and spats[0].off.off == 0 this /// makes the movement linewise without moving the match position. /// /// @param dirc if 0: use previous dir. /// @param pat NULL or empty : use previous string. -/// @param options if TRUE and -/// SEARCH_REV == TRUE : go in reverse of previous dir. -/// SEARCH_ECHO == TRUE : echo the search command and handle options -/// SEARCH_MSG == TRUE : may give error message -/// SEARCH_OPT == TRUE : interpret optional flags -/// SEARCH_HIS == TRUE : put search pattern in history -/// SEARCH_NOOF == TRUE : don't add offset to position -/// SEARCH_MARK == TRUE : set previous context mark -/// SEARCH_KEEP == TRUE : keep previous search pattern -/// SEARCH_START == TRUE : accept match at curpos itself -/// SEARCH_PEEK == TRUE : check for typed char, cancel search +/// @param options if true and +/// SEARCH_REV == true : go in reverse of previous dir. +/// SEARCH_ECHO == true : echo the search command and handle options +/// SEARCH_MSG == true : may give error message +/// SEARCH_OPT == true : interpret optional flags +/// SEARCH_HIS == true : put search pattern in history +/// SEARCH_NOOF == true : don't add offset to position +/// SEARCH_MARK == true : set previous context mark +/// SEARCH_KEEP == true : keep previous search pattern +/// SEARCH_START == true : accept match at curpos itself +/// SEARCH_PEEK == true : check for typed char, cancel search /// @param oap can be NULL /// @param dirc '/' or '?' /// @param search_delim delimiter for search, e.g. '%' in s%regex%replacement @@ -1044,25 +1012,19 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, size_t len; bool has_offset = false; - /* - * A line offset is not remembered, this is vi compatible. - */ + // A line offset is not remembered, this is vi compatible. if (spats[0].off.line && vim_strchr(p_cpo, CPO_LINEOFF) != NULL) { spats[0].off.line = false; spats[0].off.off = 0; } - /* - * Save the values for when (options & SEARCH_KEEP) is used. - * (there is no "if ()" around this because gcc wants them initialized) - */ + // 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; pos = curwin->w_cursor; // start searching at the cursor position - /* - * Find out the direction of the search. - */ + // Find out the direction of the search. if (dirc == 0) { dirc = (char_u)spats[0].off.dir; } else { @@ -1089,17 +1051,13 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, } } - /* - * Turn 'hlsearch' highlighting back on. - */ + // Turn 'hlsearch' highlighting back on. if (no_hlsearch && !(options & SEARCH_KEEP)) { - redraw_all_later(SOME_VALID); + redraw_all_later(UPD_SOME_VALID); set_no_hlsearch(false); } - /* - * Repeat the search when pattern followed by ';', e.g. "/foo/;?bar". - */ + // Repeat the search when pattern followed by ';', e.g. "/foo/;?bar". for (;;) { bool show_top_bot_msg = false; @@ -1121,15 +1079,13 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, } if (pat != NULL && *pat != NUL) { // look for (new) offset - /* - * Find end of regular expression. - * If there is a matching '/' or '?', toss it. - */ + // Find end of regular expression. + // If there is a matching '/' or '?', toss it. ps = (char_u *)strcopy; - p = skip_regexp(pat, search_delim, p_magic, &strcopy); + p = (char_u *)skip_regexp((char *)pat, search_delim, p_magic, &strcopy); if (strcopy != (char *)ps) { // made a copy of "pat" to change "\?" to "?" - searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy)); + searchcmdlen += (int)(STRLEN(pat) - strlen(strcopy)); pat = (char_u *)strcopy; searchstr = (char_u *)strcopy; } @@ -1137,8 +1093,8 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, dircp = p; // remember where we put the NUL *p++ = NUL; } - spats[0].off.line = FALSE; - spats[0].off.end = FALSE; + spats[0].off.line = false; + spats[0].off.end = false; spats[0].off.off = 0; // Check for a line offset or a character offset. // For get_address (echo off) we don't check for a character @@ -1252,7 +1208,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, memmove(msgbuf + STRLEN(p) + 1, off_buf, off_len); } - trunc = msg_strtrunc(msgbuf, true); + trunc = (char_u *)msg_strtrunc((char *)msgbuf, true); if (trunc != NULL) { xfree(msgbuf); msgbuf = trunc; @@ -1263,7 +1219,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, // it would be blanked out again very soon. Show it on the // left, but do reverse the text. if (curwin->w_p_rl && *curwin->w_p_rlc == 's') { - char_u *r = reverse_text(trunc != NULL ? trunc : msgbuf); + char_u *r = (char_u *)reverse_text(trunc != NULL ? (char *)trunc : (char *)msgbuf); xfree(msgbuf); msgbuf = r; // move reversed text to beginning of buffer @@ -1289,16 +1245,14 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, } } - /* - * If there is a character offset, subtract it from the current - * position, so we don't get stuck at "?pat?e+2" or "/pat/s-2". - * Skip this if pos.col is near MAXCOL (closed fold). - * This is not done for a line offset, because then we would not be vi - * compatible. - */ + // If there is a character offset, subtract it from the current + // position, so we don't get stuck at "?pat?e+2" or "/pat/s-2". + // Skip this if pos.col is near MAXCOL (closed fold). + // This is not done for a line offset, because then we would not be vi + // compatible. if (!spats[0].off.line && spats[0].off.off && pos.col < MAXCOL - 2) { if (spats[0].off.off > 0) { - for (c = spats[0].off.off; c; --c) { + for (c = spats[0].off.off; c; c--) { if (decl(&pos) == -1) { break; } @@ -1308,7 +1262,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, pos.col = MAXCOL; } } else { - for (c = spats[0].off.off; c; ++c) { + for (c = spats[0].off.off; c; c++) { if (incl(&pos) == -1) { break; } @@ -1352,9 +1306,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, apply_autocmds(EVENT_SEARCHWRAPPED, NULL, NULL, false, NULL); } - /* - * Add character and/or line offset - */ + // Add character and/or line offset if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';')) { pos_T org_pos = pos; @@ -1435,7 +1387,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, setpcmark(); } curwin->w_cursor = pos; - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; end_do_search: if ((options & SEARCH_KEEP) || (cmdmod.cmod_flags & CMOD_KEEPPATTERNS)) { @@ -1446,15 +1398,13 @@ end_do_search: return retval; } -/* - * search_for_exact_line(buf, pos, dir, pat) - * - * Search for a line starting with the given pattern (ignoring leading - * white-space), starting from pos and going in direction "dir". "pos" will - * contain the position of the match found. Blank lines match only if - * ADDING is set. If p_ic is set then the pattern must be in lowercase. - * Return OK for success, or FAIL if no line found. - */ +// search_for_exact_line(buf, pos, dir, pat) +// +// Search for a line starting with the given pattern (ignoring leading +// white-space), starting from pos and going in direction "dir". "pos" will +// contain the position of the match found. Blank lines match only if +// ADDING is set. If p_ic is set then the pattern must be in lowercase. +// Return OK for success, or FAIL if no line found. int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) { linenr_T start = 0; @@ -1493,22 +1443,21 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) if (start == 0) { start = pos->lnum; } - ptr = ml_get_buf(buf, pos->lnum, false); + ptr = (char_u *)ml_get_buf(buf, pos->lnum, false); p = (char_u *)skipwhite((char *)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_cont_status & CONT_ADDING) - && !(compl_cont_status & CONT_SOL)) { + if (compl_status_adding() && !compl_status_sol()) { if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) { return OK; } } else if (*p != NUL) { // Ignore empty lines. // Expanding lines or words. - assert(compl_length >= 0); - if ((p_ic ? mb_strnicmp(p, pat, (size_t)compl_length) - : STRNCMP(p, pat, compl_length)) == 0) { + assert(ins_compl_len() >= 0); + if ((p_ic ? mb_strnicmp((char *)p, (char *)pat, (size_t)ins_compl_len()) + : STRNCMP(p, pat, ins_compl_len())) == 0) { return OK; } } @@ -1516,16 +1465,12 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) return FAIL; } -/* - * Character Searches - */ +// Character Searches -/* - * Search for a character in a line. If "t_cmd" is FALSE, move to the - * position of the character, otherwise move to just before the char. - * Do this "cap->count1" times. - * Return FAIL or OK. - */ +/// Search for a character in a line. If "t_cmd" is false, move to the +/// position of the character, otherwise move to just before the char. +/// Do this "cap->count1" times. +/// Return FAIL or OK. int searchc(cmdarg_T *cap, int t_cmd) FUNC_ATTR_NONNULL_ALL { @@ -1579,7 +1524,7 @@ int searchc(cmdarg_T *cap, int t_cmd) cap->oap->inclusive = true; } - p = get_cursor_line_ptr(); + p = (char_u *)get_cursor_line_ptr(); col = curwin->w_cursor.col; len = (int)STRLEN(p); @@ -1594,7 +1539,7 @@ int searchc(cmdarg_T *cap, int t_cmd) if (col == 0) { return FAIL; } - col -= utf_head_off(p, p + col - 1) + 1; + col -= utf_head_off((char *)p, (char *)p + col - 1) + 1; } if (lastc_bytelen == 1) { if (p[col] == c && stop) { @@ -1615,7 +1560,7 @@ int searchc(cmdarg_T *cap, int t_cmd) col += lastc_bytelen - 1; } else { // To previous char, which may be multi-byte. - col -= utf_head_off(p, p + col); + col -= utf_head_off((char *)p, (char *)p + col); } } curwin->w_cursor.col = col; @@ -1623,15 +1568,11 @@ int searchc(cmdarg_T *cap, int t_cmd) return OK; } -/* - * "Other" Searches - */ +// "Other" Searches -/* - * findmatch - find the matching paren or brace - * - * Improvement over vi: Braces inside quotes are ignored. - */ +// findmatch - find the matching paren or brace +// +// Improvement over vi: Braces inside quotes are ignored. pos_T *findmatch(oparg_T *oap, int initc) { return findmatchlimit(oap, initc, 0, 0); @@ -1646,7 +1587,7 @@ static bool check_prevcol(char_u *linep, int col, int ch, int *prevcol) { col--; if (col > 0) { - col -= utf_head_off(linep, linep + col); + col -= utf_head_off((char *)linep, (char *)linep + col); } if (prevcol) { *prevcol = col; @@ -1654,22 +1595,21 @@ static bool check_prevcol(char_u *linep, int col, int ch, int *prevcol) return col >= 0 && linep[col] == ch; } -/* - * Raw string start is found at linep[startpos.col - 1]. - * Return true if the matching end can be found between startpos and endpos. - */ -static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos) +/// Raw string start is found at linep[startpos.col - 1]. +/// +/// @return true if the matching end can be found between startpos and endpos. +static bool find_rawstring_end(char *linep, pos_T *startpos, pos_T *endpos) { - char_u *p; + char *p; linenr_T lnum; for (p = linep + startpos->col + 1; *p && *p != '('; p++) {} size_t delim_len = (size_t)((p - linep) - startpos->col - 1); - char_u *delim_copy = vim_strnsave(linep + startpos->col + 1, delim_len); + char *delim_copy = xstrnsave(linep + startpos->col + 1, delim_len); bool found = false; for (lnum = startpos->lnum; lnum <= endpos->lnum; lnum++) { - char_u *line = ml_get(lnum); + char *line = ml_get(lnum); for (p = line + (lnum == startpos->lnum ? startpos->col + 1 : 0); *p; p++) { if (lnum == endpos->lnum && (colnr_T)(p - line) >= endpos->col) { @@ -1697,61 +1637,58 @@ static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos) static void find_mps_values(int *initc, int *findc, bool *backwards, bool switchit) FUNC_ATTR_NONNULL_ALL { - char_u *ptr = curbuf->b_p_mps; + char *ptr = curbuf->b_p_mps; while (*ptr != NUL) { - if (utf_ptr2char((char *)ptr) == *initc) { + if (utf_ptr2char(ptr) == *initc) { if (switchit) { *findc = *initc; - *initc = utf_ptr2char((char *)ptr + utfc_ptr2len((char *)ptr) + 1); + *initc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1); *backwards = true; } else { - *findc = utf_ptr2char((char *)ptr + utfc_ptr2len((char *)ptr) + 1); + *findc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1); *backwards = false; } return; } - char_u *prev = ptr; - ptr += utfc_ptr2len((char *)ptr) + 1; - if (utf_ptr2char((char *)ptr) == *initc) { + char *prev = ptr; + ptr += utfc_ptr2len(ptr) + 1; + if (utf_ptr2char(ptr) == *initc) { if (switchit) { *findc = *initc; - *initc = utf_ptr2char((char *)prev); + *initc = utf_ptr2char(prev); *backwards = false; } else { - *findc = utf_ptr2char((char *)prev); + *findc = utf_ptr2char(prev); *backwards = true; } return; } - ptr += utfc_ptr2len((char *)ptr); + ptr += utfc_ptr2len(ptr); if (*ptr == ',') { ptr++; } } } -/* - * findmatchlimit -- find the matching paren or brace, if it exists within - * maxtravel lines of the cursor. A maxtravel of 0 means search until falling - * off the edge of the file. - * - * "initc" is the character to find a match for. NUL means to find the - * character at or after the cursor. Special values: - * '*' look for C-style comment / * - * '/' look for C-style comment / *, ignoring comment-end - * '#' look for preprocessor directives - * 'R' look for raw string start: R"delim(text)delim" (only backwards) - * - * flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#') - * FM_FORWARD search forwards (when initc is '/', '*' or '#') - * FM_BLOCKSTOP stop at start/end of block ({ or } in column 0) - * FM_SKIPCOMM skip comments (not implemented yet!) - * - * "oap" is only used to set oap->motion_type for a linewise motion, it can be - * NULL - */ - +// findmatchlimit -- find the matching paren or brace, if it exists within +// maxtravel lines of the cursor. A maxtravel of 0 means search until falling +// off the edge of the file. +// +// "initc" is the character to find a match for. NUL means to find the +// character at or after the cursor. Special values: +// '*' look for C-style comment / * +// '/' look for C-style comment / *, ignoring comment-end +// '#' look for preprocessor directives +// 'R' look for raw string start: R"delim(text)delim" (only backwards) +// +// flags: FM_BACKWARD search backwards (when initc is '/', '*' or '#') +// FM_FORWARD search forwards (when initc is '/', '*' or '#') +// FM_BLOCKSTOP stop at start/end of block ({ or } in column 0) +// FM_SKIPCOMM skip comments (not implemented yet!) +// +// "oap" is only used to set oap->motion_type for a linewise motion, it can be +// NULL pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) { static pos_T pos; // current search position @@ -1773,7 +1710,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) pos = curwin->w_cursor; pos.coladd = 0; - char_u *linep = ml_get(pos.lnum); // pointer to current line + char_u *linep = (char_u *)ml_get(pos.lnum); // pointer to current line // vi compatible matching bool cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL); @@ -1789,12 +1726,10 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) dir = 0; } - /* - * if initc given, look in the table for the matching character - * '/' and '*' are special cases: look for start or end of comment. - * When '/' is used, we ignore running backwards into a star-slash, for - * "[*" command, we just want to find any comment. - */ + // if initc given, look in the table for the matching character + // '/' and '*' are special cases: look for start or end of comment. + // When '/' is used, we ignore running backwards into a star-slash, for + // "[*" command, we just want to find any comment. if (initc == '/' || initc == '*' || initc == 'R') { comment_dir = dir; if (initc == '/') { @@ -1812,18 +1747,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) return NULL; } } else { - /* - * Either initc is '#', or no initc was given and we need to look - * under the cursor. - */ + // Either initc is '#', or no initc was given and we need to look + // under the cursor. if (initc == '#') { hash_dir = dir; } else { - /* - * initc was not given, must look for something to match under - * or near the cursor. - * Only check for special things when 'cpo' doesn't have '%'. - */ + // initc was not given, must look for something to match under + // or near the cursor. + // Only check for special things when 'cpo' doesn't have '%'. if (!cpo_match) { // Are we before or at #if, #else etc.? ptr = (char_u *)skipwhite((char *)linep); @@ -1857,18 +1788,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } - /* - * If we are not on a comment or the # at the start of a line, then - * look for brace anywhere on this line after the cursor. - */ + // If we are not on a comment or the # at the start of a line, then + // look for brace anywhere on this line after the cursor. if (!hash_dir && !comment_dir) { - /* - * Find the brace under or after the cursor. - * If beyond the end of the line, use the last character in - * the line. - */ + // Find the brace under or after the cursor. + // If beyond the end of the line, use the last character in + // the line. if (linep[pos.col] == NUL && pos.col) { - --pos.col; + pos.col--; } for (;;) { initc = utf_ptr2char((char *)linep + pos.col); @@ -1902,9 +1829,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } if (hash_dir) { - /* - * Look for matching #if, #else, #elif, or #endif - */ + // Look for matching #if, #else, #elif, or #endif if (oap != NULL) { oap->motion_type = kMTLineWise; // Linewise for this case only } @@ -1928,7 +1853,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) break; } pos.lnum += hash_dir; - linep = ml_get(pos.lnum); + linep = (char_u *)ml_get(pos.lnum); line_breakcheck(); // check for CTRL-C typed ptr = (char_u *)skipwhite((char *)linep); if (*ptr != '#') { @@ -1982,17 +1907,15 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) // backward search: Check if this line contains a single-line comment if ((backwards && comment_dir) || lisp) { - comment_col = check_linecomment(linep); + comment_col = check_linecomment((char *)linep); } if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) { lispcomm = true; // find match inside this comment } while (!got_int) { - /* - * Go to the next position, forward or backward. We could use - * inc() and dec() here, but that is much slower - */ + // Go to the next position, forward or backward. We could use + // inc() and dec() here, but that is much slower if (backwards) { // char to match is inside of comment, don't search outside if (lispcomm && pos.col < (colnr_T)comment_col) { @@ -2002,20 +1925,20 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) if (pos.lnum == 1) { // start of file break; } - --pos.lnum; + pos.lnum--; if (maxtravel > 0 && ++traveled > maxtravel) { break; } - linep = ml_get(pos.lnum); + linep = (char_u *)ml_get(pos.lnum); pos.col = (colnr_T)STRLEN(linep); // pos.col on trailing NUL do_quotes = -1; line_breakcheck(); // Check if this line contains a single-line comment if (comment_dir || lisp) { - comment_col = check_linecomment(linep); + comment_col = check_linecomment((char *)linep); } // skip comment if (lisp && comment_col != MAXCOL) { @@ -2023,7 +1946,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } else { pos.col--; - pos.col -= utf_head_off(linep, linep + pos.col); + pos.col -= utf_head_off((char *)linep, (char *)linep + pos.col); } } else { // forward search if (linep[pos.col] == NUL @@ -2037,18 +1960,18 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) || lispcomm) { break; } - ++pos.lnum; + pos.lnum++; if (maxtravel && traveled++ > maxtravel) { break; } - linep = ml_get(pos.lnum); + linep = (char_u *)ml_get(pos.lnum); pos.col = 0; do_quotes = -1; line_breakcheck(); if (lisp) { // find comment pos in new line - comment_col = check_linecomment(linep); + comment_col = check_linecomment((char *)linep); } } else { pos.col += utfc_ptr2len((char *)linep + pos.col); @@ -2073,10 +1996,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) return &pos; } } else { // Searching backwards - /* - * A comment may contain / * or / /, it may also start or end - * with / * /. Ignore a / * after / / and after *. - */ + // A comment may contain / * or / /, it may also start or end + // with / * /. Ignore a / * after / / and after *. if (pos.col == 0) { continue; } else if (raw_string) { @@ -2087,13 +2008,13 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) // delimiter we can check if it ends before where we // started searching, or before the previously found // raw string start. - if (!find_rawstring_end(linep, &pos, + if (!find_rawstring_end((char *)linep, &pos, count > 0 ? &match_pos : &curwin->w_cursor)) { count++; match_pos = pos; match_pos.col--; } - linep = ml_get(pos.lnum); // may have been released + linep = (char_u *)ml_get(pos.lnum); // may have been released } } else if (linep[pos.col - 1] == '/' && linep[pos.col] == '*' @@ -2119,20 +2040,16 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) continue; } - /* - * If smart matching ('cpoptions' does not contain '%'), braces inside - * of quotes are ignored, but only if there is an even number of - * quotes in the line. - */ + // If smart matching ('cpoptions' does not contain '%'), braces inside + // of quotes are ignored, but only if there is an even number of + // quotes in the line. if (cpo_match) { do_quotes = 0; } else if (do_quotes == -1) { - /* - * Count the number of quotes in the line, skipping \" and '"'. - * Watch out for "\\". - */ + // Count the number of quotes in the line, skipping \" and '"'. + // Watch out for "\\". at_start = do_quotes; - for (ptr = linep; *ptr; ++ptr) { + for (ptr = linep; *ptr; ptr++) { if (ptr == linep + pos.col + backwards) { at_start = (do_quotes & 1); } @@ -2146,10 +2063,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } do_quotes &= 1; // result is 1 with even number of quotes - /* - * If we find an uneven count, check current line and previous - * one for a '\' at the end. - */ + // If we find an uneven count, check current line and previous + // one for a '\' at the end. if (!do_quotes) { inquote = false; if (ptr[-1] == '\\') { @@ -2163,7 +2078,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } if (pos.lnum > 1) { - ptr = ml_get(pos.lnum - 1); + ptr = (char_u *)ml_get(pos.lnum - 1); if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\\') { do_quotes = 1; if (start_in_quotes == kNone) { @@ -2177,7 +2092,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } // ml_get() only keeps one line, need to get linep again - linep = ml_get(pos.lnum); + linep = (char_u *)ml_get(pos.lnum); } } } @@ -2185,17 +2100,15 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) start_in_quotes = kFalse; } - /* - * If 'smartmatch' is set: - * Things inside quotes are ignored by setting 'inquote'. If we - * find a quote without a preceding '\' invert 'inquote'. At the - * end of a line not ending in '\' we reset 'inquote'. - * - * In lines with an uneven number of quotes (without preceding '\') - * we do not know which part to ignore. Therefore we only set - * inquote if the number of quotes in a line is even, unless this - * line or the previous one ends in a '\'. Complicated, isn't it? - */ + // If 'smartmatch' is set: + // Things inside quotes are ignored by setting 'inquote'. If we + // find a quote without a preceding '\' invert 'inquote'. At the + // end of a line not ending in '\' we reset 'inquote'. + // + // In lines with an uneven number of quotes (without preceding '\') + // we do not know which part to ignore. Therefore we only set + // inquote if the number of quotes in a line is even, unless this + // line or the previous one ends in a '\'. Complicated, isn't it? const int c = utf_ptr2char((char *)linep + pos.col); switch (c) { case NUL: @@ -2212,7 +2125,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) if (do_quotes) { int col; - for (col = pos.col - 1; col >= 0; --col) { + for (col = pos.col - 1; col >= 0; col--) { if (linep[col] != '\\') { break; } @@ -2224,13 +2137,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } break; - /* - * If smart matching ('cpoptions' does not contain '%'): - * Skip things in single quotes: 'x' or '\x'. Be careful for single - * single quotes, eg jon's. Things like '\233' or '\x3f' are not - * skipped, there is never a brace in them. - * Ignore this when finding matches for `'. - */ + // If smart matching ('cpoptions' does not contain '%'): + // Skip things in single quotes: 'x' or '\x'. Be careful for single + // single quotes, eg jon's. Things like '\233' or '\x3f' are not + // skipped, there is never a brace in them. + // Ignore this when finding matches for `'. case '\'': if (!cpo_match && initc != '\'' && findc != '\'') { if (backwards) { @@ -2258,10 +2169,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) FALLTHROUGH; default: - /* - * For Lisp skip over backslashed (), {} and []. - * (actually, we skip #\( et al) - */ + // For Lisp skip over backslashed (), {} and []. + // (actually, we skip #\( et al) if (curbuf->b_p_lisp && vim_strchr("(){}[]", c) != NULL && pos.col > 1 @@ -2306,15 +2215,15 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) /// Check if line[] contains a / / comment. /// @returns MAXCOL if not, otherwise return the column. -int check_linecomment(const char_u *line) +int check_linecomment(const char *line) { - const char_u *p = line; // scan from start + 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 bool in_str = false; // inside of string - while ((p = (char_u *)strpbrk((char *)p, "\";")) != NULL) { + while ((p = strpbrk((char *)p, "\";")) != NULL) { if (*p == '"') { if (in_str) { if (*(p - 1) != '\\') { // skip escaped quote @@ -2327,7 +2236,7 @@ int check_linecomment(const char_u *line) } } else if (!in_str && ((p - line) < 2 || (*(p - 1) != '\\' && *(p - 2) != '#')) - && !is_pos_in_string(line, (colnr_T)(p - line))) { + && !is_pos_in_string((char_u *)line, (colnr_T)(p - line))) { break; // found! } p++; @@ -2336,12 +2245,12 @@ int check_linecomment(const char_u *line) p = NULL; } } else { - while ((p = (char_u *)vim_strchr((char *)p, '/')) != NULL) { + while ((p = vim_strchr((char *)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. if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*') - && !is_pos_in_string(line, (colnr_T)(p - line))) { + && !is_pos_in_string((char_u *)line, (colnr_T)(p - line))) { break; } p++; @@ -2373,11 +2282,9 @@ void showmatch(int c) colnr_T save_dollar_vcol; char_u *p; - /* - * Only show match for chars in the 'matchpairs' option. - */ + // Only show match for chars in the 'matchpairs' option. // 'matchpairs' is "x:y,x:y" - for (p = curbuf->b_p_mps; *p != NUL; p++) { + for (p = (char_u *)curbuf->b_p_mps; *p != NUL; p++) { if (utf_ptr2char((char *)p) == c && (curwin->w_p_rl ^ p_ri)) { break; } @@ -2414,7 +2321,7 @@ void showmatch(int c) dollar_vcol = -1; } curwin->w_virtcol++; // do display ')' just before "$" - update_screen(VALID); // show the new char first + update_screen(); // show the new char first save_dollar_vcol = dollar_vcol; save_state = State; @@ -2431,10 +2338,8 @@ void showmatch(int c) // and has a higher column number. dollar_vcol = save_dollar_vcol; - /* - * brief pause, unless 'm' is present in 'cpo' and a character is - * available. - */ + // 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); } else if (!char_avail()) { @@ -2449,1814 +2354,6 @@ void showmatch(int c) } } -// Find the start of the next sentence, searching in the direction specified -// by the "dir" argument. The cursor is positioned on the start of the next -// sentence when found. If the next sentence is found, return OK. Return FAIL -// otherwise. See ":h sentence" for the precise definition of a "sentence" -// text object. -int findsent(Direction dir, long count) -{ - pos_T pos, tpos; - int c; - int (*func)(pos_T *); - bool noskip = false; // do not skip blanks - - pos = curwin->w_cursor; - if (dir == FORWARD) { - func = incl; - } else { - func = decl; - } - - while (count--) { - const pos_T prev_pos = pos; - - // if on an empty line, skip up to a non-empty line - if (gchar_pos(&pos) == NUL) { - do { - if ((*func)(&pos) == -1) { - break; - } - } while (gchar_pos(&pos) == NUL); - if (dir == FORWARD) { - goto found; - } - // if on the start of a paragraph or a section and searching forward, - // go to the next line - } else if (dir == FORWARD && pos.col == 0 - && startPS(pos.lnum, NUL, false)) { - if (pos.lnum == curbuf->b_ml.ml_line_count) { - return FAIL; - } - pos.lnum++; - goto found; - } else if (dir == BACKWARD) { - decl(&pos); - } - - // go back to the previous non-white non-punctuation character - bool found_dot = false; - while (c = gchar_pos(&pos), ascii_iswhite(c) - || vim_strchr(".!?)]\"'", c) != NULL) { - tpos = pos; - if (decl(&tpos) == -1 || (LINEEMPTY(tpos.lnum) && dir == FORWARD)) { - break; - } - if (found_dot) { - break; - } - if (vim_strchr(".!?", c) != NULL) { - found_dot = true; - } - if (vim_strchr(")]\"'", c) != NULL - && vim_strchr(".!?)]\"'", gchar_pos(&tpos)) == NULL) { - break; - } - decl(&pos); - } - - // remember the line where the search started - const int startlnum = pos.lnum; - const bool cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL; - - for (;;) { // find end of sentence - c = gchar_pos(&pos); - if (c == NUL || (pos.col == 0 && startPS(pos.lnum, NUL, FALSE))) { - if (dir == BACKWARD && pos.lnum != startlnum) { - ++pos.lnum; - } - break; - } - if (c == '.' || c == '!' || c == '?') { - tpos = pos; - do { - if ((c = inc(&tpos)) == -1) { - break; - } - } while (vim_strchr(")]\"'", c = gchar_pos(&tpos)) - != NULL); - if (c == -1 || (!cpo_J && (c == ' ' || c == '\t')) || c == NUL - || (cpo_J && (c == ' ' && inc(&tpos) >= 0 - && gchar_pos(&tpos) == ' '))) { - pos = tpos; - if (gchar_pos(&pos) == NUL) { // skip NUL at EOL - inc(&pos); - } - break; - } - } - if ((*func)(&pos) == -1) { - if (count) { - return FAIL; - } - noskip = true; - break; - } - } -found: - // skip white space - while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t')) { - if (incl(&pos) == -1) { - break; - } - } - - if (equalpos(prev_pos, pos)) { - // didn't actually move, advance one character and try again - if ((*func)(&pos) == -1) { - if (count) { - return FAIL; - } - break; - } - count++; - } - } - - setpcmark(); - curwin->w_cursor = pos; - return OK; -} - -/// Find the next paragraph or section in direction 'dir'. -/// Paragraphs are currently supposed to be separated by empty lines. -/// If 'what' is NUL we go to the next paragraph. -/// If 'what' is '{' or '}' we go to the next section. -/// If 'both' is TRUE also stop at '}'. -/// -/// @param pincl Return: true if last char is to be included -/// -/// @return TRUE if the next paragraph or section was found. -bool findpar(bool *pincl, int dir, long count, int what, int both) -{ - linenr_T curr; - bool did_skip; // true after separating lines have been skipped - bool first; // true on first line - linenr_T fold_first; // first line of a closed fold - linenr_T fold_last; // last line of a closed fold - bool fold_skipped; // true if a closed fold was skipped this - // iteration - - curr = curwin->w_cursor.lnum; - - while (count--) { - did_skip = false; - for (first = true;; first = false) { - if (*ml_get(curr) != NUL) { - did_skip = true; - } - - // skip folded lines - fold_skipped = false; - if (first && hasFolding(curr, &fold_first, &fold_last)) { - curr = ((dir > 0) ? fold_last : fold_first) + dir; - fold_skipped = true; - } - - if (!first && did_skip && startPS(curr, what, both)) { - break; - } - - if (fold_skipped) { - curr -= dir; - } - if ((curr += dir) < 1 || curr > curbuf->b_ml.ml_line_count) { - if (count) { - return false; - } - curr -= dir; - break; - } - } - } - setpcmark(); - if (both && *ml_get(curr) == '}') { // include line with '}' - curr++; - } - curwin->w_cursor.lnum = curr; - if (curr == curbuf->b_ml.ml_line_count && what != '}') { - char_u *line = ml_get(curr); - - // Put the cursor on the last character in the last line and make the - // motion inclusive. - if ((curwin->w_cursor.col = (colnr_T)STRLEN(line)) != 0) { - curwin->w_cursor.col--; - curwin->w_cursor.col -= utf_head_off(line, line + curwin->w_cursor.col); - *pincl = true; - } - } else { - curwin->w_cursor.col = 0; - } - return true; -} - -/* - * check if the string 's' is a nroff macro that is in option 'opt' - */ -static int inmacro(char_u *opt, char_u *s) -{ - char_u *macro; - - for (macro = opt; macro[0]; macro++) { - // Accept two characters in the option being equal to two characters - // in the line. A space in the option matches with a space in the - // line or the line having ended. - if ((macro[0] == s[0] - || (macro[0] == ' ' - && (s[0] == NUL || s[0] == ' '))) - && (macro[1] == s[1] - || ((macro[1] == NUL || macro[1] == ' ') - && (s[0] == NUL || s[1] == NUL || s[1] == ' ')))) { - break; - } - macro++; - if (macro[0] == NUL) { - break; - } - } - return macro[0] != NUL; -} - -/* - * startPS: return TRUE if line 'lnum' is the start of a section or paragraph. - * If 'para' is '{' or '}' only check for sections. - * If 'both' is TRUE also stop at '}' - */ -int startPS(linenr_T lnum, int para, int both) -{ - char_u *s; - - s = ml_get(lnum); - if (*s == para || *s == '\f' || (both && *s == '}')) { - return true; - } - if (*s == '.' && (inmacro(p_sections, s + 1) - || (!para && inmacro(p_para, s + 1)))) { - return true; - } - return false; -} - -/* - * The following routines do the word searches performed by the 'w', 'W', - * 'b', 'B', 'e', and 'E' commands. - */ - -/* - * To perform these searches, characters are placed into one of three - * classes, and transitions between classes determine word boundaries. - * - * The classes are: - * - * 0 - white space - * 1 - punctuation - * 2 or higher - keyword characters (letters, digits and underscore) - */ - -static int cls_bigword; // TRUE for "W", "B" or "E" - -/* - * cls() - returns the class of character at curwin->w_cursor - * - * If a 'W', 'B', or 'E' motion is being done (cls_bigword == TRUE), chars - * from class 2 and higher are reported as class 1 since only white space - * boundaries are of interest. - */ -static int cls(void) -{ - int c; - - c = gchar_cursor(); - if (c == ' ' || c == '\t' || c == NUL) { - return 0; - } - - c = utf_class(c); - - // If cls_bigword is TRUE, report all non-blanks as class 1. - if (c != 0 && cls_bigword) { - return 1; - } - return c; -} - -/// fwd_word(count, type, eol) - move forward one word -/// -/// @return FAIL if the cursor was already at the end of the file. -/// If eol is TRUE, last word stops at end of line (for operators). -/// -/// @param bigword "W", "E" or "B" -int fwd_word(long count, int bigword, int eol) -{ - int sclass; // starting class - int i; - int last_line; - - curwin->w_cursor.coladd = 0; - cls_bigword = bigword; - while (--count >= 0) { - // When inside a range of folded lines, move to the last char of the - // last line. - if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum)) { - coladvance(MAXCOL); - } - sclass = cls(); - - /* - * We always move at least one character, unless on the last - * character in the buffer. - */ - last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count); - i = inc_cursor(); - if (i == -1 || (i >= 1 && last_line)) { // started at last char in file - return FAIL; - } - if (i >= 1 && eol && count == 0) { // started at last char in line - return OK; - } - - /* - * Go one char past end of current word (if any) - */ - if (sclass != 0) { - while (cls() == sclass) { - i = inc_cursor(); - if (i == -1 || (i >= 1 && eol && count == 0)) { - return OK; - } - } - } - - /* - * go to next non-white - */ - while (cls() == 0) { - /* - * We'll stop if we land on a blank line - */ - if (curwin->w_cursor.col == 0 && *get_cursor_line_ptr() == NUL) { - break; - } - - i = inc_cursor(); - if (i == -1 || (i >= 1 && eol && count == 0)) { - return OK; - } - } - } - return OK; -} - -/* - * bck_word() - move backward 'count' words - * - * If stop is TRUE and we are already on the start of a word, move one less. - * - * Returns FAIL if top of the file was reached. - */ -int bck_word(long count, int bigword, int stop) -{ - int sclass; // starting class - - curwin->w_cursor.coladd = 0; - cls_bigword = bigword; - while (--count >= 0) { - /* When inside a range of folded lines, move to the first char of the - * first line. */ - if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL)) { - curwin->w_cursor.col = 0; - } - sclass = cls(); - if (dec_cursor() == -1) { // started at start of file - return FAIL; - } - - if (!stop || sclass == cls() || sclass == 0) { - /* - * Skip white space before the word. - * Stop on an empty line. - */ - while (cls() == 0) { - if (curwin->w_cursor.col == 0 - && LINEEMPTY(curwin->w_cursor.lnum)) { - goto finished; - } - if (dec_cursor() == -1) { // hit start of file, stop here - return OK; - } - } - - /* - * Move backward to start of this word. - */ - if (skip_chars(cls(), BACKWARD)) { - return OK; - } - } - - inc_cursor(); // overshot - forward one -finished: - stop = FALSE; - } - return OK; -} - -/* - * end_word() - move to the end of the word - * - * There is an apparent bug in the 'e' motion of the real vi. At least on the - * System V Release 3 version for the 80386. Unlike 'b' and 'w', the 'e' - * motion crosses blank lines. When the real vi crosses a blank line in an - * 'e' motion, the cursor is placed on the FIRST character of the next - * non-blank line. The 'E' command, however, works correctly. Since this - * appears to be a bug, I have not duplicated it here. - * - * Returns FAIL if end of the file was reached. - * - * If stop is TRUE and we are already on the end of a word, move one less. - * If empty is TRUE stop on an empty line. - */ -int end_word(long count, int bigword, int stop, int empty) -{ - int sclass; // starting class - - curwin->w_cursor.coladd = 0; - cls_bigword = bigword; - while (--count >= 0) { - /* When inside a range of folded lines, move to the last char of the - * last line. */ - if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum)) { - coladvance(MAXCOL); - } - sclass = cls(); - if (inc_cursor() == -1) { - return FAIL; - } - - /* - * If we're in the middle of a word, we just have to move to the end - * of it. - */ - if (cls() == sclass && sclass != 0) { - /* - * Move forward to end of the current word - */ - if (skip_chars(sclass, FORWARD)) { - return FAIL; - } - } else if (!stop || sclass == 0) { - /* - * We were at the end of a word. Go to the end of the next word. - * First skip white space, if 'empty' is TRUE, stop at empty line. - */ - while (cls() == 0) { - if (empty && curwin->w_cursor.col == 0 - && LINEEMPTY(curwin->w_cursor.lnum)) { - goto finished; - } - if (inc_cursor() == -1) { // hit end of file, stop here - return FAIL; - } - } - - /* - * Move forward to the end of this word. - */ - if (skip_chars(cls(), FORWARD)) { - return FAIL; - } - } - dec_cursor(); // overshot - one char backward -finished: - stop = FALSE; // we move only one word less - } - return OK; -} - -/// Move back to the end of the word. -/// -/// @param bigword TRUE for "B" -/// @param eol if true, then stop at end of line. -/// -/// @return FAIL if start of the file was reached. -int bckend_word(long count, int bigword, bool eol) -{ - int sclass; // starting class - int i; - - curwin->w_cursor.coladd = 0; - cls_bigword = bigword; - while (--count >= 0) { - sclass = cls(); - if ((i = dec_cursor()) == -1) { - return FAIL; - } - if (eol && i == 1) { - return OK; - } - - /* - * Move backward to before the start of this word. - */ - if (sclass != 0) { - while (cls() == sclass) { - if ((i = dec_cursor()) == -1 || (eol && i == 1)) { - return OK; - } - } - } - - /* - * Move backward to end of the previous word - */ - while (cls() == 0) { - if (curwin->w_cursor.col == 0 && LINEEMPTY(curwin->w_cursor.lnum)) { - break; - } - if ((i = dec_cursor()) == -1 || (eol && i == 1)) { - return OK; - } - } - } - return OK; -} - -/// Skip a row of characters of the same class. -/// -/// @return true when end-of-file reached, false otherwise. -static bool skip_chars(int cclass, int dir) -{ - while (cls() == cclass) { - if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1) { - return true; - } - } - return false; -} - -/* - * Go back to the start of the word or the start of white space - */ -static void back_in_line(void) -{ - int sclass; // starting class - - sclass = cls(); - for (;;) { - if (curwin->w_cursor.col == 0) { // stop at start of line - break; - } - dec_cursor(); - if (cls() != sclass) { // stop at start of word - inc_cursor(); - break; - } - } -} - -static void find_first_blank(pos_T *posp) -{ - int c; - - while (decl(posp) != -1) { - c = gchar_pos(posp); - if (!ascii_iswhite(c)) { - incl(posp); - break; - } - } -} - -/// Skip count/2 sentences and count/2 separating white spaces. -/// -/// @param at_start_sent cursor is at start of sentence -static void findsent_forward(long count, bool at_start_sent) -{ - while (count--) { - findsent(FORWARD, 1L); - if (at_start_sent) { - find_first_blank(&curwin->w_cursor); - } - if (count == 0 || at_start_sent) { - decl(&curwin->w_cursor); - } - at_start_sent = !at_start_sent; - } -} - -/// Find word under cursor, cursor at end. -/// Used while an operator is pending, and in Visual mode. -/// -/// @param include TRUE: include word and white space -/// @param bigword FALSE == word, TRUE == WORD -int current_word(oparg_T *oap, long count, int include, int bigword) -{ - pos_T start_pos; - pos_T pos; - bool inclusive = true; - int include_white = FALSE; - - cls_bigword = bigword; - clearpos(&start_pos); - - // Correct cursor when 'selection' is exclusive - if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor)) { - dec_cursor(); - } - - /* - * When Visual mode is not active, or when the VIsual area is only one - * character, select the word and/or white space under the cursor. - */ - if (!VIsual_active || equalpos(curwin->w_cursor, VIsual)) { - /* - * Go to start of current word or white space. - */ - back_in_line(); - start_pos = curwin->w_cursor; - - /* - * If the start is on white space, and white space should be included - * (" word"), or start is not on white space, and white space should - * not be included ("word"), find end of word. - */ - if ((cls() == 0) == include) { - if (end_word(1L, bigword, TRUE, TRUE) == FAIL) { - return FAIL; - } - } else { - /* - * If the start is not on white space, and white space should be - * included ("word "), or start is on white space and white - * space should not be included (" "), find start of word. - * If we end up in the first column of the next line (single char - * word) back up to end of the line. - */ - fwd_word(1L, bigword, TRUE); - if (curwin->w_cursor.col == 0) { - decl(&curwin->w_cursor); - } else { - oneleft(); - } - - if (include) { - include_white = TRUE; - } - } - - if (VIsual_active) { - // should do something when inclusive == false ! - VIsual = start_pos; - redraw_curbuf_later(INVERTED); // update the inversion - } else { - oap->start = start_pos; - oap->motion_type = kMTCharWise; - } - count--; - } - - /* - * When count is still > 0, extend with more objects. - */ - while (count > 0) { - inclusive = true; - if (VIsual_active && lt(curwin->w_cursor, VIsual)) { - /* - * In Visual mode, with cursor at start: move cursor back. - */ - if (decl(&curwin->w_cursor) == -1) { - return FAIL; - } - if (include != (cls() != 0)) { - if (bck_word(1L, bigword, TRUE) == FAIL) { - return FAIL; - } - } else { - if (bckend_word(1L, bigword, true) == FAIL) { - return FAIL; - } - (void)incl(&curwin->w_cursor); - } - } else { - /* - * Move cursor forward one word and/or white area. - */ - if (incl(&curwin->w_cursor) == -1) { - return FAIL; - } - if (include != (cls() == 0)) { - if (fwd_word(1L, bigword, TRUE) == FAIL && count > 1) { - return FAIL; - } - /* - * If end is just past a new-line, we don't want to include - * the first character on the line. - * Put cursor on last char of white. - */ - if (oneleft() == FAIL) { - inclusive = false; - } - } else { - if (end_word(1L, bigword, TRUE, TRUE) == FAIL) { - return FAIL; - } - } - } - count--; - } - - if (include_white && (cls() != 0 - || (curwin->w_cursor.col == 0 && !inclusive))) { - /* - * If we don't include white space at the end, move the start - * to include some white space there. This makes "daw" work - * better on the last word in a sentence (and "2daw" on last-but-one - * word). Also when "2daw" deletes "word." at the end of the line - * (cursor is at start of next line). - * But don't delete white space at start of line (indent). - */ - pos = curwin->w_cursor; // save cursor position - curwin->w_cursor = start_pos; - if (oneleft() == OK) { - back_in_line(); - if (cls() == 0 && curwin->w_cursor.col > 0) { - if (VIsual_active) { - VIsual = curwin->w_cursor; - } else { - oap->start = curwin->w_cursor; - } - } - } - curwin->w_cursor = pos; // put cursor back at end - } - - if (VIsual_active) { - if (*p_sel == 'e' && inclusive && ltoreq(VIsual, curwin->w_cursor)) { - inc_cursor(); - } - if (VIsual_mode == 'V') { - VIsual_mode = 'v'; - redraw_cmdline = true; // show mode later - } - } else { - oap->inclusive = inclusive; - } - - return OK; -} - -/* - * Find sentence(s) under the cursor, cursor at end. - * When Visual active, extend it by one or more sentences. - */ -int current_sent(oparg_T *oap, long count, int include) -{ - pos_T start_pos; - pos_T pos; - bool start_blank; - int c; - bool at_start_sent; - long ncount; - - start_pos = curwin->w_cursor; - pos = start_pos; - findsent(FORWARD, 1L); // Find start of next sentence. - - /* - * When the Visual area is bigger than one character: Extend it. - */ - if (VIsual_active && !equalpos(start_pos, VIsual)) { -extend: - if (lt(start_pos, VIsual)) { - /* - * Cursor at start of Visual area. - * Find out where we are: - * - in the white space before a sentence - * - in a sentence or just after it - * - at the start of a sentence - */ - at_start_sent = true; - decl(&pos); - while (lt(pos, curwin->w_cursor)) { - c = gchar_pos(&pos); - if (!ascii_iswhite(c)) { - at_start_sent = false; - break; - } - incl(&pos); - } - if (!at_start_sent) { - findsent(BACKWARD, 1L); - if (equalpos(curwin->w_cursor, start_pos)) { - at_start_sent = true; // exactly at start of sentence - } else { - // inside a sentence, go to its end (start of next) - findsent(FORWARD, 1L); - } - } - if (include) { // "as" gets twice as much as "is" - count *= 2; - } - while (count--) { - if (at_start_sent) { - find_first_blank(&curwin->w_cursor); - } - c = gchar_cursor(); - if (!at_start_sent || (!include && !ascii_iswhite(c))) { - findsent(BACKWARD, 1L); - } - at_start_sent = !at_start_sent; - } - } else { - /* - * Cursor at end of Visual area. - * Find out where we are: - * - just before a sentence - * - just before or in the white space before a sentence - * - in a sentence - */ - incl(&pos); - at_start_sent = true; - if (!equalpos(pos, curwin->w_cursor)) { // not just before a sentence - at_start_sent = false; - while (lt(pos, curwin->w_cursor)) { - c = gchar_pos(&pos); - if (!ascii_iswhite(c)) { - at_start_sent = true; - break; - } - incl(&pos); - } - if (at_start_sent) { // in the sentence - findsent(BACKWARD, 1L); - } else { // in/before white before a sentence - curwin->w_cursor = start_pos; - } - } - - if (include) { // "as" gets twice as much as "is" - count *= 2; - } - findsent_forward(count, at_start_sent); - if (*p_sel == 'e') { - ++curwin->w_cursor.col; - } - } - return OK; - } - - /* - * If the cursor started on a blank, check if it is just before the start - * of the next sentence. - */ - while (c = gchar_pos(&pos), ascii_iswhite(c)) { - incl(&pos); - } - if (equalpos(pos, curwin->w_cursor)) { - start_blank = true; - find_first_blank(&start_pos); // go back to first blank - } else { - start_blank = false; - findsent(BACKWARD, 1L); - start_pos = curwin->w_cursor; - } - if (include) { - ncount = count * 2; - } else { - ncount = count; - if (start_blank) { - ncount--; - } - } - if (ncount > 0) { - findsent_forward(ncount, true); - } else { - decl(&curwin->w_cursor); - } - - if (include) { - /* - * If the blank in front of the sentence is included, exclude the - * blanks at the end of the sentence, go back to the first blank. - * If there are no trailing blanks, try to include leading blanks. - */ - if (start_blank) { - find_first_blank(&curwin->w_cursor); - c = gchar_pos(&curwin->w_cursor); - if (ascii_iswhite(c)) { - decl(&curwin->w_cursor); - } - } else if (c = gchar_cursor(), !ascii_iswhite(c)) { - find_first_blank(&start_pos); - } - } - - if (VIsual_active) { - // Avoid getting stuck with "is" on a single space before a sentence. - if (equalpos(start_pos, curwin->w_cursor)) { - goto extend; - } - if (*p_sel == 'e') { - ++curwin->w_cursor.col; - } - VIsual = start_pos; - VIsual_mode = 'v'; - redraw_cmdline = true; // show mode later - redraw_curbuf_later(INVERTED); // update the inversion - } else { - // include a newline after the sentence, if there is one - if (incl(&curwin->w_cursor) == -1) { - oap->inclusive = true; - } else { - oap->inclusive = false; - } - oap->start = start_pos; - oap->motion_type = kMTCharWise; - } - return OK; -} - -/// Find block under the cursor, cursor at end. -/// "what" and "other" are two matching parenthesis/brace/etc. -/// -/// @param include TRUE == include white space -/// @param what '(', '{', etc. -/// @param other ')', '}', etc. -int current_block(oparg_T *oap, long count, int include, int what, int other) -{ - pos_T old_pos; - pos_T *pos = NULL; - pos_T start_pos; - pos_T *end_pos; - pos_T old_start, old_end; - char *save_cpo; - bool sol = false; // '{' at start of line - - old_pos = curwin->w_cursor; - old_end = curwin->w_cursor; // remember where we started - old_start = old_end; - - /* - * If we start on '(', '{', ')', '}', etc., use the whole block inclusive. - */ - if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) { - setpcmark(); - if (what == '{') { // ignore indent - while (inindent(1)) { - if (inc_cursor() != 0) { - break; - } - } - } - if (gchar_cursor() == what) { - // cursor on '(' or '{', move cursor just after it - ++curwin->w_cursor.col; - } - } else if (lt(VIsual, curwin->w_cursor)) { - old_start = VIsual; - curwin->w_cursor = VIsual; // cursor at low end of Visual - } else { - old_end = VIsual; - } - - // Search backwards for unclosed '(', '{', etc.. - // Put this position in start_pos. - // Ignore quotes here. Keep the "M" flag in 'cpo', as that is what the - // user wants. - save_cpo = p_cpo; - p_cpo = vim_strchr(p_cpo, CPO_MATCHBSL) != NULL ? "%M" : "%"; - if ((pos = findmatch(NULL, what)) != NULL) { - while (count-- > 0) { - if ((pos = findmatch(NULL, what)) == NULL) { - break; - } - curwin->w_cursor = *pos; - start_pos = *pos; // the findmatch for end_pos will overwrite *pos - } - } else { - while (count-- > 0) { - if ((pos = findmatchlimit(NULL, what, FM_FORWARD, 0)) == NULL) { - break; - } - curwin->w_cursor = *pos; - start_pos = *pos; // the findmatch for end_pos will overwrite *pos - } - } - p_cpo = save_cpo; - - /* - * Search for matching ')', '}', etc. - * Put this position in curwin->w_cursor. - */ - if (pos == NULL || (end_pos = findmatch(NULL, other)) == NULL) { - curwin->w_cursor = old_pos; - return FAIL; - } - curwin->w_cursor = *end_pos; - - // Try to exclude the '(', '{', ')', '}', etc. when "include" is FALSE. - // If the ending '}', ')' or ']' is only preceded by indent, skip that - // indent. But only if the resulting area is not smaller than what we - // started with. - while (!include) { - incl(&start_pos); - sol = (curwin->w_cursor.col == 0); - decl(&curwin->w_cursor); - while (inindent(1)) { - sol = true; - if (decl(&curwin->w_cursor) != 0) { - break; - } - } - - // In Visual mode, when the resulting area is not bigger than what we - // started with, extend it to the next block, and then exclude again. - // Don't try to expand the area if the area is empty. - if (!lt(start_pos, old_start) && !lt(old_end, curwin->w_cursor) - && !equalpos(start_pos, curwin->w_cursor) - && VIsual_active) { - curwin->w_cursor = old_start; - decl(&curwin->w_cursor); - if ((pos = findmatch(NULL, what)) == NULL) { - curwin->w_cursor = old_pos; - return FAIL; - } - start_pos = *pos; - curwin->w_cursor = *pos; - if ((end_pos = findmatch(NULL, other)) == NULL) { - curwin->w_cursor = old_pos; - return FAIL; - } - curwin->w_cursor = *end_pos; - } else { - break; - } - } - - if (VIsual_active) { - if (*p_sel == 'e') { - inc(&curwin->w_cursor); - } - if (sol && gchar_cursor() != NUL) { - inc(&curwin->w_cursor); // include the line break - } - VIsual = start_pos; - VIsual_mode = 'v'; - redraw_curbuf_later(INVERTED); // update the inversion - showmode(); - } else { - oap->start = start_pos; - oap->motion_type = kMTCharWise; - oap->inclusive = false; - if (sol) { - incl(&curwin->w_cursor); - } else if (ltoreq(start_pos, curwin->w_cursor)) { - // Include the character under the cursor. - oap->inclusive = true; - } else { - // End is before the start (no text in between <>, [], etc.): don't - // operate on any text. - curwin->w_cursor = start_pos; - } - } - - return OK; -} - -/// @param end_tag when true, return true if the cursor is on "</aaa>". -/// -/// @return true if the cursor is on a "<aaa>" tag. Ignore "<aaa/>". -static bool in_html_tag(bool end_tag) -{ - char_u *line = get_cursor_line_ptr(); - char_u *p; - int c; - int lc = NUL; - pos_T pos; - - for (p = line + curwin->w_cursor.col; p > line;) { - if (*p == '<') { // find '<' under/before cursor - break; - } - MB_PTR_BACK(line, p); - if (*p == '>') { // find '>' before cursor - break; - } - } - if (*p != '<') { - return false; - } - - pos.lnum = curwin->w_cursor.lnum; - pos.col = (colnr_T)(p - line); - - MB_PTR_ADV(p); - if (end_tag) { - // check that there is a '/' after the '<' - return *p == '/'; - } - - // check that there is no '/' after the '<' - if (*p == '/') { - return false; - } - - // check that the matching '>' is not preceded by '/' - for (;;) { - if (inc(&pos) < 0) { - return false; - } - c = *ml_get_pos(&pos); - if (c == '>') { - break; - } - lc = c; - } - return lc != '/'; -} - -/// Find tag block under the cursor, cursor at end. -/// -/// @param include true == include white space -int current_tagblock(oparg_T *oap, long count_arg, bool include) -{ - long count = count_arg; - pos_T old_pos; - pos_T start_pos; - pos_T end_pos; - pos_T old_start, old_end; - char_u *p; - char_u *cp; - int len; - bool do_include = include; - bool save_p_ws = p_ws; - int retval = FAIL; - int is_inclusive = true; - - p_ws = false; - - old_pos = curwin->w_cursor; - old_end = curwin->w_cursor; // remember where we started - old_start = old_end; - if (!VIsual_active || *p_sel == 'e') { - decl(&old_end); // old_end is inclusive - } - /* - * If we start on "<aaa>" select that block. - */ - if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) { - setpcmark(); - - // ignore indent - while (inindent(1)) { - if (inc_cursor() != 0) { - break; - } - } - - if (in_html_tag(false)) { - // cursor on start tag, move to its '>' - while (*get_cursor_pos_ptr() != '>') { - if (inc_cursor() < 0) { - break; - } - } - } else if (in_html_tag(true)) { - // cursor on end tag, move to just before it - while (*get_cursor_pos_ptr() != '<') { - if (dec_cursor() < 0) { - break; - } - } - dec_cursor(); - old_end = curwin->w_cursor; - } - } else if (lt(VIsual, curwin->w_cursor)) { - old_start = VIsual; - curwin->w_cursor = VIsual; // cursor at low end of Visual - } else { - old_end = VIsual; - } - -again: - /* - * Search backwards for unclosed "<aaa>". - * Put this position in start_pos. - */ - for (long n = 0; n < count; n++) { - if (do_searchpair("<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)", - "", - "</[^>]*>", BACKWARD, NULL, 0, - NULL, (linenr_T)0, 0L) <= 0) { - curwin->w_cursor = old_pos; - goto theend; - } - } - start_pos = curwin->w_cursor; - - /* - * Search for matching "</aaa>". First isolate the "aaa". - */ - inc_cursor(); - p = get_cursor_pos_ptr(); - for (cp = p; - *cp != NUL && *cp != '>' && !ascii_iswhite(*cp); - MB_PTR_ADV(cp)) {} - len = (int)(cp - p); - if (len == 0) { - curwin->w_cursor = old_pos; - goto theend; - } - const size_t spat_len = (size_t)len + 39; - char *const spat = xmalloc(spat_len); - const size_t epat_len = (size_t)len + 9; - char *const epat = xmalloc(epat_len); - snprintf(spat, spat_len, - "<%.*s\\>\\%%(\\_s\\_[^>]\\{-}\\_[^/]>\\|\\_s\\?>\\)\\c", len, p); - snprintf(epat, epat_len, "</%.*s>\\c", len, p); - - const int r = (int)do_searchpair(spat, "", epat, FORWARD, NULL, 0, NULL, (linenr_T)0, 0L); - - xfree(spat); - xfree(epat); - - if (r < 1 || lt(curwin->w_cursor, old_end)) { - // Can't find other end or it's before the previous end. Could be a - // HTML tag that doesn't have a matching end. Search backwards for - // another starting tag. - count = 1; - curwin->w_cursor = start_pos; - goto again; - } - - if (do_include) { - // Include up to the '>'. - while (*get_cursor_pos_ptr() != '>') { - if (inc_cursor() < 0) { - break; - } - } - } else { - char_u *c = get_cursor_pos_ptr(); - // Exclude the '<' of the end tag. - // If the closing tag is on new line, do not decrement cursor, but make - // operation exclusive, so that the linefeed will be selected - if (*c == '<' && !VIsual_active && curwin->w_cursor.col == 0) { - // do not decrement cursor - is_inclusive = false; - } else if (*c == '<') { - dec_cursor(); - } - } - end_pos = curwin->w_cursor; - - if (!do_include) { - // Exclude the start tag. - curwin->w_cursor = start_pos; - while (inc_cursor() >= 0) { - if (*get_cursor_pos_ptr() == '>') { - inc_cursor(); - start_pos = curwin->w_cursor; - break; - } - } - curwin->w_cursor = end_pos; - - // If we are in Visual mode and now have the same text as before set - // "do_include" and try again. - if (VIsual_active - && equalpos(start_pos, old_start) - && equalpos(end_pos, old_end)) { - do_include = true; - curwin->w_cursor = old_start; - count = count_arg; - goto again; - } - } - - if (VIsual_active) { - // If the end is before the start there is no text between tags, select - // the char under the cursor. - if (lt(end_pos, start_pos)) { - curwin->w_cursor = start_pos; - } else if (*p_sel == 'e') { - inc_cursor(); - } - VIsual = start_pos; - VIsual_mode = 'v'; - redraw_curbuf_later(INVERTED); // update the inversion - showmode(); - } else { - oap->start = start_pos; - oap->motion_type = kMTCharWise; - if (lt(end_pos, start_pos)) { - // End is before the start: there is no text between tags; operate - // on an empty area. - curwin->w_cursor = start_pos; - oap->inclusive = false; - } else { - oap->inclusive = is_inclusive; - } - } - retval = OK; - -theend: - p_ws = save_p_ws; - return retval; -} - -/// @param include TRUE == include white space -/// @param type 'p' for paragraph, 'S' for section -int current_par(oparg_T *oap, long count, int include, int type) -{ - linenr_T start_lnum; - linenr_T end_lnum; - int white_in_front; - int dir; - int start_is_white; - int prev_start_is_white; - int retval = OK; - int do_white = FALSE; - int t; - int i; - - if (type == 'S') { // not implemented yet - return FAIL; - } - - start_lnum = curwin->w_cursor.lnum; - - /* - * When visual area is more than one line: extend it. - */ - if (VIsual_active && start_lnum != VIsual.lnum) { -extend: - if (start_lnum < VIsual.lnum) { - dir = BACKWARD; - } else { - dir = FORWARD; - } - for (i = (int)count; --i >= 0;) { - if (start_lnum == - (dir == BACKWARD ? 1 : curbuf->b_ml.ml_line_count)) { - retval = FAIL; - break; - } - - prev_start_is_white = -1; - for (t = 0; t < 2; ++t) { - start_lnum += dir; - start_is_white = linewhite(start_lnum); - if (prev_start_is_white == start_is_white) { - start_lnum -= dir; - break; - } - for (;;) { - if (start_lnum == (dir == BACKWARD - ? 1 : curbuf->b_ml.ml_line_count)) { - break; - } - if (start_is_white != linewhite(start_lnum + dir) - || (!start_is_white - && startPS(start_lnum + (dir > 0 - ? 1 : 0), 0, 0))) { - break; - } - start_lnum += dir; - } - if (!include) { - break; - } - if (start_lnum == (dir == BACKWARD - ? 1 : curbuf->b_ml.ml_line_count)) { - break; - } - prev_start_is_white = start_is_white; - } - } - curwin->w_cursor.lnum = start_lnum; - curwin->w_cursor.col = 0; - return retval; - } - - /* - * First move back to the start_lnum of the paragraph or white lines - */ - white_in_front = linewhite(start_lnum); - while (start_lnum > 1) { - if (white_in_front) { // stop at first white line - if (!linewhite(start_lnum - 1)) { - break; - } - } else { // stop at first non-white line of start of paragraph - if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0)) { - break; - } - } - start_lnum--; - } - - /* - * Move past the end of any white lines. - */ - end_lnum = start_lnum; - while (end_lnum <= curbuf->b_ml.ml_line_count && linewhite(end_lnum)) { - end_lnum++; - } - - end_lnum--; - i = (int)count; - if (!include && white_in_front) { - i--; - } - while (i--) { - if (end_lnum == curbuf->b_ml.ml_line_count) { - return FAIL; - } - - if (!include) { - do_white = linewhite(end_lnum + 1); - } - - if (include || !do_white) { - end_lnum++; - // skip to end of paragraph - while (end_lnum < curbuf->b_ml.ml_line_count - && !linewhite(end_lnum + 1) - && !startPS(end_lnum + 1, 0, 0)) { - end_lnum++; - } - } - - if (i == 0 && white_in_front && include) { - break; - } - - /* - * skip to end of white lines after paragraph - */ - if (include || do_white) { - while (end_lnum < curbuf->b_ml.ml_line_count - && linewhite(end_lnum + 1)) { - end_lnum++; - } - } - } - - /* - * If there are no empty lines at the end, try to find some empty lines at - * the start (unless that has been done already). - */ - if (!white_in_front && !linewhite(end_lnum) && include) { - while (start_lnum > 1 && linewhite(start_lnum - 1)) { - start_lnum--; - } - } - - if (VIsual_active) { - // Problem: when doing "Vipipip" nothing happens in a single white - // line, we get stuck there. Trap this here. - if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum) { - goto extend; - } - if (VIsual.lnum != start_lnum) { - VIsual.lnum = start_lnum; - VIsual.col = 0; - } - VIsual_mode = 'V'; - redraw_curbuf_later(INVERTED); // update the inversion - showmode(); - } else { - oap->start.lnum = start_lnum; - oap->start.col = 0; - oap->motion_type = kMTLineWise; - } - curwin->w_cursor.lnum = end_lnum; - curwin->w_cursor.col = 0; - - return OK; -} - -/// Search quote char from string line[col]. -/// Quote character escaped by one of the characters in "escape" is not counted -/// as a quote. -/// -/// @param escape escape characters, can be NULL -/// -/// @return column number of "quotechar" or -1 when not found. -static int find_next_quote(char_u *line, int col, int quotechar, char_u *escape) -{ - int c; - - for (;;) { - c = line[col]; - if (c == NUL) { - return -1; - } else if (escape != NULL && vim_strchr((char *)escape, c)) { - col++; - if (line[col] == NUL) { - return -1; - } - } else if (c == quotechar) { - break; - } - col += utfc_ptr2len((char *)line + col); - } - return col; -} - -/// Search backwards in "line" from column "col_start" to find "quotechar". -/// Quote character escaped by one of the characters in "escape" is not counted -/// as a quote. -/// -/// @param escape escape characters, can be NULL -/// -/// @return the found column or zero. -static int find_prev_quote(char_u *line, int col_start, int quotechar, char_u *escape) -{ - int n; - - while (col_start > 0) { - col_start--; - col_start -= utf_head_off(line, line + col_start); - n = 0; - if (escape != NULL) { - while (col_start - n > 0 && vim_strchr((char *)escape, - line[col_start - n - 1]) != NULL) { - n++; - } - } - if (n & 1) { - col_start -= n; // uneven number of escape chars, skip it - } else if (line[col_start] == quotechar) { - break; - } - } - return col_start; -} - -/// Find quote under the cursor, cursor at end. -/// -/// @param include true == include quote char -/// @param quotechar Quote character -/// -/// @return true if found, else false. -bool current_quote(oparg_T *oap, long count, bool include, int quotechar) - FUNC_ATTR_NONNULL_ALL -{ - char_u *line = get_cursor_line_ptr(); - int col_end; - int col_start = curwin->w_cursor.col; - bool inclusive = false; - bool vis_empty = true; // Visual selection <= 1 char - bool vis_bef_curs = false; // Visual starts before cursor - bool did_exclusive_adj = false; // adjusted pos for 'selection' - bool inside_quotes = false; // Looks like "i'" done before - bool selected_quote = false; // Has quote inside selection - int i; - bool restore_vis_bef = false; // resotre VIsual on abort - - // When 'selection' is "exclusive" move the cursor to where it would be - // with 'selection' "inclusive", so that the logic is the same for both. - // The cursor then is moved forward after adjusting the area. - if (VIsual_active) { - // this only works within one line - if (VIsual.lnum != curwin->w_cursor.lnum) { - return false; - } - - vis_bef_curs = lt(VIsual, curwin->w_cursor); - vis_empty = equalpos(VIsual, curwin->w_cursor); - if (*p_sel == 'e') { - if (vis_bef_curs) { - dec_cursor(); - did_exclusive_adj = true; - } else if (!vis_empty) { - dec(&VIsual); - did_exclusive_adj = true; - } - vis_empty = equalpos(VIsual, curwin->w_cursor); - if (!vis_bef_curs && !vis_empty) { - // VIsual needs to be start of Visual selection. - pos_T t = curwin->w_cursor; - - curwin->w_cursor = VIsual; - VIsual = t; - vis_bef_curs = true; - restore_vis_bef = true; - } - } - } - - if (!vis_empty) { - // Check if the existing selection exactly spans the text inside - // quotes. - if (vis_bef_curs) { - inside_quotes = VIsual.col > 0 - && line[VIsual.col - 1] == quotechar - && line[curwin->w_cursor.col] != NUL - && line[curwin->w_cursor.col + 1] == quotechar; - i = VIsual.col; - col_end = curwin->w_cursor.col; - } else { - inside_quotes = curwin->w_cursor.col > 0 - && line[curwin->w_cursor.col - 1] == quotechar - && line[VIsual.col] != NUL - && line[VIsual.col + 1] == quotechar; - i = curwin->w_cursor.col; - col_end = VIsual.col; - } - - // Find out if we have a quote in the selection. - while (i <= col_end) { - // check for going over the end of the line, which can happen if - // the line was changed after the Visual area was selected. - if (line[i] == NUL) { - break; - } - if (line[i++] == quotechar) { - selected_quote = true; - break; - } - } - } - - if (!vis_empty && line[col_start] == quotechar) { - // Already selecting something and on a quote character. Find the - // next quoted string. - if (vis_bef_curs) { - // Assume we are on a closing quote: move to after the next - // opening quote. - col_start = find_next_quote(line, col_start + 1, quotechar, NULL); - if (col_start < 0) { - goto abort_search; - } - col_end = find_next_quote(line, col_start + 1, quotechar, - curbuf->b_p_qe); - if (col_end < 0) { - // We were on a starting quote perhaps? - col_end = col_start; - col_start = curwin->w_cursor.col; - } - } else { - col_end = find_prev_quote(line, col_start, quotechar, NULL); - if (line[col_end] != quotechar) { - goto abort_search; - } - col_start = find_prev_quote(line, col_end, quotechar, - curbuf->b_p_qe); - if (line[col_start] != quotechar) { - // We were on an ending quote perhaps? - col_start = col_end; - col_end = curwin->w_cursor.col; - } - } - } else if (line[col_start] == quotechar || !vis_empty) { - int first_col = col_start; - - if (!vis_empty) { - if (vis_bef_curs) { - first_col = find_next_quote(line, col_start, quotechar, NULL); - } else { - first_col = find_prev_quote(line, col_start, quotechar, NULL); - } - } - // The cursor is on a quote, we don't know if it's the opening or - // closing quote. Search from the start of the line to find out. - // Also do this when there is a Visual area, a' may leave the cursor - // in between two strings. - col_start = 0; - for (;;) { - // Find open quote character. - col_start = find_next_quote(line, col_start, quotechar, NULL); - if (col_start < 0 || col_start > first_col) { - goto abort_search; - } - // Find close quote character. - col_end = find_next_quote(line, col_start + 1, quotechar, - curbuf->b_p_qe); - if (col_end < 0) { - goto abort_search; - } - // If is cursor between start and end quote character, it is - // target text object. - if (col_start <= first_col && first_col <= col_end) { - break; - } - col_start = col_end + 1; - } - } else { - // Search backward for a starting quote. - col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe); - if (line[col_start] != quotechar) { - // No quote before the cursor, look after the cursor. - col_start = find_next_quote(line, col_start, quotechar, NULL); - if (col_start < 0) { - goto abort_search; - } - } - - // Find close quote character. - col_end = find_next_quote(line, col_start + 1, quotechar, - curbuf->b_p_qe); - if (col_end < 0) { - goto abort_search; - } - } - - // When "include" is true, include spaces after closing quote or before - // the starting quote. - if (include) { - if (ascii_iswhite(line[col_end + 1])) { - while (ascii_iswhite(line[col_end + 1])) { - col_end++; - } - } else { - while (col_start > 0 && ascii_iswhite(line[col_start - 1])) { - col_start--; - } - } - } - - // Set start position. After vi" another i" must include the ". - // For v2i" include the quotes. - if (!include && count < 2 && (vis_empty || !inside_quotes)) { - col_start++; - } - curwin->w_cursor.col = col_start; - if (VIsual_active) { - // Set the start of the Visual area when the Visual area was empty, we - // were just inside quotes or the Visual area didn't start at a quote - // and didn't include a quote. - if (vis_empty - || (vis_bef_curs - && !selected_quote - && (inside_quotes - || (line[VIsual.col] != quotechar - && (VIsual.col == 0 - || line[VIsual.col - 1] != quotechar))))) { - VIsual = curwin->w_cursor; - redraw_curbuf_later(INVERTED); - } - } else { - oap->start = curwin->w_cursor; - oap->motion_type = kMTCharWise; - } - - // Set end position. - curwin->w_cursor.col = col_end; - if ((include || count > 1 - // After vi" another i" must include the ". - || (!vis_empty && inside_quotes) - ) && inc_cursor() == 2) { - inclusive = true; - } - if (VIsual_active) { - if (vis_empty || vis_bef_curs) { - // decrement cursor when 'selection' is not exclusive - if (*p_sel != 'e') { - dec_cursor(); - } - } else { - // Cursor is at start of Visual area. Set the end of the Visual - // area when it was just inside quotes or it didn't end at a - // quote. - if (inside_quotes - || (!selected_quote - && line[VIsual.col] != quotechar - && (line[VIsual.col] == NUL - || line[VIsual.col + 1] != quotechar))) { - dec_cursor(); - VIsual = curwin->w_cursor; - } - curwin->w_cursor.col = col_start; - } - if (VIsual_mode == 'V') { - VIsual_mode = 'v'; - redraw_cmdline = true; // show mode later - } - } else { - // Set inclusive and other oap's flags. - oap->inclusive = inclusive; - } - - return true; - -abort_search: - if (VIsual_active && *p_sel == 'e') { - if (did_exclusive_adj) { - inc_cursor(); - } - if (restore_vis_bef) { - pos_T t = curwin->w_cursor; - - curwin->w_cursor = VIsual; - VIsual = t; - } - } - return false; -} - /// Find next search match under cursor, cursor at end. /// Used while an operator is pending, and in Visual mode. /// @@ -4347,7 +2444,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)); } } } @@ -4389,7 +2486,7 @@ int current_search(long count, bool forward) may_start_select('c'); setmouse(); - redraw_curbuf_later(INVERTED); + redraw_curbuf_later(UPD_INVERTED); showmode(); return OK; @@ -4399,7 +2496,7 @@ int current_search(long count, bool forward) /// If move is true, check from the beginning of the buffer, /// 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_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction) { regmmatch_T regmatch; @@ -4456,14 +2553,12 @@ static int is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direct return result; } -/* - * return TRUE if line 'lnum' is empty or has white chars only. - */ +/// return true if line 'lnum' is empty or has white chars only. int linewhite(linenr_T lnum) { char_u *p; - p = (char_u *)skipwhite((char *)ml_get(lnum)); + p = (char_u *)skipwhite(ml_get(lnum)); return *p == NUL; } @@ -4622,7 +2717,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst } if (done_search) { xfree(lastpat); - lastpat = vim_strsave(spats[last_idx].pat); + lastpat = (char_u *)xstrdup((char *)spats[last_idx].pat); chgtick = (int)buf_get_changedtick(curbuf); lbuf = curbuf; lastpos = p; @@ -4637,7 +2732,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst } // "searchcount()" function -void f_searchcount(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { pos_T pos = curwin->w_cursor; char_u *pattern = NULL; @@ -4732,7 +2827,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, FunPtr fptr) goto the_end; } xfree(spats[last_idx].pat); - spats[last_idx].pat = vim_strsave(pattern); + spats[last_idx].pat = (char_u *)xstrdup((char *)pattern); } if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) { goto the_end; // the previous pattern was never defined @@ -4869,7 +2964,7 @@ static int fuzzy_match_compute_score(const char_u *const str, const int strSz, if (currIdx > 0) { // Camel case const char_u *p = str; - int neighbor; + int neighbor = ' '; for (uint32_t sidx = 0; sidx < currIdx; sidx++) { neighbor = utf_ptr2char((char *)p); @@ -5008,7 +3103,7 @@ bool fuzzy_match(char_u *const str, const char_u *const pat_arg, const bool matc *outScore = 0; - char_u *const save_pat = vim_strsave(pat_arg); + char_u *const save_pat = (char_u *)xstrdup((char *)pat_arg); char_u *pat = save_pat; char_u *p = pat; @@ -5287,13 +3382,13 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv, } /// "matchfuzzy()" function -void f_matchfuzzy(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_matchfuzzy(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { do_fuzzymatch(argvars, rettv, false); } /// "matchfuzzypos()" function -void f_matchfuzzypos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +void f_matchfuzzypos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { do_fuzzymatch(argvars, rettv, true); } @@ -5303,13 +3398,13 @@ void f_matchfuzzypos(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// mark. static char_u *get_line_and_copy(linenr_T lnum, char_u *buf) { - char_u *line = ml_get(lnum); + char_u *line = (char_u *)ml_get(lnum); STRLCPY(buf, line, LSIZE); return buf; } /// Find identifiers or defines in included files. -/// If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase. +/// If p_ic && compl_status_sol() then ptr must be in lowercase. /// /// @param ptr pointer to search pattern /// @param dir direction of expansion @@ -5351,7 +3446,6 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo int i; char_u *already = NULL; char_u *startp = NULL; - char_u *inc_opt = NULL; win_T *curwin_save = NULL; const int l_g_do_tagpreview = g_do_tagpreview; @@ -5362,9 +3456,9 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo 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_cont_status & CONT_SOL)) { + // 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()) { pat = xmalloc(len + 5); assert(len <= INT_MAX); sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr); @@ -5376,22 +3470,22 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo goto fpip_end; } } - inc_opt = (*curbuf->b_p_inc == NUL) ? p_inc : curbuf->b_p_inc; + char *inc_opt = (*curbuf->b_p_inc == NUL) ? p_inc : curbuf->b_p_inc; if (*inc_opt != NUL) { - incl_regmatch.regprog = vim_regcomp((char *)inc_opt, p_magic ? RE_MAGIC : 0); + incl_regmatch.regprog = vim_regcomp(inc_opt, p_magic ? RE_MAGIC : 0); if (incl_regmatch.regprog == NULL) { goto fpip_end; } - incl_regmatch.rm_ic = FALSE; // don't ignore case in incl. pat. + incl_regmatch.rm_ic = false; // don't ignore case in incl. pat. } if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) { def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL - ? (char *)p_def : (char *)curbuf->b_p_def, + ? p_def : curbuf->b_p_def, p_magic ? RE_MAGIC : 0); if (def_regmatch.regprog == NULL) { goto fpip_end; } - def_regmatch.rm_ic = FALSE; // don't ignore case in define pat. + 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; @@ -5412,19 +3506,19 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo char_u *p_fname = (curr_fname == (char_u *)curbuf->b_fname) ? (char_u *)curbuf->b_ffname : curr_fname; - if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) { + if (inc_opt != NULL && strstr(inc_opt, "\\zs") != NULL) { // Use text from '\zs' to '\ze' (or end) of 'include'. - new_fname = find_file_name_in_path(incl_regmatch.startp[0], - (size_t)(incl_regmatch.endp[0] - - incl_regmatch.startp[0]), - FNAME_EXP|FNAME_INCL|FNAME_REL, - 1L, p_fname); + new_fname = (char_u *)find_file_name_in_path(incl_regmatch.startp[0], + (size_t)(incl_regmatch.endp[0] + - incl_regmatch.startp[0]), + FNAME_EXP|FNAME_INCL|FNAME_REL, + 1L, (char *)p_fname); } else { // Use text after match with 'include'. - new_fname = file_name_in_line(incl_regmatch.endp[0], 0, + new_fname = file_name_in_line((char_u *)incl_regmatch.endp[0], 0, FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL); } - already_searched = FALSE; + already_searched = false; if (new_fname != NULL) { // Check whether we have already searched in this file for (i = 0;; i++) { @@ -5441,7 +3535,7 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo msg_putchar('\n'); // cursor below last one */ if (!got_int) { // don't display if 'q' typed at "--more--" // message - msg_home_replace_hl(new_fname); + msg_home_replace_hl((char *)new_fname); msg_puts(_(" (includes previously listed match)")); prev_fname = NULL; } @@ -5471,7 +3565,7 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo for (i = 0; i < depth_displayed; i++) { msg_puts(" "); } - msg_home_replace(files[depth_displayed].name); + msg_home_replace((char *)files[depth_displayed].name); msg_puts(" -->\n"); } if (!got_int) { // don't display if 'q' typed @@ -5482,28 +3576,26 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo 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_attr((char *)new_fname, HL_ATTR(HLF_D)); } else { - /* - * Isolate the file name. - * Include the surrounding "" or <> if present. - */ + // Isolate the file name. + // Include the surrounding "" or <> if present. if (inc_opt != NULL - && strstr((char *)inc_opt, "\\zs") != NULL) { + && strstr(inc_opt, "\\zs") != NULL) { // pattern contains \zs, use the match - p = incl_regmatch.startp[0]; + p = (char_u *)incl_regmatch.startp[0]; i = (int)(incl_regmatch.endp[0] - incl_regmatch.startp[0]); } else { // find the file name after the end of the match - for (p = incl_regmatch.endp[0]; + for (p = (char_u *)incl_regmatch.endp[0]; *p && !vim_isfilec(*p); p++) {} for (i = 0; vim_isfilec(p[i]); i++) {} } if (i == 0) { // Nothing found, use the rest of the line. - p = incl_regmatch.endp[0]; + p = (char_u *)incl_regmatch.endp[0]; i = (int)STRLEN(p); } else if (p > line) { // Avoid checking before the start of the line, can @@ -5518,7 +3610,7 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo } save_char = p[i]; p[i] = NUL; - msg_outtrans_attr(p, HL_ATTR(HLF_D)); + msg_outtrans_attr((char *)p, HL_ATTR(HLF_D)); p[i] = save_char; } @@ -5530,7 +3622,6 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo } } } - ui_flush(); // output each line directly } if (new_fname != NULL) { @@ -5544,7 +3635,7 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo bigger[i].fp = NULL; bigger[i].name = NULL; bigger[i].lnum = 0; - bigger[i].matched = FALSE; + bigger[i].matched = false; } for (i = old_files; i < max_path_depth; i++) { bigger[i + max_path_depth] = files[i]; @@ -5565,7 +3656,7 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo } files[depth].name = curr_fname = new_fname; files[depth].lnum = 0; - files[depth].matched = FALSE; + files[depth].matched = false; if (action == ACTION_EXPAND) { msg_hist_off = true; // reset in msg_trunc_attr() vim_snprintf((char *)IObuff, IOSIZE, @@ -5581,9 +3672,7 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo } } } else { - /* - * Check if the line is a define (type == FIND_DEFINE) - */ + // Check if the line is a define (type == FIND_DEFINE) p = line; search_line: define_matched = false; @@ -5592,24 +3681,21 @@ search_line: // 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. - p = def_regmatch.endp[0]; + p = (char_u *)def_regmatch.endp[0]; while (*p && !vim_iswordc(*p)) { p++; } define_matched = true; } - /* - * Look for a match. Don't do this if we are looking for a - * define and this line didn't match define_prog above. - */ + // Look for a match. Don't do this if we are looking for a + // define and this line didn't match define_prog above. if (def_regmatch.regprog == NULL || define_matched) { - if (define_matched - || (compl_cont_status & CONT_SOL)) { + if (define_matched || compl_status_sol()) { // compare the first "len" chars from "ptr" startp = (char_u *)skipwhite((char *)p); if (p_ic) { - matched = !mb_strnicmp(startp, ptr, len); + matched = !mb_strnicmp((char *)startp, (char *)ptr, len); } else { matched = !STRNCMP(startp, ptr, len); } @@ -5620,7 +3706,7 @@ search_line: } else if (regmatch.regprog != NULL && vim_regexec(®match, (char *)line, (colnr_T)(p - line))) { matched = true; - startp = regmatch.startp[0]; + startp = (char_u *)regmatch.startp[0]; // Check if the line is not a comment line (unless we are // looking for a define). A line starting with "# define" // is not considered to be a comment line. @@ -5631,16 +3717,14 @@ search_line: matched = false; } - /* - * Also check for a "/ *" or "/ /" before the match. - * Skips lines like "int backwards; / * normal index - * * /" when looking for "normal". - * Note: Doesn't skip "/ *" in comments. - */ + // Also check for a "/ *" or "/ /" before the match. + // Skips lines like "int backwards; / * normal index + // * /" when looking for "normal". + // Note: Doesn't skip "/ *" in comments. p = (char_u *)skipwhite((char *)line); if (matched || (p[0] == '/' && p[1] == '*') || p[0] == '*') { - for (p = line; *p && p < startp; ++p) { + for (p = line; *p && p < startp; p++) { if (matched && p[0] == '/' && (p[1] == '*' || p[1] == '/')) { @@ -5671,8 +3755,8 @@ search_line: } found = true; aux = p = startp; - if (compl_cont_status & CONT_ADDING) { - p += compl_length; + if (compl_status_adding()) { + p += ins_compl_len(); if (vim_iswordp(p)) { goto exit_matched; } @@ -5681,7 +3765,7 @@ search_line: p = find_word_end(p); i = (int)(p - aux); - if ((compl_cont_status & CONT_ADDING) && i == compl_length) { + if (compl_status_adding() && i == ins_compl_len()) { // IOSIZE > compl_length, so the STRNCPY works STRNCPY(IObuff, aux, i); @@ -5726,9 +3810,9 @@ search_line: cont_s_ipos = true; } IObuff[i] = NUL; - aux = IObuff; + aux = (char_u *)IObuff; - if (i == compl_length) { + if (i == ins_compl_len()) { goto exit_matched; } } @@ -5754,7 +3838,7 @@ search_line: } if (!got_int) { // don't display if 'q' typed // at "--more--" message - msg_home_replace_hl(curr_fname); + msg_home_replace_hl((char *)curr_fname); } prev_fname = curr_fname; } @@ -5820,14 +3904,14 @@ search_line: } if (action != ACTION_SHOW) { curwin->w_cursor.col = (colnr_T)(startp - line); - curwin->w_set_curswant = TRUE; + curwin->w_set_curswant = true; } if (l_g_do_tagpreview != 0 && curwin != curwin_save && win_valid(curwin_save)) { // Return cursor to where we were validate_cursor(); - redraw_later(curwin, VALID); + redraw_later(curwin, UPD_VALID); win_enter(curwin_save, true); } break; @@ -5838,7 +3922,7 @@ exit_matched: // are not at the end of it already if (def_regmatch.regprog == NULL && action == ACTION_EXPAND - && !(compl_cont_status & CONT_SOL) + && !compl_status_sol() && *startp != NUL && *(p = startp + utfc_ptr2len((char *)startp)) != NUL) { goto search_line; @@ -5852,11 +3936,9 @@ exit_matched: break; } - /* - * Read the next line. When reading an included file and encountering - * end-of-file, close the file and continue in the file that included - * it. - */ + // Read the next line. When reading an included file and encountering + // end-of-file, close the file and continue in the file that included + // it. while (depth >= 0 && !already && vim_fgets(line = file_line, LSIZE, files[depth].fp)) { fclose(files[depth].fp); @@ -5963,8 +4045,7 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action, msg_puts_attr((const char *)IObuff, HL_ATTR(HLF_N)); msg_puts(" "); } - msg_prt_line(line, FALSE); - ui_flush(); // show one line at a time + msg_prt_line((char *)line, false); // Definition continues until line that doesn't end with '\' if (got_int || type != FIND_DEFINE || p < line || *p != '\\') { @@ -5980,7 +4061,7 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action, if (++*lnum > curbuf->b_ml.ml_line_count) { break; } - line = ml_get(*lnum); + line = (char_u *)ml_get(*lnum); } msg_putchar('\n'); } |