From 5284b23e148063648be0ff46c730ca574e3ca9fa Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Sat, 4 Mar 2023 19:57:32 +0000 Subject: [PATCH] patch 9.0.1379: functions for handling options are not ordered Problem: Functions for handling options are not ordered. Solution: Put functions in alphabetical order. (Yegappan Lakshmanan, closes #12101) --- src/option.c | 1918 ++++++++++++++-------------- src/optiondefs.h | 4 +- src/optionstr.c | 93 +- src/proto/option.pro | 102 +- src/proto/optionstr.pro | 1 + src/testdir/test_backspace_opt.vim | 28 + src/testdir/test_highlight.vim | 7 + src/testdir/test_python3.vim | 7 +- src/version.c | 2 + 9 files changed, 1090 insertions(+), 1072 deletions(-) diff --git a/src/option.c b/src/option.c index 1203180fb..743546798 100644 --- a/src/option.c +++ b/src/option.c @@ -66,7 +66,6 @@ static void check_win_options(win_T *win); static void option_value2string(struct vimoption *, int scope); static void check_winopt(winopt_T *wop); static int wc_use_keyname(char_u *varp, long *wcp); -static void paste_option_changed(void); static void compatible_set(void); /* @@ -3111,160 +3110,164 @@ apply_optionset_autocmd( } #endif +#if defined(FEAT_ARABIC) || defined(PROTO) /* - * Process the updated 'compatible' option value. + * Process the updated 'arabic' option value. */ char * -did_set_compatible(optset_T *args UNUSED) +did_set_arabic(optset_T *args UNUSED) { - compatible_set(); - return NULL; -} + char *errmsg = NULL; -#if defined(FEAT_LANGMAP) || defined(PROTO) -/* - * Process the updated 'langremap' option value. - */ - char * -did_set_langremap(optset_T *args UNUSED) -{ - // 'langremap' -> !'langnoremap' - p_lnr = !p_lrm; - return NULL; -} + if (curwin->w_p_arab) + { + // 'arabic' is set, handle various sub-settings. + if (!p_tbidi) + { + // set rightleft mode + if (!curwin->w_p_rl) + { + curwin->w_p_rl = TRUE; + changed_window_setting(); + } -/* - * Process the updated 'langnoremap' option value. - */ - char * -did_set_langnoremap(optset_T *args UNUSED) -{ - // 'langnoremap' -> !'langremap' - p_lrm = !p_lnr; - return NULL; -} -#endif + // Enable Arabic shaping (major part of what Arabic requires) + if (!p_arshape) + { + p_arshape = TRUE; + redraw_later_clear(); + } + } -#if defined(FEAT_PERSISTENT_UNDO) || defined(PROTO) -/* - * Process the updated 'undofile' option value. - */ - char * -did_set_undofile(optset_T *args) -{ - // Only take action when the option was set. - if (!curbuf->b_p_udf && !p_udf) - return NULL; + // Arabic requires a utf-8 encoding, inform the user if it's not + // set. + if (STRCMP(p_enc, "utf-8") != 0) + { + static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"); - // When reset we do not delete the undo file, the option may be set again - // without making any changes in between. - char_u hash[UNDO_HASH_SIZE]; - buf_T *save_curbuf = curbuf; + msg_source(HL_ATTR(HLF_W)); + msg_attr(_(w_arabic), HL_ATTR(HLF_W)); +#ifdef FEAT_EVAL + set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1); +#endif + } - FOR_ALL_BUFFERS(curbuf) + // set 'delcombine' + p_deco = TRUE; + +# ifdef FEAT_KEYMAP + // Force-set the necessary keymap for arabic + errmsg = set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic", + OPT_LOCAL); +# endif + } + else { - // When 'undofile' is set globally: for every buffer, otherwise - // only for the current buffer: Try to read in the undofile, - // if one exists, the buffer wasn't changed and the buffer was - // loaded - if ((curbuf == save_curbuf - || (args->os_flags & OPT_GLOBAL) - || args->os_flags == 0) - && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL) + // 'arabic' is reset, handle various sub-settings. + if (!p_tbidi) { -#ifdef FEAT_CRYPT - if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD) - continue; -#endif - u_compute_hash(hash); - u_read_undo(NULL, hash, curbuf->b_fname); + // reset rightleft mode + if (curwin->w_p_rl) + { + curwin->w_p_rl = FALSE; + changed_window_setting(); + } + + // 'arabicshape' isn't reset, it is a global option and + // another window may still need it "on". } + + // 'delcombine' isn't reset, it is a global option and another + // window may still want it "on". + +# ifdef FEAT_KEYMAP + // Revert to the default keymap + curbuf->b_p_iminsert = B_IMODE_NONE; + curbuf->b_p_imsearch = B_IMODE_USE_INSERT; +# endif } - curbuf = save_curbuf; - return NULL; + return errmsg; } #endif +#if defined(FEAT_AUTOCHDIR) || defined(PROTO) /* - * Process the updated 'readonly' option value. + * Process the updated 'autochdir' option value. */ char * -did_set_readonly(optset_T *args) +did_set_autochdir(optset_T *args UNUSED) { - // when 'readonly' is reset globally, also reset readonlymode - if (!curbuf->b_p_ro && (args->os_flags & OPT_LOCAL) == 0) - readonlymode = FALSE; - - // when 'readonly' is set may give W10 again - if (curbuf->b_p_ro) - curbuf->b_did_warn = FALSE; - - redraw_titles(); - + // Change directories when the 'acd' option is set now. + DO_AUTOCHDIR; return NULL; } +#endif -#if defined(FEAT_GUI) || defined(PROTO) +#if defined(FEAT_BEVAL_GUI) || defined(PROTO) /* - * Process the updated 'mousehide' option value. + * Process the updated 'ballooneval' option value. */ char * -did_set_mousehide(optset_T *args UNUSED) +did_set_ballooneval(optset_T *args) { - if (!p_mh) - gui_mch_mousehide(FALSE); + if (balloonEvalForTerm) + return NULL; + + if (p_beval && !args->os_oldval.boolean) + gui_mch_enable_beval_area(balloonEval); + else if (!p_beval && args->os_oldval.boolean) + gui_mch_disable_beval_area(balloonEval); + return NULL; } #endif +#if defined(FEAT_BEVAL_TERM) || defined(PROTO) /* - * Process the updated 'modifiable' option value. + * Process the updated 'balloonevalterm' option value. */ char * -did_set_modifiable(optset_T *args UNUSED) +did_set_balloonevalterm(optset_T *args UNUSED) { - // when 'modifiable' is changed, redraw the window title - -# ifdef FEAT_TERMINAL - // Cannot set 'modifiable' when in Terminal mode. - if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf) - && curbuf->b_term != NULL && !term_is_finished(curbuf)))) - { - curbuf->b_p_ma = FALSE; - args->os_doskip = TRUE; - return e_cannot_make_terminal_with_running_job_modifiable; - } -# endif - redraw_titles(); - + mch_bevalterm_changed(); return NULL; } +#endif /* - * Process the updated 'endoffile' or 'endofline' or 'fixendofline' or 'bomb' - * option value. + * Process the updated 'binary' option value. */ char * -did_set_eof_eol_fixeol_bomb(optset_T *args UNUSED) +did_set_binary(optset_T *args) { - // redraw the window title and tab page text + // when 'bin' is set also set some other options + set_options_bin(args->os_oldval.boolean, curbuf->b_p_bin, args->os_flags); redraw_titles(); + return NULL; } +#if defined(FEAT_LINEBREAK) || defined(PROTO) /* - * Process the updated 'binary' option value. + * Called when the 'breakat' option changes value. */ char * -did_set_binary(optset_T *args) +did_set_breakat(optset_T *args UNUSED) { - // when 'bin' is set also set some other options - set_options_bin(args->os_oldval.boolean, curbuf->b_p_bin, args->os_flags); - redraw_titles(); + char_u *p; + int i; + + for (i = 0; i < 256; i++) + breakat_flags[i] = FALSE; + + if (p_breakat != NULL) + for (p = p_breakat; *p; p++) + breakat_flags[*p] = TRUE; return NULL; } +#endif /* * Process the updated 'buflisted' option value. @@ -3280,93 +3283,168 @@ did_set_buflisted(optset_T *args) } /* - * Process the updated 'swapfile' option value. + * Process the new 'cmdheight' option value. */ char * -did_set_swapfile(optset_T *args UNUSED) +did_set_cmdheight(optset_T *args) { - // when 'swf' is set, create swapfile, when reset remove swapfile - if (curbuf->b_p_swf && p_uc) - ml_open_file(curbuf); // create the swap file - else - // no need to reset curbuf->b_may_swap, ml_open_file() will check - // buf->b_p_swf - mf_close_file(curbuf, TRUE); // remove the swap file - return NULL; + long old_value = args->os_oldval.number; + char *errmsg = NULL; + + // if p_ch changed value, change the command line height + if (p_ch < 1) + { + errmsg = e_argument_must_be_positive; + p_ch = 1; + } + if (p_ch > Rows - min_rows() + 1) + p_ch = Rows - min_rows() + 1; + + // Only compute the new window layout when startup has been + // completed. Otherwise the frame sizes may be wrong. + if ((p_ch != old_value + || tabline_height() + topframe->fr_height != Rows - p_ch) + && full_screen +#ifdef FEAT_GUI + && !gui.starting +#endif + ) + command_height(); + + return errmsg; } /* - * Process the updated 'terse' option value. + * Process the updated 'compatible' option value. */ char * -did_set_terse(optset_T *args UNUSED) +did_set_compatible(optset_T *args UNUSED) { - char_u *p; + compatible_set(); + return NULL; +} - // when 'terse' is set change 'shortmess' - p = vim_strchr(p_shm, SHM_SEARCH); +#if defined(FEAT_CONCEAL) || defined(PROTO) +/* + * Process the new 'conceallevel' option value. + */ + char * +did_set_conceallevel(optset_T *args UNUSED) +{ + char *errmsg = NULL; - // insert 's' in p_shm - if (p_terse && p == NULL) + if (curwin->w_p_cole < 0) { - STRCPY(IObuff, p_shm); - STRCAT(IObuff, "s"); - set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0); + errmsg = e_argument_must_be_positive; + curwin->w_p_cole = 0; } - // remove 's' from p_shm - else if (!p_terse && p != NULL) - STRMOVE(p, p + 1); + else if (curwin->w_p_cole > 3) + { + errmsg = e_invalid_argument; + curwin->w_p_cole = 3; + } + + return errmsg; +} +#endif + +#if defined(FEAT_DIFF) || defined(PROTO) +/* + * Process the updated 'diff' option value. + */ + char * +did_set_diff(optset_T *args UNUSED) +{ + // May add or remove the buffer from the list of diff buffers. + diff_buf_adjust(curwin); +# ifdef FEAT_FOLDING + if (foldmethodIsDiff(curwin)) + foldUpdateAll(curwin); +# endif return NULL; } +#endif /* - * Process the updated 'paste' option value. + * Process the updated 'endoffile' or 'endofline' or 'fixendofline' or 'bomb' + * option value. */ char * -did_set_paste(optset_T *args UNUSED) +did_set_eof_eol_fixeol_bomb(optset_T *args UNUSED) { - // when 'paste' is set or reset also change other options - paste_option_changed(); + // redraw the window title and tab page text + redraw_titles(); return NULL; } /* - * Process the updated 'insertmode' option value. + * Process the updated 'equalalways' option value. */ char * -did_set_insertmode(optset_T *args) +did_set_equalalways(optset_T *args) { - // when 'insertmode' is set from an autocommand need to do work here - if (p_im) + if (p_ea && !args->os_oldval.boolean) + win_equal(curwin, FALSE, 0); + + return NULL; +} + +#if defined(FEAT_FOLDING) || defined(PROTO) +/* + * Process the new 'foldcolumn' option value. + */ + char * +did_set_foldcolumn(optset_T *args UNUSED) +{ + char *errmsg = NULL; + + if (curwin->w_p_fdc < 0) { - if ((State & MODE_INSERT) == 0) - need_start_insertmode = TRUE; - stop_insert_mode = FALSE; + errmsg = e_argument_must_be_positive; + curwin->w_p_fdc = 0; } - // only reset if it was set previously - else if (args->os_oldval.boolean) + else if (curwin->w_p_fdc > 12) { - need_start_insertmode = FALSE; - stop_insert_mode = TRUE; - if (restart_edit != 0 && mode_displayed) - clear_cmdline = TRUE; // remove "(insert)" - restart_edit = 0; + errmsg = e_invalid_argument; + curwin->w_p_fdc = 12; } + return errmsg; +} + +/* + * Process the new 'foldlevel' option value. + */ + char * +did_set_foldlevel(optset_T *args UNUSED) +{ + if (curwin->w_p_fdl < 0) + curwin->w_p_fdl = 0; + newFoldLevel(); return NULL; } /* - * Process the updated 'ignorecase' option value. + * Process the new 'foldminlines' option value. */ char * -did_set_ignorecase(optset_T *args UNUSED) +did_set_foldminlines(optset_T *args UNUSED) { - // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw - if (p_hls) - redraw_all_later(UPD_SOME_VALID); + foldUpdateAll(curwin); + return NULL; +} + +/* + * Process the new 'foldnestmax' option value. + */ + char * +did_set_foldnestmax(optset_T *args UNUSED) +{ + if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin)) + foldUpdateAll(curwin); return NULL; } +#endif #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) /* @@ -3382,806 +3460,912 @@ did_set_hlsearch(optset_T *args UNUSED) #endif /* - * Process the updated 'scrollbind' option value. + * Process the updated 'ignorecase' option value. */ char * -did_set_scrollbind(optset_T *args UNUSED) +did_set_ignorecase(optset_T *args UNUSED) { - // when 'scrollbind' is set: snapshot the current position to avoid a jump - // at the end of normal_cmd() - if (!curwin->w_p_scb) - return NULL; - - do_check_scrollbind(FALSE); - curwin->w_scbind_pos = curwin->w_topline; + // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw + if (p_hls) + redraw_all_later(UPD_SOME_VALID); return NULL; } -#ifdef FEAT_QUICKFIX +#if defined(HAVE_INPUT_METHOD) || defined(PROTO) /* - * Process the updated 'previewwindow' option value. + * Process the updated 'imdisable' option value. */ char * -did_set_previewwindow(optset_T *args) +did_set_imdisable(optset_T *args UNUSED) { - if (!curwin->w_p_pvw) - return NULL; - - // There can be only one window with 'previewwindow' set. - win_T *win; - - FOR_ALL_WINDOWS(win) - if (win->w_p_pvw && win != curwin) - { - curwin->w_p_pvw = FALSE; - args->os_doskip = TRUE; - return e_preview_window_already_exists; - } - + // Only de-activate it here, it will be enabled when changing mode. + if (p_imdisable) + im_set_active(FALSE); + else if (State & MODE_INSERT) + // When the option is set from an autocommand, it may need to take + // effect right away. + im_set_active(curbuf->b_p_iminsert == B_IMODE_IM); return NULL; } #endif /* - * Process the updated 'smoothscroll' option value. + * Process the new 'iminsert' option value. */ char * -did_set_smoothscroll(optset_T *args UNUSED) +did_set_iminsert(optset_T *args UNUSED) { - if (curwin->w_p_sms) - return NULL; + char *errmsg = NULL; - curwin->w_skipcol = 0; - changed_line_abv_curs(); - return NULL; + if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST) + { + errmsg = e_invalid_argument; + curbuf->b_p_iminsert = B_IMODE_NONE; + } + p_iminsert = curbuf->b_p_iminsert; + if (termcap_active) // don't do this in the alternate screen + showmode(); +#if defined(FEAT_KEYMAP) + // Show/unshow value of 'keymap' in status lines. + status_redraw_curbuf(); +#endif + + return errmsg; } /* - * Process the updated 'textmode' option value. + * Process the new 'imsearch' option value. */ char * -did_set_textmode(optset_T *args) +did_set_imsearch(optset_T *args UNUSED) { - // when 'textmode' is set or reset also change 'fileformat' - set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, args->os_flags); + char *errmsg = NULL; - return NULL; + if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST) + { + errmsg = e_invalid_argument; + curbuf->b_p_imsearch = B_IMODE_NONE; + } + p_imsearch = curbuf->b_p_imsearch; + + return errmsg; } +#if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) || defined(PROTO) /* - * Process the updated 'textauto' option value. + * Process the new 'imstyle' option value. */ char * -did_set_textauto(optset_T *args) +did_set_imstyle(optset_T *args UNUSED) { - // when 'textauto' is set or reset also change 'fileformats' - set_string_option_direct((char_u *)"ffs", -1, - p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"", - OPT_FREE | args->os_flags, 0); + char *errmsg = NULL; - return NULL; + if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT) + errmsg = e_invalid_argument; + + return errmsg; } +#endif /* - * Process the updated 'lisp' option value. + * Process the updated 'insertmode' option value. */ char * -did_set_lisp(optset_T *args UNUSED) +did_set_insertmode(optset_T *args) { - // When 'lisp' option changes include/exclude '-' in keyword characters. - (void)buf_init_chartab(curbuf, FALSE); // ignore errors + // when 'insertmode' is set from an autocommand need to do work here + if (p_im) + { + if ((State & MODE_INSERT) == 0) + need_start_insertmode = TRUE; + stop_insert_mode = FALSE; + } + // only reset if it was set previously + else if (args->os_oldval.boolean) + { + need_start_insertmode = FALSE; + stop_insert_mode = TRUE; + if (restart_edit != 0 && mode_displayed) + clear_cmdline = TRUE; // remove "(insert)" + restart_edit = 0; + } + return NULL; } +#if defined(FEAT_LANGMAP) || defined(PROTO) /* - * Process the updated 'title' or the 'icon' option value. + * Process the updated 'langnoremap' option value. */ char * -did_set_title_icon(optset_T *args UNUSED) +did_set_langnoremap(optset_T *args UNUSED) { - // when 'title' changed, may need to change the title; same for 'icon' - did_set_title(); + // 'langnoremap' -> !'langremap' + p_lrm = !p_lnr; return NULL; } /* - * Process the updated 'modified' option value. + * Process the updated 'langremap' option value. */ char * -did_set_modified(optset_T *args) +did_set_langremap(optset_T *args UNUSED) { - if (!args->os_newval.boolean) - save_file_ff(curbuf); // Buffer is unchanged - redraw_titles(); - modified_was_set = args->os_newval.boolean; + // 'langremap' -> !'langnoremap' + p_lnr = !p_lrm; return NULL; } +#endif -#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) /* - * Process the updated 'shellslash' option value. + * Process the new 'laststatus' option value. */ char * -did_set_shellslash(optset_T *args UNUSED) +did_set_laststatus(optset_T *args UNUSED) { - if (p_ssl) - { - psepc = '/'; - psepcN = '\\'; - pseps[0] = '/'; - } - else - { - psepc = '\\'; - psepcN = '/'; - pseps[0] = '\\'; - } - - // need to adjust the file name arguments and buffer names. - buflist_slash_adjust(); - alist_slash_adjust(); -# ifdef FEAT_EVAL - scriptnames_slash_adjust(); -# endif + last_status(FALSE); // (re)set last window status line return NULL; } -#endif +#if defined(FEAT_GUI) || defined(PROTO) /* - * Process the updated 'wrap' option value. + * Process the new 'linespace' option value. */ char * -did_set_wrap(optset_T *args UNUSED) +did_set_linespace(optset_T *args UNUSED) { - // If 'wrap' is set, set w_leftcol to zero. - if (curwin->w_p_wrap) - curwin->w_leftcol = 0; + // Recompute gui.char_height and resize the Vim window to keep the + // same number of lines. + if (gui.in_use && gui_mch_adjust_charheight() == OK) + gui_set_shellsize(FALSE, FALSE, RESIZE_VERT); return NULL; } +#endif /* - * Process the updated 'equalalways' option value. + * Process the updated 'lisp' option value. */ char * -did_set_equalalways(optset_T *args) +did_set_lisp(optset_T *args UNUSED) { - if (p_ea && !args->os_oldval.boolean) - win_equal(curwin, FALSE, 0); - + // When 'lisp' option changes include/exclude '-' in keyword characters. + (void)buf_init_chartab(curbuf, FALSE); // ignore errors return NULL; } /* - * Process the updated 'weirdinvert' option value. + * Process the new 'maxcombine' option value. */ char * -did_set_weirdinvert(optset_T *args) +did_set_maxcombine(optset_T *args UNUSED) { - // When 'weirdinvert' changed, set/reset 't_xs'. - // Then set 'weirdinvert' according to value of 't_xs'. - if (p_wiv && !args->os_oldval.boolean) - T_XS = (char_u *)"y"; - else if (!p_wiv && args->os_oldval.boolean) - T_XS = empty_option; - p_wiv = (*T_XS != NUL); - + if (p_mco > MAX_MCO) + p_mco = MAX_MCO; + else if (p_mco < 0) + p_mco = 0; + screenclear(); // will re-allocate the screen return NULL; } -#if defined(FEAT_BEVAL_GUI) || defined(PROTO) /* - * Process the updated 'ballooneval' option value. + * Process the updated 'modifiable' option value. */ char * -did_set_ballooneval(optset_T *args) +did_set_modifiable(optset_T *args UNUSED) { - if (balloonEvalForTerm) - return NULL; + // when 'modifiable' is changed, redraw the window title - if (p_beval && !args->os_oldval.boolean) - gui_mch_enable_beval_area(balloonEval); - else if (!p_beval && args->os_oldval.boolean) - gui_mch_disable_beval_area(balloonEval); +# ifdef FEAT_TERMINAL + // Cannot set 'modifiable' when in Terminal mode. + if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf) + && curbuf->b_term != NULL && !term_is_finished(curbuf)))) + { + curbuf->b_p_ma = FALSE; + args->os_doskip = TRUE; + return e_cannot_make_terminal_with_running_job_modifiable; + } +# endif + redraw_titles(); return NULL; } -#endif -#if defined(FEAT_BEVAL_TERM) || defined(PROTO) /* - * Process the updated 'balloonevalterm' option value. + * Process the updated 'modified' option value. */ char * -did_set_balloonevalterm(optset_T *args UNUSED) +did_set_modified(optset_T *args) { - mch_bevalterm_changed(); + if (!args->os_newval.boolean) + save_file_ff(curbuf); // Buffer is unchanged + redraw_titles(); + modified_was_set = args->os_newval.boolean; return NULL; } -#endif -#if defined(FEAT_AUTOCHDIR) || defined(PROTO) +#if defined(FEAT_GUI) || defined(PROTO) /* - * Process the updated 'autochdir' option value. + * Process the updated 'mousehide' option value. */ char * -did_set_autochdir(optset_T *args UNUSED) +did_set_mousehide(optset_T *args UNUSED) { - // Change directories when the 'acd' option is set now. - DO_AUTOCHDIR; + if (!p_mh) + gui_mch_mousehide(FALSE); return NULL; } #endif -#if defined(FEAT_DIFF) || defined(PROTO) /* - * Process the updated 'diff' option value. + * Process the updated 'number' or 'relativenumber' option value. */ char * -did_set_diff(optset_T *args UNUSED) +did_set_number_relativenumber(optset_T *args UNUSED) { - // May add or remove the buffer from the list of diff buffers. - diff_buf_adjust(curwin); -# ifdef FEAT_FOLDING - if (foldmethodIsDiff(curwin)) - foldUpdateAll(curwin); -# endif - return NULL; -} +#if (defined(FEAT_SIGNS) && defined(FEAT_GUI)) || defined(PROTO) + if (gui.in_use + && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u') + && curbuf->b_signlist != NULL) + { + // If the 'number' or 'relativenumber' options are modified and + // 'signcolumn' is set to 'number', then clear the screen for a full + // refresh. Otherwise the sign icons are not displayed properly in the + // number column. If the 'number' option is set and only the + // 'relativenumber' option is toggled, then don't refresh the screen + // (optimization). + if (!(curwin->w_p_nu && ((int *)args->os_varp == &curwin->w_p_rnu))) + redraw_all_later(UPD_CLEAR); + } #endif - -#if defined(HAVE_INPUT_METHOD) || defined(PROTO) -/* - * Process the updated 'imdisable' option value. - */ - char * -did_set_imdisable(optset_T *args UNUSED) -{ - // Only de-activate it here, it will be enabled when changing mode. - if (p_imdisable) - im_set_active(FALSE); - else if (State & MODE_INSERT) - // When the option is set from an autocommand, it may need to take - // effect right away. - im_set_active(curbuf->b_p_iminsert == B_IMODE_IM); return NULL; } -#endif -#if defined(FEAT_SPELL) || defined(PROTO) +#if defined(FEAT_LINEBREAK) || defined(PROTO) /* - * Process the updated 'spell' option value. + * Process the new 'numberwidth' option value. */ char * -did_set_spell(optset_T *args UNUSED) +did_set_numberwidth(optset_T *args UNUSED) { - if (curwin->w_p_spell) - return parse_spelllang(curwin); + char *errmsg = NULL; - return NULL; + // 'numberwidth' must be positive + if (curwin->w_p_nuw < 1) + { + errmsg = e_argument_must_be_positive; + curwin->w_p_nuw = 1; + } + if (curwin->w_p_nuw > 20) + { + errmsg = e_invalid_argument; + curwin->w_p_nuw = 20; + } + curwin->w_nrwidth_line_count = 0; // trigger a redraw + + return errmsg; } #endif -#if defined(FEAT_ARABIC) || defined(PROTO) /* - * Process the updated 'arabic' option value. + * Process the updated 'paste' option value. Called after p_paste was set or + * reset. When 'paste' is set or reset also change other options. */ char * -did_set_arabic(optset_T *args UNUSED) +did_set_paste(optset_T *args UNUSED) { - char *errmsg = NULL; + static int old_p_paste = FALSE; + static int save_sm = 0; + static int save_sta = 0; + static int save_ru = 0; +#ifdef FEAT_RIGHTLEFT + static int save_ri = 0; + static int save_hkmap = 0; +#endif + buf_T *buf; - if (curwin->w_p_arab) + if (p_paste) { - // 'arabic' is set, handle various sub-settings. - if (!p_tbidi) + // Paste switched from off to on. + // Save the current values, so they can be restored later. + if (!old_p_paste) { - // set rightleft mode - if (!curwin->w_p_rl) + // save options for each buffer + FOR_ALL_BUFFERS(buf) { - curwin->w_p_rl = TRUE; - changed_window_setting(); + 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; +#ifdef FEAT_VARTABS + if (buf->b_p_vsts_nopaste) + vim_free(buf->b_p_vsts_nopaste); + buf->b_p_vsts_nopaste = + buf->b_p_vsts && buf->b_p_vsts != empty_option + ? vim_strsave(buf->b_p_vsts) : NULL; +#endif } - // Enable Arabic shaping (major part of what Arabic requires) - if (!p_arshape) - { - p_arshape = TRUE; - redraw_later_clear(); - } + // save global options + save_sm = p_sm; + save_sta = p_sta; + save_ru = p_ru; +#ifdef FEAT_RIGHTLEFT + save_ri = p_ri; + save_hkmap = p_hkmap; +#endif + // 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; +#ifdef FEAT_VARTABS + if (p_vsts_nopaste) + vim_free(p_vsts_nopaste); + p_vsts_nopaste = p_vsts && p_vsts != empty_option + ? vim_strsave(p_vsts) : NULL; +#endif } - // Arabic requires a utf-8 encoding, inform the user if it's not - // set. - if (STRCMP(p_enc, "utf-8") != 0) + // Always set the option values, also when 'paste' is set when it is + // already on. Set options for each buffer. + FOR_ALL_BUFFERS(buf) { - static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"); + 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 +#ifdef FEAT_VARTABS + if (buf->b_p_vsts) + free_string_option(buf->b_p_vsts); + buf->b_p_vsts = empty_option; + VIM_CLEAR(buf->b_p_vsts_array); +#endif + } - msg_source(HL_ATTR(HLF_W)); - msg_attr(_(w_arabic), HL_ATTR(HLF_W)); -#ifdef FEAT_EVAL - set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1); + // 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 +#ifdef FEAT_RIGHTLEFT + p_ri = 0; // no reverse insert + p_hkmap = 0; // no Hebrew keyboard +#endif + // set global values for local buffer options + p_tw = 0; + p_wm = 0; + p_sts = 0; + p_ai = 0; +#ifdef FEAT_VARTABS + if (p_vsts) + free_string_option(p_vsts); + p_vsts = empty_option; #endif - } - - // set 'delcombine' - p_deco = TRUE; - -# ifdef FEAT_KEYMAP - // Force-set the necessary keymap for arabic - errmsg = set_option_value((char_u *)"keymap", - 0L, (char_u *)"arabic", OPT_LOCAL); -# endif } - else + + // Paste switched from on to off: Restore saved values. + else if (old_p_paste) { - // 'arabic' is reset, handle various sub-settings. - if (!p_tbidi) + // restore options for each buffer + FOR_ALL_BUFFERS(buf) { - // reset rightleft mode - if (curwin->w_p_rl) - { - curwin->w_p_rl = FALSE; - changed_window_setting(); - } - - // 'arabicshape' isn't reset, it is a global option and - // another window may still need it "on". + 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; +#ifdef FEAT_VARTABS + if (buf->b_p_vsts) + free_string_option(buf->b_p_vsts); + buf->b_p_vsts = buf->b_p_vsts_nopaste + ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option; + vim_free(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; +#endif } - // 'delcombine' isn't reset, it is a global option and another - // window may still want it "on". - -# ifdef FEAT_KEYMAP - // Revert to the default keymap - curbuf->b_p_iminsert = B_IMODE_NONE; - curbuf->b_p_imsearch = B_IMODE_USE_INSERT; -# endif + // 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; +#ifdef FEAT_RIGHTLEFT + p_ri = save_ri; + p_hkmap = save_hkmap; +#endif + // 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; +#ifdef FEAT_VARTABS + if (p_vsts) + free_string_option(p_vsts); + p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option; +#endif } - return errmsg; + old_p_paste = p_paste; + + return NULL; } -#endif + +#ifdef FEAT_QUICKFIX /* - * Process the updated 'number' or 'relativenumber' option value. + * Process the updated 'previewwindow' option value. */ char * -did_set_number_relativenumber(optset_T *args UNUSED) +did_set_previewwindow(optset_T *args) { -#if (defined(FEAT_SIGNS) && defined(FEAT_GUI)) || defined(PROTO) - if (gui.in_use - && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u') - && curbuf->b_signlist != NULL) - { - // If the 'number' or 'relativenumber' options are modified and - // 'signcolumn' is set to 'number', then clear the screen for a full - // refresh. Otherwise the sign icons are not displayed properly in the - // number column. If the 'number' option is set and only the - // 'relativenumber' option is toggled, then don't refresh the screen - // (optimization). - if (!(curwin->w_p_nu && ((int *)args->os_varp == &curwin->w_p_rnu))) - redraw_all_later(UPD_CLEAR); - } -#endif - return NULL; -} + if (!curwin->w_p_pvw) + return NULL; -#ifdef FEAT_TERMGUICOLORS - char * -did_set_termguicolors(optset_T *args UNUSED) -{ -# ifdef FEAT_VTP - // Do not turn on 'tgc' when 24-bit colors are not supported. - if ( -# ifdef VIMDLL - !gui.in_use && !gui.starting && -# endif - !has_vtp_working()) - { - p_tgc = 0; - args->os_doskip = TRUE; - return e_24_bit_colors_are_not_supported_on_this_environment; - } - if (is_term_win32()) - swap_tcap(); -# endif -# ifdef FEAT_GUI - if (!gui.in_use && !gui.starting) -# endif - highlight_gui_started(); -# ifdef FEAT_VTP - // reset t_Co - if (is_term_win32()) - { - control_console_color_rgb(); - set_termname(T_NAME); - init_highlight(TRUE, FALSE); - } -# endif -# ifdef FEAT_TERMINAL - term_update_colors_all(); - term_update_palette_all(); - term_update_wincolor_all(); -# endif + // There can be only one window with 'previewwindow' set. + win_T *win; + + FOR_ALL_WINDOWS(win) + if (win->w_p_pvw && win != curwin) + { + curwin->w_p_pvw = FALSE; + args->os_doskip = TRUE; + return e_preview_window_already_exists; + } return NULL; } #endif +#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO) /* - * Set the value of a boolean option, and take care of side effects. - * Returns NULL for success, or an error message for an error. + * Process the new 'pyxversion' option value. */ - static char * -set_bool_option( - int opt_idx, // index in options[] table - char_u *varp, // pointer to the option variable - int value, // new value - int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL + char * +did_set_pyxversion(optset_T *args UNUSED) { - int old_value = *(int *)varp; -#if defined(FEAT_EVAL) - int old_global_value = 0; -#endif - char *errmsg = NULL; - - // Disallow changing some options from secure mode - if ((secure -#ifdef HAVE_SANDBOX - || sandbox != 0 -#endif - ) && (options[opt_idx].flags & P_SECURE)) - return e_not_allowed_here; - -#if defined(FEAT_EVAL) - // Save the global value before changing anything. This is needed as for - // a global-only option setting the "local value" in fact sets the global - // value (since there is only one value). - if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) - old_global_value = *(int *)get_varp_scope(&(options[opt_idx]), - OPT_GLOBAL); -#endif + char *errmsg = NULL; - *(int *)varp = value; // set the new value -#ifdef FEAT_EVAL - // Remember where the option was set. - set_option_sctx_idx(opt_idx, opt_flags, current_sctx); -#endif + if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3) + errmsg = e_invalid_argument; -#ifdef FEAT_GUI - need_mouse_correct = TRUE; + return errmsg; +} #endif - // May set global value for local option. - if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) - *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value; - - // Handle side effects of changing a bool option. - if (options[opt_idx].opt_did_set_cb != NULL) - { - optset_T args; - - args.os_varp = varp; - args.os_flags = opt_flags; - args.os_oldval.boolean = old_value; - args.os_newval.boolean = value; - args.os_doskip = FALSE; - args.os_errbuf = NULL; - errmsg = options[opt_idx].opt_did_set_cb(&args); - if (args.os_doskip) - return errmsg; - } - - // after handling side effects, call autocommand - - options[opt_idx].flags |= P_WAS_SET; - -#if defined(FEAT_EVAL) - apply_optionset_autocmd(opt_idx, opt_flags, - (long)(old_value ? TRUE : FALSE), - (long)(old_global_value ? TRUE : FALSE), - (long)(value ? TRUE : FALSE), NULL); -#endif +/* + * Process the updated 'readonly' option value. + */ + char * +did_set_readonly(optset_T *args) +{ + // when 'readonly' is reset globally, also reset readonlymode + if (!curbuf->b_p_ro && (args->os_flags & OPT_LOCAL) == 0) + readonlymode = FALSE; - comp_col(); // in case 'ruler' or 'showcmd' changed - if (curwin->w_curswant != MAXCOL - && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) - curwin->w_set_curswant = TRUE; + // when 'readonly' is set may give W10 again + if (curbuf->b_p_ro) + curbuf->b_did_warn = FALSE; - if ((opt_flags & OPT_NO_REDRAW) == 0) - check_redraw(options[opt_idx].flags); + redraw_titles(); - return errmsg; + return NULL; } /* - * Process the new 'winheight' or the 'helpheight' option value. + * Process the updated 'scrollbind' option value. */ char * -did_set_winheight_helpheight(optset_T *args) +did_set_scrollbind(optset_T *args UNUSED) { - long *pp = (long *)args->os_varp; - char *errmsg = NULL; - - if (p_wh < 1) - { - errmsg = e_argument_must_be_positive; - p_wh = 1; - } - if (p_wmh > p_wh) - { - errmsg = e_winheight_cannot_be_smaller_than_winminheight; - p_wh = p_wmh; - } - if (p_hh < 0) - { - errmsg = e_argument_must_be_positive; - p_hh = 0; - } - - // Change window height NOW - if (!ONE_WINDOW) - { - if (pp == &p_wh && curwin->w_height < p_wh) - win_setheight((int)p_wh); - if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh) - win_setheight((int)p_hh); - } + // when 'scrollbind' is set: snapshot the current position to avoid a jump + // at the end of normal_cmd() + if (!curwin->w_p_scb) + return NULL; - return errmsg; + do_check_scrollbind(FALSE); + curwin->w_scbind_pos = curwin->w_topline; + return NULL; } +#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO) /* - * Process the new 'winminheight' option value. + * Process the updated 'shellslash' option value. */ char * -did_set_winminheight(optset_T *args UNUSED) +did_set_shellslash(optset_T *args UNUSED) { - char *errmsg = NULL; - - if (p_wmh < 0) + if (p_ssl) { - errmsg = e_argument_must_be_positive; - p_wmh = 0; + psepc = '/'; + psepcN = '\\'; + pseps[0] = '/'; } - if (p_wmh > p_wh) + else { - errmsg = e_winheight_cannot_be_smaller_than_winminheight; - p_wmh = p_wh; + psepc = '\\'; + psepcN = '/'; + pseps[0] = '\\'; } - win_setminheight(); - return errmsg; + // need to adjust the file name arguments and buffer names. + buflist_slash_adjust(); + alist_slash_adjust(); +# ifdef FEAT_EVAL + scriptnames_slash_adjust(); +# endif + return NULL; } +#endif /* - * Process the new 'winwidth' option value. + * Process the new 'shiftwidth' or the 'tabstop' option value. */ char * -did_set_winwidth(optset_T *args UNUSED) +did_set_shiftwidth_tabstop(optset_T *args) { - char *errmsg = NULL; + long *pp = (long *)args->os_varp; + char *errmsg = NULL; - if (p_wiw < 1) + if (curbuf->b_p_sw < 0) { errmsg = e_argument_must_be_positive; - p_wiw = 1; - } - if (p_wmw > p_wiw) - { - errmsg = e_winwidth_cannot_be_smaller_than_winminwidth; - p_wiw = p_wmw; +#ifdef FEAT_VARTABS + // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use. + curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0 + ? tabstop_first(curbuf->b_p_vts_array) + : curbuf->b_p_ts; +#else + curbuf->b_p_sw = curbuf->b_p_ts; +#endif } - // Change window width NOW - if (!ONE_WINDOW && curwin->w_width < p_wiw) - win_setwidth((int)p_wiw); +#ifdef FEAT_FOLDING + if (foldmethodIsIndent(curwin)) + foldUpdateAll(curwin); +#endif + // When 'shiftwidth' changes, or it's zero and 'tabstop' changes: + // parse 'cinoptions'. + if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0) + parse_cino(curbuf); return errmsg; } /* - * Process the new 'winminwidth' option value. + * Process the new 'showtabline' option value. */ char * -did_set_winminwidth(optset_T *args UNUSED) +did_set_showtabline(optset_T *args UNUSED) { - char *errmsg = NULL; - - if (p_wmw < 0) - { - errmsg = e_argument_must_be_positive; - p_wmw = 0; - } - if (p_wmw > p_wiw) - { - errmsg = e_winwidth_cannot_be_smaller_than_winminwidth; - p_wmw = p_wiw; - } - win_setminwidth(); - - return errmsg; + shell_new_rows(); // recompute window positions and heights + return NULL; } /* - * Process the new 'laststatus' option value. + * Process the updated 'smoothscroll' option value. */ char * -did_set_laststatus(optset_T *args UNUSED) +did_set_smoothscroll(optset_T *args UNUSED) { - last_status(FALSE); // (re)set last window status line + if (curwin->w_p_sms) + return NULL; + + curwin->w_skipcol = 0; + changed_line_abv_curs(); return NULL; } +#if defined(FEAT_SPELL) || defined(PROTO) /* - * Process the new 'showtabline' option value. + * Process the updated 'spell' option value. */ char * -did_set_showtabline(optset_T *args UNUSED) +did_set_spell(optset_T *args UNUSED) { - shell_new_rows(); // recompute window positions and heights + if (curwin->w_p_spell) + return parse_spelllang(curwin); + return NULL; } +#endif -#if defined(FEAT_GUI) || defined(PROTO) /* - * Process the new 'linespace' option value. + * Process the updated 'swapfile' option value. */ char * -did_set_linespace(optset_T *args UNUSED) +did_set_swapfile(optset_T *args UNUSED) { - // Recompute gui.char_height and resize the Vim window to keep the - // same number of lines. - if (gui.in_use && gui_mch_adjust_charheight() == OK) - gui_set_shellsize(FALSE, FALSE, RESIZE_VERT); + // when 'swf' is set, create swapfile, when reset remove swapfile + if (curbuf->b_p_swf && p_uc) + ml_open_file(curbuf); // create the swap file + else + // no need to reset curbuf->b_may_swap, ml_open_file() will check + // buf->b_p_swf + mf_close_file(curbuf, TRUE); // remove the swap file + return NULL; +} + +#if defined(FEAT_TERMGUICOLORS) || defined(PROTO) + char * +did_set_termguicolors(optset_T *args UNUSED) +{ +# ifdef FEAT_VTP + // Do not turn on 'tgc' when 24-bit colors are not supported. + if ( +# ifdef VIMDLL + !gui.in_use && !gui.starting && +# endif + !has_vtp_working()) + { + p_tgc = 0; + args->os_doskip = TRUE; + return e_24_bit_colors_are_not_supported_on_this_environment; + } + if (is_term_win32()) + swap_tcap(); +# endif +# ifdef FEAT_GUI + if (!gui.in_use && !gui.starting) +# endif + highlight_gui_started(); +# ifdef FEAT_VTP + // reset t_Co + if (is_term_win32()) + { + control_console_color_rgb(); + set_termname(T_NAME); + init_highlight(TRUE, FALSE); + } +# endif +# ifdef FEAT_TERMINAL + term_update_colors_all(); + term_update_palette_all(); + term_update_wincolor_all(); +# endif + return NULL; } #endif -#if defined(FEAT_FOLDING) || defined(PROTO) /* - * Process the new 'foldlevel' option value. + * Process the updated 'terse' option value. */ char * -did_set_foldlevel(optset_T *args UNUSED) +did_set_terse(optset_T *args UNUSED) { - if (curwin->w_p_fdl < 0) - curwin->w_p_fdl = 0; - newFoldLevel(); + char_u *p; + + // when 'terse' is set change 'shortmess' + p = vim_strchr(p_shm, SHM_SEARCH); + + // insert 's' in p_shm + if (p_terse && p == NULL) + { + STRCPY(IObuff, p_shm); + STRCAT(IObuff, "s"); + set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0); + } + // remove 's' from p_shm + else if (!p_terse && p != NULL) + STRMOVE(p, p + 1); return NULL; } /* - * Process the new 'foldminlines' option value. + * Process the updated 'textauto' option value. */ char * -did_set_foldminlines(optset_T *args UNUSED) +did_set_textauto(optset_T *args) { - foldUpdateAll(curwin); + // when 'textauto' is set or reset also change 'fileformats' + set_string_option_direct((char_u *)"ffs", -1, + p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"", + OPT_FREE | args->os_flags, 0); + return NULL; } /* - * Process the new 'foldnestmax' option value. + * Process the updated 'textmode' option value. */ char * -did_set_foldnestmax(optset_T *args UNUSED) +did_set_textmode(optset_T *args) { - if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin)) - foldUpdateAll(curwin); + // when 'textmode' is set or reset also change 'fileformat' + set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, args->os_flags); + return NULL; } /* - * Process the new 'foldcolumn' option value. + * Process the new 'textwidth' option value. */ char * -did_set_foldcolumn(optset_T *args UNUSED) +did_set_textwidth(optset_T *args UNUSED) { char *errmsg = NULL; - if (curwin->w_p_fdc < 0) + if (curbuf->b_p_tw < 0) { errmsg = e_argument_must_be_positive; - curwin->w_p_fdc = 0; + curbuf->b_p_tw = 0; } - else if (curwin->w_p_fdc > 12) +#ifdef FEAT_SYN_HL { - errmsg = e_invalid_argument; - curwin->w_p_fdc = 12; + win_T *wp; + tabpage_T *tp; + + FOR_ALL_TAB_WINDOWS(tp, wp) + check_colorcolumn(wp); } +#endif return errmsg; } -#endif /* - * Process the new 'shiftwidth' or the 'tabstop' option value. + * Process the updated 'title' or the 'icon' option value. */ char * -did_set_shiftwidth_tabstop(optset_T *args) +did_set_title_icon(optset_T *args UNUSED) { - long *pp = (long *)args->os_varp; - char *errmsg = NULL; + // when 'title' changed, may need to change the title; same for 'icon' + did_set_title(); + return NULL; +} - if (curbuf->b_p_sw < 0) +/* + * Process the new 'titlelen' option value. + */ + char * +did_set_titlelen(optset_T *args) +{ + long old_value = args->os_oldval.number; + char *errmsg = NULL; + + // if 'titlelen' has changed, redraw the title + if (p_titlelen < 0) { errmsg = e_argument_must_be_positive; -#ifdef FEAT_VARTABS - // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use. - curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0 - ? tabstop_first(curbuf->b_p_vts_array) - : curbuf->b_p_ts; -#else - curbuf->b_p_sw = curbuf->b_p_ts; + p_titlelen = 85; + } + if (starting != NO_SCREEN && old_value != p_titlelen) + need_maketitle = TRUE; + + return errmsg; +} + +#if defined(FEAT_PERSISTENT_UNDO) || defined(PROTO) +/* + * Process the updated 'undofile' option value. + */ + char * +did_set_undofile(optset_T *args) +{ + // Only take action when the option was set. + if (!curbuf->b_p_udf && !p_udf) + return NULL; + + // When reset we do not delete the undo file, the option may be set again + // without making any changes in between. + char_u hash[UNDO_HASH_SIZE]; + buf_T *save_curbuf = curbuf; + + FOR_ALL_BUFFERS(curbuf) + { + // When 'undofile' is set globally: for every buffer, otherwise + // only for the current buffer: Try to read in the undofile, + // if one exists, the buffer wasn't changed and the buffer was + // loaded + if ((curbuf == save_curbuf + || (args->os_flags & OPT_GLOBAL) + || args->os_flags == 0) + && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL) + { +#ifdef FEAT_CRYPT + if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD) + continue; #endif + u_compute_hash(hash); + u_read_undo(NULL, hash, curbuf->b_fname); + } } + curbuf = save_curbuf; -#ifdef FEAT_FOLDING - if (foldmethodIsIndent(curwin)) - foldUpdateAll(curwin); + return NULL; +} #endif - // When 'shiftwidth' changes, or it's zero and 'tabstop' changes: - // parse 'cinoptions'. - if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0) - parse_cino(curbuf); - return errmsg; +/* + * Process the new global 'undolevels' option value. + */ + static void +update_global_undolevels(long value, long old_value) +{ + // sync undo before 'undolevels' changes + + // use the old value, otherwise u_sync() may not work properly + p_ul = old_value; + u_sync(TRUE); + p_ul = value; } /* - * Process the new 'maxcombine' option value. + * Process the new buffer local 'undolevels' option value. + */ + static void +update_buflocal_undolevels(long value, long old_value) +{ + // use the old value, otherwise u_sync() may not work properly + curbuf->b_p_ul = old_value; + u_sync(TRUE); + curbuf->b_p_ul = value; +} + +/* + * Process the new 'undolevels' option value. */ char * -did_set_maxcombine(optset_T *args UNUSED) +did_set_undolevels(optset_T *args) { - if (p_mco > MAX_MCO) - p_mco = MAX_MCO; - else if (p_mco < 0) - p_mco = 0; - screenclear(); // will re-allocate the screen + long *pp = (long *)args->os_varp; + + if (pp == &p_ul) // global 'undolevels' + update_global_undolevels(args->os_newval.number, + args->os_oldval.number); + else if (pp == &curbuf->b_p_ul) // buffer local 'undolevels' + update_buflocal_undolevels(args->os_newval.number, + args->os_oldval.number); + return NULL; } /* - * Process the new 'iminsert' option value. + * Process the new 'updatecount' option value. */ char * -did_set_iminsert(optset_T *args UNUSED) +did_set_updatecount(optset_T *args) { + long old_value = args->os_oldval.number; char *errmsg = NULL; - if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST) + // when 'updatecount' changes from zero to non-zero, open swap files + if (p_uc < 0) { - errmsg = e_invalid_argument; - curbuf->b_p_iminsert = B_IMODE_NONE; + errmsg = e_argument_must_be_positive; + p_uc = 100; } - p_iminsert = curbuf->b_p_iminsert; - if (termcap_active) // don't do this in the alternate screen - showmode(); -#if defined(FEAT_KEYMAP) - // Show/unshow value of 'keymap' in status lines. - status_redraw_curbuf(); -#endif + if (p_uc && !old_value) + ml_open_files(); return errmsg; } -#if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) || defined(PROTO) /* - * Process the new 'imstyle' option value. + * Process the updated 'weirdinvert' option value. */ char * -did_set_imstyle(optset_T *args UNUSED) +did_set_weirdinvert(optset_T *args) { - char *errmsg = NULL; - - if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT) - errmsg = e_invalid_argument; + // When 'weirdinvert' changed, set/reset 't_xs'. + // Then set 'weirdinvert' according to value of 't_xs'. + if (p_wiv && !args->os_oldval.boolean) + T_XS = (char_u *)"y"; + else if (!p_wiv && args->os_oldval.boolean) + T_XS = empty_option; + p_wiv = (*T_XS != NUL); - return errmsg; + return NULL; } -#endif /* * Process the new 'window' option value. @@ -4197,231 +4381,210 @@ did_set_window(optset_T *args UNUSED) } /* - * Process the new 'imsearch' option value. + * Process the new 'winheight' or the 'helpheight' option value. */ char * -did_set_imsearch(optset_T *args UNUSED) +did_set_winheight_helpheight(optset_T *args) { - char *errmsg = NULL; + long *pp = (long *)args->os_varp; + char *errmsg = NULL; - if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST) + if (p_wh < 1) { - errmsg = e_invalid_argument; - curbuf->b_p_imsearch = B_IMODE_NONE; + errmsg = e_argument_must_be_positive; + p_wh = 1; } - p_imsearch = curbuf->b_p_imsearch; - - return errmsg; -} - -/* - * Process the new 'titlelen' option value. - */ - char * -did_set_titlelen(optset_T *args) -{ - long old_value = args->os_oldval.number; - char *errmsg = NULL; - - // if 'titlelen' has changed, redraw the title - if (p_titlelen < 0) + if (p_wmh > p_wh) + { + errmsg = e_winheight_cannot_be_smaller_than_winminheight; + p_wh = p_wmh; + } + if (p_hh < 0) { errmsg = e_argument_must_be_positive; - p_titlelen = 85; + p_hh = 0; + } + + // Change window height NOW + if (!ONE_WINDOW) + { + if (pp == &p_wh && curwin->w_height < p_wh) + win_setheight((int)p_wh); + if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh) + win_setheight((int)p_hh); } - if (starting != NO_SCREEN && old_value != p_titlelen) - need_maketitle = TRUE; return errmsg; } /* - * Process the new 'cmdheight' option value. + * Process the new 'winminheight' option value. */ char * -did_set_cmdheight(optset_T *args) +did_set_winminheight(optset_T *args UNUSED) { - long old_value = args->os_oldval.number; char *errmsg = NULL; - // if p_ch changed value, change the command line height - if (p_ch < 1) + if (p_wmh < 0) { errmsg = e_argument_must_be_positive; - p_ch = 1; + p_wmh = 0; } - if (p_ch > Rows - min_rows() + 1) - p_ch = Rows - min_rows() + 1; - - // Only compute the new window layout when startup has been - // completed. Otherwise the frame sizes may be wrong. - if ((p_ch != old_value - || tabline_height() + topframe->fr_height != Rows - p_ch) - && full_screen -#ifdef FEAT_GUI - && !gui.starting -#endif - ) - command_height(); + if (p_wmh > p_wh) + { + errmsg = e_winheight_cannot_be_smaller_than_winminheight; + p_wmh = p_wh; + } + win_setminheight(); return errmsg; } /* - * Process the new 'updatecount' option value. + * Process the new 'winminwidth' option value. */ char * -did_set_updatecount(optset_T *args) +did_set_winminwidth(optset_T *args UNUSED) { - long old_value = args->os_oldval.number; char *errmsg = NULL; - // when 'updatecount' changes from zero to non-zero, open swap files - if (p_uc < 0) + if (p_wmw < 0) { errmsg = e_argument_must_be_positive; - p_uc = 100; + p_wmw = 0; } - if (p_uc && !old_value) - ml_open_files(); + if (p_wmw > p_wiw) + { + errmsg = e_winwidth_cannot_be_smaller_than_winminwidth; + p_wmw = p_wiw; + } + win_setminwidth(); return errmsg; } -#if defined(FEAT_CONCEAL) || defined(PROTO) /* - * Process the new 'conceallevel' option value. + * Process the new 'winwidth' option value. */ char * -did_set_conceallevel(optset_T *args UNUSED) +did_set_winwidth(optset_T *args UNUSED) { char *errmsg = NULL; - if (curwin->w_p_cole < 0) + if (p_wiw < 1) { errmsg = e_argument_must_be_positive; - curwin->w_p_cole = 0; + p_wiw = 1; } - else if (curwin->w_p_cole > 3) + if (p_wmw > p_wiw) { - errmsg = e_invalid_argument; - curwin->w_p_cole = 3; + errmsg = e_winwidth_cannot_be_smaller_than_winminwidth; + p_wiw = p_wmw; } + // Change window width NOW + if (!ONE_WINDOW && curwin->w_width < p_wiw) + win_setwidth((int)p_wiw); + return errmsg; } -#endif -#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO) /* - * Process the new 'pyxversion' option value. + * Process the updated 'wrap' option value. */ char * -did_set_pyxversion(optset_T *args UNUSED) +did_set_wrap(optset_T *args UNUSED) { - char *errmsg = NULL; - - if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3) - errmsg = e_invalid_argument; - - return errmsg; + // If 'wrap' is set, set w_leftcol to zero. + if (curwin->w_p_wrap) + curwin->w_leftcol = 0; + return NULL; } -#endif /* - * Process the new global 'undolevels' option value. + * Set the value of a boolean option, and take care of side effects. + * Returns NULL for success, or an error message for an error. */ - static void -did_set_global_undolevels(long value, long old_value) + static char * +set_bool_option( + int opt_idx, // index in options[] table + char_u *varp, // pointer to the option variable + int value, // new value + int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL { - // sync undo before 'undolevels' changes - - // use the old value, otherwise u_sync() may not work properly - p_ul = old_value; - u_sync(TRUE); - p_ul = value; -} + int old_value = *(int *)varp; +#if defined(FEAT_EVAL) + int old_global_value = 0; +#endif + char *errmsg = NULL; -/* - * Process the new buffer local 'undolevels' option value. - */ - static void -did_set_buflocal_undolevels(long value, long old_value) -{ - // use the old value, otherwise u_sync() may not work properly - curbuf->b_p_ul = old_value; - u_sync(TRUE); - curbuf->b_p_ul = value; -} + // Disallow changing some options from secure mode + if ((secure +#ifdef HAVE_SANDBOX + || sandbox != 0 +#endif + ) && (options[opt_idx].flags & P_SECURE)) + return e_not_allowed_here; -#if defined(FEAT_LINEBREAK) || defined(PROTO) -/* - * Process the new 'numberwidth' option value. - */ - char * -did_set_numberwidth(optset_T *args UNUSED) -{ - char *errmsg = NULL; +#if defined(FEAT_EVAL) + // Save the global value before changing anything. This is needed as for + // a global-only option setting the "local value" in fact sets the global + // value (since there is only one value). + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + old_global_value = *(int *)get_varp_scope(&(options[opt_idx]), + OPT_GLOBAL); +#endif - // 'numberwidth' must be positive - if (curwin->w_p_nuw < 1) - { - errmsg = e_argument_must_be_positive; - curwin->w_p_nuw = 1; - } - if (curwin->w_p_nuw > 20) - { - errmsg = e_invalid_argument; - curwin->w_p_nuw = 20; - } - curwin->w_nrwidth_line_count = 0; // trigger a redraw + *(int *)varp = value; // set the new value +#ifdef FEAT_EVAL + // Remember where the option was set. + set_option_sctx_idx(opt_idx, opt_flags, current_sctx); +#endif - return errmsg; -} +#ifdef FEAT_GUI + need_mouse_correct = TRUE; #endif -/* - * Process the new 'textwidth' option value. - */ - char * -did_set_textwidth(optset_T *args UNUSED) -{ - char *errmsg = NULL; + // May set global value for local option. + if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) + *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value; - if (curbuf->b_p_tw < 0) - { - errmsg = e_argument_must_be_positive; - curbuf->b_p_tw = 0; - } -#ifdef FEAT_SYN_HL + // Handle side effects of changing a bool option. + if (options[opt_idx].opt_did_set_cb != NULL) { - win_T *wp; - tabpage_T *tp; + optset_T args; - FOR_ALL_TAB_WINDOWS(tp, wp) - check_colorcolumn(wp); + CLEAR_FIELD(args); + args.os_varp = varp; + args.os_flags = opt_flags; + args.os_oldval.boolean = old_value; + args.os_newval.boolean = value; + args.os_errbuf = NULL; + errmsg = options[opt_idx].opt_did_set_cb(&args); + if (args.os_doskip) + return errmsg; } -#endif - return errmsg; -} + // after handling side effects, call autocommand -/* - * Process the new 'undolevels' option value. - */ - char * -did_set_undolevels(optset_T *args) -{ - long *pp = (long *)args->os_varp; + options[opt_idx].flags |= P_WAS_SET; - if (pp == &p_ul) // global 'undolevels' - did_set_global_undolevels(args->os_newval.number, - args->os_oldval.number); - else if (pp == &curbuf->b_p_ul) // buffer local 'undolevels' - did_set_buflocal_undolevels(args->os_newval.number, - args->os_oldval.number); +#if defined(FEAT_EVAL) + apply_optionset_autocmd(opt_idx, opt_flags, + (long)(old_value ? TRUE : FALSE), + (long)(old_global_value ? TRUE : FALSE), + (long)(value ? TRUE : FALSE), NULL); +#endif - return NULL; + comp_col(); // in case 'ruler' or 'showcmd' changed + if (curwin->w_curswant != MAXCOL + && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) + curwin->w_set_curswant = TRUE; + + if ((opt_flags & OPT_NO_REDRAW) == 0) + check_redraw(options[opt_idx].flags); + + return errmsg; } /* @@ -4632,6 +4795,7 @@ set_num_option( { optset_T args; + CLEAR_FIELD(args); args.os_varp = varp; args.os_flags = opt_flags; args.os_oldval.number = old_value; @@ -7655,156 +7819,6 @@ shortmess(int x) && vim_strchr((char_u *)SHM_A, 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; -#ifdef FEAT_RIGHTLEFT - static int save_ri = 0; - static int save_hkmap = 0; -#endif - buf_T *buf; - - 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; -#ifdef FEAT_VARTABS - if (buf->b_p_vsts_nopaste) - vim_free(buf->b_p_vsts_nopaste); - buf->b_p_vsts_nopaste = - buf->b_p_vsts && buf->b_p_vsts != empty_option - ? vim_strsave(buf->b_p_vsts) : NULL; -#endif - } - - // save global options - save_sm = p_sm; - save_sta = p_sta; - save_ru = p_ru; -#ifdef FEAT_RIGHTLEFT - save_ri = p_ri; - save_hkmap = p_hkmap; -#endif - // 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; -#ifdef FEAT_VARTABS - if (p_vsts_nopaste) - vim_free(p_vsts_nopaste); - p_vsts_nopaste = p_vsts && p_vsts != empty_option - ? vim_strsave(p_vsts) : NULL; -#endif - } - - // 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 -#ifdef FEAT_VARTABS - if (buf->b_p_vsts) - free_string_option(buf->b_p_vsts); - buf->b_p_vsts = empty_option; - VIM_CLEAR(buf->b_p_vsts_array); -#endif - } - - // 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 -#ifdef FEAT_RIGHTLEFT - p_ri = 0; // no reverse insert - p_hkmap = 0; // no Hebrew keyboard -#endif - // set global values for local buffer options - p_tw = 0; - p_wm = 0; - p_sts = 0; - p_ai = 0; -#ifdef FEAT_VARTABS - if (p_vsts) - free_string_option(p_vsts); - p_vsts = empty_option; -#endif - } - - // Paste switched from on to off: Restore saved values. - else if (old_p_paste) - { - // 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; -#ifdef FEAT_VARTABS - if (buf->b_p_vsts) - free_string_option(buf->b_p_vsts); - buf->b_p_vsts = buf->b_p_vsts_nopaste - ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option; - vim_free(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; -#endif - } - - // 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; -#ifdef FEAT_RIGHTLEFT - p_ri = save_ri; - p_hkmap = save_hkmap; -#endif - // 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; -#ifdef FEAT_VARTABS - if (p_vsts) - free_string_option(p_vsts); - p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option; -#endif - } - - old_p_paste = p_paste; -} - /* * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found. * @@ -7919,28 +7933,6 @@ compatible_set(void) didset_options2(); } -#if defined(FEAT_LINEBREAK) || defined(PROTO) - -/* - * Called when the 'breakat' option changes value. - */ - char * -did_set_breakat(optset_T *args UNUSED) -{ - char_u *p; - int i; - - for (i = 0; i < 256; i++) - breakat_flags[i] = FALSE; - - if (p_breakat != NULL) - for (p = p_breakat; *p; p++) - breakat_flags[*p] = TRUE; - - return NULL; -} -#endif - /* * Check if backspacing over something is allowed. */ diff --git a/src/optiondefs.h b/src/optiondefs.h index 668e62f57..5bd82fce7 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -2506,7 +2506,7 @@ static struct vimoption options[] = #endif SCTX_INIT}, {"term", NULL, P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL, - (char_u *)&T_NAME, PV_NONE, NULL, + (char_u *)&T_NAME, PV_NONE, did_set_term, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"termbidi", "tbidi", P_BOOL|P_VI_DEF, #ifdef FEAT_ARABIC @@ -2662,7 +2662,7 @@ static struct vimoption options[] = (char_u *)&p_ttyscroll, PV_NONE, NULL, {(char_u *)999L, (char_u *)0L} SCTX_INIT}, {"ttytype", "tty", P_STRING|P_EXPAND|P_NODEFAULT|P_NO_MKRC|P_VI_DEF|P_RALL, - (char_u *)&T_NAME, PV_NONE, NULL, + (char_u *)&T_NAME, PV_NONE, did_set_term, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"undodir", "udir", P_STRING|P_EXPAND|P_ONECOMMA|P_NODUP|P_SECURE |P_VI_DEF, diff --git a/src/optionstr.c b/src/optionstr.c index aff8b6129..0389ed030 100644 --- a/src/optionstr.c +++ b/src/optionstr.c @@ -2247,8 +2247,7 @@ did_set_scrollopt(optset_T *args UNUSED) char * did_set_selection(optset_T *args UNUSED) { - if (*p_sel == NUL - || check_opt_strings(p_sel, p_sel_values, FALSE) != OK) + if (*p_sel == NUL || check_opt_strings(p_sel, p_sel_values, FALSE) != OK) return e_invalid_argument; return NULL; @@ -2398,7 +2397,7 @@ did_set_spelloptions(optset_T *args) { char_u **varp = (char_u **)args->os_varp; - if (**varp != NUL && STRCMP("camel", *varp) != 0) + if (**varp != NUL && STRCMP(*varp, "camel") != 0) return e_invalid_argument; return NULL; @@ -2499,34 +2498,24 @@ did_set_tagcase(optset_T *args) /* * The 'term' option is changed. */ - static char * -did_set_term(int *opt_idx, long_u *free_oldval) + char * +did_set_term(optset_T *args UNUSED) { - char *errmsg = NULL; - if (T_NAME[0] == NUL) - errmsg = e_cannot_set_term_to_empty_string; + return e_cannot_set_term_to_empty_string; #ifdef FEAT_GUI - else if (gui.in_use) - errmsg = e_cannot_change_term_in_GUI; - else if (term_is_gui(T_NAME)) - errmsg = e_use_gui_to_start_GUI; + if (gui.in_use) + return e_cannot_change_term_in_GUI; + if (term_is_gui(T_NAME)) + return e_use_gui_to_start_GUI; #endif - else if (set_termname(T_NAME) == FAIL) - errmsg = e_not_found_in_termcap; - else - { - // Screen colors may have changed. - redraw_later_clear(); + if (set_termname(T_NAME) == FAIL) + return e_not_found_in_termcap; - // Both 'term' and 'ttytype' point to T_NAME, only set the - // P_ALLOCED flag on 'term'. - *opt_idx = findoption((char_u *)"term"); - if (*opt_idx >= 0) - *free_oldval = (get_option_flags(*opt_idx) & P_ALLOCED); - } + // Screen colors may have changed. + redraw_later_clear(); - return errmsg; + return NULL; } /* @@ -2604,8 +2593,7 @@ did_set_term_option(optset_T *args) char * did_set_termwinkey(optset_T *args UNUSED) { - if (*curwin->w_p_twk != NUL - && string_to_key(curwin->w_p_twk, TRUE) == 0) + if (*curwin->w_p_twk != NUL && string_to_key(curwin->w_p_twk, TRUE) == 0) return e_invalid_argument; return NULL; @@ -2664,8 +2652,8 @@ did_set_titlestring(optset_T *args) char * did_set_toolbar(optset_T *args UNUSED) { - if (opt_strings_flags(p_toolbar, p_toolbar_values, - &toolbar_flags, TRUE) != OK) + if (opt_strings_flags(p_toolbar, p_toolbar_values, &toolbar_flags, + TRUE) != OK) return e_invalid_argument; out_flush(); @@ -2971,8 +2959,7 @@ did_set_winaltkeys(optset_T *args UNUSED) { char *errmsg = NULL; - if (*p_wak == NUL - || check_opt_strings(p_wak, p_wak_values, FALSE) != OK) + if (*p_wak == NUL || check_opt_strings(p_wak, p_wak_values, FALSE) != OK) errmsg = e_invalid_argument; # ifdef FEAT_MENU # if defined(FEAT_GUI_MOTIF) @@ -3097,13 +3084,24 @@ did_set_string_option( // need to set P_INSECURE { char *errmsg = NULL; - int restore_chartab = FALSE; long_u free_oldval = (get_option_flags(opt_idx) & P_ALLOCED); - int value_changed = FALSE; -#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) - int did_swaptcap = FALSE; -#endif opt_did_set_cb_T did_set_cb = get_option_did_set_cb(opt_idx); + optset_T args; + + // 'ttytype' is an alias for 'term'. Both 'term' and 'ttytype' point to + // T_NAME. If 'term' or 'ttytype' is modified, then use the index for the + // 'term' option. Only set the P_ALLOCED flag on 'term'. + if (varp == &T_NAME) + { + opt_idx = findoption((char_u *)"term"); + if (opt_idx >= 0) + { + free_oldval = (get_option_flags(opt_idx) & P_ALLOCED); + did_set_cb = get_option_did_set_cb(opt_idx); + } + } + + CLEAR_FIELD(args); // Disallow changing some options from secure mode if ((secure @@ -3117,9 +3115,6 @@ did_set_string_option( errmsg = e_invalid_argument; else if (did_set_cb != NULL) { - optset_T args; - - CLEAR_FIELD(args); args.os_varp = (char_u *)varp; args.os_idx = opt_idx; args.os_flags = opt_flags; @@ -3130,22 +3125,10 @@ did_set_string_option( // the new option value. errmsg = did_set_cb(&args); - // The 'filetype' and 'syntax' option callback functions may change - // the os_value_changed field. - value_changed = args.os_value_changed; // The 'keymap', 'filetype' and 'syntax' option callback functions // may change the os_value_checked field. *value_checked = args.os_value_checked; - // The 'isident', 'iskeyword', 'isprint' and 'isfname' options may - // change the character table. On failure, this needs to be restored. - restore_chartab = args.os_restore_chartab; -#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) - // The 't_xxx' terminal options may swap the termcap entries. - did_swaptcap = args.os_did_swaptcap; -#endif } - else if (varp == &T_NAME) // 'term' - errmsg = did_set_term(&opt_idx, &free_oldval); // If an error is detected, restore the previous value. if (errmsg != NULL) @@ -3153,7 +3136,7 @@ did_set_string_option( free_string_option(*varp); *varp = oldval; // When resetting some values, need to act on it. - if (restore_chartab) + if (args.os_restore_chartab) (void)init_chartab(); if (varp == &p_hl) (void)highlight_changed(); @@ -3188,10 +3171,10 @@ did_set_string_option( // Trigger the autocommand only after setting the flags. #ifdef FEAT_SYN_HL if (varp == &(curbuf->b_p_syn)) - do_syntax_autocmd(value_changed); + do_syntax_autocmd(args.os_value_changed); #endif else if (varp == &(curbuf->b_p_ft)) - do_filetype_autocmd(varp, opt_flags, value_changed); + do_filetype_autocmd(varp, opt_flags, args.os_value_changed); #ifdef FEAT_SPELL if (varp == &(curwin->w_s->b_p_spl)) do_spelllang_source(); @@ -3252,7 +3235,7 @@ did_set_string_option( } #if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) - if (did_swaptcap) + if (args.os_did_swaptcap) { set_termname((char_u *)"win32"); init_highlight(TRUE, FALSE); diff --git a/src/proto/option.pro b/src/proto/option.pro index a4a2b9f81..7b558eded 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -24,68 +24,69 @@ int valid_name(char_u *val, char *allowed); void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx); sctx_T *get_option_sctx(char *name); void set_term_option_sctx_idx(char *name, int opt_idx); +char *did_set_arabic(optset_T *args); +char *did_set_autochdir(optset_T *args); +char *did_set_ballooneval(optset_T *args); +char *did_set_balloonevalterm(optset_T *args); +char *did_set_binary(optset_T *args); +char *did_set_breakat(optset_T *args); +char *did_set_buflisted(optset_T *args); +char *did_set_cmdheight(optset_T *args); char *did_set_compatible(optset_T *args); -char *did_set_langremap(optset_T *args); +char *did_set_conceallevel(optset_T *args); +char *did_set_diff(optset_T *args); +char *did_set_eof_eol_fixeol_bomb(optset_T *args); +char *did_set_equalalways(optset_T *args); +char *did_set_foldcolumn(optset_T *args); +char *did_set_foldlevel(optset_T *args); +char *did_set_foldminlines(optset_T *args); +char *did_set_foldnestmax(optset_T *args); +char *did_set_hlsearch(optset_T *args); +char *did_set_ignorecase(optset_T *args); +char *did_set_imdisable(optset_T *args); +char *did_set_iminsert(optset_T *args); +char *did_set_imsearch(optset_T *args); +char *did_set_imstyle(optset_T *args); +char *did_set_insertmode(optset_T *args); char *did_set_langnoremap(optset_T *args); -char *did_set_undofile(optset_T *args); -char *did_set_readonly(optset_T *args); -char *did_set_mousehide(optset_T *args); +char *did_set_langremap(optset_T *args); +char *did_set_laststatus(optset_T *args); +char *did_set_linespace(optset_T *args); +char *did_set_lisp(optset_T *args); +char *did_set_maxcombine(optset_T *args); char *did_set_modifiable(optset_T *args); -char *did_set_eof_eol_fixeol_bomb(optset_T *args); -char *did_set_binary(optset_T *args); -char *did_set_buflisted(optset_T *args); -char *did_set_swapfile(optset_T *args); -char *did_set_terse(optset_T *args); +char *did_set_modified(optset_T *args); +char *did_set_mousehide(optset_T *args); +char *did_set_number_relativenumber(optset_T *args); +char *did_set_numberwidth(optset_T *args); char *did_set_paste(optset_T *args); -char *did_set_insertmode(optset_T *args); -char *did_set_ignorecase(optset_T *args); -char *did_set_hlsearch(optset_T *args); -char *did_set_scrollbind(optset_T *args); char *did_set_previewwindow(optset_T *args); +char *did_set_pyxversion(optset_T *args); +char *did_set_readonly(optset_T *args); +char *did_set_scrollbind(optset_T *args); +char *did_set_shellslash(optset_T *args); +char *did_set_shiftwidth_tabstop(optset_T *args); +char *did_set_showtabline(optset_T *args); char *did_set_smoothscroll(optset_T *args); -char *did_set_textmode(optset_T *args); +char *did_set_spell(optset_T *args); +char *did_set_swapfile(optset_T *args); +char *did_set_termguicolors(optset_T *args); +char *did_set_terse(optset_T *args); char *did_set_textauto(optset_T *args); -char *did_set_lisp(optset_T *args); +char *did_set_textmode(optset_T *args); +char *did_set_textwidth(optset_T *args); char *did_set_title_icon(optset_T *args); -char *did_set_modified(optset_T *args); -char *did_set_shellslash(optset_T *args); -char *did_set_wrap(optset_T *args); -char *did_set_equalalways(optset_T *args); +char *did_set_titlelen(optset_T *args); +char *did_set_undofile(optset_T *args); +char *did_set_undolevels(optset_T *args); +char *did_set_updatecount(optset_T *args); char *did_set_weirdinvert(optset_T *args); -char *did_set_ballooneval(optset_T *args); -char *did_set_balloonevalterm(optset_T *args); -char *did_set_autochdir(optset_T *args); -char *did_set_diff(optset_T *args); -char *did_set_imdisable(optset_T *args); -char *did_set_spell(optset_T *args); -char *did_set_arabic(optset_T *args); -char *did_set_number_relativenumber(optset_T *args); -char *did_set_termguicolors(optset_T *args); +char *did_set_window(optset_T *args); char *did_set_winheight_helpheight(optset_T *args); char *did_set_winminheight(optset_T *args); -char *did_set_winwidth(optset_T *args); char *did_set_winminwidth(optset_T *args); -char *did_set_laststatus(optset_T *args); -char *did_set_showtabline(optset_T *args); -char *did_set_linespace(optset_T *args); -char *did_set_foldlevel(optset_T *args); -char *did_set_foldminlines(optset_T *args); -char *did_set_foldnestmax(optset_T *args); -char *did_set_foldcolumn(optset_T *args); -char *did_set_shiftwidth_tabstop(optset_T *args); -char *did_set_maxcombine(optset_T *args); -char *did_set_iminsert(optset_T *args); -char *did_set_imstyle(optset_T *args); -char *did_set_window(optset_T *args); -char *did_set_imsearch(optset_T *args); -char *did_set_titlelen(optset_T *args); -char *did_set_cmdheight(optset_T *args); -char *did_set_updatecount(optset_T *args); -char *did_set_conceallevel(optset_T *args); -char *did_set_pyxversion(optset_T *args); -char *did_set_numberwidth(optset_T *args); -char *did_set_textwidth(optset_T *args); -char *did_set_undolevels(optset_T *args); +char *did_set_winwidth(optset_T *args); +char *did_set_wrap(optset_T *args); void check_redraw(long_u flags); int findoption(char_u *arg); getoption_T get_option_value(char_u *name, long *numval, char_u **stringval, int *flagsp, int scope); @@ -135,7 +136,6 @@ void vimrc_found(char_u *fname, char_u *envname); void change_compatible(int on); int option_was_set(char_u *name); int reset_option_was_set(char_u *name); -char *did_set_breakat(optset_T *args); int can_bs(int what); long get_scrolloff_value(void); long get_sidescrolloff_value(void); diff --git a/src/proto/optionstr.pro b/src/proto/optionstr.pro index 43f285a48..db13f10d9 100644 --- a/src/proto/optionstr.pro +++ b/src/proto/optionstr.pro @@ -100,6 +100,7 @@ char *did_set_swapsync(optset_T *args); char *did_set_switchbuf(optset_T *args); char *did_set_tabline(optset_T *args); char *did_set_tagcase(optset_T *args); +char *did_set_term(optset_T *args); char *did_set_term_option(optset_T *args); char *did_set_termwinkey(optset_T *args); char *did_set_termwinsize(optset_T *args); diff --git a/src/testdir/test_backspace_opt.vim b/src/testdir/test_backspace_opt.vim index d70a6d00e..ea28803e7 100644 --- a/src/testdir/test_backspace_opt.vim +++ b/src/testdir/test_backspace_opt.vim @@ -138,4 +138,32 @@ func Test_backspace_ctrl_u() close! endfunc +" Test for setting 'backspace' to a number value (for backward compatibility) +func Test_backspace_number_value() + new + + set backspace=0 + call setline(1, ['one two', 'three four']) + call cursor(2, 1) + exe "normal! A\\" + call assert_equal('three four', getline(2)) + + set backspace=1 + exe "normal! A\five\\\\" + call assert_equal(['one two', 'three four'], getline(1, '$')) + + set backspace=2 + call cursor(2, 7) + exe "normal! ihalf\" + call assert_equal('three four', getline(2)) + + set backspace=3 + call cursor(2, 7) + exe "normal! ihalf\" + call assert_equal('four', getline(2)) + + bw! + set backspace& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim index feccf84b6..a8ef8028b 100644 --- a/src/testdir/test_highlight.vim +++ b/src/testdir/test_highlight.vim @@ -878,6 +878,13 @@ func Test_highlight_start_stop() call assert_match("stop=^[[27h;^[[ r;", HighlightArgs('HlGrp2')) hi HlGrp2 stop=NONE call assert_notmatch("stop=", HighlightArgs('HlGrp2')) + set t_xy=^[foo; + set t_xz=^[bar; + hi HlGrp3 start=t_xy stop=t_xz + let d = hlget('HlGrp3') + call assert_equal('^[foo;', d[0].start) + call assert_equal('^[bar;', d[0].stop) + set t_xy= t_xz= hi clear endfunc diff --git a/src/testdir/test_python3.vim b/src/testdir/test_python3.vim index 5de94649a..b7140ee7b 100644 --- a/src/testdir/test_python3.vim +++ b/src/testdir/test_python3.vim @@ -375,6 +375,7 @@ func Test_python3_opt_reset_local_to_global() \ ['include', 'ginc', 'linc', ''], \ ['dict', 'gdict', 'ldict', ''], \ ['thesaurus', 'gtsr', 'ltsr', ''], + \ ['thesaurusfunc', 'Gtsrfu', 'Ltsrfu', ''], \ ['formatprg', 'gfprg', 'lfprg', ''], \ ['errorformat', '%f:%l:%m', '%s-%l-%m', ''], \ ['grepprg', 'ggprg', 'lgprg', ''], @@ -408,9 +409,13 @@ func Test_python3_opt_reset_local_to_global() " Set the global and window-local option values and then clear the " window-local option value. let wopts = [ + \ ['fillchars', 'fold:>', 'fold:+', ''], + \ ['listchars', 'tab:>>', 'tab:--', ''], \ ['scrolloff', 5, 10, -1], + \ ['showbreak', '>>', '++', ''], \ ['sidescrolloff', 6, 12, -1], - \ ['statusline', '%<%f', '%<%F', '']] + \ ['statusline', '%<%f', '%<%F', ''], + \ ['virtualedit', 'block', 'insert', '']] for opt in wopts py3 << trim pyopt = vim.bindeval("opt") diff --git a/src/version.c b/src/version.c index c93499c41..3f40fd180 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1379, /**/ 1378, /**/ -- 2.40.0