summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-12-27 23:44:44 +0100
committerBram Moolenaar <Bram@vim.org>2018-12-27 23:44:44 +0100
commit5976f8ff00efcb3e155a89346e44f2ad43d2405a (patch)
tree31bff7f7afdc7884dbcee07406e6c575784c16b5 /src
parentd385b5d329a6a98539fa21cfb60ed632cd03d544 (diff)
patch 8.1.0648: custom operators can't act upon a forced motionv8.1.0648
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)
Diffstat (limited to 'src')
-rw-r--r--src/evalfunc.c4
-rw-r--r--src/globals.h2
-rw-r--r--src/normal.c10
-rw-r--r--src/testdir/test_mapping.vim54
-rw-r--r--src/version.c2
5 files changed, 69 insertions, 3 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index a29f0ffbec..d94bf8d297 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -8506,7 +8506,11 @@ f_mode(typval_T *argvars, typval_T *rettv)
{
buf[0] = 'n';
if (finish_op)
+ {
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'
|| restart_edit == 'V')
{
diff --git a/src/globals.h b/src/globals.h
index 71400caf36..eaced2a08f 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -928,6 +928,7 @@ EXTERN char_u composing_hangul_buffer[5];
* "Visual_mode" When State is NORMAL or INSERT.
* "finish_op" When State is NORMAL, after typing the operator and before
* typing the motion command.
+ * "motion_force" Last motion_force from do_pending_operator()
* "debug_mode" Debug mode.
*/
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 long opcount INIT(= 0); /* count for pending operator */
+EXTERN int motion_force INIT(= 0); // motion force for pending operator
/*
* Ex mode (Q) state
diff --git a/src/normal.c b/src/normal.c
index 78e3f201cb..77191c67ee 100644
--- a/src/normal.c
+++ b/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)
{
/* Change line- or characterwise motion into Visual block mode. */
- VIsual_active = TRUE;
- VIsual = oap->start;
+ if (!VIsual_active)
+ {
+ VIsual_active = TRUE;
+ VIsual = oap->start;
+ }
VIsual_mode = Ctrl_V;
VIsual_select = FALSE;
VIsual_reselect = FALSE;
@@ -2129,6 +2132,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
}
oap->block_mode = FALSE;
clearop(oap);
+ motion_force = NUL;
}
#ifdef FEAT_LINEBREAK
curwin->w_p_lbr = lbr_saved;
@@ -7689,7 +7693,7 @@ nv_visual(cmdarg_T *cap)
* characterwise, linewise, or blockwise. */
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 */
return;
}
diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim
index fd7e28f798..4ac06a10c9 100644
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -230,3 +230,57 @@ func Test_cabbr_visual_mode()
call assert_equal(expected, getreg(':'))
cunabbr s
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
diff --git a/src/version.c b/src/version.c
index 6178a84770..9ea9fc1f6d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -800,6 +800,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 648,
+/**/
647,
/**/
646,