]> granicus.if.org Git - vim/commitdiff
patch 8.2.3280: 'virtualedit' local to buffer is not the best solution v8.2.3280
authorGary Johnson <garyjohn@spocom.com>
Tue, 3 Aug 2021 16:33:08 +0000 (18:33 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 3 Aug 2021 16:33:08 +0000 (18:33 +0200)
Problem:    'virtualedit' local to buffer is not the best solution.
Solution:   Make it window-local. (Gary Johnson, closes #8685)

runtime/doc/options.txt
src/buffer.c
src/drawscreen.c
src/ops.c
src/option.c
src/option.h
src/optionstr.c
src/structs.h
src/testdir/test_virtualedit.vim
src/version.c

index 5c925dff228545cf7fb81f0589c7b35276cf7a35..ebb408dd4971e30f6809eede2504e33712d57152 100644 (file)
@@ -8643,7 +8643,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 
                                            *'virtualedit'* *'ve'*
 'virtualedit' 've'     string  (default "")
-                       global or local to buffer |global-local|
+                       global or local to window |global-local|
        A comma separated list of these words:
            block       Allow virtual editing in Visual block mode.
            insert      Allow virtual editing in Insert mode.
index 628c82f18698c7dcacf6c975572bae2275dc8a0b..bc3378a995237526db5cbe63035fbd43b7dee9f7 100644 (file)
@@ -2388,7 +2388,6 @@ 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 36aad637b24c38579f7228389f4946803dd6a613..82e53753bf9b6783392110df7814a73501452839 100644 (file)
@@ -2006,15 +2006,15 @@ win_update(win_T *wp)
            {
                colnr_T     fromc, toc;
 #if defined(FEAT_LINEBREAK)
-               int         save_ve_flags = curbuf->b_ve_flags;
+               int         save_ve_flags = curwin->w_ve_flags;
 
                if (curwin->w_p_lbr)
-                   curbuf->b_ve_flags = VE_ALL;
+                   curwin->w_ve_flags = VE_ALL;
 #endif
                getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc);
                ++toc;
 #if defined(FEAT_LINEBREAK)
-               curbuf->b_ve_flags = save_ve_flags;
+               curwin->w_ve_flags = save_ve_flags;
 #endif
                // Highlight to the end of the line, unless 'virtualedit' has
                // "block".
index 75619c570cd6e4d2dea637f90629201eed6bf19e..614ada5dff9bc4cb917f78dfdcb2ba5d8bd4c059 100644 (file)
--- a/src/ops.c
+++ b/src/ops.c
@@ -1475,21 +1475,21 @@ op_insert(oparg_T *oap, long count1)
        // 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.
+       // state for the current window.  To override that state, we need to
+       // set the window-local value of ve_flags rather than the global value.
        if (curwin->w_cursor.coladd > 0)
        {
-           int         old_ve_flags = curbuf->b_ve_flags;
+           int         old_ve_flags = curwin->w_ve_flags;
 
            if (u_save_cursor() == FAIL)
                return;
 
-           curbuf->b_ve_flags = VE_ALL;
+           curwin->w_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;
-           curbuf->b_ve_flags = old_ve_flags;
+           curwin->w_ve_flags = old_ve_flags;
        }
        // Get the info about the block before entering the text
        block_prep(oap, &bd, oap->start.lnum, TRUE);
index decba501a91d0c972b7c2bbe288eb168dee6afcc..4e0e5a6ac6acd306f76288b945e1e2a59cf96f9e 100644 (file)
@@ -5182,8 +5182,8 @@ unset_global_local_option(char_u *name, void *from)
            redraw_later(NOT_VALID);
            break;
        case PV_VE:
-           clear_string_option(&buf->b_p_ve);
-           buf->b_ve_flags = 0;
+           clear_string_option(&((win_T *)from)->w_p_ve);
+           ((win_T *)from)->w_ve_flags = 0;
            break;
     }
 }
@@ -5244,7 +5244,7 @@ get_varp_scope(struct vimoption *p, int opt_flags)
            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_VE:   return (char_u *)&(curbuf->b_p_ve);
+           case PV_VE:   return (char_u *)&(curwin->w_p_ve);
 
        }
        return NULL; // "cannot happen"
@@ -5345,6 +5345,8 @@ get_varp(struct vimoption *p)
        case PV_LIST:   return (char_u *)&(curwin->w_p_list);
        case PV_LCS:    return *curwin->w_p_lcs != NUL
                                    ? (char_u *)&(curwin->w_p_lcs) : p->var;
+       case PV_VE:     return *curwin->w_p_ve != NUL
+                                   ? (char_u *)&(curwin->w_p_ve) : p->var;
 #ifdef FEAT_SPELL
        case PV_SPELL:  return (char_u *)&(curwin->w_p_spell);
 #endif
@@ -5512,8 +5514,6 @@ 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!
@@ -5593,6 +5593,8 @@ copy_winopt(winopt_T *from, winopt_T *to)
     to->wo_lcs = vim_strsave(from->wo_lcs);
     to->wo_nu = from->wo_nu;
     to->wo_rnu = from->wo_rnu;
+    to->wo_ve = vim_strsave(from->wo_ve);
+    to->wo_ve_flags = from->wo_ve_flags;
 #ifdef FEAT_LINEBREAK
     to->wo_nuw = from->wo_nuw;
 #endif
@@ -5726,6 +5728,7 @@ check_winopt(winopt_T *wop UNUSED)
 #endif
     check_string_option(&wop->wo_wcr);
     check_string_option(&wop->wo_lcs);
+    check_string_option(&wop->wo_ve);
 }
 
 /*
@@ -5772,6 +5775,7 @@ clear_winopt(winopt_T *wop UNUSED)
     clear_string_option(&wop->wo_tws);
 #endif
     clear_string_option(&wop->wo_lcs);
+    clear_string_option(&wop->wo_ve);
 }
 
 #ifdef FEAT_EVAL
@@ -6091,8 +6095,6 @@ 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,
@@ -7041,8 +7043,8 @@ get_bkc_value(buf_T *buf)
     unsigned int
 get_ve_flags(void)
 {
-    return (curbuf->b_ve_flags ? curbuf->b_ve_flags : ve_flags)
-          & ~(VE_NONE | VE_NONEU);
+    return (curwin->w_ve_flags ? curwin->w_ve_flags : ve_flags)
+           & ~(VE_NONE | VE_NONEU);
 }
 
 #if defined(FEAT_LINEBREAK) || defined(PROTO)
index 5732e8256701abb8aa25711c0930e69bac5e446a..48a3ec34b282b1be81aea5470b41ec261189f253 100644 (file)
@@ -1052,8 +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
+#define VE_NONE                16      // "none"
+#define VE_NONEU       32      // "NONE"
 EXTERN long    p_verbose;      // 'verbose'
 #ifdef IN_OPTION_C
 char_u *p_vfile = (char_u *)""; // used before options are initialized
index c22a441ff7e515bbc6256e6ecc5e10655e88f528..a394d8d06f6c322ce021ad14e1fa7d3cc4bf39c6 100644 (file)
@@ -298,7 +298,6 @@ 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);
 }
 
 /*
@@ -2083,8 +2082,8 @@ ambw_end:
 
        if (opt_flags & OPT_LOCAL)
        {
-           ve = curbuf->b_p_ve;
-           flags = &curbuf->b_ve_flags;
+           ve = curwin->w_p_ve;
+           flags = &curwin->w_ve_flags;
        }
 
        if ((opt_flags & OPT_LOCAL) && *ve == NUL)
index 09f07030c6fd91f2c503b6aa979eff2e7e04c2ab..0418be92c0c6e145569245908e98edbda5247438 100644 (file)
@@ -231,6 +231,10 @@ typedef struct
 #define w_p_nu w_onebuf_opt.wo_nu      // 'number'
     int                wo_rnu;
 #define w_p_rnu w_onebuf_opt.wo_rnu    // 'relativenumber'
+    char_u     *wo_ve;
+#define w_p_ve w_onebuf_opt.wo_ve      // 'virtualedit'
+    unsigned   wo_ve_flags;
+#define        w_ve_flags w_onebuf_opt.wo_ve_flags     // flags for 'virtualedit'
 #ifdef FEAT_LINEBREAK
     long       wo_nuw;
 # define w_p_nuw w_onebuf_opt.wo_nuw   // 'numberwidth'
@@ -2969,8 +2973,6 @@ 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 f3cc2602510d377a1f79e2be91fbb3fcb6ba6507..b31f3a2b4d3bac1fce981ae6ad27d1bb72b64c0c 100644 (file)
@@ -407,7 +407,7 @@ endfunc
 let s:result_ve_on  = 'a      x'
 let s:result_ve_off = 'x'
 
-" Utility function for Test_global_local()
+" Utility function for Test_global_local_virtualedit()
 func s:TryVirtualeditReplace()
   call setline(1, 'a')
   normal gg7l
@@ -415,7 +415,7 @@ func s:TryVirtualeditReplace()
 endfunc
 
 " Test for :set and :setlocal
-func Test_global_local()
+func Test_global_local_virtualedit()
   new
 
   " Verify that 'virtualedit' is initialized to empty, can be set globally to
@@ -435,8 +435,8 @@ func Test_global_local()
   call s:TryVirtualeditReplace()
   call assert_equal(s:result_ve_off, getline(1))
 
-  " Verify that :set affects multiple buffers
-  new
+  " Verify that :set affects multiple windows.
+  split
   set ve=all
   call s:TryVirtualeditReplace()
   call assert_equal(s:result_ve_on, getline(1))
@@ -449,17 +449,15 @@ func Test_global_local()
   call assert_equal(s:result_ve_off, getline(1))
   bwipe!
 
-  " Verify that :setlocal affects only the current buffer
-  setlocal ve=all
+  " Verify that :setlocal affects only the current window.
   new
-  call s:TryVirtualeditReplace()
-  call assert_equal(s:result_ve_off, getline(1))
+  split
   setlocal ve=all
-  wincmd p
-  setlocal ve=
-  wincmd p
   call s:TryVirtualeditReplace()
   call assert_equal(s:result_ve_on, getline(1))
+  wincmd p
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
   bwipe!
   call s:TryVirtualeditReplace()
   call assert_equal(s:result_ve_off, getline(1))
@@ -518,6 +516,23 @@ func Test_global_local()
 
   bwipe!
 
+  " Verify that the 'virtualedit' state is copied to new windows.
+  new
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  split
+  setlocal ve=all
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  split
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_on, getline(1))
+  setlocal ve=
+  split
+  call s:TryVirtualeditReplace()
+  call assert_equal(s:result_ve_off, getline(1))
+  bwipe!
+
   setlocal virtualedit&
   set virtualedit&
 endfunc
index 69df6714950db237b30b69a8febc76e2af833942..32403f45c860ef540280133e8b25e8f0b19eb1dc 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3280,
 /**/
     3279,
 /**/