summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-04-29 21:04:15 +0200
committerBram Moolenaar <Bram@vim.org>2020-04-29 21:04:15 +0200
commited8ce057b7a2fcd89b5f55680ae8f85d62a992a5 (patch)
treefea5d30140297aa6888bf6d68a4c00b62f425622
parent939b5db4808770d3a2ec35e3902a9d5165adc0cf (diff)
patch 8.2.0660: the search.c file is a bit bigv8.2.0660
Problem: The search.c file is a bit big. Solution: Split off the text object code to a separate file. (Yegappan Lakshmanan, closes #6007)
-rw-r--r--Filelist2
-rw-r--r--src/Make_cyg_ming.mak1
-rw-r--r--src/Make_morph.mak1
-rw-r--r--src/Make_mvc.mak4
-rw-r--r--src/Make_vms.mms5
-rw-r--r--src/Makefile34
-rw-r--r--src/README.md1
-rw-r--r--src/proto.h1
-rw-r--r--src/proto/search.pro13
-rw-r--r--src/proto/textobject.pro16
-rw-r--r--src/search.c1951
-rw-r--r--src/textobject.c1965
-rw-r--r--src/version.c2
13 files changed, 2020 insertions, 1976 deletions
diff --git a/Filelist b/Filelist
index 46f6774e76..ef65b8da24 100644
--- a/Filelist
+++ b/Filelist
@@ -128,6 +128,7 @@ SRC_ALL = \
src/term.h \
src/termlib.c \
src/testing.c \
+ src/textobject.c \
src/textprop.c \
src/time.c \
src/ui.c \
@@ -279,6 +280,7 @@ SRC_ALL = \
src/proto/terminal.pro \
src/proto/termlib.pro \
src/proto/testing.pro \
+ src/proto/textobject.pro \
src/proto/textprop.pro \
src/proto/time.pro \
src/proto/ui.pro \
diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak
index 750e940e06..7964b0a1f2 100644
--- a/src/Make_cyg_ming.mak
+++ b/src/Make_cyg_ming.mak
@@ -787,6 +787,7 @@ OBJ = \
$(OUTDIR)/tag.o \
$(OUTDIR)/term.o \
$(OUTDIR)/testing.o \
+ $(OUTDIR)/textobject.o \
$(OUTDIR)/textprop.o \
$(OUTDIR)/time.o \
$(OUTDIR)/ui.o \
diff --git a/src/Make_morph.mak b/src/Make_morph.mak
index 1830d85b50..d326174cd2 100644
--- a/src/Make_morph.mak
+++ b/src/Make_morph.mak
@@ -103,6 +103,7 @@ SRC = arabic.c \
tag.c \
term.c \
testing.c \
+ textobject.c \
textprop.c \
time.c \
ui.c \
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index ebc059f862..c873ca0840 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -806,6 +806,7 @@ OBJ = \
$(OUTDIR)\tag.obj \
$(OUTDIR)\term.obj \
$(OUTDIR)\testing.obj \
+ $(OUTDIR)\textobject.obj \
$(OUTDIR)\textprop.obj \
$(OUTDIR)\time.obj \
$(OUTDIR)\ui.obj \
@@ -1744,6 +1745,8 @@ $(OUTDIR)/term.obj: $(OUTDIR) term.c $(INCL)
$(OUTDIR)/term.obj: $(OUTDIR) testing.c $(INCL)
+$(OUTDIR)/textobject.obj: $(OUTDIR) textobject.c $(INCL)
+
$(OUTDIR)/textprop.obj: $(OUTDIR) textprop.c $(INCL)
$(OUTDIR)/time.obj: $(OUTDIR) time.c $(INCL)
@@ -1942,6 +1945,7 @@ proto.h: \
proto/tag.pro \
proto/term.pro \
proto/testing.pro \
+ proto/textobject.pro \
proto/textprop.pro \
proto/time.pro \
proto/ui.pro \
diff --git a/src/Make_vms.mms b/src/Make_vms.mms
index fdd7ba7c1e..e04020172a 100644
--- a/src/Make_vms.mms
+++ b/src/Make_vms.mms
@@ -382,6 +382,7 @@ SRC = \
term.c \
termlib.c \
testing.c \
+ textobject.c \
textprop.c \
time.c \
ui.c \
@@ -491,6 +492,7 @@ OBJ = \
term.obj \
termlib.obj \
testing.obj \
+ textobject.obj \
textprop.obj \
time.obj \
ui.obj \
@@ -989,6 +991,9 @@ termlib.obj : termlib.c vim.h [.auto]config.h feature.h os_unix.h \
testing.obj : testing.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h
+textobject.obj : textobject.c vim.h [.auto]config.h feature.h os_unix.h \
+ ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
+ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h
textprop.obj : textprop.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h
diff --git a/src/Makefile b/src/Makefile
index 19453c7421..c8e0f087fe 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -404,7 +404,7 @@ CClink = $(CC)
# Use --with-luajit if you want to use LuaJIT instead of Lua.
# Set PATH environment variable to find lua or luajit executable.
# This requires at least "normal" features, "tiny" and "small" don't work.
-#CONF_OPT_LUA = --enable-luainterp
+CONF_OPT_LUA = --enable-luainterp
#CONF_OPT_LUA = --enable-luainterp=dynamic
#CONF_OPT_LUA = --enable-luainterp --with-luajit
#CONF_OPT_LUA = --enable-luainterp=dynamic --with-luajit
@@ -433,7 +433,7 @@ CClink = $(CC)
# When you get an error for a missing "perl.exp" file, try creating an empty
# one: "touch perl.exp".
# This requires at least "normal" features, "tiny" and "small" don't work.
-#CONF_OPT_PERL = --enable-perlinterp
+CONF_OPT_PERL = --enable-perlinterp
#CONF_OPT_PERL = --enable-perlinterp=dynamic
# PYTHON
@@ -447,10 +447,10 @@ CClink = $(CC)
# dlopen(), dlsym(), dlclose(), i.e. pythonX.Y.so must be available
# However, this may still cause problems, such as "import termios" failing.
# Build two separate versions of Vim in that case.
-#CONF_OPT_PYTHON = --enable-pythoninterp
+CONF_OPT_PYTHON = --enable-pythoninterp
#CONF_OPT_PYTHON = --enable-pythoninterp --with-python-command=python2.7
#CONF_OPT_PYTHON = --enable-pythoninterp=dynamic
-#CONF_OPT_PYTHON3 = --enable-python3interp
+CONF_OPT_PYTHON3 = --enable-python3interp
#CONF_OPT_PYTHON3 = --enable-python3interp --with-python3-command=python3.6
#CONF_OPT_PYTHON3 = --enable-python3interp=dynamic
@@ -460,19 +460,19 @@ CClink = $(CC)
# Note: you need the development package (e.g., ruby1.9.1-dev on Ubuntu).
# This requires at least "normal" features, "tiny" and "small" don't work.
#CONF_OPT_RUBY = --enable-rubyinterp
-#CONF_OPT_RUBY = --enable-rubyinterp=dynamic
+CONF_OPT_RUBY = --enable-rubyinterp=dynamic
#CONF_OPT_RUBY = --enable-rubyinterp --with-ruby-command=ruby1.9.1
# TCL
# Uncomment this when you want to include the Tcl interface.
# First one is for static linking, second one for dynamic loading.
#CONF_OPT_TCL = --enable-tclinterp
-#CONF_OPT_TCL = --enable-tclinterp=dynamic
+CONF_OPT_TCL = --enable-tclinterp=dynamic
#CONF_OPT_TCL = --enable-tclinterp --with-tclsh=tclsh8.4
# CSCOPE
# Uncomment this when you want to include the Cscope interface.
-#CONF_OPT_CSCOPE = --enable-cscope
+CONF_OPT_CSCOPE = --enable-cscope
# NETBEANS - NetBeans interface. Only works with Motif, GTK, and gnome.
# Motif version must have XPM libraries (see |netbeans-xpm|).
@@ -540,7 +540,7 @@ CClink = $(CC)
#CONF_OPT_FEAT = --with-features=small
#CONF_OPT_FEAT = --with-features=normal
#CONF_OPT_FEAT = --with-features=big
-#CONF_OPT_FEAT = --with-features=huge
+CONF_OPT_FEAT = --with-features=huge
# COMPILED BY - For including a specific e-mail address for ":version".
#CONF_OPT_COMPBY = "--with-compiledby=John Doe <JohnDoe@yahoo.com>"
@@ -614,11 +614,11 @@ CClink = $(CC)
# Use this with GCC to check for mistakes, unused arguments, etc.
# Note: If you use -Wextra and get warnings in GTK code about function
# parameters, you can add -Wno-cast-function-type
-#CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wunreachable-code -Wno-cast-function-type -Wno-deprecated-declarations -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
+CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wunreachable-code -Wno-cast-function-type -Wno-deprecated-declarations -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
# Add -Wpedantic to find // comments and other C99 constructs.
# Better disable Perl and Python to avoid a lot of warnings.
#CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wpedantic -Wunreachable-code -Wunused-result -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
-#CFLAGS = -g -O2 -Wall -Wextra -Wshadow -Wmissing-prototypes -Wpedantic -Wunreachable-code -Wunused-result -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
+#CFLAGS = -g -O2 -Wall -Wextra -Wshadow -Wmissing-prototypes -Wpedantic -Wunreachable-code -Wno-cast-function-type -Wunused-result -Wno-deprecated-declarations -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
#PYTHON_CFLAGS_EXTRA = -Wno-missing-field-initializers
#MZSCHEME_CFLAGS_EXTRA = -Wno-unreachable-code -Wno-unused-parameter
@@ -707,12 +707,12 @@ SANITIZER_LIBS = $(SANITIZER_CFLAGS)
# Configuration is in the .ccmalloc or ~/.ccmalloc file.
# Doesn't work very well, since memory linked to from global variables
# (in libraries) is also marked as leaked memory.
-#LEAK_CFLAGS = -DEXITFREE
+LEAK_CFLAGS = -DEXITFREE
#LEAK_LIBS = -lccmalloc
# Uncomment this line to have Vim call abort() when an internal error is
# detected. Useful when using a tool to find errors.
-#ABORT_CFLAGS = -DABORT_ON_INTERNAL_ERROR
+ABORT_CFLAGS = -DABORT_ON_INTERNAL_ERROR
#####################################################
### Specific systems, check if yours is listed! ### {{{
@@ -1680,6 +1680,7 @@ BASIC_SRC = \
term.c \
terminal.c \
testing.c \
+ textobject.c \
textprop.c \
time.c \
ui.c \
@@ -1822,6 +1823,7 @@ OBJ_COMMON = \
objects/term.o \
objects/terminal.o \
objects/testing.o \
+ objects/textobject.o \
objects/textprop.o \
objects/time.o \
objects/ui.o \
@@ -1996,6 +1998,7 @@ PRO_AUTO = \
terminal.pro \
termlib.pro \
testing.pro \
+ textobject.pro \
textprop.pro \
time.pro \
ui.pro \
@@ -3469,6 +3472,9 @@ objects/terminal.o: terminal.c $(TERM_DEPS)
objects/testing.o: testing.c
$(CCC) -o $@ testing.c
+objects/textobject.o: textobject.c
+ $(CCC) -o $@ textobject.c
+
objects/textprop.o: textprop.c
$(CCC) -o $@ textprop.c
@@ -4060,6 +4066,10 @@ objects/testing.o: testing.c vim.h protodef.h auto/config.h feature.h os_unix.h
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
proto.h globals.h
+objects/textobject.o: textobject.c vim.h protodef.h auto/config.h feature.h os_unix.h \
+ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
+ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
+ proto.h globals.h
objects/textprop.o: textprop.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
diff --git a/src/README.md b/src/README.md
index 54be08284f..765313da7e 100644
--- a/src/README.md
+++ b/src/README.md
@@ -80,6 +80,7 @@ syntax.c | syntax and other highlighting
tag.c | tags
term.c | terminal handling, termcap codes
testing.c | testing: assert and test functions
+textobject.c | text objects
textprop.c | text properties
time.c | time and timer functions
undo.c | undo and redo
diff --git a/src/proto.h b/src/proto.h
index 0115c68d19..d54936c751 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -223,6 +223,7 @@ void mbyte_im_set_active(int active_arg);
# include "textprop.pro"
# endif
# include "testing.pro"
+# include "textobject.pro"
# include "time.pro"
# include "ui.pro"
# include "undo.pro"
diff --git a/src/proto/search.pro b/src/proto/search.pro
index 018c33a4f2..1e15a8828e 100644
--- a/src/proto/search.pro
+++ b/src/proto/search.pro
@@ -30,19 +30,6 @@ int searchc(cmdarg_T *cap, int t_cmd);
pos_T *findmatch(oparg_T *oap, int initc);
pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int maxtravel);
void showmatch(int c);
-int findsent(int dir, long count);
-int findpar(int *pincl, int dir, long count, int what, int both);
-int startPS(linenr_T lnum, int para, int both);
-int fwd_word(long count, int bigword, int eol);
-int bck_word(long count, int bigword, int stop);
-int end_word(long count, int bigword, int stop, int empty);
-int bckend_word(long count, int bigword, int eol);
-int current_word(oparg_T *oap, long count, int include, int bigword);
-int current_sent(oparg_T *oap, long count, int include);
-int current_block(oparg_T *oap, long count, int include, int what, int other);
-int current_tagblock(oparg_T *oap, long count_arg, int include);
-int current_par(oparg_T *oap, long count, int include, int type);
-int current_quote(oparg_T *oap, long count, int include, int quotechar);
int current_search(long count, int forward);
int linewhite(linenr_T lnum);
void find_pattern_in_path(char_u *ptr, int dir, int len, int whole, int skip_comments, int type, long count, int action, linenr_T start_lnum, linenr_T end_lnum);
diff --git a/src/proto/textobject.pro b/src/proto/textobject.pro
new file mode 100644
index 0000000000..7931979140
--- /dev/null
+++ b/src/proto/textobject.pro
@@ -0,0 +1,16 @@
+/* textobject.c */
+int findsent(int dir, long count);
+int findpar(int *pincl, int dir, long count, int what, int both);
+int startPS(linenr_T lnum, int para, int both);
+int fwd_word(long count, int bigword, int eol);
+int bck_word(long count, int bigword, int stop);
+int end_word(long count, int bigword, int stop, int empty);
+int bckend_word(long count, int bigword, int eol);
+int current_word(oparg_T *oap, long count, int include, int bigword);
+int current_sent(oparg_T *oap, long count, int include);
+int current_block(oparg_T *oap, long count, int include, int what, int other);
+int current_tagblock(oparg_T *oap, long count_arg, int include);
+int current_par(oparg_T *oap, long count, int include, int type);
+int current_quote(oparg_T *oap, long count, int include, int quotechar);
+/* vim: set ft=c : */
+
diff --git a/src/search.c b/src/search.c
index 8c335ffd3a..0bf49629eb 100644
--- a/src/search.c
+++ b/src/search.c
@@ -17,8 +17,6 @@ static void set_vv_searchforward(void);
static int first_submatch(regmmatch_T *rp);
#endif
static int check_linecomment(char_u *line);
-static int cls(void);
-static int skip_chars(int, int);
#ifdef FEAT_FIND_ID
static void show_pat_in_path(char_u *, int,
int, int, FILE *, linenr_T *, long);
@@ -2838,1955 +2836,6 @@ showmatch(
}
/*
- * 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(int dir, long count)
-{
- pos_T pos, tpos;
- int c;
- int (*func)(pos_T *);
- int startlnum;
- int noskip = FALSE; // do not skip blanks
- int cpo_J;
- int found_dot;
-
- pos = curwin->w_cursor;
- if (dir == FORWARD)
- func = incl;
- else
- func = decl;
-
- while (count--)
- {
- /*
- * 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
- found_dot = FALSE;
- while (c = gchar_pos(&pos), VIM_ISWHITE(c)
- || vim_strchr((char_u *)".!?)]\"'", c) != NULL)
- {
- tpos = pos;
- if (decl(&tpos) == -1 || (LINEEMPTY(tpos.lnum) && dir == FORWARD))
- break;
-
- if (found_dot)
- break;
- if (vim_strchr((char_u *) ".!?", c) != NULL)
- found_dot = TRUE;
-
- if (vim_strchr((char_u *) ")]\"'", c) != NULL
- && vim_strchr((char_u *) ".!?)]\"'", gchar_pos(&tpos)) == NULL)
- break;
-
- decl(&pos);
- }
-
- // remember the line where the search started
- startlnum = pos.lnum;
- 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((char_u *)")]\"'", 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;
- }
-
- 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 '}'.
- * Return TRUE if the next paragraph or section was found.
- */
- int
-findpar(
- int *pincl, // Return: TRUE if last char is to be included
- int dir,
- long count,
- int what,
- int both)
-{
- linenr_T curr;
- int did_skip; // TRUE after separating lines have been skipped
- int first; // TRUE on first line
- int posix = (vim_strchr(p_cpo, CPO_PARA) != NULL);
-#ifdef FEAT_FOLDING
- linenr_T fold_first; // first line of a closed fold
- linenr_T fold_last; // last line of a closed fold
- int fold_skipped; // TRUE if a closed fold was skipped this
- // iteration
-#endif
-
- curr = curwin->w_cursor.lnum;
-
- while (count--)
- {
- did_skip = FALSE;
- for (first = TRUE; ; first = FALSE)
- {
- if (*ml_get(curr) != NUL)
- did_skip = TRUE;
-
-#ifdef FEAT_FOLDING
- // 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;
- }
-#endif
-
- // POSIX has its own ideas of what a paragraph boundary is and it
- // doesn't match historical Vi: It also stops at a "{" in the
- // first column and at an empty line.
- if (!first && did_skip && (startPS(curr, what, both)
- || (posix && what == NUL && *ml_get(curr) == '{')))
- break;
-
-#ifdef FEAT_FOLDING
- if (fold_skipped)
- curr -= dir;
-#endif
- 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 -=
- (*mb_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;
- if (enc_dbcs != 0 && c > 0xFF)
- {
- // If cls_bigword, report multi-byte chars as class 1.
- if (enc_dbcs == DBCS_KOR && cls_bigword)
- return 1;
-
- // process code leading/trailing bytes
- return dbcs_class(((unsigned)c >> 8), (c & 0xFF));
- }
- if (enc_utf8)
- {
- c = utf_class(c);
- if (c != 0 && cls_bigword)
- return 1;
- return c;
- }
-
- // If cls_bigword is TRUE, report all non-blanks as class 1.
- if (cls_bigword)
- return 1;
-
- if (vim_iswordc(c))
- return 2;
- return 1;
-}
-
-
-/*
- * fwd_word(count, type, eol) - move forward one word
- *
- * Returns 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).
- */
- int
-fwd_word(
- long count,
- int bigword, // "W", "E" or "B"
- int eol)
-{
- int sclass; // starting class
- int i;
- int last_line;
-
- curwin->w_cursor.coladd = 0;
- cls_bigword = bigword;
- while (--count >= 0)
- {
-#ifdef FEAT_FOLDING
- // 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((colnr_T)MAXCOL);
-#endif
- 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 && *ml_get_curline() == 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)
- {
-#ifdef FEAT_FOLDING
- // 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;
-#endif
- 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)
- {
-#ifdef FEAT_FOLDING
- // 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((colnr_T)MAXCOL);
-#endif
- 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.
- *
- * Returns FAIL if start of the file was reached.
- */
- int
-bckend_word(
- long count,
- int bigword, // TRUE for "B"
- int eol) // TRUE: stop at end of line.
-{
- 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 int
-skip_chars(int cclass, int dir)
-{
- while (cls() == cclass)
- if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1)
- return TRUE;
- return FALSE;
-}
-
-#ifdef FEAT_TEXTOBJ
-/*
- * 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 (!VIM_ISWHITE(c))
- {
- incl(posp);
- break;
- }
- }
-}
-
-/*
- * Skip count/2 sentences and count/2 separating white spaces.
- */
- static void
-findsent_forward(
- long count,
- int at_start_sent) // cursor is at start of sentence
-{
- 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.
- */
- int
-current_word(
- oparg_T *oap,
- long count,
- int include, // TRUE: include word and white space
- int bigword) // FALSE == word, TRUE == WORD
-{
- pos_T start_pos;
- pos_T pos;
- int inclusive = TRUE;
- int include_white = FALSE;
-
- cls_bigword = bigword;
- CLEAR_POS(&start_pos);
-
- // Correct cursor when 'selection' is exclusive
- if (VIsual_active && *p_sel == 'e' && LT_POS(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 || EQUAL_POS(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