]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.3227: 'virtualedit' can only be set globally v8.2.3227
authorGary Johnson <garyjohn@spocom.com>
Mon, 26 Jul 2021 20:19:10 +0000 (22:19 +0200)
committerBram Moolenaar <Bram@vim.org>
Mon, 26 Jul 2021 20:19:10 +0000 (22:19 +0200)
Problem:    'virtualedit' can only be set globally.
Solution:   Make 'virtualedit' global-local. (Gary Johnson, closes #8638)

17 files changed:
runtime/doc/options.txt
src/buffer.c
src/change.c
src/drawscreen.c
src/edit.c
src/misc2.c
src/normal.c
src/ops.c
src/option.c
src/option.h
src/optiondefs.h
src/optionstr.c
src/proto/option.pro
src/register.c
src/structs.h
src/testdir/test_virtualedit.vim
src/version.c

index e5a76b767736b18853c4f10ee743449b5760f657..e0c14a82630d0ec1a61b94ea7ab4cc5cb50b8784 100644 (file)
@@ -8643,12 +8643,16 @@ A jump table for the options with a short description can be found at |Q_op|.
 
                                            *'virtualedit'* *'ve'*
 'virtualedit' 've'     string  (default "")
-                       global
+                       global or local to buffer |global-local|
        A comma separated list of these words:
            block       Allow virtual editing in Visual block mode.
            insert      Allow virtual editing in Insert mode.
            all         Allow virtual editing in all modes.
            onemore     Allow the cursor to move just past the end of the line
+           none        When used as the local value, do not allow virtual
+                       editing even when the global value is set.  When used
+                       as the global value, "none" is the same as "".
+           NONE        Alternative spelling of "none".
 
        Virtual editing means that the cursor can be positioned where there is
        no actual character.  This can be halfway into a tab or beyond the end
index 25efea1f3e2f0e9c1572cf0ab1a7bbc37d9ad6e2..59397e4a5004ca244e46474ad5d05bef7415e712 100644 (file)
@@ -2384,6 +2384,7 @@ free_buf_options(
 #endif
     clear_string_option(&buf->b_p_bkc);
     clear_string_option(&buf->b_p_menc);
+    clear_string_option(&buf->b_p_ve);
 }
 
 /*
index ee1bd6fca867daae742f48f3f56c1a3e9d365ed9..f77b48c742425ca867b8de97224af04d9db76220 100644 (file)
@@ -1257,7 +1257,7 @@ del_bytes(
        // fixpos is TRUE, we don't want to end up positioned at the NUL,
        // unless "restart_edit" is set or 'virtualedit' contains "onemore".
        if (col > 0 && fixpos && restart_edit == 0
-                                             && (ve_flags & VE_ONEMORE) == 0)
+                                             && (get_ve_flags() & VE_ONEMORE) == 0)
        {
            --curwin->w_cursor.col;
            curwin->w_cursor.coladd = 0;
index 49615bda60178cdd0e799d54196b7119d5750a50..36aad637b24c38579f7228389f4946803dd6a613 100644 (file)
@@ -2006,21 +2006,21 @@ win_update(win_T *wp)
            {
                colnr_T     fromc, toc;
 #if defined(FEAT_LINEBREAK)
-               int         save_ve_flags = ve_flags;
+               int         save_ve_flags = curbuf->b_ve_flags;
 
                if (curwin->w_p_lbr)
-                   ve_flags = VE_ALL;
+                   curbuf->b_ve_flags = VE_ALL;
 #endif
                getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc);
                ++toc;
 #if defined(FEAT_LINEBREAK)
-               ve_flags = save_ve_flags;
+               curbuf->b_ve_flags = save_ve_flags;
 #endif
                // Highlight to the end of the line, unless 'virtualedit' has
                // "block".
                if (curwin->w_curswant == MAXCOL)
                {
-                   if (ve_flags & VE_BLOCK)
+                   if (get_ve_flags() & VE_BLOCK)
                    {
                        pos_T       pos;
                        int         cursor_above =
index 267c76d3175661012b9b506f3d2ed4bf5a452c3e..6bdeded000bc0b4f5723ce4755955ecbf30c8f59 100644 (file)
@@ -861,7 +861,7 @@ doESCkey:
            ins_ctrl_o();
 
            // don't move the cursor left when 'virtualedit' has "onemore".
-           if (ve_flags & VE_ONEMORE)
+           if (get_ve_flags() & VE_ONEMORE)
            {
                ins_at_eol = FALSE;
                nomove = TRUE;
@@ -2673,7 +2673,7 @@ oneright(void)
 
     // move "l" bytes right, but don't end up on the NUL, unless 'virtualedit'
     // contains "onemore".
-    if (ptr[l] == NUL && (ve_flags & VE_ONEMORE) == 0)
+    if (ptr[l] == NUL && (get_ve_flags() & VE_ONEMORE) == 0)
        return FAIL;
     curwin->w_cursor.col += l;
 
@@ -3656,7 +3656,7 @@ ins_esc(
 #endif
                                      )
     {
-       if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL)
+       if (curwin->w_cursor.coladd > 0 || get_ve_flags() == VE_ALL)
        {
            oneleft();
            if (restart_edit != NUL)
index a8e34df7ee873ea08df927574d040d20599cd3ad..8e99b01a5e08c4a025c35b3a5bde0ae3b1aca25b 100644 (file)
@@ -22,14 +22,16 @@ static int coladvance2(pos_T *pos, int addspaces, int finetune, colnr_T wcol);
     int
 virtual_active(void)
 {
+    unsigned int cur_ve_flags = get_ve_flags();
+
     // While an operator is being executed we return "virtual_op", because
     // VIsual_active has already been reset, thus we can't check for "block"
     // being used.
     if (virtual_op != MAYBE)
        return virtual_op;
-    return (ve_flags == VE_ALL
-           || ((ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
-           || ((ve_flags & VE_INSERT) && (State & INSERT)));
+    return (cur_ve_flags == VE_ALL
+           || ((cur_ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
+           || ((cur_ve_flags & VE_INSERT) && (State & INSERT)));
 }
 
 /*
@@ -137,7 +139,7 @@ coladvance2(
     one_more = (State & INSERT)
                    || restart_edit != NUL
                    || (VIsual_active && *p_sel != 'o')
-                   || ((ve_flags & VE_ONEMORE) && wcol < MAXCOL);
+                   || ((get_ve_flags() & VE_ONEMORE) && wcol < MAXCOL);
     line = ml_get_buf(curbuf, pos->lnum, FALSE);
 
     if (wcol >= MAXCOL)
@@ -549,9 +551,10 @@ check_cursor_col(void)
     void
 check_cursor_col_win(win_T *win)
 {
-    colnr_T len;
-    colnr_T oldcol = win->w_cursor.col;
-    colnr_T oldcoladd = win->w_cursor.col + win->w_cursor.coladd;
+    colnr_T      len;
+    colnr_T      oldcol = win->w_cursor.col;
+    colnr_T      oldcoladd = win->w_cursor.col + win->w_cursor.coladd;
+    unsigned int cur_ve_flags = get_ve_flags();
 
     len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, FALSE));
     if (len == 0)
@@ -564,7 +567,7 @@ check_cursor_col_win(win_T *win)
        // - 'virtualedit' is set
        if ((State & INSERT) || restart_edit
                || (VIsual_active && *p_sel != 'o')
-               || (ve_flags & VE_ONEMORE)
+               || (cur_ve_flags & VE_ONEMORE)
                || virtual_active())
            win->w_cursor.col = len;
        else
@@ -583,7 +586,7 @@ check_cursor_col_win(win_T *win)
     // line.
     if (oldcol == MAXCOL)
        win->w_cursor.coladd = 0;
-    else if (ve_flags == VE_ALL)
+    else if (cur_ve_flags == VE_ALL)
     {
        if (oldcoladd > win->w_cursor.col)
        {
index 56f89f518c3babfea91540068b7c848d122af712..74c76b2d205be8020a11b76f78979e061bc3c92c 100644 (file)
@@ -5757,7 +5757,7 @@ n_start_visual_mode(int c)
 
     // Corner case: the 0 position in a tab may change when going into
     // virtualedit.  Recalculate curwin->w_cursor to avoid bad highlighting.
-    if (c == Ctrl_V && (ve_flags & VE_BLOCK) && gchar_cursor() == TAB)
+    if (c == Ctrl_V && (get_ve_flags() & VE_BLOCK) && gchar_cursor() == TAB)
     {
        validate_virtcol();
        coladvance(curwin->w_virtcol);
@@ -6780,7 +6780,7 @@ adjust_cursor(oparg_T *oap)
     // - 'virtualedit' is not "all" and not "onemore".
     if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL
                && (!VIsual_active || *p_sel == 'o')
-               && !virtual_active() && (ve_flags & VE_ONEMORE) == 0)
+               && !virtual_active() && (get_ve_flags() & VE_ONEMORE) == 0)
     {
        --curwin->w_cursor.col;
        // prevent cursor from moving on the trail byte
@@ -7014,7 +7014,7 @@ nv_esc(cmdarg_T *cap)
 set_cursor_for_append_to_line(void)
 {
     curwin->w_set_curswant = TRUE;
-    if (ve_flags == VE_ALL)
+    if (get_ve_flags() == VE_ALL)
     {
        int save_State = State;
 
index 59d5bff50d31b7c82581759397d422c1d3d7d910..75619c570cd6e4d2dea637f90629201eed6bf19e 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -1474,18 +1474,22 @@ op_insert(oparg_T *oap, long count1)
        // doing block_prep().  When only "block" is used, virtual edit is
        // already disabled, but still need it when calling
        // coladvance_force().
+       // coladvance_force() uses get_ve_flags() to get the 'virtualedit'
+       // state for the current buffer.  To override that state, we need to
+       // set the buffer-local value of ve_flags rather than the global value.
        if (curwin->w_cursor.coladd > 0)
        {
-           int         old_ve_flags = ve_flags;
+           int         old_ve_flags = curbuf->b_ve_flags;
 
-           ve_flags = VE_ALL;
            if (u_save_cursor() == FAIL)
                return;
+
+           curbuf->b_ve_flags = VE_ALL;
            coladvance_force(oap->op_type == OP_APPEND
                                           ? oap->end_vcol + 1 : getviscol());
            if (oap->op_type == OP_APPEND)
                --curwin->w_cursor.col;
-           ve_flags = old_ve_flags;
+           curbuf->b_ve_flags = old_ve_flags;
        }
        // Get the info about the block before entering the text
        block_prep(oap, &bd, oap->start.lnum, TRUE);
@@ -1816,15 +1820,17 @@ op_change(oparg_T *oap)
     void
 adjust_cursor_eol(void)
 {
+    unsigned int cur_ve_flags = get_ve_flags();
+
     if (curwin->w_cursor.col > 0
            && gchar_cursor() == NUL
-           && (ve_flags & VE_ONEMORE) == 0
+           && (cur_ve_flags & VE_ONEMORE) == 0
            && !(restart_edit || (State & INSERT)))
     {
        // Put the cursor on the last character in the line.
        dec_cursor();
 
-       if (ve_flags == VE_ALL)
+       if (cur_ve_flags == VE_ALL)
        {
            colnr_T         scol, ecol;
 
index 21d113e27edadbbff2021d98a25798b4db3b452f..182ff341cf37dad0b367d5a877c32f4bc3dee0a9 100644 (file)
@@ -5181,6 +5181,10 @@ unset_global_local_option(char_u *name, void *from)
            set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs);
            redraw_later(NOT_VALID);
            break;
+       case PV_VE:
+           clear_string_option(&buf->b_p_ve);
+           buf->b_ve_flags = 0;
+           break;
     }
 }
 #endif
@@ -5239,7 +5243,8 @@ get_varp_scope(struct vimoption *p, int opt_flags)
 #endif
            case PV_BKC:  return (char_u *)&(curbuf->b_p_bkc);
            case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
-           case PV_LCS: return (char_u *)&(curwin->w_p_lcs);
+           case PV_LCS:  return (char_u *)&(curwin->w_p_lcs);
+           case PV_VE:   return (char_u *)&(curbuf->b_p_ve);
 
        }
        return NULL; // "cannot happen"
@@ -5507,6 +5512,8 @@ get_varp(struct vimoption *p)
        case PV_VSTS:   return (char_u *)&(curbuf->b_p_vsts);
        case PV_VTS:    return (char_u *)&(curbuf->b_p_vts);
 #endif
+       case PV_VE:     return *curbuf->b_p_ve != NUL
+                                   ? (char_u *)&(curbuf->b_p_ve) : p->var;
        default:        iemsg(_("E356: get_varp ERROR"));
     }
     // always return a valid pointer to avoid a crash!
@@ -6084,6 +6091,8 @@ buf_copy_options(buf_T *buf, int flags)
            buf->b_p_lw = empty_option;
 #endif
            buf->b_p_menc = empty_option;
+           buf->b_p_ve = empty_option;
+           buf->b_ve_flags = 0;
 
            /*
             * Don't copy the options set by ex_help(), use the saved values,
@@ -7026,6 +7035,16 @@ get_bkc_value(buf_T *buf)
     return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
 }
 
+/*
+ * Get the local or global value of the 'virtualedit' flags.
+ */
+    unsigned int
+get_ve_flags(void)
+{
+    return (curbuf->b_ve_flags ? curbuf->b_ve_flags : ve_flags)
+          & ~(VE_NONE | VE_NONEU);
+}
+
 #if defined(FEAT_LINEBREAK) || defined(PROTO)
 /*
  * Get the local or global value of 'showbreak'.
index 7be729a85a1e077aceccc0227215a727fc8a6e73..5732e8256701abb8aa25711c0930e69bac5e446a 100644 (file)
@@ -1052,6 +1052,8 @@ EXTERN unsigned ve_flags;
 #define VE_INSERT      6       // includes "all"
 #define VE_ALL         4
 #define VE_ONEMORE     8
+#define VE_NONE                16
+#define VE_NONEU       32      // Upper-case NONE
 EXTERN long    p_verbose;      // 'verbose'
 #ifdef IN_OPTION_C
 char_u *p_vfile = (char_u *)""; // used before options are initialized
@@ -1228,6 +1230,7 @@ enum
     , BV_VSTS
     , BV_VTS
 #endif
+    , BV_VE
     , BV_COUNT     // must be the last one
 };
 
index 782e4ef44a1031c961374a9dc8f832724104e855..ec89558f15696e0662a18e2b19848413113f0922 100644 (file)
 # define PV_VSTS               OPT_BUF(BV_VSTS)
 # define PV_VTS                OPT_BUF(BV_VTS)
 #endif
+#define PV_VE          OPT_BOTH(OPT_BUF(BV_VE))
 
 // Definition of the PV_ values for window-local options.
 // The WV_ values are defined in option.h.
@@ -2806,7 +2807,7 @@ static struct vimoption options[] =
                            SCTX_INIT},
     {"virtualedit", "ve",   P_STRING|P_ONECOMMA|P_NODUP|P_VI_DEF
                                                            |P_VIM|P_CURSWANT,
-                           (char_u *)&p_ve, PV_NONE,
+                           (char_u *)&p_ve, PV_VE,
                            {(char_u *)"", (char_u *)""}
                            SCTX_INIT},
     {"visualbell",  "vb",   P_BOOL|P_VI_DEF,
index 4c1cacc5cfd57eb684275e9b54105ba2a09c1949..c22a441ff7e515bbc6256e6ecc5e10655e88f528 100644 (file)
@@ -56,7 +56,7 @@ static char *(p_tbis_values[]) = {"tiny", "small", "medium", "large", "huge", "g
 #if defined(UNIX) || defined(VMS)
 static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL};
 #endif
-static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL};
+static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", "none", "NONE", NULL};
 static char *(p_wop_values[]) = {"tagfile", NULL};
 #ifdef FEAT_WAK
 static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
@@ -298,6 +298,7 @@ check_buf_options(buf_T *buf)
     check_string_option(&buf->b_p_vsts);
     check_string_option(&buf->b_p_vts);
 #endif
+    check_string_option(&buf->b_p_ve);
 }
 
 /*
@@ -2075,16 +2076,31 @@ ambw_end:
 #endif
 
     // 'virtualedit'
-    else if (varp == &p_ve)
+    else if (gvarp == &p_ve)
     {
-       if (opt_strings_flags(p_ve, p_ve_values, &ve_flags, TRUE) != OK)
-           errmsg = e_invarg;
-       else if (STRCMP(p_ve, oldval) != 0)
+       char_u          *ve = p_ve;
+       unsigned int    *flags = &ve_flags;
+
+       if (opt_flags & OPT_LOCAL)
+       {
+           ve = curbuf->b_p_ve;
+           flags = &curbuf->b_ve_flags;
+       }
+
+       if ((opt_flags & OPT_LOCAL) && *ve == NUL)
+           // make the local value empty: use the global value
+           *flags = 0;
+       else
        {
-           // Recompute cursor position in case the new 've' setting
-           // changes something.
-           validate_virtcol();
-           coladvance(curwin->w_virtcol);
+           if (opt_strings_flags(ve, p_ve_values, flags, TRUE) != OK)
+               errmsg = e_invarg;
+           else if (STRCMP(p_ve, oldval) != 0)
+           {
+               // Recompute cursor position in case the new 've' setting
+               // changes something.
+               validate_virtcol();
+               coladvance(curwin->w_virtcol);
+           }
        }
     }
 
index 25cfb6541fb53b5461ef1a963186d21de98ede28..13b9c1b7edf3a95712ca6500de49514ce40ed134 100644 (file)
@@ -73,6 +73,7 @@ int can_bs(int what);
 long get_scrolloff_value(void);
 long get_sidescrolloff_value(void);
 unsigned int get_bkc_value(buf_T *buf);
+unsigned int get_ve_flags(void);
 char_u *get_showbreak_value(win_T *win);
 dict_T *get_winbuf_options(int bufopt);
 int fill_culopt_flags(char_u *val, win_T *wp);
index 0c714c69c50efbbee1001304e41a1917c8fa7e5f..161587423258a272a4493f4a406f71cec556cc92 100644 (file)
@@ -1556,6 +1556,7 @@ do_put(
     long       cnt;
     pos_T      orig_start = curbuf->b_op_start;
     pos_T      orig_end = curbuf->b_op_end;
+    unsigned int cur_ve_flags = get_ve_flags();
 
 #ifdef FEAT_CLIPBOARD
     // Adjust register name for "unnamed" in 'clipboard'.
@@ -1742,7 +1743,7 @@ do_put(
 
     yanklen = (int)STRLEN(y_array[0]);
 
-    if (ve_flags == VE_ALL && y_type == MCHAR)
+    if (cur_ve_flags == VE_ALL && y_type == MCHAR)
     {
        if (gchar_cursor() == TAB)
        {
@@ -1777,7 +1778,7 @@ do_put(
 
        if (dir == FORWARD && c != NUL)
        {
-           if (ve_flags == VE_ALL)
+           if (cur_ve_flags == VE_ALL)
                getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
            else
                getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
@@ -1786,7 +1787,7 @@ do_put(
                // move to start of next multi-byte character
                curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
            else
-           if (c != TAB || ve_flags != VE_ALL)
+           if (c != TAB || cur_ve_flags != VE_ALL)
                ++curwin->w_cursor.col;
            ++col;
        }
@@ -1794,7 +1795,7 @@ do_put(
            getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
 
        col += curwin->w_cursor.coladd;
-       if (ve_flags == VE_ALL
+       if (cur_ve_flags == VE_ALL
                && (curwin->w_cursor.coladd > 0
                    || endcol2 == curwin->w_cursor.col))
        {
index bf8102cd79534fa8e7ffdbcdb96485ef8895fbda..09f07030c6fd91f2c503b6aa979eff2e7e04c2ab 100644 (file)
@@ -2969,6 +2969,8 @@ struct file_buffer
 #ifdef FEAT_TERMINAL
     long       b_p_twsl;       // 'termwinscroll'
 #endif
+    char_u     *b_p_ve;        // 'virtualedit' local value
+    unsigned   b_ve_flags;     // flags for 'virtualedit'
 
     /*
      * end of buffer options
index 7f6e08c7c7e099192002e0244209df4d194aea18..f3cc2602510d377a1f79e2be91fbb3fcb6ba6507 100644 (file)
@@ -402,4 +402,124 @@ func Test_delete_past_eol()
   bw!
 endfunc
 
+" After calling s:TryVirtualeditReplace(), line 1 will contain one of these
+" two strings, depending on whether virtual editing is on or off.
+let s:result_ve_on  = 'a      x'
+let s:result_ve_off = 'x'
+
+" Utility function for Test_global_local()
+func s:TryVirtualeditReplace()
+  call setline(1, 'a')
+  normal gg7l
+  normal rx
+endfunc
+
+" Test for :set and :setlocal
+func Test_global_local()
+  new
+
+  " Verify that 'virtualedit' is initialized to empty, can be set globally to
+  " all and to empty, and can be set locally to all and to empty.
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  set ve=all
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  set ve=
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  setlocal ve=all
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  setlocal ve=
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+
+  " Verify that :set affects multiple buffers
+  new
+  set ve=all
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  wincmd p
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  set ve=
+  wincmd p
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  bwipe!
+
+  " Verify that :setlocal affects only the current buffer
+  setlocal ve=all
+  new
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  setlocal ve=all
+  wincmd p
+  setlocal ve=
+  wincmd p
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  bwipe!
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+
+  " Verify that the buffer 'virtualedit' state follows the global value only
+  " when empty and that "none" works as expected.
+  "
+  "          'virtualedit' State
+  " +--------+--------------------------+
+  " | Local  |          Global          |
+  " |        |                          |
+  " +--------+--------+--------+--------+
+  " |        | ""     | "all"  | "none" |
+  " +--------+--------+--------+--------+
+  " | ""     |  off   |  on    |  off   |
+  " | "all"  |  on    |  on    |  on    |
+  " | "none" |  off   |  off   |  off   |
+  " +--------+--------+--------+--------+
+  new
+
+  setglobal ve=
+  setlocal ve=
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  setlocal ve=all
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  setlocal ve=none
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+
+  setglobal ve=all
+  setlocal ve=
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  setlocal ve=all
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  setlocal ve=none
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  setlocal ve=NONE
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+
+  setglobal ve=none
+  setlocal ve=
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  setlocal ve=all
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  setlocal ve=none
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+
+  bwipe!
+
+  setlocal virtualedit&
+  set virtualedit&
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 0d60cc223232388a38f21153c08396eb315a55ba..cdf5d4e4e96f2b6ff9a681031a90982b90b6beeb 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3227,
 /**/
     3226,
 /**/