aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-08-24 09:09:46 +0200
committerGitHub <noreply@github.com>2018-08-24 09:09:46 +0200
commit2ab80b944bad532113023dc967dc58af654bef23 (patch)
tree8b12674904464a88a271e090063a8dcf45c488dc
parent925c153f86908a601a19d0142d8c601cf35df88a (diff)
parent748cd91c20bdffe34ac5c9997ac8342cdf9438e1 (diff)
downloadrneovim-2ab80b944bad532113023dc967dc58af654bef23.tar.gz
rneovim-2ab80b944bad532113023dc967dc58af654bef23.tar.bz2
rneovim-2ab80b944bad532113023dc967dc58af654bef23.zip
Merge #8896 from janlazo/vim-8.1.0083
-rw-r--r--src/nvim/search.c56
-rw-r--r--src/nvim/testdir/test_textobjects.vim75
2 files changed, 101 insertions, 30 deletions
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 7be7dc2187..40d3f74103 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -2211,21 +2211,17 @@ showmatch(
}
}
-/*
- * findsent(dir, count) - Find the start of the next sentence in direction
- * "dir" Sentences are supposed to end in ".", "!" or "?" followed by white
- * space or a line break. Also stop at an empty line.
- * Return OK if the next sentence was found.
- */
-int findsent(int dir, long count)
+// 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 *);
- int startlnum;
- int noskip = FALSE; /* do not skip blanks */
- int cpo_J;
- int found_dot;
+ bool noskip = false; // do not skip blanks
pos = curwin->w_cursor;
if (dir == FORWARD)
@@ -2259,30 +2255,30 @@ int findsent(int dir, long count)
decl(&pos);
}
- // go back to the previous non-blank char
- found_dot = false;
- while ((c = gchar_pos(&pos)) == ' ' || c == '\t'
- || (dir == BACKWARD
- && vim_strchr((char_u *)".!?)]\"'", c) != NULL)) {
- if (vim_strchr((char_u *)".!?", c) != NULL) {
- /* Only skip over a '.', '!' and '?' once. */
- if (found_dot)
- break;
- found_dot = TRUE;
+ // go back to the previous non-white non-punctuation character
+ bool found_dot = false;
+ while (c = gchar_pos(&pos), ascii_iswhite(c)
+ || vim_strchr((char_u *)".!?)]\"'", c) != NULL) {
+ tpos = pos;
+ if (decl(&tpos) == -1 || (LINEEMPTY(tpos.lnum) && dir == FORWARD)) {
+ break;
}
- if (decl(&pos) == -1) {
+ if (found_dot) {
break;
}
- // when going forward: Stop in front of empty line
- if (LINEEMPTY(pos.lnum) && dir == FORWARD) {
- incl(&pos);
- goto found;
+ 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;
+ // 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);
@@ -2310,7 +2306,7 @@ int findsent(int dir, long count)
if ((*func)(&pos) == -1) {
if (count)
return FAIL;
- noskip = TRUE;
+ noskip = true;
break;
}
}
diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim
index 52c0c3698e..6a2f5044cc 100644
--- a/src/nvim/testdir/test_textobjects.vim
+++ b/src/nvim/testdir/test_textobjects.vim
@@ -182,3 +182,78 @@ x
norm it
q!
endfunc
+
+func Test_sentence()
+ enew!
+ call setline(1, 'A sentence. A sentence? A sentence!')
+
+ normal yis
+ call assert_equal('A sentence.', @")
+ normal yas
+ call assert_equal('A sentence. ', @")
+
+ normal )
+
+ normal yis
+ call assert_equal('A sentence?', @")
+ normal yas
+ call assert_equal('A sentence? ', @")
+
+ normal )
+
+ normal yis
+ call assert_equal('A sentence!', @")
+ normal yas
+ call assert_equal(' A sentence!', @")
+
+ normal 0
+ normal 2yis
+ call assert_equal('A sentence. ', @")
+ normal 3yis
+ call assert_equal('A sentence. A sentence?', @")
+ normal 2yas
+ call assert_equal('A sentence. A sentence? ', @")
+
+ %delete _
+endfunc
+
+func Test_sentence_with_quotes()
+ enew!
+ call setline(1, 'A "sentence." A sentence.')
+
+ normal yis
+ call assert_equal('A "sentence."', @")
+ normal yas
+ call assert_equal('A "sentence." ', @")
+
+ normal )
+
+ normal yis
+ call assert_equal('A sentence.', @")
+ normal yas
+ call assert_equal(' A sentence.', @")
+
+ %delete _
+endfunc
+
+func! Test_sentence_with_cursor_on_delimiter()
+ enew!
+ call setline(1, "A '([sentence.])' A sentence.")
+
+ normal! 15|yis
+ call assert_equal("A '([sentence.])'", @")
+ normal! 15|yas
+ call assert_equal("A '([sentence.])' ", @")
+
+ normal! 16|yis
+ call assert_equal("A '([sentence.])'", @")
+ normal! 16|yas
+ call assert_equal("A '([sentence.])' ", @")
+
+ normal! 17|yis
+ call assert_equal("A '([sentence.])'", @")
+ normal! 17|yas
+ call assert_equal("A '([sentence.])' ", @")
+
+ %delete _
+endfunc