diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/globals.h | 2 | ||||
-rw-r--r-- | src/nvim/normal.c | 11 | ||||
-rw-r--r-- | src/nvim/state.c | 4 | ||||
-rw-r--r-- | src/nvim/testdir/test_mapping.vim | 54 |
4 files changed, 66 insertions, 5 deletions
diff --git a/src/nvim/globals.h b/src/nvim/globals.h index f2bd6408e8..f749c119cd 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -661,11 +661,13 @@ EXTERN int* (*iconv_errno)(void); /// 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() EXTERN int State INIT(= NORMAL); // This is the current state of the // command interpreter. EXTERN bool 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 EXTERN int exmode_active INIT(= 0); // Zero, EXMODE_NORMAL or EXMODE_VIM. diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 705dea4e88..29c5d27258 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1445,8 +1445,10 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) oap->motion_type = kMTCharWise; } 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; @@ -2039,6 +2041,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) curwin->w_cursor = old_cursor; } clearop(oap); + motion_force = NUL; } curwin->w_p_lbr = lbr_saved; } @@ -6389,8 +6392,8 @@ static void nv_visual(cmdarg_T *cap) /* 'v', 'V' and CTRL-V can be used while an operator is pending to make it * characterwise, linewise, or blockwise. */ if (cap->oap->op_type != OP_NOP) { - cap->oap->motion_force = cap->cmdchar; - finish_op = false; /* operator doesn't finish now but later */ + motion_force = cap->oap->motion_force = cap->cmdchar; + finish_op = false; // operator doesn't finish now but later return; } diff --git a/src/nvim/state.c b/src/nvim/state.c index d75f4038ae..bfd73050c3 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -113,7 +113,7 @@ int get_real_state(void) /// @returns[allocated] mode string char *get_mode(void) { - char *buf = xcalloc(3, sizeof(char)); + char *buf = xcalloc(4, sizeof(char)); if (VIsual_active) { if (VIsual_select) { @@ -160,6 +160,8 @@ char *get_mode(void) buf[0] = 'n'; if (finish_op) { buf[1] = 'o'; + // to be able to detect force-linewise/blockwise/characterwise operations + buf[2] = (char)motion_force; } } diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index 247c01c98d..32593a423a 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -230,3 +230,57 @@ func Test_abbreviation_CR() delfunc Eatchar bw! 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 |