diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-01-15 19:21:17 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-01-15 19:21:17 +0800 |
commit | 87e54f123aa1c9c769d3ff35bdd1b5a980ba701c (patch) | |
tree | 1cb66900f9e0a0275c53803ca685872ddb9a294e | |
parent | d391940b9a074bca7ee82460ccaaabf46b5f2ba9 (diff) | |
download | rneovim-87e54f123aa1c9c769d3ff35bdd1b5a980ba701c.tar.gz rneovim-87e54f123aa1c9c769d3ff35bdd1b5a980ba701c.tar.bz2 rneovim-87e54f123aa1c9c769d3ff35bdd1b5a980ba701c.zip |
vim-patch:8.2.3280: 'virtualedit' local to buffer is not the best solution
Problem: 'virtualedit' local to buffer is not the best solution.
Solution: Make it window-local. (Gary Johnson, closes vim/vim#8685)
https://github.com/vim/vim/commit/51ad850f5fbafa7aa3f60affa74ec9c9f992c6cc
-rw-r--r-- | runtime/doc/options.txt | 2 | ||||
-rw-r--r-- | src/nvim/buffer.c | 1 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 6 | ||||
-rw-r--r-- | src/nvim/ops.c | 10 | ||||
-rw-r--r-- | src/nvim/option.c | 24 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/screen.c | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_virtualedit.vim | 37 |
8 files changed, 54 insertions, 36 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 08f719f16c..4536079cea 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -6782,7 +6782,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. diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 3753d67d54..abd22fba26 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1941,7 +1941,6 @@ void free_buf_options(buf_T *buf, int free_p_ff) clear_string_option(&buf->b_p_lw); clear_string_option(&buf->b_p_bkc); clear_string_option(&buf->b_p_menc); - clear_string_option(&buf->b_p_ve); } diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index a14dfff085..2856a7390d 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -204,6 +204,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' long wo_nuw; #define w_p_nuw w_onebuf_opt.wo_nuw // 'numberwidth' int wo_wfh; @@ -772,8 +776,6 @@ struct file_buffer { long b_p_ul; ///< 'undolevels' local value int b_p_udf; ///< 'undofile' char_u *b_p_lw; ///< 'lispwords' local value - char_u *b_p_ve; ///< 'virtualedit' local value - unsigned b_ve_flags; ///< flags for 'virtualedit' // end of buffer options diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 74033df313..c845bd3717 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2197,21 +2197,21 @@ void 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) { - unsigned old_ve_flags = curbuf->b_ve_flags; + unsigned 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); diff --git a/src/nvim/option.c b/src/nvim/option.c index fd4cc9ebb2..a79523f800 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2065,7 +2065,6 @@ void check_buf_options(buf_T *buf) check_string_option(&buf->b_p_menc); check_string_option(&buf->b_p_vsts); check_string_option(&buf->b_p_vts); - check_string_option(&buf->b_p_ve); } /// Free the string allocated for an option. @@ -3090,8 +3089,8 @@ ambw_end: unsigned int *flags = &ve_flags; 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) { @@ -5763,8 +5762,8 @@ void unset_global_local_option(char *name, void *from) redraw_later((win_T *)from, 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; } } @@ -5833,7 +5832,7 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags) case PV_LCS: return (char_u *)&(curwin->w_p_lcs); case PV_VE: - return (char_u *)&(curbuf->b_p_ve); + return (char_u *)&(curwin->w_p_ve); } return NULL; // "cannot happen" } @@ -5928,6 +5927,9 @@ static char_u *get_varp(vimoption_T *p) 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; case PV_ARAB: return (char_u *)&(curwin->w_p_arab); @@ -6126,8 +6128,6 @@ static char_u *get_varp(vimoption_T *p) return (char_u *)&(curbuf->b_p_vsts); case PV_VTS: return (char_u *)&(curbuf->b_p_vts); - case PV_VE: - return *curbuf->b_p_ve != NUL ? (char_u *)&curbuf->b_p_ve : p->var; case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap); case PV_SCL: @@ -6170,6 +6170,8 @@ void copy_winopt(winopt_T *from, winopt_T *to) to->wo_list = from->wo_list; 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; to->wo_nuw = from->wo_nuw; to->wo_rl = from->wo_rl; to->wo_rlc = vim_strsave(from->wo_rlc); @@ -6246,6 +6248,7 @@ static void check_winopt(winopt_T *wop) check_string_option(&wop->wo_winhl); check_string_option(&wop->wo_fcs); check_string_option(&wop->wo_lcs); + check_string_option(&wop->wo_ve); } /// Free the allocated memory inside a winopt_T. @@ -6270,6 +6273,7 @@ void clear_winopt(winopt_T *wop) clear_string_option(&wop->wo_winhl); clear_string_option(&wop->wo_fcs); clear_string_option(&wop->wo_lcs); + clear_string_option(&wop->wo_ve); } void didset_window_options(win_T *wp) @@ -6460,8 +6464,6 @@ void buf_copy_options(buf_T *buf, int flags) buf->b_p_udf = p_udf; buf->b_p_lw = empty_option; 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, @@ -7842,7 +7844,7 @@ unsigned int get_bkc_value(buf_T *buf) /// 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); + return (curwin->w_ve_flags ? curwin->w_ve_flags : ve_flags) & ~(VE_NONE | VE_NONEU); } /// Get the local or global value of 'showbreak'. diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index aed2868a09..db8bc83395 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -711,8 +711,8 @@ static char *(p_ve_values[]) = { "block", "insert", "all", "onemore", "none", "N #define VE_INSERT 6U // includes "all" #define VE_ALL 4U #define VE_ONEMORE 8U -#define VE_NONE 16U -#define VE_NONEU 32U // Upper-case NONE +#define VE_NONE 16U // "none" +#define VE_NONEU 32U // "NONE" EXTERN long p_verbose; // 'verbose' #ifdef IN_OPTION_C char_u *p_vfile = (char_u *)""; // used before options are initialized diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 9aea42cda3..9b253fad01 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1215,14 +1215,14 @@ static void win_update(win_T *wp, Providers *providers) */ if (VIsual_mode == Ctrl_V) { colnr_T fromc, toc; - unsigned int save_ve_flags = curbuf->b_ve_flags; + unsigned 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; } getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc); - curbuf->b_ve_flags = save_ve_flags; + curwin->w_ve_flags = save_ve_flags; toc++; // Highlight to the end of the line, unless 'virtualedit' has // "block". diff --git a/src/nvim/testdir/test_virtualedit.vim b/src/nvim/testdir/test_virtualedit.vim index c19a9500bd..d2a5258bd3 100644 --- a/src/nvim/testdir/test_virtualedit.vim +++ b/src/nvim/testdir/test_virtualedit.vim @@ -263,7 +263,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 @@ -271,7 +271,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 @@ -291,8 +291,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)) @@ -305,17 +305,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)) @@ -374,6 +372,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 |