summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-02-22 15:04:17 +0100
committerBram Moolenaar <Bram@vim.org>2019-02-22 15:04:17 +0100
commit55d3bdbbe2bfc7a78b4aa17763788dbddf87cab0 (patch)
tree854f1684ba2c3ef73cecd0820115e544b6a7aafa
parented79d1e348c40e2432802423bf22e4f7b536bf8a (diff)
downloadvim-git-55d3bdbbe2bfc7a78b4aa17763788dbddf87cab0.tar.gz
patch 8.1.0971: failure for selecting quoted text object moves cursorv8.1.0971
Problem: Failure for selecting quoted text object moves cursor. Solution: Restore the Visual selection on failure. (Christian Brabandt, closes #4024)
-rw-r--r--src/search.c38
-rw-r--r--src/testdir/test_textobjects.vim25
-rw-r--r--src/version.c2
3 files changed, 54 insertions, 11 deletions
diff --git a/src/search.c b/src/search.c
index 20f6299ee..d2554e2d9 100644
--- a/src/search.c
+++ b/src/search.c
@@ -4359,11 +4359,12 @@ current_quote(
int col_end;
int col_start = curwin->w_cursor.col;
int inclusive = FALSE;
- int vis_empty = TRUE; /* Visual selection <= 1 char */
- int vis_bef_curs = FALSE; /* Visual starts before cursor */
- int inside_quotes = FALSE; /* Looks like "i'" done before */
- int selected_quote = FALSE; /* Has quote inside selection */
+ int vis_empty = TRUE; // Visual selection <= 1 char
+ int vis_bef_curs = FALSE; // Visual starts before cursor
+ int inside_quotes = FALSE; // Looks like "i'" done before
+ int selected_quote = FALSE; // Has quote inside selection
int i;
+ int restore_vis_bef = FALSE; // restore VIsual on abort
/* Correct cursor when 'selection' is "exclusive". */
if (VIsual_active)
@@ -4377,12 +4378,13 @@ current_quote(
{
if (!vis_bef_curs)
{
- /* VIsual needs to be start of Visual selection. */
+ // VIsual needs to be the start of Visual selection.
pos_T t = curwin->w_cursor;
curwin->w_cursor = VIsual;
VIsual = t;
vis_bef_curs = TRUE;
+ restore_vis_bef = TRUE;
}
dec_cursor();
}
@@ -4431,7 +4433,7 @@ current_quote(
* opening quote. */
col_start = find_next_quote(line, col_start + 1, quotechar, NULL);
if (col_start < 0)
- return FALSE;
+ goto abort_search;
col_end = find_next_quote(line, col_start + 1, quotechar,
curbuf->b_p_qe);
if (col_end < 0)
@@ -4445,7 +4447,7 @@ current_quote(
{
col_end = find_prev_quote(line, col_start, quotechar, NULL);
if (line[col_end] != quotechar)
- return FALSE;
+ goto abort_search;
col_start = find_prev_quote(line, col_end, quotechar,
curbuf->b_p_qe);
if (line[col_start] != quotechar)
@@ -4480,12 +4482,12 @@ current_quote(
/* Find open quote character. */
col_start = find_next_quote(line, col_start, quotechar, NULL);
if (col_start < 0 || col_start > first_col)
- return FALSE;
+ goto abort_search;
/* Find close quote character. */
col_end = find_next_quote(line, col_start + 1, quotechar,
curbuf->b_p_qe);
if (col_end < 0)
- return FALSE;
+ goto abort_search;
/* If is cursor between start and end quote character, it is
* target text object. */
if (col_start <= first_col && first_col <= col_end)
@@ -4502,14 +4504,14 @@ current_quote(
/* No quote before the cursor, look after the cursor. */
col_start = find_next_quote(line, col_start, quotechar, NULL);
if (col_start < 0)
- return FALSE;
+ goto abort_search;
}
/* Find close quote character. */
col_end = find_next_quote(line, col_start + 1, quotechar,
curbuf->b_p_qe);
if (col_end < 0)
- return FALSE;
+ goto abort_search;
}
/* When "include" is TRUE, include spaces after closing quote or before
@@ -4596,6 +4598,20 @@ current_quote(
}
return OK;
+
+abort_search:
+ if (VIsual_active && *p_sel == 'e')
+ {
+ inc_cursor();
+ if (restore_vis_bef)
+ {
+ pos_T t = curwin->w_cursor;
+
+ curwin->w_cursor = VIsual;
+ VIsual = t;
+ }
+ }
+ return FALSE;
}
#endif /* FEAT_TEXTOBJ */
diff --git a/src/testdir/test_textobjects.vim b/src/testdir/test_textobjects.vim
index 3c403ab91..0baabc043 100644
--- a/src/testdir/test_textobjects.vim
+++ b/src/testdir/test_textobjects.vim
@@ -52,6 +52,31 @@ func Test_quote_selection_selection_exclusive()
bw!
endfunc
+func Test_quote_selection_selection_exclusive_abort()
+ new
+ set selection=exclusive
+ call setline(1, "'abzzc'")
+ let exp_curs = [0, 1, 6, 0]
+ call cursor(1,1)
+ exe 'norm! fcdvi"'
+ " make sure to end visual mode to have a clear state
+ exe "norm! \<esc>"
+ call assert_equal(exp_curs, getpos('.'))
+ call cursor(1,1)
+ exe 'norm! fcvi"'
+ exe "norm! \<esc>"
+ call assert_equal(exp_curs, getpos('.'))
+ call cursor(1,2)
+ exe 'norm! vfcoi"'
+ exe "norm! \<esc>"
+ let exp_curs = [0, 1, 2, 0]
+ let exp_visu = [0, 1, 7, 0]
+ call assert_equal(exp_curs, getpos('.'))
+ call assert_equal(exp_visu, getpos("'>"))
+ set selection&vim
+ bw!
+endfunc
+
" Tests for string and html text objects
func Test_string_html_objects()
enew!
diff --git a/src/version.c b/src/version.c
index c4034ee29..7c424e0d0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -780,6 +780,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 971,
+/**/
970,
/**/
969,