aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-01-15 19:21:17 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-01-15 19:21:17 +0800
commit87e54f123aa1c9c769d3ff35bdd1b5a980ba701c (patch)
tree1cb66900f9e0a0275c53803ca685872ddb9a294e
parentd391940b9a074bca7ee82460ccaaabf46b5f2ba9 (diff)
downloadrneovim-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.txt2
-rw-r--r--src/nvim/buffer.c1
-rw-r--r--src/nvim/buffer_defs.h6
-rw-r--r--src/nvim/ops.c10
-rw-r--r--src/nvim/option.c24
-rw-r--r--src/nvim/option_defs.h4
-rw-r--r--src/nvim/screen.c6
-rw-r--r--src/nvim/testdir/test_virtualedit.vim37
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