mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.1.0648: custom operators can't act upon a forced motion
Problem: Custom operators can't act upon a forced motion. (Christian Wellenbrock) Solution: Add the forced motion to the mode() result. (Christian Brabandt, closes #3490)
This commit is contained in:
parent
d385b5d329
commit
5976f8ff00
@ -6324,6 +6324,10 @@ mode([expr]) Return a string that indicates the current mode.
|
|||||||
|
|
||||||
n Normal, Terminal-Normal
|
n Normal, Terminal-Normal
|
||||||
no Operator-pending
|
no Operator-pending
|
||||||
|
nov Operator-pending (forced characterwise |o_v|)
|
||||||
|
noV Operator-pending (forced linewise |o_V|)
|
||||||
|
noCTRL-V Operator-pending (forced blockwise |o_CTRL-V|);
|
||||||
|
CTRL-V is one character
|
||||||
niI Normal using |i_CTRL-O| in |Insert-mode|
|
niI Normal using |i_CTRL-O| in |Insert-mode|
|
||||||
niR Normal using |i_CTRL-O| in |Replace-mode|
|
niR Normal using |i_CTRL-O| in |Replace-mode|
|
||||||
niV Normal using |i_CTRL-O| in |Virtual-Replace-mode|
|
niV Normal using |i_CTRL-O| in |Virtual-Replace-mode|
|
||||||
|
@ -8506,7 +8506,11 @@ f_mode(typval_T *argvars, typval_T *rettv)
|
|||||||
{
|
{
|
||||||
buf[0] = 'n';
|
buf[0] = 'n';
|
||||||
if (finish_op)
|
if (finish_op)
|
||||||
|
{
|
||||||
buf[1] = 'o';
|
buf[1] = 'o';
|
||||||
|
// to be able to detect force-linewise/blockwise/characterwise operations
|
||||||
|
buf[2] = motion_force;
|
||||||
|
}
|
||||||
else if (restart_edit == 'I' || restart_edit == 'R'
|
else if (restart_edit == 'I' || restart_edit == 'R'
|
||||||
|| restart_edit == 'V')
|
|| restart_edit == 'V')
|
||||||
{
|
{
|
||||||
|
@ -928,6 +928,7 @@ EXTERN char_u composing_hangul_buffer[5];
|
|||||||
* "Visual_mode" When State is NORMAL or INSERT.
|
* "Visual_mode" When State is NORMAL or INSERT.
|
||||||
* "finish_op" When State is NORMAL, after typing the operator and before
|
* "finish_op" When State is NORMAL, after typing the operator and before
|
||||||
* typing the motion command.
|
* typing the motion command.
|
||||||
|
* "motion_force" Last motion_force from do_pending_operator()
|
||||||
* "debug_mode" Debug mode.
|
* "debug_mode" Debug mode.
|
||||||
*/
|
*/
|
||||||
EXTERN int State INIT(= NORMAL); /* This is the current state of the
|
EXTERN int State INIT(= NORMAL); /* This is the current state of the
|
||||||
@ -938,6 +939,7 @@ EXTERN int debug_mode INIT(= FALSE);
|
|||||||
|
|
||||||
EXTERN int finish_op INIT(= FALSE);/* TRUE while an operator is pending */
|
EXTERN int finish_op INIT(= FALSE);/* TRUE while an operator is pending */
|
||||||
EXTERN long opcount INIT(= 0); /* count for pending operator */
|
EXTERN long opcount INIT(= 0); /* count for pending operator */
|
||||||
|
EXTERN int motion_force INIT(= 0); // motion force for pending operator
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ex mode (Q) state
|
* Ex mode (Q) state
|
||||||
|
10
src/normal.c
10
src/normal.c
@ -1395,8 +1395,11 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
|
|||||||
else if (oap->motion_force == Ctrl_V)
|
else if (oap->motion_force == Ctrl_V)
|
||||||
{
|
{
|
||||||
/* Change line- or characterwise motion into Visual block mode. */
|
/* Change line- or characterwise motion into Visual block mode. */
|
||||||
VIsual_active = TRUE;
|
if (!VIsual_active)
|
||||||
VIsual = oap->start;
|
{
|
||||||
|
VIsual_active = TRUE;
|
||||||
|
VIsual = oap->start;
|
||||||
|
}
|
||||||
VIsual_mode = Ctrl_V;
|
VIsual_mode = Ctrl_V;
|
||||||
VIsual_select = FALSE;
|
VIsual_select = FALSE;
|
||||||
VIsual_reselect = FALSE;
|
VIsual_reselect = FALSE;
|
||||||
@ -2129,6 +2132,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
|
|||||||
}
|
}
|
||||||
oap->block_mode = FALSE;
|
oap->block_mode = FALSE;
|
||||||
clearop(oap);
|
clearop(oap);
|
||||||
|
motion_force = NUL;
|
||||||
}
|
}
|
||||||
#ifdef FEAT_LINEBREAK
|
#ifdef FEAT_LINEBREAK
|
||||||
curwin->w_p_lbr = lbr_saved;
|
curwin->w_p_lbr = lbr_saved;
|
||||||
@ -7689,7 +7693,7 @@ nv_visual(cmdarg_T *cap)
|
|||||||
* characterwise, linewise, or blockwise. */
|
* characterwise, linewise, or blockwise. */
|
||||||
if (cap->oap->op_type != OP_NOP)
|
if (cap->oap->op_type != OP_NOP)
|
||||||
{
|
{
|
||||||
cap->oap->motion_force = cap->cmdchar;
|
motion_force = cap->oap->motion_force = cap->cmdchar;
|
||||||
finish_op = FALSE; /* operator doesn't finish now but later */
|
finish_op = FALSE; /* operator doesn't finish now but later */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -230,3 +230,57 @@ func Test_cabbr_visual_mode()
|
|||||||
call assert_equal(expected, getreg(':'))
|
call assert_equal(expected, getreg(':'))
|
||||||
cunabbr s
|
cunabbr s
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_motionforce_omap()
|
||||||
|
func GetCommand()
|
||||||
|
let g:m=mode(1)
|
||||||
|
let [g:lnum1, g:col1] = searchpos('-', 'Wb')
|
||||||
|
if g:lnum1 == 0
|
||||||
|
return "\<Esc>"
|
||||||
|
endif
|
||||||
|
let [g:lnum2, g:col2] = searchpos('-', 'W')
|
||||||
|
if g:lnum2 == 0
|
||||||
|
return "\<Esc>"
|
||||||
|
endif
|
||||||
|
return ":call Select()\<CR>"
|
||||||
|
endfunc
|
||||||
|
func Select()
|
||||||
|
call cursor([g:lnum1, g:col1])
|
||||||
|
exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2])
|
||||||
|
call cursor([g:lnum2, g:col2])
|
||||||
|
execute "normal! \<BS>"
|
||||||
|
endfunc
|
||||||
|
new
|
||||||
|
onoremap <buffer><expr> i- GetCommand()
|
||||||
|
" 1) default omap mapping
|
||||||
|
%d_
|
||||||
|
call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
|
||||||
|
call cursor(2, 1)
|
||||||
|
norm di-
|
||||||
|
call assert_equal('no', g:m)
|
||||||
|
call assert_equal(['aaa -- eee'], getline(1, '$'))
|
||||||
|
" 2) forced characterwise operation
|
||||||
|
%d_
|
||||||
|
call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
|
||||||
|
call cursor(2, 1)
|
||||||
|
norm dvi-
|
||||||
|
call assert_equal('nov', g:m)
|
||||||
|
call assert_equal(['aaa -- eee'], getline(1, '$'))
|
||||||
|
" 3) forced linewise operation
|
||||||
|
%d_
|
||||||
|
call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
|
||||||
|
call cursor(2, 1)
|
||||||
|
norm dVi-
|
||||||
|
call assert_equal('noV', g:m)
|
||||||
|
call assert_equal([''], getline(1, '$'))
|
||||||
|
" 4) forced blockwise operation
|
||||||
|
%d_
|
||||||
|
call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
|
||||||
|
call cursor(2, 1)
|
||||||
|
exe "norm d\<C-V>i-"
|
||||||
|
call assert_equal("no\<C-V>", g:m)
|
||||||
|
call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$'))
|
||||||
|
bwipe!
|
||||||
|
delfunc Select
|
||||||
|
delfunc GetCommand
|
||||||
|
endfunc
|
||||||
|
@ -799,6 +799,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
648,
|
||||||
/**/
|
/**/
|
||||||
647,
|
647,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user