Skip to content

Commit cfb3814

Browse files
committed
patch 8.1.2184: option context is not copied when splitting a window
Problem: Option context is not copied when splitting a window. (Daniel Hahler) Solution: Copy the option context, so that ":verbose set" works. (closes #5066)
1 parent ba08930 commit cfb3814

3 files changed

Lines changed: 133 additions & 11 deletions

File tree

src/option.c

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5641,6 +5641,12 @@ copy_winopt(winopt_T *from, winopt_T *to)
56415641
#ifdef FEAT_SIGNS
56425642
to->wo_scl = vim_strsave(from->wo_scl);
56435643
#endif
5644+
5645+
#ifdef FEAT_EVAL
5646+
// Copy the script context so that we know where the value was last set.
5647+
mch_memmove(to->wo_script_ctx, from->wo_script_ctx,
5648+
sizeof(to->wo_script_ctx));
5649+
#endif
56445650
check_winopt(to); /* don't want NULL pointers */
56455651
}
56465652

@@ -5738,11 +5744,36 @@ clear_winopt(winopt_T *wop UNUSED)
57385744
#endif
57395745
}
57405746

5747+
#ifdef FEAT_EVAL
5748+
// Index into the options table for a buffer-local option enum.
5749+
static int buf_opt_idx[BV_COUNT];
5750+
# define COPY_OPT_SCTX(buf, bv) buf->b_p_script_ctx[bv] = options[buf_opt_idx[bv]].script_ctx
5751+
5752+
/*
5753+
* Initialize buf_opt_idx[] if not done already.
5754+
*/
5755+
static void
5756+
init_buf_opt_idx(void)
5757+
{
5758+
static int did_init_buf_opt_idx = FALSE;
5759+
int i;
5760+
5761+
if (did_init_buf_opt_idx)
5762+
return;
5763+
did_init_buf_opt_idx = TRUE;
5764+
for (i = 0; !istermoption_idx(i); i++)
5765+
if (options[i].indir & PV_BUF)
5766+
buf_opt_idx[options[i].indir & PV_MASK] = i;
5767+
}
5768+
#else
5769+
# define COPY_OPT_SCTX(buf, bv)
5770+
#endif
5771+
57415772
/*
57425773
* Copy global option values to local options for one buffer.
57435774
* Used when creating a new buffer and sometimes when entering a buffer.
57445775
* flags:
5745-
* BCO_ENTER We will enter the buf buffer.
5776+
* BCO_ENTER We will enter the buffer "buf".
57465777
* BCO_ALWAYS Always copy the options, but only set b_p_initialized when
57475778
* appropriate.
57485779
* BCO_NOHELP Don't copy the values to a help buffer.
@@ -5781,12 +5812,16 @@ buf_copy_options(buf_T *buf, int flags)
57815812

57825813
if (should_copy || (flags & BCO_ALWAYS))
57835814
{
5784-
/* Don't copy the options specific to a help buffer when
5785-
* BCO_NOHELP is given or the options were initialized already
5786-
* (jumping back to a help file with CTRL-T or CTRL-O) */
5815+
vim_memset(buf->b_p_script_ctx, 0, sizeof(buf->b_p_script_ctx));
5816+
#ifdef FEAT_EVAL
5817+
init_buf_opt_idx();
5818+
#endif
5819+
// Don't copy the options specific to a help buffer when
5820+
// BCO_NOHELP is given or the options were initialized already
5821+
// (jumping back to a help file with CTRL-T or CTRL-O)
57875822
dont_do_help = ((flags & BCO_NOHELP) && buf->b_help)
57885823
|| buf->b_p_initialized;
5789-
if (dont_do_help) /* don't free b_p_isk */
5824+
if (dont_do_help) // don't free b_p_isk
57905825
{
57915826
save_p_isk = buf->b_p_isk;
57925827
buf->b_p_isk = NULL;
@@ -5821,39 +5856,62 @@ buf_copy_options(buf_T *buf, int flags)
58215856
free_buf_options(buf, FALSE);
58225857

58235858
buf->b_p_ai = p_ai;
5859+
COPY_OPT_SCTX(buf, BV_AI);
58245860
buf->b_p_ai_nopaste = p_ai_nopaste;
58255861
buf->b_p_sw = p_sw;
5862+
COPY_OPT_SCTX(buf, BV_SW);
58265863
buf->b_p_tw = p_tw;
5864+
COPY_OPT_SCTX(buf, BV_TW);
58275865
buf->b_p_tw_nopaste = p_tw_nopaste;
58285866
buf->b_p_tw_nobin = p_tw_nobin;
58295867
buf->b_p_wm = p_wm;
5868+
COPY_OPT_SCTX(buf, BV_WM);
58305869
buf->b_p_wm_nopaste = p_wm_nopaste;
58315870
buf->b_p_wm_nobin = p_wm_nobin;
58325871
buf->b_p_bin = p_bin;
5872+
COPY_OPT_SCTX(buf, BV_BIN);
58335873
buf->b_p_bomb = p_bomb;
5874+
COPY_OPT_SCTX(buf, BV_BOMB);
58345875
buf->b_p_fixeol = p_fixeol;
5876+
COPY_OPT_SCTX(buf, BV_FIXEOL);
58355877
buf->b_p_et = p_et;
5878+
COPY_OPT_SCTX(buf, BV_ET);
58365879
buf->b_p_et_nobin = p_et_nobin;
58375880
buf->b_p_et_nopaste = p_et_nopaste;
58385881
buf->b_p_ml = p_ml;
5882+
COPY_OPT_SCTX(buf, BV_ML);
58395883
buf->b_p_ml_nobin = p_ml_nobin;
58405884
buf->b_p_inf = p_inf;
5841-
buf->b_p_swf = cmdmod.noswapfile ? FALSE : p_swf;
5885+
COPY_OPT_SCTX(buf, BV_INF);
5886+
if (cmdmod.noswapfile)
5887+
buf->b_p_swf = FALSE;
5888+
else
5889+
{
5890+
buf->b_p_swf = p_swf;
5891+
COPY_OPT_SCTX(buf, BV_INF);
5892+
}
58425893
buf->b_p_cpt = vim_strsave(p_cpt);
5894+
COPY_OPT_SCTX(buf, BV_CPT);
58435895
#ifdef BACKSLASH_IN_FILENAME
58445896
buf->b_p_csl = vim_strsave(p_csl);
5897+
COPY_OPT_SCTX(buf, BV_CSL);
58455898
#endif
58465899
#ifdef FEAT_COMPL_FUNC
58475900
buf->b_p_cfu = vim_strsave(p_cfu);
5901+
COPY_OPT_SCTX(buf, BV_CFU);
58485902
buf->b_p_ofu = vim_strsave(p_ofu);
5903+
COPY_OPT_SCTX(buf, BV_OFU);
58495904
#endif
58505905
#ifdef FEAT_EVAL
58515906
buf->b_p_tfu = vim_strsave(p_tfu);
5907+
COPY_OPT_SCTX(buf, BV_TFU);
58525908
#endif
58535909
buf->b_p_sts = p_sts;
5910+
COPY_OPT_SCTX(buf, BV_STS);
58545911
buf->b_p_sts_nopaste = p_sts_nopaste;
58555912
#ifdef FEAT_VARTABS
58565913
buf->b_p_vsts = vim_strsave(p_vsts);
5914+
COPY_OPT_SCTX(buf, BV_VSTS);
58575915
if (p_vsts && p_vsts != empty_option)
58585916
tabstop_set(p_vsts, &buf->b_p_vsts_array);
58595917
else
@@ -5862,71 +5920,99 @@ buf_copy_options(buf_T *buf, int flags)
58625920
? vim_strsave(p_vsts_nopaste) : NULL;
58635921
#endif
58645922
buf->b_p_sn = p_sn;
5923+
COPY_OPT_SCTX(buf, BV_SN);
58655924
buf->b_p_com = vim_strsave(p_com);
5925+
COPY_OPT_SCTX(buf, BV_COM);
58665926
#ifdef FEAT_FOLDING
58675927
buf->b_p_cms = vim_strsave(p_cms);
5928+
COPY_OPT_SCTX(buf, BV_CMS);
58685929
#endif
58695930
buf->b_p_fo = vim_strsave(p_fo);
5931+
COPY_OPT_SCTX(buf, BV_FO);
58705932
buf->b_p_flp = vim_strsave(p_flp);
5933+
COPY_OPT_SCTX(buf, BV_FLP);
58715934
// NOTE: Valgrind may report a bogus memory leak for 'nrformats'
58725935
// when it is set to 8 bytes in defaults.vim.
58735936
buf->b_p_nf = vim_strsave(p_nf);
5937+
COPY_OPT_SCTX(buf, BV_NF);
58745938
buf->b_p_mps = vim_strsave(p_mps);
5939+
COPY_OPT_SCTX(buf, BV_MPS);
58755940
#ifdef FEAT_SMARTINDENT
58765941
buf->b_p_si = p_si;
5942+
COPY_OPT_SCTX(buf, BV_SI);
58775943
#endif
58785944
buf->b_p_ci = p_ci;
5945+
COPY_OPT_SCTX(buf, BV_CI);
58795946
#ifdef FEAT_CINDENT
58805947
buf->b_p_cin = p_cin;
5948+
COPY_OPT_SCTX(buf, BV_CIN);
58815949
buf->b_p_cink = vim_strsave(p_cink);
5950+
COPY_OPT_SCTX(buf, BV_CINK);
58825951
buf->b_p_cino = vim_strsave(p_cino);
5952+
COPY_OPT_SCTX(buf, BV_CINO);
58835953
#endif
5884-
/* Don't copy 'filetype', it must be detected */
5954+
// Don't copy 'filetype', it must be detected
58855955
buf->b_p_ft = empty_option;
58865956
buf->b_p_pi = p_pi;
5957+
COPY_OPT_SCTX(buf, BV_PI);
58875958
#if defined(FEAT_SMARTINDENT) || defined(FEAT_CINDENT)
58885959
buf->b_p_cinw = vim_strsave(p_cinw);
5960+
COPY_OPT_SCTX(buf, BV_CINW);
58895961
#endif
58905962
#ifdef FEAT_LISP
58915963
buf->b_p_lisp = p_lisp;
5964+
COPY_OPT_SCTX(buf, BV_LISP);
58925965
#endif
58935966
#ifdef FEAT_SYN_HL
58945967
/* Don't copy 'syntax', it must be set */
58955968
buf->b_p_syn = empty_option;
58965969
buf->b_p_smc = p_smc;
5970+
COPY_OPT_SCTX(buf, BV_SMC);
58975971
buf->b_s.b_syn_isk = empty_option;
58985972
#endif
58995973
#ifdef FEAT_SPELL
59005974
buf->b_s.b_p_spc = vim_strsave(p_spc);
5975+
COPY_OPT_SCTX(buf, BV_SPC);
59015976
(void)compile_cap_prog(&buf->b_s);
59025977
buf->b_s.b_p_spf = vim_strsave(p_spf);
5978+
COPY_OPT_SCTX(buf, BV_SPF);
59035979
buf->b_s.b_p_spl = vim_strsave(p_spl);
5980+
COPY_OPT_SCTX(buf, BV_SPL);
59045981
#endif
59055982
#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
59065983
buf->b_p_inde = vim_strsave(p_inde);
5984+
COPY_OPT_SCTX(buf, BV_INDE);
59075985
buf->b_p_indk = vim_strsave(p_indk);
5986+
COPY_OPT_SCTX(buf, BV_INDK);
59085987
#endif
59095988
buf->b_p_fp = empty_option;
59105989
#if defined(FEAT_EVAL)
59115990
buf->b_p_fex = vim_strsave(p_fex);
5991+
COPY_OPT_SCTX(buf, BV_FEX);
59125992
#endif
59135993
#ifdef FEAT_CRYPT
59145994
buf->b_p_key = vim_strsave(p_key);
5995+
COPY_OPT_SCTX(buf, BV_KEY);
59155996
#endif
59165997
#ifdef FEAT_SEARCHPATH
59175998
buf->b_p_sua = vim_strsave(p_sua);
5999+
COPY_OPT_SCTX(buf, BV_SUA);
59186000
#endif
59196001
#ifdef FEAT_KEYMAP
59206002
buf->b_p_keymap = vim_strsave(p_keymap);
6003+
COPY_OPT_SCTX(buf, BV_KMAP);
59216004
buf->b_kmap_state |= KEYMAP_INIT;
59226005
#endif
59236006
#ifdef FEAT_TERMINAL
59246007
buf->b_p_twsl = p_twsl;
6008+
COPY_OPT_SCTX(buf, BV_TWSL);
59256009
#endif
59266010
/* This isn't really an option, but copying the langmap and IME
59276011
* state from the current buffer is better than resetting it. */
59286012
buf->b_p_iminsert = p_iminsert;
6013+
COPY_OPT_SCTX(buf, BV_IMI);
59296014
buf->b_p_imsearch = p_imsearch;
6015+
COPY_OPT_SCTX(buf, BV_IMS);
59306016

59316017
/* options that are normally global but also have a local value
59326018
* are not copied, start using the global value */
@@ -5950,12 +6036,14 @@ buf_copy_options(buf_T *buf, int flags)
59506036
buf->b_p_inc = empty_option;
59516037
# ifdef FEAT_EVAL
59526038
buf->b_p_inex = vim_strsave(p_inex);
6039+
COPY_OPT_SCTX(buf, BV_INEX);
59536040
# endif
59546041
#endif
59556042
buf->b_p_dict = empty_option;
59566043
buf->b_p_tsr = empty_option;
59576044
#ifdef FEAT_TEXTOBJ
59586045
buf->b_p_qe = vim_strsave(p_qe);
6046+
COPY_OPT_SCTX(buf, BV_QE);
59596047
#endif
59606048
#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
59616049
buf->b_p_bexpr = empty_option;
@@ -5965,6 +6053,7 @@ buf_copy_options(buf_T *buf, int flags)
59656053
#endif
59666054
#ifdef FEAT_PERSISTENT_UNDO
59676055
buf->b_p_udf = p_udf;
6056+
COPY_OPT_SCTX(buf, BV_UDF);
59686057
#endif
59696058
#ifdef FEAT_LISP
59706059
buf->b_p_lw = empty_option;
@@ -5990,10 +6079,12 @@ buf_copy_options(buf_T *buf, int flags)
59906079
else
59916080
{
59926081
buf->b_p_isk = vim_strsave(p_isk);
6082+
COPY_OPT_SCTX(buf, BV_ISK);
59936083
did_isk = TRUE;
59946084
buf->b_p_ts = p_ts;
59956085
#ifdef FEAT_VARTABS
59966086
buf->b_p_vts = vim_strsave(p_vts);
6087+
COPY_OPT_SCTX(buf, BV_VTS);
59976088
if (p_vts && p_vts != empty_option && !buf->b_p_vts_array)
59986089
tabstop_set(p_vts, &buf->b_p_vts_array);
59996090
else
@@ -6003,6 +6094,7 @@ buf_copy_options(buf_T *buf, int flags)
60036094
if (buf->b_p_bt[0] == 'h')
60046095
clear_string_option(&buf->b_p_bt);
60056096
buf->b_p_ma = p_ma;
6097+
COPY_OPT_SCTX(buf, BV_MA);
60066098
}
60076099
}
60086100

src/testdir/test_options.vim

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,20 +296,48 @@ func Test_set_errors()
296296
call assert_fails('set t_foo=', 'E846:')
297297
endfunc
298298

299+
func CheckWasSet(name)
300+
let verb_cm = execute('verbose set ' .. a:name .. '?')
301+
call assert_match('Last set from.*test_options.vim', verb_cm)
302+
endfunc
303+
func CheckWasNotSet(name)
304+
let verb_cm = execute('verbose set ' .. a:name .. '?')
305+
call assert_notmatch('Last set from', verb_cm)
306+
endfunc
307+
299308
" Must be executed before other tests that set 'term'.
300309
func Test_000_term_option_verbose()
301310
CheckNotGui
302311

303-
let verb_cm = execute('verbose set t_cm')
304-
call assert_notmatch('Last set from', verb_cm)
312+
call CheckWasNotSet('t_cm')
305313

306314
let term_save = &term
307315
set term=ansi
308-
let verb_cm = execute('verbose set t_cm')
309-
call assert_match('Last set from.*test_options.vim', verb_cm)
316+
call CheckWasSet('t_cm')
310317
let &term = term_save
311318
endfunc
312319

320+
func Test_copy_context()
321+
setlocal list
322+
call CheckWasSet('list')
323+
split
324+
call CheckWasSet('list')
325+
quit
326+
setlocal nolist
327+
328+
set ai
329+
call CheckWasSet('ai')
330+
set filetype=perl
331+
call CheckWasSet('filetype')
332+
set fo=tcroq
333+
call CheckWasSet('fo')
334+
335+
split Xsomebuf
336+
call CheckWasSet('ai')
337+
call CheckWasNotSet('filetype')
338+
call CheckWasSet('fo')
339+
endfunc
340+
313341
func Test_set_ttytype()
314342
CheckUnix
315343
CheckNotGui

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ static char *(features[]) =
741741

742742
static int included_patches[] =
743743
{ /* Add new patch number below this line */
744+
/**/
745+
2184,
744746
/**/
745747
2183,
746748
/**/

0 commit comments

Comments
 (0)