changeset 14131:ec85acd49b8e v8.1.0083

patch 8.1.0083: "is" and "as" have trouble with quoted punctuation commit https://github.com/vim/vim/commit/8516071124dbb7ad7caa43cc98ae3c57ae093c9e Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jun 19 18:27:41 2018 +0200 patch 8.1.0083: "is" and "as" have trouble with quoted punctuation Problem: "is" and "as" have trouble with quoted punctuation. Solution: Check for punctuation before a quote. (Jason Franklin)
author Christian Brabandt <cb@256bit.org>
date Tue, 19 Jun 2018 18:30:07 +0200
parents 92b622f22745
children 0aeb4cc130cf
files src/search.c src/testdir/test_textobjects.vim src/version.c
diffstat 3 files changed, 97 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/search.c
+++ b/src/search.c
@@ -2707,10 +2707,11 @@ 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.
+ * 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)
@@ -2758,26 +2759,25 @@ findsent(int dir, long count)
 	else if (dir == BACKWARD)
 	    decl(&pos);
 
-	/* go back to the previous non-blank char */
+	// go back to the previous non-white non-punctuation character
 	found_dot = FALSE;
-	while ((c = gchar_pos(&pos)) == ' ' || c == '\t' ||
-	     (dir == BACKWARD && vim_strchr((char_u *)".!?)]\"'", c) != NULL))
+	while (c = gchar_pos(&pos), VIM_ISWHITE(c)
+				|| vim_strchr((char_u *)".!?)]\"'", c) != NULL)
 	{
-	    if (vim_strchr((char_u *)".!?", c) != NULL)
-	    {
-		/* Only skip over a '.', '!' and '?' once. */
-		if (found_dot)
-		    break;
+	    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 (decl(&pos) == -1)
+
+	    if (vim_strchr((char_u *) ")]\"'", c) != NULL
+		&& vim_strchr((char_u *) ".!?)]\"'", gchar_pos(&tpos)) == NULL)
 		break;
-	    /* when going forward: Stop in front of empty line */
-	    if (LINEEMPTY(pos.lnum) && dir == FORWARD)
-	    {
-		incl(&pos);
-		goto found;
-	    }
+
+	    decl(&pos);
 	}
 
 	/* remember the line where the search started */
--- a/src/testdir/test_textobjects.vim
+++ b/src/testdir/test_textobjects.vim
@@ -165,3 +165,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
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    83,
+/**/
     82,
 /**/
     81,