From 0ba27bb51d3297aec43e78050cc3adcf6879db22 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 23 Aug 2023 16:32:15 +0800 Subject: vim-patch:9.0.1710: scrolloff options work slightly different Problem: sidescrolloff and scrolloff options work slightly different than other global-local options Solution: Make it behave consistent for all global-local options It was noticed, that sidescrolloff and scrolloff options behave differently in comparison to other global-local window options like 'listchars' So make those two behave like other global-local options. Also add some extra documentation for a few special local-window options. Add a few tests to make sure all global-local window options behave similar closes: vim/vim#12956 closes: vim/vim#12643 https://github.com/vim/vim/commit/4a8eb6e7a9df10f79bf95301ced012f0d6a13088 Co-authored-by: Christian Brabandt --- src/nvim/buffer_defs.h | 6 ++++-- src/nvim/option.c | 2 ++ src/nvim/window.c | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 0a7c742798..c94dbfa7fb 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -230,6 +230,10 @@ typedef struct { #define w_p_crb_save w_onebuf_opt.wo_crb_save char *wo_scl; #define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn' + long wo_siso; +#define w_p_siso w_onebuf_opt.wo_siso // 'sidescrolloff' local value + long wo_so; +#define w_p_so w_onebuf_opt.wo_so // 'scrolloff' local value char *wo_winhl; #define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight' char *wo_lcs; @@ -1321,8 +1325,6 @@ struct window_S { uint32_t w_p_fdt_flags; // flags for 'foldtext' int *w_p_cc_cols; // array of columns to highlight or NULL uint8_t w_p_culopt_flags; // flags for cursorline highlighting - long w_p_siso; // 'sidescrolloff' local value - long w_p_so; // 'scrolloff' local value int w_briopt_min; // minimum width for breakindent int w_briopt_shift; // additional shift for breakindent diff --git a/src/nvim/option.c b/src/nvim/option.c index 4ca52baa78..56881cbe58 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4702,6 +4702,8 @@ void copy_winopt(winopt_T *from, winopt_T *to) to->wo_sms = from->wo_sms; to->wo_crb = from->wo_crb; to->wo_crb_save = from->wo_crb_save; + to->wo_siso = from->wo_siso; + to->wo_so = from->wo_so; to->wo_spell = from->wo_spell; to->wo_cuc = from->wo_cuc; to->wo_cul = from->wo_cul; diff --git a/src/nvim/window.c b/src/nvim/window.c index 175a79568c..6ff9e07260 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5132,8 +5132,8 @@ static win_T *win_alloc(win_T *after, bool hidden) new_wp->w_ns_hl = -1; // use global option for global-local options - new_wp->w_p_so = -1; - new_wp->w_p_siso = -1; + new_wp->w_allbuf_opt.wo_so = new_wp->w_p_so = -1; + new_wp->w_allbuf_opt.wo_siso = new_wp->w_p_siso = -1; // We won't calculate w_fraction until resizing the window new_wp->w_fraction = 0; -- cgit From 3f32cb88c2cf2bcc1ca95fe24a800abd9d731827 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 23 Aug 2023 17:59:54 +0800 Subject: vim-patch:9.0.1781: Problems when setting bin/paste option Problem: Problems when setting bin/paste option Solution: When setting binary/paste, remember that this also affects depending options, so that :verbose set returns the right location. Mention if depending options for 'binary' or 'paste' have been reset indirectly. Add a test to verify it works. Also noticed as small bug, that the global option value for expandtab was not reset when paste option is set, so fix that while at it. closes: vim/vim#12837 closes: vim/vim#12879 https://github.com/vim/vim/commit/757593c07a4f4ac43eb6c6e52fc299abc9bc08bc Co-authored-by: Christian Brabandt --- src/nvim/option.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 56881cbe58..3648601ab8 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -160,6 +160,14 @@ typedef enum { # include "options.generated.h" #endif +static char *(p_bin_dep_opts[]) = { + "textwidth", "wrapmargin", "modeline", "expandtab", NULL +}; +static char *(p_paste_dep_opts[]) = { + "autoindent", "expandtab", "ruler", "showmatch", "smarttab", + "softtabstop", "textwidth", "wrapmargin", "revins", "varsofttabstop", NULL +}; + void set_init_tablocal(void) { // susy baka: cmdheight calls itself OPT_GLOBAL but is really tablocal! @@ -1681,6 +1689,9 @@ void set_options_bin(int oldval, int newval, int opt_flags) p_et = p_et_nobin; } } + + // Remember where the dependent option were reset + didset_options_sctx(opt_flags, p_bin_dep_opts); } /// Find the parameter represented by the given character (eg ', :, ", or /), @@ -5608,6 +5619,7 @@ static void paste_option_changed(void) p_wm = 0; p_sts = 0; p_ai = 0; + p_et = 0; if (p_vsts) { free_string_option(p_vsts); } @@ -5655,6 +5667,9 @@ static void paste_option_changed(void) } old_p_paste = p_paste; + + // Remember where the dependent options were reset + didset_options_sctx((OPT_LOCAL | OPT_GLOBAL), p_paste_dep_opts); } /// vimrc_found() - Called when a vimrc or "VIMINIT" has been found. @@ -5820,6 +5835,20 @@ int option_set_callback_func(char *optval, Callback *optcb) return OK; } +static void didset_options_sctx(int opt_flags, char **buf) +{ + for (int i = 0;; i++) { + if (buf[i] == NULL) { + break; + } + + int idx = findoption(buf[i]); + if (idx >= 0) { + set_option_sctx_idx(idx, opt_flags, current_sctx); + } + } +} + /// Check if backspacing over something is allowed. /// @param what BS_INDENT, BS_EOL, BS_START, or BS_NOSTOP bool can_bs(int what) -- cgit From a1e5cef557ec7c989b3db29026f2c8123d295a43 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 23 Aug 2023 18:10:30 +0800 Subject: refactor(option.c): move paste_option_changed() into did_set_paste() --- src/nvim/option.c | 252 ++++++++++++++++++++++++++---------------------------- 1 file changed, 123 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/nvim/option.c b/src/nvim/option.c index 3648601ab8..62a93f1293 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2161,8 +2161,129 @@ static const char *did_set_swapfile(optset_T *args) /// Process the updated 'paste' option value. static const char *did_set_paste(optset_T *args FUNC_ATTR_UNUSED) { - // when 'paste' is set or reset also change other options - paste_option_changed(); + static int old_p_paste = false; + static int save_sm = 0; + static int save_sta = 0; + static int save_ru = 0; + static int save_ri = 0; + + if (p_paste) { + // Paste switched from off to on. + // Save the current values, so they can be restored later. + if (!old_p_paste) { + // save options for each buffer + FOR_ALL_BUFFERS(buf) { + buf->b_p_tw_nopaste = buf->b_p_tw; + buf->b_p_wm_nopaste = buf->b_p_wm; + buf->b_p_sts_nopaste = buf->b_p_sts; + buf->b_p_ai_nopaste = buf->b_p_ai; + buf->b_p_et_nopaste = buf->b_p_et; + if (buf->b_p_vsts_nopaste) { + xfree(buf->b_p_vsts_nopaste); + } + buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option + ? xstrdup(buf->b_p_vsts) + : NULL; + } + + // save global options + save_sm = p_sm; + save_sta = p_sta; + save_ru = p_ru; + save_ri = p_ri; + // save global values for local buffer options + p_ai_nopaste = p_ai; + p_et_nopaste = p_et; + p_sts_nopaste = p_sts; + p_tw_nopaste = p_tw; + p_wm_nopaste = p_wm; + if (p_vsts_nopaste) { + xfree(p_vsts_nopaste); + } + p_vsts_nopaste = p_vsts && p_vsts != empty_option ? xstrdup(p_vsts) : NULL; + } + + // Always set the option values, also when 'paste' is set when it is + // already on. + // set options for each buffer + FOR_ALL_BUFFERS(buf) { + buf->b_p_tw = 0; // textwidth is 0 + buf->b_p_wm = 0; // wrapmargin is 0 + buf->b_p_sts = 0; // softtabstop is 0 + buf->b_p_ai = 0; // no auto-indent + buf->b_p_et = 0; // no expandtab + if (buf->b_p_vsts) { + free_string_option(buf->b_p_vsts); + } + buf->b_p_vsts = empty_option; + XFREE_CLEAR(buf->b_p_vsts_array); + } + + // set global options + p_sm = 0; // no showmatch + p_sta = 0; // no smarttab + if (p_ru) { + status_redraw_all(); // redraw to remove the ruler + } + p_ru = 0; // no ruler + p_ri = 0; // no reverse insert + // set global values for local buffer options + p_tw = 0; + p_wm = 0; + p_sts = 0; + p_ai = 0; + p_et = 0; + if (p_vsts) { + free_string_option(p_vsts); + } + p_vsts = empty_option; + } else if (old_p_paste) { + // Paste switched from on to off: Restore saved values. + + // restore options for each buffer + FOR_ALL_BUFFERS(buf) { + buf->b_p_tw = buf->b_p_tw_nopaste; + buf->b_p_wm = buf->b_p_wm_nopaste; + buf->b_p_sts = buf->b_p_sts_nopaste; + buf->b_p_ai = buf->b_p_ai_nopaste; + buf->b_p_et = buf->b_p_et_nopaste; + if (buf->b_p_vsts) { + free_string_option(buf->b_p_vsts); + } + buf->b_p_vsts = buf->b_p_vsts_nopaste ? xstrdup(buf->b_p_vsts_nopaste) : empty_option; + xfree(buf->b_p_vsts_array); + if (buf->b_p_vsts && buf->b_p_vsts != empty_option) { + (void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array); + } else { + buf->b_p_vsts_array = NULL; + } + } + + // restore global options + p_sm = save_sm; + p_sta = save_sta; + if (p_ru != save_ru) { + status_redraw_all(); // redraw to draw the ruler + } + p_ru = save_ru; + p_ri = save_ri; + // set global values for local buffer options + p_ai = p_ai_nopaste; + p_et = p_et_nopaste; + p_sts = p_sts_nopaste; + p_tw = p_tw_nopaste; + p_wm = p_wm_nopaste; + if (p_vsts) { + free_string_option(p_vsts); + } + p_vsts = p_vsts_nopaste ? xstrdup(p_vsts_nopaste) : empty_option; + } + + old_p_paste = p_paste; + + // Remember where the dependent options were reset + didset_options_sctx((OPT_LOCAL | OPT_GLOBAL), p_paste_dep_opts); + return NULL; } @@ -5545,133 +5666,6 @@ bool shortmess(int x) && vim_strchr(SHM_ALL_ABBREVIATIONS, x) != NULL))); } -/// paste_option_changed() - Called after p_paste was set or reset. -static void paste_option_changed(void) -{ - static int old_p_paste = false; - static int save_sm = 0; - static int save_sta = 0; - static int save_ru = 0; - static int save_ri = 0; - - if (p_paste) { - // Paste switched from off to on. - // Save the current values, so they can be restored later. - if (!old_p_paste) { - // save options for each buffer - FOR_ALL_BUFFERS(buf) { - buf->b_p_tw_nopaste = buf->b_p_tw; - buf->b_p_wm_nopaste = buf->b_p_wm; - buf->b_p_sts_nopaste = buf->b_p_sts; - buf->b_p_ai_nopaste = buf->b_p_ai; - buf->b_p_et_nopaste = buf->b_p_et; - if (buf->b_p_vsts_nopaste) { - xfree(buf->b_p_vsts_nopaste); - } - buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option - ? xstrdup(buf->b_p_vsts) - : NULL; - } - - // save global options - save_sm = p_sm; - save_sta = p_sta; - save_ru = p_ru; - save_ri = p_ri; - // save global values for local buffer options - p_ai_nopaste = p_ai; - p_et_nopaste = p_et; - p_sts_nopaste = p_sts; - p_tw_nopaste = p_tw; - p_wm_nopaste = p_wm; - if (p_vsts_nopaste) { - xfree(p_vsts_nopaste); - } - p_vsts_nopaste = p_vsts && p_vsts != empty_option ? xstrdup(p_vsts) : NULL; - } - - // Always set the option values, also when 'paste' is set when it is - // already on. - // set options for each buffer - FOR_ALL_BUFFERS(buf) { - buf->b_p_tw = 0; // textwidth is 0 - buf->b_p_wm = 0; // wrapmargin is 0 - buf->b_p_sts = 0; // softtabstop is 0 - buf->b_p_ai = 0; // no auto-indent - buf->b_p_et = 0; // no expandtab - if (buf->b_p_vsts) { - free_string_option(buf->b_p_vsts); - } - buf->b_p_vsts = empty_option; - XFREE_CLEAR(buf->b_p_vsts_array); - } - - // set global options - p_sm = 0; // no showmatch - p_sta = 0; // no smarttab - if (p_ru) { - status_redraw_all(); // redraw to remove the ruler - } - p_ru = 0; // no ruler - p_ri = 0; // no reverse insert - // set global values for local buffer options - p_tw = 0; - p_wm = 0; - p_sts = 0; - p_ai = 0; - p_et = 0; - if (p_vsts) { - free_string_option(p_vsts); - } - p_vsts = empty_option; - } else if (old_p_paste) { - // Paste switched from on to off: Restore saved values. - - // restore options for each buffer - FOR_ALL_BUFFERS(buf) { - buf->b_p_tw = buf->b_p_tw_nopaste; - buf->b_p_wm = buf->b_p_wm_nopaste; - buf->b_p_sts = buf->b_p_sts_nopaste; - buf->b_p_ai = buf->b_p_ai_nopaste; - buf->b_p_et = buf->b_p_et_nopaste; - if (buf->b_p_vsts) { - free_string_option(buf->b_p_vsts); - } - buf->b_p_vsts = buf->b_p_vsts_nopaste ? xstrdup(buf->b_p_vsts_nopaste) : empty_option; - xfree(buf->b_p_vsts_array); - if (buf->b_p_vsts && buf->b_p_vsts != empty_option) { - (void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array); - } else { - buf->b_p_vsts_array = NULL; - } - } - - // restore global options - p_sm = save_sm; - p_sta = save_sta; - if (p_ru != save_ru) { - status_redraw_all(); // redraw to draw the ruler - } - p_ru = save_ru; - p_ri = save_ri; - // set global values for local buffer options - p_ai = p_ai_nopaste; - p_et = p_et_nopaste; - p_sts = p_sts_nopaste; - p_tw = p_tw_nopaste; - p_wm = p_wm_nopaste; - if (p_vsts) { - free_string_option(p_vsts); - } - p_vsts = p_vsts_nopaste ? xstrdup(p_vsts_nopaste) : empty_option; - } - - old_p_paste = p_paste; - - // Remember where the dependent options were reset - didset_options_sctx((OPT_LOCAL | OPT_GLOBAL), p_paste_dep_opts); -} - /// vimrc_found() - Called when a vimrc or "VIMINIT" has been found. /// /// Set the values for options that didn't get set yet to the defaults. -- cgit