📄 search.c
字号:
* 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;
}
/*
* bckend_word(count, type) - move back to the end of the word
*
* If 'eol' is TRUE, stop at end of line.
*
* Returns FAIL if start of the file was reached.
*/
int
bckend_word(count, type, eol)
long count;
int type;
int eol;
{
int sclass; /* starting class */
int i;
stype = type;
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(cclass, dir)
int cclass;
int dir;
{
while (cls() == cclass)
if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1)
return TRUE;
return FALSE;
}
#ifdef TEXT_OBJECTS
/*
* Go back to the start of the word or the start of white space
*/
static void
back_in_line()
{
int sclass; /* starting class */
sclass = cls();
for (;;)
{
if (curwin->w_cursor.col == 0) /* stop at start of line */
break;
--curwin->w_cursor.col;
if (cls() != sclass) /* stop at start of word */
{
++curwin->w_cursor.col;
break;
}
}
}
static void
find_first_blank(posp)
FPOS *posp;
{
int c;
while (decl(posp) != -1)
{
c = gchar(posp);
if (!vim_iswhite(c))
{
incl(posp);
break;
}
}
}
/*
* Skip count/2 sentences and count/2 separating white spaces.
*/
static void
findsent_forward(count, at_start_sent)
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(oap, count, include, type)
OPARG *oap;
long count;
int include; /* TRUE: include word and white space */
int type; /* FALSE == word, TRUE == WORD */
{
FPOS start_pos;
FPOS pos;
int inclusive = TRUE;
stype = type;
/* 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 || equal(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, type, 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 (fwd_word(1L, type, TRUE) == FAIL)
return FAIL;
/*
* If end is just past a new-line, we don't want to include the
* first character on the line
*/
if (oneleft() == FAIL) /* put cursor on last char of area */
inclusive = FALSE;
else if (include)
{
/*
* 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. Don't delete white
* space at start of line (indent).
*/
if (cls() != 0)
{
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)
start_pos = curwin->w_cursor;
}
curwin->w_cursor = pos; /* put cursor back at end */
}
}
}
if (VIsual_active)
{
/* should do something when inclusive == FALSE ! */
VIsual = start_pos;
VIsual_mode = 'v';
update_curbuf(NOT_VALID); /* update the inversion */
}
else
{
oap->start = start_pos;
oap->motion_type = MCHAR;
}
--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, type, TRUE) == FAIL)
return FAIL;
}
else
{
if (bckend_word(1L, type, 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, type, TRUE) == FAIL)
return FAIL;
/*
* If end is just past a new-line, we don't want to include
* the first character on the line
*/
if (oneleft() == FAIL) /* put cursor on last char of white */
inclusive = FALSE;
}
else
{
if (end_word(1L, type, TRUE, TRUE) == FAIL)
return FAIL;
}
}
--count;
}
if (VIsual_active)
{
if (*p_sel == 'e' && inclusive && lt(VIsual, curwin->w_cursor))
inc_cursor();
}
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(oap, count, include)
OPARG *oap;
long count;
int include;
{
FPOS start_pos;
FPOS pos;
int start_blank;
int c;
int at_start_sent;
long ncount;
start_pos = curwin->w_cursor;
pos = start_pos;
findsent(FORWARD, 1L); /* Find start of next sentence. */
/*
* When visual area is bigger than one character: Extend it.
*/
if (VIsual_active && !equal(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);
if (!vim_iswhite(c))
{
at_start_sent = FALSE;
break;
}
incl(&pos);
}
if (!at_start_sent)
{
findsent(BACKWARD, 1L);
if (equal(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 && !vim_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 (!equal(pos, curwin->w_cursor)) /* not just before a sentence */
{
at_start_sent = FALSE;
while (lt(pos, curwin->w_cursor))
{
c = gchar(&pos);
if (!vim_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);
}
return OK;
}
/*
* If cursor started on blank, check if it is just before the start of the
* next sentence.
*/
while (c = gchar(&pos), vim_iswhite(c)) /* vim_iswhite() is a macro */
incl(&pos);
if (equal(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 (!include && start_blank)
--ncount;
if (ncount)
findsent_forward(ncount, TRUE);
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);
else if (c = gchar_cursor(), !vim_iswhite(c))
find_first_blank(&start_pos);
}
if (VIsual_active)
{
/* avoid getting stuck with "is" on a single space before a sent. */
if (equal(start_pos, curwin->w_cursor))
goto extend;
VIsual = start_pos;
VIsual_mode = 'v';
update_curbuf(NOT_VALID); /* update the inversion */
}
else
{
/* include a newline after the sentence */
incl(&curwin->w_cursor);
oap->start = start_pos;
oap->motion_type = MCHAR;
oap->inclusive = FALSE;
}
return OK;
}
int
current_block(oap, count, include, what, other)
OPARG *oap;
long count;
int include; /* TRUE == include white space */
int what; /* '(', '{', etc. */
int other; /* ')', '}', etc. */
{
FPOS old_pos;
FPOS *pos = NULL;
FPOS start_pos;
FPOS *end_pos;
FPOS old_start, old_end;
char_u *save_cpo;
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 || equal(VIsual, curwin->w_cursor))
{
setpcmark();
if (what == '{') /* ignore indent */
while (inindent(1))
if (inc_cursor() != 0)
break;
if (gchar_cursor() == what) /* cursor on '(' or '{' */
++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.
* Ignory quotes here.
*/
save_cpo = p_cpo;
p_cpo = (char_u *)"%";
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 */
}
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 '(', '
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -