# HG changeset patch # User Bram Moolenaar # Date 1675945804 -3600 # Node ID 440256d039909ffe93cd683b3673e4db2345d044 # Parent f23a4fc4520e41cc681449b66274cb71dbdef192 patch 9.0.1293: the set_num_option() is too long Commit: https://github.com/vim/vim/commit/0caaf1e46511f7a92e036f05e6aa9d5992540117 Author: Yegappan Lakshmanan Date: Thu Feb 9 12:23:17 2023 +0000 patch 9.0.1293: the set_num_option() is too long Problem: The set_num_option() is too long. Solution: Move code to separate functions. (Yegappan Lakshmanan, closes #11954) diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -540,7 +540,7 @@ static char_u *fencs_utf8_default = (cha * utf-8. */ void -set_fencs_unicode() +set_fencs_unicode(void) { set_string_option_direct((char_u *)"fencs", -1, fencs_utf8_default, OPT_FREE, 0); @@ -3479,410 +3479,556 @@ set_bool_option( } /* - * Set the value of a number option, and take care of side effects. - * Returns NULL for success, or an error message for an error. + * Process the new 'winheight' or the 'helpheight' option value. */ static char * -set_num_option( - int opt_idx, // index in options[] table - char_u *varp, // pointer to the option variable - long value, // new value - char *errbuf, // buffer for error messages - size_t errbuflen, // length of "errbuf" - int opt_flags) // OPT_LOCAL, OPT_GLOBAL, - // OPT_MODELINE, etc. -{ - char *errmsg = NULL; - long old_value = *(long *)varp; -#if defined(FEAT_EVAL) - long old_global_value = 0; // only used when setting a local and - // global option -#endif - long old_Rows = Rows; // remember old Rows - long old_Columns = Columns; // remember old Columns - long *pp = (long *)varp; - - // 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 = *(long *)get_varp_scope(&(options[opt_idx]), - OPT_GLOBAL); -#endif - - *pp = value; -#ifdef FEAT_EVAL - // Remember where the option was set. - set_option_sctx_idx(opt_idx, opt_flags, current_sctx); -#endif -#ifdef FEAT_GUI - need_mouse_correct = TRUE; -#endif - - if (curbuf->b_p_sw < 0) +did_set_winheight_helpheight(long *pp, char *errmsg) +{ + 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); + } + + return errmsg; +} + +/* + * Process the new 'winminheight' option value. + */ + static char * +did_set_winminheight(char *errmsg) +{ + if (p_wmh < 0) + { + errmsg = e_argument_must_be_positive; + p_wmh = 0; + } + if (p_wmh > p_wh) + { + errmsg = e_winheight_cannot_be_smaller_than_winminheight; + p_wmh = p_wh; + } + win_setminheight(); + + return errmsg; +} + +/* + * Process the new 'winwidth' option value. + */ + static char * +did_set_winwidth(char *errmsg) +{ + if (p_wiw < 1) { 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; -#endif - } - - /* - * Number options that need some action when changed - */ - if (pp == &p_wh || pp == &p_hh) - { - // 'winheight' and 'helpheight' - 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); - } - } - else if (pp == &p_wmh) - { - // 'winminheight' - if (p_wmh < 0) - { - errmsg = e_argument_must_be_positive; - p_wmh = 0; - } - if (p_wmh > p_wh) - { - errmsg = e_winheight_cannot_be_smaller_than_winminheight; - p_wmh = p_wh; - } - win_setminheight(); - } - else if (pp == &p_wiw) - { - // 'winwidth' - if (p_wiw < 1) - { - 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; - } - - // Change window width NOW - if (!ONE_WINDOW && curwin->w_width < p_wiw) - win_setwidth((int)p_wiw); - } - else if (pp == &p_wmw) - { - // 'winminwidth' - 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(); - } - - // (re)set last window status line - else if (pp == &p_ls) - { - last_status(FALSE); - } - - // (re)set tab page line - else if (pp == &p_stal) - { - shell_new_rows(); // recompute window positions and heights - } + p_wiw = 1; + } + if (p_wmw > p_wiw) + { + 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; +} + +/* + * Process the new 'winminwidth' option value. + */ + static char * +did_set_winminwidth(char *errmsg) +{ + 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; +} + +/* + * Process the new 'laststatus' option value. + */ + static void +did_set_laststatus(void) +{ + last_status(FALSE); // (re)set last window status line +} + +/* + * Process the new 'showtabline' option value. + */ + static void +did_set_showtabline(void) +{ + shell_new_rows(); // recompute window positions and heights +} #ifdef FEAT_GUI - else if (pp == &p_linespace) - { - // 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); - } +/* + * Process the new 'linespace' option value. + */ + static void +did_set_linespace(void) +{ + // 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); +} #endif #ifdef FEAT_FOLDING - // 'foldlevel' - else if (pp == &curwin->w_p_fdl) - { - if (curwin->w_p_fdl < 0) - curwin->w_p_fdl = 0; - newFoldLevel(); - } - - // 'foldminlines' - else if (pp == &curwin->w_p_fml) - { +/* + * Process the new 'foldlevel' option value. + */ + static void +did_set_foldlevel(void) +{ + if (curwin->w_p_fdl < 0) + curwin->w_p_fdl = 0; + newFoldLevel(); +} + +/* + * Process the new 'foldminlines' option value. + */ + static void +did_set_foldminlines(void) +{ + foldUpdateAll(curwin); +} + +/* + * Process the new 'foldnestmax' option value. + */ + static void +did_set_foldnestmax(void) +{ + if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin)) foldUpdateAll(curwin); - } - - // 'foldnestmax' - else if (pp == &curwin->w_p_fdn) - { - if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin)) - foldUpdateAll(curwin); - } - - // 'foldcolumn' - else if (pp == &curwin->w_p_fdc) - { - if (curwin->w_p_fdc < 0) - { - errmsg = e_argument_must_be_positive; - curwin->w_p_fdc = 0; - } - else if (curwin->w_p_fdc > 12) - { - errmsg = e_invalid_argument; - curwin->w_p_fdc = 12; - } - } -#endif // FEAT_FOLDING - - // 'shiftwidth' or 'tabstop' - else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts) - { +} + +/* + * Process the new 'foldcolumn' option value. + */ + static char * +did_set_foldcolumn(char *errmsg) +{ + if (curwin->w_p_fdc < 0) + { + errmsg = e_argument_must_be_positive; + curwin->w_p_fdc = 0; + } + else if (curwin->w_p_fdc > 12) + { + errmsg = e_invalid_argument; + curwin->w_p_fdc = 12; + } + + return errmsg; +} +#endif + +/* + * Process the new 'shiftwidth' or the 'tabstop' option value. + */ + static void +did_set_shiftwidth_tabstop(long *pp) +{ #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); - } - - // 'maxcombine' - else if (pp == &p_mco) - { - if (p_mco > MAX_MCO) - p_mco = MAX_MCO; - else if (p_mco < 0) - p_mco = 0; - screenclear(); // will re-allocate the screen - } - - else if (pp == &curbuf->b_p_iminsert) - { - 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 (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); +} + +/* + * Process the new 'maxcombine' option value. + */ + static void +did_set_maxcombine(void) +{ + if (p_mco > MAX_MCO) + p_mco = MAX_MCO; + else if (p_mco < 0) + p_mco = 0; + screenclear(); // will re-allocate the screen +} + +/* + * Process the new 'iminsert' option value. + */ + static char * +did_set_iminsert(char *errmsg) +{ + 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 - } + // Show/unshow value of 'keymap' in status lines. + status_redraw_curbuf(); +#endif + + return errmsg; +} #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) - // 'imstyle' - else if (pp == &p_imst) - { - if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT) - errmsg = e_invalid_argument; - } -#endif - - else if (pp == &p_window) - { - if (p_window < 1) - p_window = 1; - else if (p_window >= Rows) - p_window = Rows - 1; - } - - else if (pp == &curbuf->b_p_imsearch) - { - 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; - } - +/* + * Process the new 'imstyle' option value. + */ + static char * +did_set_imstyle(char *errmsg) +{ + if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT) + errmsg = e_invalid_argument; + + return errmsg; +} +#endif + +/* + * Process the new 'window' option value. + */ + static void +did_set_window(void) +{ + if (p_window < 1) + p_window = 1; + else if (p_window >= Rows) + p_window = Rows - 1; +} + +/* + * Process the new 'imsearch' option value. + */ + static char * +did_set_imsearch(char *errmsg) +{ + 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; +} + +/* + * Process the new 'titlelen' option value. + */ + static char * +did_set_titlelen(long old_value, char *errmsg) +{ // if 'titlelen' has changed, redraw the title - else if (pp == &p_titlelen) - { - if (p_titlelen < 0) - { - errmsg = e_argument_must_be_positive; - p_titlelen = 85; - } - if (starting != NO_SCREEN && old_value != p_titlelen) - need_maketitle = TRUE; - } - + if (p_titlelen < 0) + { + errmsg = e_argument_must_be_positive; + p_titlelen = 85; + } + if (starting != NO_SCREEN && old_value != p_titlelen) + need_maketitle = TRUE; + + return errmsg; +} + +/* + * Process the new 'cmdheight' option value. + */ + static char * +did_set_cmdheight(long old_value, char *errmsg) +{ // if p_ch changed value, change the command line height - else if (pp == &p_ch) - { - 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 + 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(); - } - + && !gui.starting +#endif + ) + command_height(); + + return errmsg; +} + +/* + * Process the new 'updatecount' option value. + */ + static char * +did_set_updatecount(long old_value, char *errmsg) +{ // when 'updatecount' changes from zero to non-zero, open swap files - else if (pp == &p_uc) - { - if (p_uc < 0) - { - errmsg = e_argument_must_be_positive; - p_uc = 100; - } - if (p_uc && !old_value) - ml_open_files(); - } + if (p_uc < 0) + { + errmsg = e_argument_must_be_positive; + p_uc = 100; + } + if (p_uc && !old_value) + ml_open_files(); + + return errmsg; +} + #ifdef FEAT_CONCEAL - else if (pp == &curwin->w_p_cole) - { - if (curwin->w_p_cole < 0) - { - errmsg = e_argument_must_be_positive; - curwin->w_p_cole = 0; - } - else if (curwin->w_p_cole > 3) - { - errmsg = e_invalid_argument; - curwin->w_p_cole = 3; - } - } -#endif -#ifdef MZSCHEME_GUI_THREADS - else if (pp == &p_mzq) - mzvim_reset_timer(); +/* + * Process the new 'conceallevel' option value. + */ + static char * +did_set_conceallevel(char *errmsg) +{ + if (curwin->w_p_cole < 0) + { + errmsg = e_argument_must_be_positive; + curwin->w_p_cole = 0; + } + else if (curwin->w_p_cole > 3) + { + errmsg = e_invalid_argument; + curwin->w_p_cole = 3; + } + + return errmsg; +} #endif #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) - // 'pyxversion' - else if (pp == &p_pyx) - { - if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3) - errmsg = e_invalid_argument; - } -#endif - +/* + * Process the new 'pyxversion' option value. + */ + static char * +did_set_pyxversion(char *errmsg) +{ + if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3) + errmsg = e_invalid_argument; + + return errmsg; +} +#endif + +/* + * Process the new global 'undolevels' option value. + */ + static void +did_set_global_undolevels(long value, long old_value) +{ // sync undo before 'undolevels' changes - else if (pp == &p_ul) - { - // use the old value, otherwise u_sync() may not work properly - p_ul = old_value; - u_sync(TRUE); - p_ul = value; - } - else if (pp == &curbuf->b_p_ul) - { - // 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; - } + + // use the old value, otherwise u_sync() may not work properly + p_ul = old_value; + u_sync(TRUE); + p_ul = value; +} + +/* + * 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; +} #ifdef FEAT_LINEBREAK +/* + * Process the new 'numberwidth' option value. + */ + static char * +did_set_numberwidth(char *errmsg) +{ // 'numberwidth' must be positive - else if (pp == &curwin->w_p_nuw) - { - 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 - } -#endif - - else if (pp == &curbuf->b_p_tw) - { - if (curbuf->b_p_tw < 0) - { - errmsg = e_argument_must_be_positive; - curbuf->b_p_tw = 0; - } + 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 + +/* + * Process the new 'textwidth' option value. + */ + static char * +did_set_textwidth(char *errmsg) +{ + if (curbuf->b_p_tw < 0) + { + errmsg = e_argument_must_be_positive; + curbuf->b_p_tw = 0; + } #ifdef FEAT_SYN_HL - { - win_T *wp; - tabpage_T *tp; - - FOR_ALL_TAB_WINDOWS(tp, wp) - check_colorcolumn(wp); - } -#endif - } - - /* - * Check the bounds for numeric options here - */ + { + win_T *wp; + tabpage_T *tp; + + FOR_ALL_TAB_WINDOWS(tp, wp) + check_colorcolumn(wp); + } +#endif + + return errmsg; +} + +/* + * When some number options are changed, need to take some action. + */ + static char * +did_set_num_option(long *pp, long value, long old_value, char *errmsg) +{ + if (pp == &p_wh // 'winheight' + || pp == &p_hh) // 'helpheight' + errmsg = did_set_winheight_helpheight(pp, errmsg); + else if (pp == &p_wmh) // 'winminheight' + errmsg = did_set_winminheight(errmsg); + else if (pp == &p_wiw) // 'winwidth' + errmsg = did_set_winwidth(errmsg); + else if (pp == &p_wmw) // 'winminwidth' + errmsg = did_set_winminwidth(errmsg); + else if (pp == &p_ls) + did_set_laststatus(); // 'laststatus' + else if (pp == &p_stal) + did_set_showtabline(); // 'showtabline' +#ifdef FEAT_GUI + else if (pp == &p_linespace) // 'linespace' + did_set_linespace(); +#endif +#ifdef FEAT_FOLDING + else if (pp == &curwin->w_p_fdl) // 'foldlevel' + did_set_foldlevel(); + else if (pp == &curwin->w_p_fml) // 'foldminlines' + did_set_foldminlines(); + else if (pp == &curwin->w_p_fdn) // 'foldnestmax' + did_set_foldnestmax(); + else if (pp == &curwin->w_p_fdc) // 'foldcolumn' + errmsg = did_set_foldcolumn(errmsg); +#endif // FEAT_FOLDING + else if ( pp == &curbuf->b_p_sw // 'shiftwidth' + || pp == &curbuf->b_p_ts) // 'tabstop' + did_set_shiftwidth_tabstop(pp); + else if (pp == &p_mco) // 'maxcombine' + did_set_maxcombine(); + else if (pp == &curbuf->b_p_iminsert) // 'iminsert' + errmsg = did_set_iminsert(errmsg); +#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) + else if (pp == &p_imst) // 'imstyle' + errmsg = did_set_imstyle(errmsg); +#endif + else if (pp == &p_window) // 'window' + did_set_window(); + else if (pp == &curbuf->b_p_imsearch) // 'imsearch' + errmsg = did_set_imsearch(errmsg); + else if (pp == &p_titlelen) // 'titlelen' + errmsg = did_set_titlelen(old_value, errmsg); + else if (pp == &p_ch) // 'cmdheight' + errmsg = did_set_cmdheight(old_value, errmsg); + else if (pp == &p_uc) // 'updatecount' + errmsg = did_set_updatecount(old_value, errmsg); +#ifdef FEAT_CONCEAL + else if (pp == &curwin->w_p_cole) // 'conceallevel' + errmsg = did_set_conceallevel(errmsg); +#endif +#ifdef MZSCHEME_GUI_THREADS + else if (pp == &p_mzq) // 'mzquantum' + mzvim_reset_timer(); +#endif +#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) + else if (pp == &p_pyx) // 'pyxversion' + errmsg = did_set_pyxversion(errmsg); +#endif + else if (pp == &p_ul) // global 'undolevels' + did_set_global_undolevels(value, old_value); + else if (pp == &curbuf->b_p_ul) // buffer local 'undolevels' + did_set_buflocal_undolevels(value, old_value); +#ifdef FEAT_LINEBREAK + else if (pp == &curwin->w_p_nuw) // 'numberwidth' + errmsg = did_set_numberwidth(errmsg); +#endif + else if (pp == &curbuf->b_p_tw) // 'textwidth' + errmsg = did_set_textwidth(errmsg); + + return errmsg; +} + +/* + * Check the bounds of numeric options. + */ + static char * +check_num_option_bounds( + long *pp, + long old_value, + long old_Rows, + long old_Columns, + char *errbuf, + size_t errbuflen, + char *errmsg) +{ if (Rows < min_rows() && full_screen) { if (errbuf != NULL) { vim_snprintf(errbuf, errbuflen, - _(e_need_at_least_nr_lines), min_rows()); + _(e_need_at_least_nr_lines), min_rows()); errmsg = errbuf; } Rows = min_rows(); @@ -3892,7 +4038,7 @@ set_num_option( if (errbuf != NULL) { vim_snprintf(errbuf, errbuflen, - _(e_need_at_least_nr_columns), MIN_COLUMNS); + _(e_need_at_least_nr_columns), MIN_COLUMNS); errmsg = errbuf; } Columns = MIN_COLUMNS; @@ -3912,7 +4058,7 @@ set_num_option( #ifdef FEAT_GUI && !gui.starting #endif - ) + ) set_shellsize((int)Columns, (int)Rows, TRUE); else { @@ -4015,6 +4161,83 @@ set_num_option( p_ss = 0; } + return errmsg; +} + +/* + * Set the value of a number option, and take care of side effects. + * Returns NULL for success, or an error message for an error. + */ + static char * +set_num_option( + int opt_idx, // index in options[] table + char_u *varp, // pointer to the option variable + long value, // new value + char *errbuf, // buffer for error messages + size_t errbuflen, // length of "errbuf" + int opt_flags) // OPT_LOCAL, OPT_GLOBAL, + // OPT_MODELINE, etc. +{ + char *errmsg = NULL; + long old_value = *(long *)varp; +#if defined(FEAT_EVAL) + long old_global_value = 0; // only used when setting a local and + // global option +#endif + long old_Rows = Rows; // remember old Rows + long old_Columns = Columns; // remember old Columns + long *pp = (long *)varp; + + // 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 = *(long *)get_varp_scope(&(options[opt_idx]), + OPT_GLOBAL); +#endif + + *pp = value; +#ifdef FEAT_EVAL + // Remember where the option was set. + set_option_sctx_idx(opt_idx, opt_flags, current_sctx); +#endif +#ifdef FEAT_GUI + need_mouse_correct = TRUE; +#endif + + if (curbuf->b_p_sw < 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; +#endif + } + + /* + * Number options that need some action when changed + */ + errmsg = did_set_num_option(pp, value, old_value, errmsg); + + /* + * Check the bounds for numeric options here + */ + errmsg = check_num_option_bounds(pp, old_value, old_Rows, old_Columns, + errbuf, errbuflen, errmsg); + // May set global value for local option. if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1293, +/**/ 1292, /**/ 1291,