aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/textobject.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:39:54 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:39:54 +0000
commit21cb7d04c387e4198ca8098a884c78b56ffcf4c2 (patch)
tree84fe5690df1551f0bb2bdfe1a13aacd29ebc1de7 /src/nvim/textobject.c
parentd9c904f85a23a496df4eb6be42aa43f007b22d50 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-colorcolchar.tar.gz
rneovim-colorcolchar.tar.bz2
rneovim-colorcolchar.zip
Merge remote-tracking branch 'upstream/master' into colorcolcharcolorcolchar
Diffstat (limited to 'src/nvim/textobject.c')
-rw-r--r--src/nvim/textobject.c192
1 files changed, 79 insertions, 113 deletions
diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c
index 8e786c271c..d4310d47a4 100644
--- a/src/nvim/textobject.c
+++ b/src/nvim/textobject.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
// textobject.c: functions for text objects
#include <stdbool.h>
@@ -8,28 +5,27 @@
#include <stdio.h>
#include <string.h>
-#include "nvim/ascii.h"
-#include "nvim/buffer_defs.h"
+#include "nvim/ascii_defs.h"
#include "nvim/cursor.h"
#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval/funcs.h"
#include "nvim/fold.h"
+#include "nvim/func_attr.h"
#include "nvim/globals.h"
#include "nvim/indent.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
-#include "nvim/normal.h"
-#include "nvim/option_defs.h"
-#include "nvim/pos.h"
-#include "nvim/screen.h"
+#include "nvim/move.h"
+#include "nvim/option_vars.h"
+#include "nvim/pos_defs.h"
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/textobject.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "textobject.c.generated.h"
@@ -40,14 +36,13 @@
/// 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)
+int findsent(Direction dir, int count)
{
- pos_T pos, tpos;
int c;
int (*func)(pos_T *);
bool noskip = false; // do not skip blanks
- pos = curwin->w_cursor;
+ pos_T pos = curwin->w_cursor;
if (dir == FORWARD) {
func = incl;
} else {
@@ -84,7 +79,7 @@ int findsent(Direction dir, long count)
bool found_dot = false;
while (c = gchar_pos(&pos), ascii_iswhite(c)
|| vim_strchr(".!?)]\"'", c) != NULL) {
- tpos = pos;
+ pos_T tpos = pos;
if (decl(&tpos) == -1 || (LINEEMPTY(tpos.lnum) && dir == FORWARD)) {
break;
}
@@ -105,7 +100,7 @@ int findsent(Direction dir, long count)
const int startlnum = pos.lnum;
const bool cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL;
- for (;;) { // find end of sentence
+ while (true) { // 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) {
@@ -114,7 +109,7 @@ int findsent(Direction dir, long count)
break;
}
if (c == '.' || c == '!' || c == '?') {
- tpos = pos;
+ pos_T tpos = pos;
do {
if ((c = inc(&tpos)) == -1) {
break;
@@ -173,10 +168,9 @@ found:
/// @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, bool both)
+bool findpar(bool *pincl, int dir, int count, int what, bool 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
@@ -186,7 +180,7 @@ bool findpar(bool *pincl, int dir, long count, int what, bool both)
curr = curwin->w_cursor.lnum;
while (count--) {
- did_skip = false;
+ bool did_skip = false; // true after separating lines have been skipped
for (first = true;; first = false) {
if (*ml_get(curr) != NUL) {
did_skip = true;
@@ -322,12 +316,8 @@ static int cls(void)
/// If eol is true, last word stops at end of line (for operators).
///
/// @param bigword "W", "E" or "B"
-int fwd_word(long count, bool bigword, bool eol)
+int fwd_word(int count, bool bigword, bool eol)
{
- int sclass; // starting class
- int i;
- int last_line;
-
curwin->w_cursor.coladd = 0;
cls_bigword = bigword;
while (--count >= 0) {
@@ -336,12 +326,12 @@ int fwd_word(long count, bool bigword, bool eol)
if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum)) {
coladvance(MAXCOL);
}
- sclass = cls();
+ int sclass = cls(); // starting class
// 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();
+ int last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count);
+ int i = inc_cursor();
if (i == -1 || (i >= 1 && last_line)) { // started at last char in file
return FAIL;
}
@@ -380,7 +370,7 @@ int fwd_word(long count, bool bigword, bool eol)
/// 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, bool bigword, bool stop)
+int bck_word(int count, bool bigword, bool stop)
{
int sclass; // starting class
@@ -420,6 +410,7 @@ int bck_word(long count, bool bigword, bool stop)
finished:
stop = false;
}
+ adjust_skipcol();
return OK;
}
@@ -436,7 +427,7 @@ finished:
///
/// 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, bool bigword, bool stop, bool empty)
+int end_word(int count, bool bigword, bool stop, bool empty)
{
int sclass; // starting class
@@ -491,15 +482,13 @@ finished:
/// @param eol if true, then stop at end of line.
///
/// @return FAIL if start of the file was reached.
-int bckend_word(long count, bool bigword, bool eol)
+int bckend_word(int count, bool bigword, bool eol)
{
- int sclass; // starting class
- int i;
-
curwin->w_cursor.coladd = 0;
cls_bigword = bigword;
while (--count >= 0) {
- sclass = cls();
+ int i;
+ int sclass = cls(); // starting class
if ((i = dec_cursor()) == -1) {
return FAIL;
}
@@ -526,6 +515,7 @@ int bckend_word(long count, bool bigword, bool eol)
}
}
}
+ adjust_skipcol();
return OK;
}
@@ -548,7 +538,7 @@ static void back_in_line(void)
int sclass; // starting class
sclass = cls();
- for (;;) {
+ while (true) {
if (curwin->w_cursor.col == 0) { // stop at start of line
break;
}
@@ -562,10 +552,8 @@ static void back_in_line(void)
static void find_first_blank(pos_T *posp)
{
- int c;
-
while (decl(posp) != -1) {
- c = gchar_pos(posp);
+ int c = gchar_pos(posp);
if (!ascii_iswhite(c)) {
incl(posp);
break;
@@ -576,10 +564,10 @@ static void find_first_blank(pos_T *posp)
/// 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)
+static void findsent_forward(int count, bool at_start_sent)
{
while (count--) {
- findsent(FORWARD, 1L);
+ findsent(FORWARD, 1);
if (at_start_sent) {
find_first_blank(&curwin->w_cursor);
}
@@ -595,10 +583,9 @@ static void findsent_forward(long count, bool at_start_sent)
///
/// @param include true: include word and white space
/// @param bigword false == word, true == WORD
-int current_word(oparg_T *oap, long count, bool include, bool bigword)
+int current_word(oparg_T *oap, int count, bool include, bool bigword)
{
pos_T start_pos;
- pos_T pos;
bool inclusive = true;
int include_white = false;
@@ -621,7 +608,7 @@ int current_word(oparg_T *oap, long count, bool include, bool bigword)
// (" 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) {
+ if (end_word(1, bigword, true, true) == FAIL) {
return FAIL;
}
} else {
@@ -630,7 +617,7 @@ int current_word(oparg_T *oap, long count, bool include, bool bigword)
// 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);
+ fwd_word(1, bigword, true);
if (curwin->w_cursor.col == 0) {
decl(&curwin->w_cursor);
} else {
@@ -662,11 +649,11 @@ int current_word(oparg_T *oap, long count, bool include, bool bigword)
return FAIL;
}
if (include != (cls() != 0)) {
- if (bck_word(1L, bigword, true) == FAIL) {
+ if (bck_word(1, bigword, true) == FAIL) {
return FAIL;
}
} else {
- if (bckend_word(1L, bigword, true) == FAIL) {
+ if (bckend_word(1, bigword, true) == FAIL) {
return FAIL;
}
(void)incl(&curwin->w_cursor);
@@ -677,7 +664,7 @@ int current_word(oparg_T *oap, long count, bool include, bool bigword)
return FAIL;
}
if (include != (cls() == 0)) {
- if (fwd_word(1L, bigword, true) == FAIL && count > 1) {
+ if (fwd_word(1, bigword, true) == FAIL && count > 1) {
return FAIL;
}
// If end is just past a new-line, we don't want to include
@@ -687,7 +674,7 @@ int current_word(oparg_T *oap, long count, bool include, bool bigword)
inclusive = false;
}
} else {
- if (end_word(1L, bigword, true, true) == FAIL) {
+ if (end_word(1, bigword, true, true) == FAIL) {
return FAIL;
}
}
@@ -703,7 +690,7 @@ int current_word(oparg_T *oap, long count, bool include, bool bigword)
// 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
+ pos_T pos = curwin->w_cursor; // save cursor position
curwin->w_cursor = start_pos;
if (oneleft() == OK) {
back_in_line();
@@ -735,18 +722,18 @@ int current_word(oparg_T *oap, long count, bool include, bool bigword)
/// 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, bool include)
+int current_sent(oparg_T *oap, int count, bool include)
{
pos_T start_pos;
pos_T pos;
bool start_blank;
int c;
bool at_start_sent;
- long ncount;
+ int ncount;
start_pos = curwin->w_cursor;
pos = start_pos;
- findsent(FORWARD, 1L); // Find start of next sentence.
+ findsent(FORWARD, 1); // Find start of next sentence.
// When the Visual area is bigger than one character: Extend it.
if (VIsual_active && !equalpos(start_pos, VIsual)) {
@@ -768,12 +755,12 @@ extend:
incl(&pos);
}
if (!at_start_sent) {
- findsent(BACKWARD, 1L);
+ findsent(BACKWARD, 1);
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);
+ findsent(FORWARD, 1);
}
}
if (include) { // "as" gets twice as much as "is"
@@ -785,7 +772,7 @@ extend:
}
c = gchar_cursor();
if (!at_start_sent || (!include && !ascii_iswhite(c))) {
- findsent(BACKWARD, 1L);
+ findsent(BACKWARD, 1);
}
at_start_sent = !at_start_sent;
}
@@ -808,7 +795,7 @@ extend:
incl(&pos);
}
if (at_start_sent) { // in the sentence
- findsent(BACKWARD, 1L);
+ findsent(BACKWARD, 1);
} else { // in/before white before a sentence
curwin->w_cursor = start_pos;
}
@@ -835,7 +822,7 @@ extend:
find_first_blank(&start_pos); // go back to first blank
} else {
start_blank = false;
- findsent(BACKWARD, 1L);
+ findsent(BACKWARD, 1);
start_pos = curwin->w_cursor;
}
if (include) {
@@ -898,19 +885,16 @@ extend:
/// @param include true == include white space
/// @param what '(', '{', etc.
/// @param other ')', '}', etc.
-int current_block(oparg_T *oap, long count, bool include, int what, int other)
+int current_block(oparg_T *oap, int count, bool 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;
+ pos_T old_pos = curwin->w_cursor;
+ pos_T old_end = curwin->w_cursor; // remember where we started
+ pos_T old_start = old_end;
// If we start on '(', '{', ')', '}', etc., use the whole block inclusive.
if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) {
@@ -937,7 +921,7 @@ int current_block(oparg_T *oap, long count, bool include, int what, int other)
// 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;
+ char *save_cpo = p_cpo;
p_cpo = vim_strchr(p_cpo, CPO_MATCHBSL) != NULL ? "%M" : "%";
if ((pos = findmatch(NULL, what)) != NULL) {
while (count-- > 0) {
@@ -1042,7 +1026,6 @@ static bool in_html_tag(bool end_tag)
{
char *line = get_cursor_line_ptr();
char *p;
- int c;
int lc = NUL;
pos_T pos;
@@ -1074,11 +1057,11 @@ static bool in_html_tag(bool end_tag)
}
// check that the matching '>' is not preceded by '/'
- for (;;) {
+ while (true) {
if (inc(&pos) < 0) {
return false;
}
- c = (uint8_t)(*ml_get_pos(&pos));
+ int c = (uint8_t)(*ml_get_pos(&pos));
if (c == '>') {
break;
}
@@ -1090,16 +1073,10 @@ static bool in_html_tag(bool end_tag)
/// 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)
+int current_tagblock(oparg_T *oap, int 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 *p;
+ int count = count_arg;
char *cp;
- int len;
bool do_include = include;
bool save_p_ws = p_ws;
int retval = FAIL;
@@ -1107,9 +1084,9 @@ int current_tagblock(oparg_T *oap, long count_arg, bool include)
p_ws = false;
- old_pos = curwin->w_cursor;
- old_end = curwin->w_cursor; // remember where we started
- old_start = old_end;
+ pos_T old_pos = curwin->w_cursor;
+ pos_T old_end = curwin->w_cursor; // remember where we started
+ pos_T old_start = old_end;
if (!VIsual_active || *p_sel == 'e') {
decl(&old_end); // old_end is inclusive
}
@@ -1152,24 +1129,24 @@ int current_tagblock(oparg_T *oap, long count_arg, bool include)
again:
// Search backwards for unclosed "<aaa>".
// Put this position in start_pos.
- for (long n = 0; n < count; n++) {
+ for (int n = 0; n < count; n++) {
if (do_searchpair("<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)",
"",
"</[^>]*>", BACKWARD, NULL, 0,
- NULL, (linenr_T)0, 0L) <= 0) {
+ NULL, 0, 0) <= 0) {
curwin->w_cursor = old_pos;
goto theend;
}
}
- start_pos = curwin->w_cursor;
+ pos_T start_pos = curwin->w_cursor;
// Search for matching "</aaa>". First isolate the "aaa".
inc_cursor();
- p = get_cursor_pos_ptr();
+ char *p = get_cursor_pos_ptr();
for (cp = p;
*cp != NUL && *cp != '>' && !ascii_iswhite(*cp);
MB_PTR_ADV(cp)) {}
- len = (int)(cp - p);
+ int len = (int)(cp - p);
if (len == 0) {
curwin->w_cursor = old_pos;
goto theend;
@@ -1182,7 +1159,7 @@ again:
"<%.*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);
+ const int r = do_searchpair(spat, "", epat, FORWARD, NULL, 0, NULL, 0, 0);
xfree(spat);
xfree(epat);
@@ -1215,7 +1192,7 @@ again:
dec_cursor();
}
}
- end_pos = curwin->w_cursor;
+ pos_T end_pos = curwin->w_cursor;
if (!do_include) {
// Exclude the start tag.
@@ -1274,24 +1251,17 @@ theend:
/// @param include true == include white space
/// @param type 'p' for paragraph, 'S' for section
-int current_par(oparg_T *oap, long count, bool include, int type)
+int current_par(oparg_T *oap, int count, bool 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;
+ linenr_T start_lnum = curwin->w_cursor.lnum;
// When visual area is more than one line: extend it.
if (VIsual_active && start_lnum != VIsual.lnum) {
@@ -1301,22 +1271,22 @@ extend:
} else {
dir = FORWARD;
}
- for (i = (int)count; --i >= 0;) {
+ for (int i = 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++) {
+ int prev_start_is_white = -1;
+ for (int t = 0; t < 2; t++) {
start_lnum += dir;
- start_is_white = linewhite(start_lnum);
+ int start_is_white = linewhite(start_lnum);
if (prev_start_is_white == start_is_white) {
start_lnum -= dir;
break;
}
- for (;;) {
+ while (true) {
if (start_lnum == (dir == BACKWARD
? 1 : curbuf->b_ml.ml_line_count)) {
break;
@@ -1345,7 +1315,7 @@ extend:
}
// First move back to the start_lnum of the paragraph or white lines
- white_in_front = linewhite(start_lnum);
+ int white_in_front = linewhite(start_lnum);
while (start_lnum > 1) {
if (white_in_front) { // stop at first white line
if (!linewhite(start_lnum - 1)) {
@@ -1360,13 +1330,13 @@ extend:
}
// Move past the end of any white lines.
- end_lnum = start_lnum;
+ linenr_T end_lnum = start_lnum;
while (end_lnum <= curbuf->b_ml.ml_line_count && linewhite(end_lnum)) {
end_lnum++;
}
end_lnum--;
- i = (int)count;
+ int i = count;
if (!include && white_in_front) {
i--;
}
@@ -1443,10 +1413,8 @@ extend:
/// @return column number of "quotechar" or -1 when not found.
static int find_next_quote(char *line, int col, int quotechar, char *escape)
{
- int c;
-
- for (;;) {
- c = (uint8_t)line[col];
+ while (true) {
+ int c = (uint8_t)line[col];
if (c == NUL) {
return -1;
} else if (escape != NULL && vim_strchr(escape, c)) {
@@ -1471,12 +1439,10 @@ static int find_next_quote(char *line, int col, int quotechar, char *escape)
/// @return the found column or zero.
static int find_prev_quote(char *line, int col_start, int quotechar, char *escape)
{
- int n;
-
while (col_start > 0) {
col_start--;
col_start -= utf_head_off(line, line + col_start);
- n = 0;
+ int n = 0;
if (escape != NULL) {
while (col_start - n > 0 && vim_strchr(escape,
(uint8_t)line[col_start - n - 1]) != NULL) {
@@ -1498,7 +1464,7 @@ static int find_prev_quote(char *line, int col_start, int quotechar, char *escap
/// @param quotechar Quote character
///
/// @return true if found, else false.
-bool current_quote(oparg_T *oap, long count, bool include, int quotechar)
+bool current_quote(oparg_T *oap, int count, bool include, int quotechar)
FUNC_ATTR_NONNULL_ALL
{
char *line = get_cursor_line_ptr();
@@ -1621,7 +1587,7 @@ bool current_quote(oparg_T *oap, long count, bool include, int quotechar)
// Also do this when there is a Visual area, a' may leave the cursor
// in between two strings.
col_start = 0;
- for (;;) {
+ while (true) {
// Find open quote character.
col_start = find_next_quote(line, col_start, quotechar, NULL);
if (col_start < 0 || col_start > first_col) {