mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 9.1.1175: inconsistent behaviour with exclusive selection and motion commands
Problem: inconsistent behaviour with exclusive selection and motion commands (aidancz) Solution: adjust cursor position when selection is exclusive (Jim Zhou) fixes: #16278 closes: #16784 Co-authored-by: Hirohito Higashi <h.east.727@gmail.com> Co-authored-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Jim Zhou <jimzhouzzy@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
b34ce3e205
commit
c8cce711dd
@@ -1144,6 +1144,8 @@ EXTERN int VIsual_select INIT(= FALSE);
|
||||
// whether Select mode is active
|
||||
EXTERN int VIsual_select_reg INIT(= 0);
|
||||
// register name for Select mode
|
||||
EXTERN int VIsual_select_exclu_adj INIT(= FALSE);
|
||||
// whether incremented cursor during exclusive selection
|
||||
EXTERN int restart_VIsual_select INIT(= 0);
|
||||
// restart Select mode when next cmd finished
|
||||
EXTERN int VIsual_reselect;
|
||||
|
17
src/normal.c
17
src/normal.c
@@ -1130,6 +1130,7 @@ call_yank_do_autocmd(int regname)
|
||||
void
|
||||
end_visual_mode(void)
|
||||
{
|
||||
VIsual_select_exclu_adj = FALSE;
|
||||
end_visual_mode_keep_button();
|
||||
reset_held_button();
|
||||
}
|
||||
@@ -4248,6 +4249,15 @@ normal_search(
|
||||
nv_csearch(cmdarg_T *cap)
|
||||
{
|
||||
int t_cmd;
|
||||
int cursor_dec = FALSE;
|
||||
|
||||
// If adjusted cursor position previously, unadjust it.
|
||||
if (*p_sel == 'e' && VIsual_active && VIsual_mode == 'v'
|
||||
&& VIsual_select_exclu_adj)
|
||||
{
|
||||
unadjust_for_sel();
|
||||
cursor_dec = TRUE;
|
||||
}
|
||||
|
||||
if (cap->cmdchar == 't' || cap->cmdchar == 'T')
|
||||
t_cmd = TRUE;
|
||||
@@ -4258,6 +4268,9 @@ nv_csearch(cmdarg_T *cap)
|
||||
if (IS_SPECIAL(cap->nchar) || searchc(cap, t_cmd) == FAIL)
|
||||
{
|
||||
clearopbeep(cap->oap);
|
||||
// Revert unadjust when failed.
|
||||
if (cursor_dec)
|
||||
adjust_for_sel(cap);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5534,6 +5547,8 @@ nv_visual(cmdarg_T *cap)
|
||||
n_start_visual_mode(cap->cmdchar);
|
||||
if (VIsual_mode != 'V' && *p_sel == 'e')
|
||||
++cap->count1; // include one more char
|
||||
else
|
||||
VIsual_select_exclu_adj = FALSE;
|
||||
if (cap->count0 > 0 && --cap->count1 > 0)
|
||||
{
|
||||
// With a count select that many characters or lines.
|
||||
@@ -6703,6 +6718,7 @@ adjust_for_sel(cmdarg_T *cap)
|
||||
else
|
||||
++curwin->w_cursor.col;
|
||||
cap->oap->inclusive = FALSE;
|
||||
VIsual_select_exclu_adj = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6728,6 +6744,7 @@ unadjust_for_sel(void)
|
||||
unadjust_for_sel_inner(pos_T *pp)
|
||||
{
|
||||
colnr_T cs, ce;
|
||||
VIsual_select_exclu_adj = FALSE;
|
||||
|
||||
if (pp->coladd > 0)
|
||||
--pp->coladd;
|
||||
|
@@ -1099,6 +1099,50 @@ func Test_exclusive_selection()
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
" Test for inclusive motion in visual mode with 'exclusive' selection
|
||||
func Test_inclusive_motion_selection_exclusive()
|
||||
func s:compare_exclu_inclu(line, keys, expected_exclu)
|
||||
let msg = "data: '" . a:line . "' operation: '" . a:keys . "'"
|
||||
call setline(1, a:line)
|
||||
set selection=exclusive
|
||||
call feedkeys(a:keys, 'xt')
|
||||
call assert_equal(a:expected_exclu, getpos('.'), msg)
|
||||
let pos_ex = col('.')
|
||||
set selection=inclusive
|
||||
call feedkeys(a:keys, 'xt')
|
||||
let pos_in = col('.')
|
||||
call assert_equal(1, pos_ex - pos_in, msg)
|
||||
endfunc
|
||||
|
||||
new
|
||||
" Test 'e' motion
|
||||
set selection=exclusive
|
||||
call setline(1, 'eins zwei drei')
|
||||
norm! ggvey
|
||||
call assert_equal('eins', @")
|
||||
call setline(1, 'abc(abc)abc')
|
||||
norm! ggveeed
|
||||
call assert_equal(')abc', getline(1))
|
||||
call setline(1, 'abc(abc)abc')
|
||||
norm! gg3lvey
|
||||
call assert_equal('(abc', @")
|
||||
call s:compare_exclu_inclu('abc(abc)abc', 'ggveee', [0, 1, 8, 0])
|
||||
" Test 'f' motion
|
||||
call s:compare_exclu_inclu('geschwindigkeit', 'ggvfefe', [0, 1, 14, 0])
|
||||
call s:compare_exclu_inclu('loooooooooooong', 'ggv2fo2fo2fo', [0, 1, 8, 0])
|
||||
" Test 't' motion
|
||||
call s:compare_exclu_inclu('geschwindigkeit', 'ggv2te', [0, 1, 13, 0])
|
||||
call s:compare_exclu_inclu('loooooooooooong', 'gglv2to2to2to', [0, 1, 6, 0])
|
||||
" Test ';' motion
|
||||
call s:compare_exclu_inclu('geschwindigkeit', 'ggvfi;;', [0, 1, 15, 0])
|
||||
call s:compare_exclu_inclu('geschwindigkeit', 'ggvti;;', [0, 1, 14, 0])
|
||||
call s:compare_exclu_inclu('loooooooooooong', 'ggv2fo;;', [0, 1, 6, 0])
|
||||
call s:compare_exclu_inclu('loooooooooooong', 'ggvl2to;;', [0, 1, 6, 0])
|
||||
" Clean up
|
||||
set selection&
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
" Test for starting linewise visual with a count.
|
||||
" This test needs to be run without any previous visual mode. Otherwise the
|
||||
" count will use the count from the previous visual mode.
|
||||
|
@@ -502,6 +502,12 @@ end_word(
|
||||
|
||||
curwin->w_cursor.coladd = 0;
|
||||
cls_bigword = bigword;
|
||||
|
||||
// If adjusted cursor position previously, unadjust it.
|
||||
if (*p_sel == 'e' && VIsual_active && VIsual_mode == 'v'
|
||||
&& VIsual_select_exclu_adj)
|
||||
unadjust_for_sel();
|
||||
|
||||
while (--count >= 0)
|
||||
{
|
||||
#ifdef FEAT_FOLDING
|
||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1175,
|
||||
/**/
|
||||
1174,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user