# HG changeset patch # User Bram Moolenaar # Date 1550844905 -3600 # Node ID e580c9d75443098f5eb6125cbad16ddeddd3774e # Parent b6a90f7931911fed77fffa9ef01aee46ed2c6306 patch 8.1.0971: failure for selecting quoted text object moves cursor commit https://github.com/vim/vim/commit/55d3bdbbe2bfc7a78b4aa17763788dbddf87cab0 Author: Bram Moolenaar Date: Fri Feb 22 15:04:17 2019 +0100 patch 8.1.0971: failure for selecting quoted text object moves cursor Problem: Failure for selecting quoted text object moves cursor. Solution: Restore the Visual selection on failure. (Christian Brabandt, closes #4024) diff --git a/src/search.c b/src/search.c --- 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 --- a/src/testdir/test_textobjects.vim +++ b/src/testdir/test_textobjects.vim @@ -52,6 +52,31 @@ func Test_quote_selection_selection_excl 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! \" + call assert_equal(exp_curs, getpos('.')) + call cursor(1,1) + exe 'norm! fcvi"' + exe "norm! \" + call assert_equal(exp_curs, getpos('.')) + call cursor(1,2) + exe 'norm! vfcoi"' + exe "norm! \" + 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 --- 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,