]> granicus.if.org Git - vim/commitdiff
patch 8.1.0648: custom operators can't act upon a forced motion v8.1.0648
authorBram Moolenaar <Bram@vim.org>
Thu, 27 Dec 2018 22:44:44 +0000 (23:44 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 27 Dec 2018 22:44:44 +0000 (23:44 +0100)
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)

runtime/doc/eval.txt
src/evalfunc.c
src/globals.h
src/normal.c
src/testdir/test_mapping.vim
src/version.c

index 85b9e4419faff376150ec0c42f4fd3a3306393fe..927912fd876dc2eea9682d98babe09a4ae464a93 100644 (file)
@@ -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|
index a29f0ffbec4fc51b49b7ae0b76bf23efc80564bf..d94bf8d297d34083a8b3328202486b650d756bfc 100644 (file)
@@ -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')
        {
index 71400caf369afbfb89f376788cdbbcb69816dd64..eaced2a08fd74996dda0ebc93c10544b474fbe05 100644 (file)
@@ -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
index 78e3f201cbe4227e7b2f97b9d3dbd4d59596780f..77191c67ee704dfeae93ac00a8981fa1479a48ab 100644 (file)
@@ -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;
     }
index fd7e28f79886899ceb7b0f597c9a882cae800cf4..4ac06a10c9a5cf38c0b9814b237ae5521c668146 100644 (file)
@@ -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
index 6178a84770de90871f68598ab9e0d3b1e16fd41e..9ea9fc1f6df18d50b291f092d2ddddc3859d45a8 100644 (file)
@@ -799,6 +799,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    648,
 /**/
     647,
 /**/