From 42428b3f857b6390084540e82c0e89a49fc4452f Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 23 Aug 2018 18:32:07 -0400 Subject: vim-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) https://github.com/vim/vim/commit/8516071124dbb7ad7caa43cc98ae3c57ae093c9e --- src/nvim/search.c | 39 +++++++++--------- src/nvim/testdir/test_textobjects.vim | 75 +++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/search.c b/src/nvim/search.c index 7be7dc2187..fab0ea4837 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2211,12 +2211,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) { pos_T pos, tpos; @@ -2259,25 +2258,25 @@ int findsent(int dir, long count) 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)) { - if (vim_strchr((char_u *)".!?", c) != NULL) { - /* Only skip over a '.', '!' and '?' once. */ - if (found_dot) - break; - found_dot = TRUE; + 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 */ 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 -- cgit From 748cd91c20bdffe34ac5c9997ac8342cdf9438e1 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Thu, 23 Aug 2018 19:07:19 -0400 Subject: search: fix types of findsent() variables dir (param) is of type Direction (enum). cpo_J, found_dot, noskip (local var) are bool. cpo_J is const. startlnum (local var) is const int. Declare it in same scope as cpo_J. --- src/nvim/search.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/nvim/search.c b/src/nvim/search.c index fab0ea4837..40d3f74103 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -2216,15 +2216,12 @@ showmatch( // 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) +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,7 +2256,7 @@ int findsent(int dir, long count) } // go back to the previous non-white non-punctuation character - found_dot = false; + bool found_dot = false; while (c = gchar_pos(&pos), ascii_iswhite(c) || vim_strchr((char_u *)".!?)]\"'", c) != NULL) { tpos = pos; @@ -2279,9 +2276,9 @@ int findsent(int dir, long count) 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); @@ -2309,7 +2306,7 @@ int findsent(int dir, long count) if ((*func)(&pos) == -1) { if (count) return FAIL; - noskip = TRUE; + noskip = true; break; } } -- cgit