diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-12-27 23:44:44 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-12-27 23:44:44 +0100 |
commit | 5976f8ff00efcb3e155a89346e44f2ad43d2405a (patch) | |
tree | 31bff7f7afdc7884dbcee07406e6c575784c16b5 | |
parent | d385b5d329a6a98539fa21cfb60ed632cd03d544 (diff) | |
download | vim-git-5976f8ff00efcb3e155a89346e44f2ad43d2405a.tar.gz |
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)
-rw-r--r-- | runtime/doc/eval.txt | 4 | ||||
-rw-r--r-- | src/evalfunc.c | 4 | ||||
-rw-r--r-- | src/globals.h | 2 | ||||
-rw-r--r-- | src/normal.c | 10 | ||||
-rw-r--r-- | src/testdir/test_mapping.vim | 54 | ||||
-rw-r--r-- | src/version.c | 2 |
6 files changed, 73 insertions, 3 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 85b9e4419..927912fd8 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -6324,6 +6324,10 @@ mode([expr]) Return a string that indicates the current mode. n Normal, Terminal-Normal 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| niR Normal using |i_CTRL-O| in |Replace-mode| niV Normal using |i_CTRL-O| in |Virtual-Replace-mode| diff --git a/src/evalfunc.c b/src/evalfunc.c index a29f0ffbe..d94bf8d29 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 71400caf3..eaced2a08 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 78e3f201c..77191c67e 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 fd7e28f79..4ac06a10c 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 6178a8477..9ea9fc1f6 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, |