diff src/optionstr.c @ 31996:ca6bc7c04163 v9.0.1330

patch 9.0.1330: handling new value of an option has a long "else if" chain Commit: https://github.com/vim/vim/commit/af93691b53f38784efce0b93fe7644c44a7e382e Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Mon Feb 20 12:16:39 2023 +0000 patch 9.0.1330: handling new value of an option has a long "else if" chain Problem: Handling new value of an option has a long "else if" chain. Solution: Use a function pointer. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/12015)
author Bram Moolenaar <Bram@vim.org>
date Mon, 20 Feb 2023 13:30:05 +0100
parents 4efcb5c68112
children 4545f58c8490
line wrap: on
line diff
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -541,7 +541,7 @@ set_string_option(
 	saved_newval = vim_strsave(s);
     }
 #endif
-    if ((errmsg = did_set_string_option(opt_idx, varp, oldval, errbuf,
+    if ((errmsg = did_set_string_option(opt_idx, varp, oldval, value, errbuf,
 		    opt_flags, &value_checked)) == NULL)
 	did_set_option(opt_idx, opt_flags, TRUE, value_checked);
 
@@ -691,22 +691,20 @@ did_set_term(int *opt_idx, long_u *free_
 /*
  * The 'backupcopy' option is changed.
  */
-    static char *
-did_set_backupcopy(
-    char_u	*oldval,
-    int		opt_flags)
+    char *
+did_set_backupcopy(optset_T *args)
 {
     char_u		*bkc = p_bkc;
     unsigned int	*flags = &bkc_flags;
     char		*errmsg = NULL;
 
-    if (opt_flags & OPT_LOCAL)
+    if (args->os_flags & OPT_LOCAL)
     {
 	bkc = curbuf->b_p_bkc;
 	flags = &curbuf->b_bkc_flags;
     }
 
-    if ((opt_flags & OPT_LOCAL) && *bkc == NUL)
+    if ((args->os_flags & OPT_LOCAL) && *bkc == NUL)
 	// make the local value empty: use the global value
 	*flags = 0;
     else
@@ -718,7 +716,8 @@ did_set_backupcopy(
 		+ (((int)*flags & BKC_NO) != 0) != 1)
 	{
 	    // Must have exactly one of "auto", "yes"  and "no".
-	    (void)opt_strings_flags(oldval, p_bkc_values, flags, TRUE);
+	    (void)opt_strings_flags(args->os_oldval.string, p_bkc_values,
+								  flags, TRUE);
 	    errmsg = e_invalid_argument;
 	}
     }
@@ -729,8 +728,8 @@ did_set_backupcopy(
 /*
  * The 'backupext' or the 'patchmode' option is changed.
  */
-    static char *
-did_set_backupext_or_patchmode(void)
+    char *
+did_set_backupext_or_patchmode(optset_T *args UNUSED)
 {
     if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
 		*p_pm == '.' ? p_pm + 1 : p_pm) == 0)
@@ -739,12 +738,12 @@ did_set_backupext_or_patchmode(void)
     return NULL;
 }
 
-#ifdef FEAT_LINEBREAK
+#if defined(FEAT_LINEBREAK) || defined(PROTO)
 /*
  * The 'breakindentopt' option is changed.
  */
-    static char *
-did_set_breakindentopt(void)
+    char *
+did_set_breakindentopt(optset_T *args UNUSED)
 {
     char *errmsg = NULL;
 
@@ -780,14 +779,15 @@ did_set_isopt(int *did_chartab)
 /*
  * The 'helpfile' option is changed.
  */
-    static void
-did_set_helpfile(void)
+    char *
+did_set_helpfile(optset_T *args UNUSED)
 {
     // May compute new values for $VIM and $VIMRUNTIME
     if (didset_vim)
 	vim_unsetenv_ext((char_u *)"VIM");
     if (didset_vimruntime)
 	vim_unsetenv_ext((char_u *)"VIMRUNTIME");
+    return NULL;
 }
 
 #ifdef FEAT_SYN_HL
@@ -804,12 +804,12 @@ did_set_cursorlineopt(char_u **varp)
 }
 #endif
 
-#ifdef FEAT_MULTI_LANG
+#if defined(FEAT_MULTI_LANG) || defined(PROTO)
 /*
  * The 'helplang' option is changed.
  */
-    static char *
-did_set_helplang(void)
+    char *
+did_set_helplang(optset_T *args UNUSED)
 {
     char *errmsg = NULL;
 
@@ -832,8 +832,8 @@ did_set_helplang(void)
 /*
  * The 'highlight' option is changed.
  */
-    static char *
-did_set_highlight(void)
+    char *
+did_set_highlight(optset_T *args UNUSED)
 {
     if (highlight_changed() == FAIL)
 	return e_invalid_argument;	// invalid flags
@@ -868,15 +868,16 @@ did_set_opt_strings(char_u *val, char **
 /*
  * The 'sessionoptions' option is changed.
  */
-    static char *
-did_set_sessionoptions(char_u *oldval)
+    char *
+did_set_sessionoptions(optset_T *args)
 {
     if (opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE) != OK)
 	return e_invalid_argument;
     if ((ssop_flags & SSOP_CURDIR) && (ssop_flags & SSOP_SESDIR))
     {
 	// Don't allow both "sesdir" and "curdir".
-	(void)opt_strings_flags(oldval, p_ssop_values, &ssop_flags, TRUE);
+	(void)opt_strings_flags(args->os_oldval.string, p_ssop_values,
+							&ssop_flags, TRUE);
 	return e_invalid_argument;
     }
 
@@ -887,8 +888,8 @@ did_set_sessionoptions(char_u *oldval)
 /*
  * The 'ambiwidth' option is changed.
  */
-    static char *
-did_set_ambiwidth(void)
+    char *
+did_set_ambiwidth(optset_T *args UNUSED)
 {
     if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
 	return e_invalid_argument;
@@ -899,8 +900,8 @@ did_set_ambiwidth(void)
 /*
  * The 'background' option is changed.
  */
-    static char *
-did_set_background(void)
+    char *
+did_set_background(optset_T *args UNUSED)
 {
     if (check_opt_strings(p_bg, p_bg_values, FALSE) == FAIL)
 	return e_invalid_argument;
@@ -935,20 +936,20 @@ did_set_background(void)
 /*
  * The 'wildmode' option is changed.
  */
-    static char *
-did_set_wildmode(void)
+    char *
+did_set_wildmode(optset_T *args UNUSED)
 {
     if (check_opt_wim() == FAIL)
 	return e_invalid_argument;
     return NULL;
 }
 
-#ifdef FEAT_WAK
+#if defined(FEAT_WAK) || defined(PROTO)
 /*
  * The 'winaltkeys' option is changed.
  */
-    static char *
-did_set_winaltkeys(void)
+    char *
+did_set_winaltkeys(optset_T *args UNUSED)
 {
     char *errmsg = NULL;
 
@@ -971,8 +972,8 @@ did_set_winaltkeys(void)
 /*
  * The 'eventignore' option is changed.
  */
-    static char *
-did_set_eventignore(void)
+    char *
+did_set_eventignore(optset_T *args UNUSED)
 {
     if (check_ei() == FAIL)
 	return e_invalid_argument;
@@ -1066,12 +1067,12 @@ did_set_encoding(char_u **varp, char_u *
     return errmsg;
 }
 
-#if defined(FEAT_POSTSCRIPT)
+#if defined(FEAT_POSTSCRIPT) || defined(PROTO)
 /*
  * The 'printencoding' option is changed.
  */
-    static void
-did_set_printencoding(void)
+    char *
+did_set_printencoding(optset_T *args UNUSED)
 {
     char_u	*s, *p;
 
@@ -1093,15 +1094,17 @@ did_set_printencoding(void)
 		*s = TOLOWER_ASC(*s);
 	}
     }
+
+    return NULL;
 }
 #endif
 
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+#if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) || defined(PROTO)
 /*
  * The 'imactivatekey' option is changed.
  */
-    static char *
-did_set_imactivatekey(void)
+    char *
+did_set_imactivatekey(optset_T *args UNUSED)
 {
     if (!im_xim_isvalid_imactivate())
 	return e_invalid_argument;
@@ -1170,12 +1173,12 @@ did_set_keymap(char_u **varp, int opt_fl
 /*
  * The 'fileformat' option is changed.
  */
-    static char *
-did_set_fileformat(char_u **varp, char_u *oldval, int opt_flags)
+    char *
+did_set_fileformat(optset_T *args)
 {
-    if (!curbuf->b_p_ma && !(opt_flags & OPT_GLOBAL))
+    if (!curbuf->b_p_ma && !(args->os_flags & OPT_GLOBAL))
 	return e_cannot_make_changes_modifiable_is_off;
-    else if (check_opt_strings(*varp, p_ff_values, FALSE) != OK)
+    else if (check_opt_strings(args->os_varp, p_ff_values, FALSE) != OK)
 	return e_invalid_argument;
 
     // may also change 'textmode'
@@ -1188,7 +1191,7 @@ did_set_fileformat(char_u **varp, char_u
     ml_setflags(curbuf);
     // Redraw needed when switching to/from "mac": a CR in the text
     // will be displayed differently.
-    if (get_fileformat(curbuf) == EOL_MAC || *oldval == 'm')
+    if (get_fileformat(curbuf) == EOL_MAC || *args->os_oldval.string == 'm')
 	redraw_curbuf_later(UPD_NOT_VALID);
 
     return NULL;
@@ -1197,8 +1200,8 @@ did_set_fileformat(char_u **varp, char_u
 /*
  * The 'fileformats' option is changed.
  */
-    static char *
-did_set_fileformats(void)
+    char *
+did_set_fileformats(optset_T *args UNUSED)
 {
     if (check_opt_strings(p_ffs, p_ff_values, TRUE) != OK)
 	return e_invalid_argument;
@@ -1212,36 +1215,38 @@ did_set_fileformats(void)
     return NULL;
 }
 
-#if defined(FEAT_CRYPT)
+#if defined(FEAT_CRYPT) || defined(PROTO)
 /*
  * The 'cryptkey' option is changed.
  */
-    static void
-did_set_cryptkey(char_u *oldval)
+    char *
+did_set_cryptkey(optset_T *args)
 {
     // Make sure the ":set" command doesn't show the new value in the
     // history.
     remove_key_from_history();
 
-    if (STRCMP(curbuf->b_p_key, oldval) != 0)
+    if (STRCMP(curbuf->b_p_key, args->os_oldval.string) != 0)
     {
 	// Need to update the swapfile.
-	ml_set_crypt_key(curbuf, oldval,
+	ml_set_crypt_key(curbuf, args->os_oldval.string,
 		*curbuf->b_p_cm == NUL ? p_cm : curbuf->b_p_cm);
 	changed_internal();
     }
+
+    return NULL;
 }
 
 /*
  * The 'cryptmethod' option is changed.
  */
-    static char *
-did_set_cryptmethod(char_u *oldval, int opt_flags)
+    char *
+did_set_cryptmethod(optset_T *args)
 {
     char_u  *p;
     char_u  *s;
 
-    if (opt_flags & OPT_LOCAL)
+    if (args->os_flags & OPT_LOCAL)
 	p = curbuf->b_p_cm;
     else
 	p = p_cm;
@@ -1259,7 +1264,7 @@ did_set_cryptmethod(char_u *oldval, int 
     // When using ":set cm=name" the local value is going to be empty.
     // Do that here, otherwise the crypt functions will still use the
     // local value.
-    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
+    if ((args->os_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
     {
 	free_string_option(curbuf->b_p_cm);
 	curbuf->b_p_cm = empty_option;
@@ -1268,10 +1273,10 @@ did_set_cryptmethod(char_u *oldval, int 
     // Need to update the swapfile when the effective method changed.
     // Set "s" to the effective old value, "p" to the effective new
     // method and compare.
-    if ((opt_flags & OPT_LOCAL) && *oldval == NUL)
+    if ((args->os_flags & OPT_LOCAL) && *args->os_oldval.string == NUL)
 	s = p_cm;  // was previously using the global value
     else
-	s = oldval;
+	s = args->os_oldval.string;
     if (*curbuf->b_p_cm == NUL)
 	p = p_cm;  // is now using the global value
     else
@@ -1281,13 +1286,14 @@ did_set_cryptmethod(char_u *oldval, int 
 
     // If the global value changes need to update the swapfile for all
     // buffers using that value.
-    if ((opt_flags & OPT_GLOBAL) && STRCMP(p_cm, oldval) != 0)
+    if ((args->os_flags & OPT_GLOBAL)
+	    && STRCMP(p_cm, args->os_oldval.string) != 0)
     {
 	buf_T	*buf;
 
 	FOR_ALL_BUFFERS(buf)
 	    if (buf != curbuf && *buf->b_p_cm == NUL)
-		ml_set_crypt_key(buf, buf->b_p_key, oldval);
+		ml_set_crypt_key(buf, buf->b_p_key, args->os_oldval.string);
     }
     return NULL;
 }
@@ -1296,14 +1302,14 @@ did_set_cryptmethod(char_u *oldval, int 
 /*
  * The 'matchpairs' option is changed.
  */
-    static char *
-did_set_matchpairs(char_u **varp)
+    char *
+did_set_matchpairs(optset_T *args)
 {
     char_u	*p;
 
     if (has_mbyte)
     {
-	for (p = *varp; *p != NUL; ++p)
+	for (p = args->os_varp; *p != NUL; ++p)
 	{
 	    int x2 = -1;
 	    int x3 = -1;
@@ -1325,7 +1331,7 @@ did_set_matchpairs(char_u **varp)
     else
     {
 	// Check for "x:y,x:y"
-	for (p = *varp; *p != NUL; p += 4)
+	for (p = args->os_varp; *p != NUL; p += 4)
 	{
 	    if (p[1] != ':' || p[2] == NUL || (p[3] != NUL && p[3] != ','))
 		return e_invalid_argument;
@@ -1419,8 +1425,8 @@ did_set_global_listfillchars(char_u **va
 /*
  * The 'verbosefile' option is changed.
  */
-    static char *
-did_set_verbosefile(void)
+    char *
+did_set_verbosefile(optset_T *args UNUSED)
 {
     verbose_stop();
     if (*p_vfile != NUL && verbose_open() == FAIL)
@@ -1560,16 +1566,16 @@ did_set_term_option(char_u **varp, int *
     }
 }
 
-#ifdef FEAT_LINEBREAK
+#if defined(FEAT_LINEBREAK) || defined(PROTO)
 /*
  * The 'showbreak' option is changed.
  */
-    static char *
-did_set_showbreak(char_u **varp)
+    char *
+did_set_showbreak(optset_T *args)
 {
     char_u	*s;
 
-    for (s = *varp; *s; )
+    for (s = args->os_varp; *s; )
     {
 	if (ptr2cells(s) != 1)
 	    return e_showbreak_contains_unprintable_or_wide_character;
@@ -1580,12 +1586,12 @@ did_set_showbreak(char_u **varp)
 }
 #endif
 
-#ifdef FEAT_GUI
+#if defined(FEAT_GUI) || defined(PROTO)
 /*
  * The 'guifont' option is changed.
  */
-    static char *
-did_set_guifont(char_u *oldval UNUSED)
+    char *
+did_set_guifont(optset_T *args UNUSED)
 {
     char_u	*p;
     char	*errmsg = NULL;
@@ -1599,9 +1605,9 @@ did_set_guifont(char_u *oldval UNUSED)
 	// give an error message.
 	if (STRCMP(p, "*") == 0)
 	{
-	    p = gui_mch_font_dialog(oldval);
+	    p = gui_mch_font_dialog(args->os_oldval.string);
 	    free_string_option(p_guifont);
-	    p_guifont = (p != NULL) ? p : vim_strsave(oldval);
+	    p_guifont = (p != NULL) ? p : vim_strsave(args->os_oldval.string);
 	}
 # endif
 	if (p != NULL && gui_init_font(p_guifont, FALSE) != OK)
@@ -1612,7 +1618,7 @@ did_set_guifont(char_u *oldval UNUSED)
 		// Dialog was cancelled: Keep the old value without giving
 		// an error message.
 		free_string_option(p_guifont);
-		p_guifont = vim_strsave(oldval);
+		p_guifont = vim_strsave(args->os_oldval.string);
 	    }
 	    else
 # endif
@@ -1623,12 +1629,12 @@ did_set_guifont(char_u *oldval UNUSED)
     return errmsg;
 }
 
-# ifdef FEAT_XFONTSET
+# if defined(FEAT_XFONTSET) || defined(PROTO)
 /*
  * The 'guifontset' option is changed.
  */
-    static char *
-did_set_guifontset()
+    char *
+did_set_guifontset(optset_T *args UNUSED)
 {
     char *errmsg = NULL;
 
@@ -1644,8 +1650,8 @@ did_set_guifontset()
 /*
  * The 'guifontwide' option is changed.
  */
-    static char *
-did_set_guifontwide(void)
+    char *
+did_set_guifontwide(optset_T *args UNUSED)
 {
     char *errmsg = NULL;
 
@@ -1658,17 +1664,21 @@ did_set_guifontwide(void)
 }
 #endif
 
-#if defined(FEAT_GUI_GTK)
-    static void
-did_set_guiligatures(void)
+#if defined(FEAT_GUI_GTK) || defined(PROTO)
+/*
+ * The 'guiligatures' option is changed.
+ */
+    char *
+did_set_guiligatures(optset_T *args UNUSED)
 {
     gui_set_ligatures();
+    return NULL;
 }
 #endif
 
-#ifdef FEAT_MOUSESHAPE
-    static char *
-did_set_mouseshape(void)
+#if defined(FEAT_MOUSESHAPE) || defined(PROTO)
+    char *
+did_set_mouseshape(optset_T *args UNUSED)
 {
     char *errmsg = NULL;
 
@@ -1682,46 +1692,81 @@ did_set_mouseshape(void)
 /*
  * The 'titlestring' or the 'iconstring' option is changed.
  */
-    static void
-did_set_titleiconstring(char_u **varp UNUSED)
+    static char *
+did_set_titleiconstring(optset_T *args UNUSED, int flagval UNUSED)
 {
 #ifdef FEAT_STL_OPT
-    int	flagval = (varp == &p_titlestring) ? STL_IN_TITLE : STL_IN_ICON;
-
     // NULL => statusline syntax
-    if (vim_strchr(*varp, '%') && check_stl_option(*varp) == NULL)
+    if (vim_strchr(args->os_varp, '%')
+				    && check_stl_option(args->os_varp) == NULL)
 	stl_syntax |= flagval;
     else
 	stl_syntax &= ~flagval;
 #endif
     did_set_title();
+
+    return NULL;
+}
+
+/*
+ * The 'titlestring' option is changed.
+ */
+    char *
+did_set_titlestring(optset_T *args)
+{
+    int flagval = 0;
+
+#ifdef FEAT_STL_OPT
+    flagval = STL_IN_TITLE;
+#endif
+    return did_set_titleiconstring(args, flagval);
+}
+
+/*
+ * The 'iconstring' option is changed.
+ */
+    char *
+did_set_iconstring(optset_T *args)
+{
+    int flagval = 0;
+
+#ifdef FEAT_STL_OPT
+    flagval = STL_IN_ICON;
+#endif
+
+    return did_set_titleiconstring(args, flagval);
 }
 
 #ifdef FEAT_GUI
 /*
  * The 'guioptions' option is changed.
  */
-    static void
-did_set_guioptions(char_u *oldval)
+    char *
+did_set_guioptions(optset_T *args)
 {
-    gui_init_which_components(oldval);
+    gui_init_which_components(args->os_oldval.string);
+    return NULL;
 }
 #endif
 
 #if defined(FEAT_GUI_TABLINE)
-    static void
-did_set_guitablabel()
+/*
+ * The 'guitablabel' option is changed.
+ */
+    char *
+did_set_guitablabel(optset_T *args UNUSED)
 {
     redraw_tabline = TRUE;
+    return NULL;
 }
 #endif
 
-#if defined(UNIX) || defined(VMS)
+#if defined(UNIX) || defined(VMS) || defined(PROTO)
 /*
  * The 'ttymouse' option is changed.
  */
-    static char *
-did_set_ttymouse(void)
+    char *
+did_set_ttymouse(optset_T *args UNUSED)
 {
     char *errmsg = NULL;
 
@@ -1742,8 +1787,8 @@ did_set_ttymouse(void)
 /*
  * The 'selection' option is changed.
  */
-    static char *
-did_set_selection(void)
+    char *
+did_set_selection(optset_T *args UNUSED)
 {
     if (*p_sel == NUL
 	    || check_opt_strings(p_sel, p_sel_values, FALSE) != OK)
@@ -1752,12 +1797,12 @@ did_set_selection(void)
     return NULL;
 }
 
-#ifdef FEAT_BROWSE
+#if defined(FEAT_BROWSE) || defined(PROTO)
 /*
  * The 'browsedir' option is changed.
  */
-    static char *
-did_set_browsedir(void)
+    char *
+did_set_browsedir(optset_T *args UNUSED)
 {
     if (check_opt_strings(p_bsdir, p_bsdir_values, FALSE) != OK
 	    && !mch_isdir(p_bsdir))
@@ -1770,8 +1815,8 @@ did_set_browsedir(void)
 /*
  * The 'keymodel' option is changed.
  */
-    static char *
-did_set_keymodel(void)
+    char *
+did_set_keymodel(optset_T *args UNUSED)
 {
     if (check_opt_strings(p_km, p_km_values, TRUE) != OK)
 	return e_invalid_argument;
@@ -1784,8 +1829,8 @@ did_set_keymodel(void)
 /*
  * The 'keyprotocol' option is changed.
  */
-    static char *
-did_set_keyprotocol(void)
+    char *
+did_set_keyprotocol(optset_T *args UNUSED)
 {
     if (match_keyprotocol(NULL) == KEYPROTOCOL_FAIL)
 	return e_invalid_argument;
@@ -1796,8 +1841,8 @@ did_set_keyprotocol(void)
 /*
  * The 'mousemodel' option is changed.
  */
-    static char *
-did_set_mousemodel(void)
+    char *
+did_set_mousemodel(optset_T *args UNUSED)
 {
     if (check_opt_strings(p_mousem, p_mousem_values, FALSE) != OK)
 	return e_invalid_argument;
@@ -1814,8 +1859,8 @@ did_set_mousemodel(void)
 /*
  * The 'display' option is changed.
  */
-    static char *
-did_set_display(void)
+    char *
+did_set_display(optset_T *args UNUSED)
 {
     if (opt_strings_flags(p_dy, p_dy_values, &dy_flags, TRUE) != OK)
 	return e_invalid_argument;
@@ -1824,14 +1869,14 @@ did_set_display(void)
     return NULL;
 }
 
-#ifdef FEAT_SPELL
+#if defined(FEAT_SPELL) || defined(PROTO)
 /*
  * The 'spellfile' option is changed.
  */
-    static char *
-did_set_spellfile(char_u **varp)
+    char *
+did_set_spellfile(optset_T *args)
 {
-    if (!valid_spellfile(*varp))
+    if (!valid_spellfile(args->os_varp))
 	return e_invalid_argument;
 
     // If there is a window for this buffer in which 'spell' is set load the
@@ -1842,10 +1887,10 @@ did_set_spellfile(char_u **varp)
 /*
  * The 'spell' option is changed.
  */
-    static char *
-did_set_spell(char_u **varp)
+    char *
+did_set_spelllang(optset_T *args)
 {
-    if (!valid_spelllang(*varp))
+    if (!valid_spelllang(args->os_varp))
 	return e_invalid_argument;
 
     // If there is a window for this buffer in which 'spell' is set load the
@@ -1856,8 +1901,8 @@ did_set_spell(char_u **varp)
 /*
  * The 'spellcapcheck' option is changed.
  */
-    static char *
-did_set_spellcapcheck(void)
+    char *
+did_set_spellcapcheck(optset_T *args UNUSED)
 {
     // compile the regexp program.
     return compile_cap_prog(curwin->w_s);
@@ -1866,10 +1911,10 @@ did_set_spellcapcheck(void)
 /*
  * The 'spelloptions' option is changed.
  */
-    static char *
-did_set_spelloptions(char_u **varp)
+    char *
+did_set_spelloptions(optset_T *args)
 {
-    if (**varp != NUL && STRCMP("camel", *varp) != 0)
+    if (*args->os_varp != NUL && STRCMP("camel", args->os_varp) != 0)
 	return e_invalid_argument;
 
     return NULL;
@@ -1878,8 +1923,8 @@ did_set_spelloptions(char_u **varp)
 /*
  * The 'spellsuggest' option is changed.
  */
-    static char *
-did_set_spellsuggest(void)
+    char *
+did_set_spellsuggest(optset_T *args UNUSED)
 {
     if (spell_check_sps() != OK)
 	return e_invalid_argument;
@@ -1890,8 +1935,8 @@ did_set_spellsuggest(void)
 /*
  * The 'mkspellmem' option is changed.
  */
-    static char *
-did_set_mkspellmem(void)
+    char *
+did_set_mkspellmem(optset_T *args UNUSED)
 {
     if (spell_check_msm() != OK)
 	return e_invalid_argument;
@@ -1903,8 +1948,8 @@ did_set_mkspellmem(void)
 /*
  * The 'buftype' option is changed.
  */
-    static char *
-did_set_buftype(void)
+    char *
+did_set_buftype(optset_T *args UNUSED)
 {
     if (check_opt_strings(curbuf->b_p_bt, p_buftype_values, FALSE) != OK)
 	return e_invalid_argument;
@@ -1923,18 +1968,19 @@ did_set_buftype(void)
 #ifdef FEAT_STL_OPT
 /*
  * The 'statusline' or the 'tabline' or the 'rulerformat' option is changed.
+ * "rulerformat" is TRUE if the 'rulerformat' option is changed.
  */
     static char *
-did_set_statusline(char_u **varp)
+did_set_statustabline_rulerformat(optset_T *args, int rulerformat)
 {
     char_u	*s;
     char	*errmsg = NULL;
     int		wid;
 
-    if (varp == &p_ruf)	// reset ru_wid first
+    if (rulerformat)	// reset ru_wid first
 	ru_wid = 0;
-    s = *varp;
-    if (varp == &p_ruf && *s == '%')
+    s = args->os_varp;
+    if (rulerformat && *s == '%')
     {
 	// set ru_wid if 'ruf' starts with "%99("
 	if (*++s == '-')	// ignore a '-'
@@ -1946,13 +1992,41 @@ did_set_statusline(char_u **varp)
 	    errmsg = check_stl_option(p_ruf);
     }
     // check 'statusline' or 'tabline' only if it doesn't start with "%!"
-    else if (varp == &p_ruf || s[0] != '%' || s[1] != '!')
+    else if (rulerformat || s[0] != '%' || s[1] != '!')
 	errmsg = check_stl_option(s);
-    if (varp == &p_ruf && errmsg == NULL)
+    if (rulerformat && errmsg == NULL)
 	comp_col();
 
     return errmsg;
 }
+
+/*
+ * The 'statusline' option is changed.
+ */
+    char *
+did_set_statusline(optset_T *args)
+{
+    return did_set_statustabline_rulerformat(args, FALSE);
+}
+
+/*
+ * The 'tabline' option is changed.
+ */
+    char *
+did_set_tabline(optset_T *args)
+{
+    return did_set_statustabline_rulerformat(args, FALSE);
+}
+
+
+/*
+ * The 'rulerformat' option is changed.
+ */
+    char *
+did_set_rulerformat(optset_T *args)
+{
+    return did_set_statustabline_rulerformat(args, TRUE);
+}
 #endif
 
 /*
@@ -2003,8 +2077,8 @@ did_set_complete(char_u **varp, char *er
 /*
  * The 'completeopt' option is changed.
  */
-    static char *
-did_set_completeopt(void)
+    char *
+did_set_completeopt(optset_T *args UNUSED)
 {
     if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
 	return e_invalid_argument;
@@ -2013,12 +2087,12 @@ did_set_completeopt(void)
     return NULL;
 }
 
-#ifdef BACKSLASH_IN_FILENAME
+#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
 /*
  * The 'completeslash' option is changed.
  */
-    static char *
-did_set_completeslash(void)
+    char *
+did_set_completeslash(optset_T *args UNUSED)
 {
     if (check_opt_strings(p_csl, p_csl_values, FALSE) != OK
 	    || check_opt_strings(curbuf->b_p_csl, p_csl_values, FALSE) != OK)
@@ -2028,18 +2102,18 @@ did_set_completeslash(void)
 }
 #endif
 
-#ifdef FEAT_SIGNS
+#if defined(FEAT_SIGNS) || defined(PROTO)
 /*
  * The 'signcolumn' option is changed.
  */
-    static char *
-did_set_signcolumn(char_u **varp, char_u *oldval)
+    char *
+did_set_signcolumn(optset_T *args)
 {
-    if (check_opt_strings(*varp, p_scl_values, FALSE) != OK)
+    if (check_opt_strings(args->os_varp, p_scl_values, FALSE) != OK)
 	return e_invalid_argument;
     // When changing the 'signcolumn' to or from 'number', recompute the
     // width of the number column if 'number' or 'relativenumber' is set.
-    if (((*oldval == 'n' && *(oldval + 1) == 'u')
+    if (((*args->os_oldval.string == 'n' && args->os_oldval.string[1] == 'u')
 		|| (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) =='u'))
 	    && (curwin->w_p_nu || curwin->w_p_rnu))
 	curwin->w_nrwidth_line_count = 0;
@@ -2048,12 +2122,12 @@ did_set_signcolumn(char_u **varp, char_u
 }
 #endif
 
-#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)
+#if (defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)) || defined(PROTO)
 /*
  * The 'toolbar' option is changed.
  */
-    static char *
-did_set_toolbar(void)
+    char *
+did_set_toolbar(optset_T *args UNUSED)
 {
     if (opt_strings_flags(p_toolbar, p_toolbar_values,
 		&toolbar_flags, TRUE) != OK)
@@ -2066,12 +2140,12 @@ did_set_toolbar(void)
 }
 #endif
 
-#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
+#if (defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)) || defined(PROTO)
 /*
  * The 'toolbariconsize' option is changed.  GTK+ 2 only.
  */
-    static char *
-did_set_toolbariconsize(void)
+    char *
+did_set_toolbariconsize(optset_T *args UNUSED)
 {
     if (opt_strings_flags(p_tbis, p_tbis_values, &tbis_flags, FALSE) != OK)
 	return e_invalid_argument;
@@ -2086,8 +2160,8 @@ did_set_toolbariconsize(void)
 /*
  * The 'pastetoggle' option is changed.
  */
-    static void
-did_set_pastetoggle(void)
+    char *
+did_set_pastetoggle(optset_T *args UNUSED)
 {
     char_u	*p;
 
@@ -2102,13 +2176,15 @@ did_set_pastetoggle(void)
 	    p_pt = p;
 	}
     }
+
+    return NULL;
 }
 
 /*
  * The 'backspace' option is changed.
  */
-    static char *
-did_set_backspace(void)
+    char *
+did_set_backspace(optset_T *args UNUSED)
 {
     if (VIM_ISDIGIT(*p_bs))
     {
@@ -2124,13 +2200,13 @@ did_set_backspace(void)
 /*
  * The 'tagcase' option is changed.
  */
-    static char *
-did_set_tagcase(int opt_flags)
+    char *
+did_set_tagcase(optset_T *args)
 {
     unsigned int	*flags;
     char_u		*p;
 
-    if (opt_flags & OPT_LOCAL)
+    if (args->os_flags & OPT_LOCAL)
     {
 	p = curbuf->b_p_tc;
 	flags = &curbuf->b_tc_flags;
@@ -2141,7 +2217,7 @@ did_set_tagcase(int opt_flags)
 	flags = &tc_flags;
     }
 
-    if ((opt_flags & OPT_LOCAL) && *p == NUL)
+    if ((args->os_flags & OPT_LOCAL) && *p == NUL)
 	// make the local value empty: use the global value
 	*flags = 0;
     else if (*p == NUL
@@ -2151,12 +2227,12 @@ did_set_tagcase(int opt_flags)
     return NULL;
 }
 
-#ifdef FEAT_DIFF
+#if defined(FEAT_DIFF) || defined(PROTO)
 /*
  * The 'diffopt' option is changed.
  */
-    static char *
-did_set_diffopt(void)
+    char *
+did_set_diffopt(optset_T *args UNUSED)
 {
     if (diffopt_changed() == FAIL)
 	return e_invalid_argument;
@@ -2165,14 +2241,14 @@ did_set_diffopt(void)
 }
 #endif
 
-#ifdef FEAT_FOLDING
+#if defined(FEAT_FOLDING) || defined(PROTO)
 /*
  * The 'foldmethod' option is changed.
  */
-    static char *
-did_set_foldmethod(char_u **varp)
+    char *
+did_set_foldmethod(optset_T *args)
 {
-    if (check_opt_strings(*varp, p_fdm_values, FALSE) != OK
+    if (check_opt_strings(args->os_varp, p_fdm_values, FALSE) != OK
 	    || *curwin->w_p_fdm == NUL)
 	return e_invalid_argument;
 
@@ -2185,15 +2261,15 @@ did_set_foldmethod(char_u **varp)
 /*
  * The 'foldmarker' option is changed.
  */
-    static char *
-did_set_foldmarker(char_u **varp)
+    char *
+did_set_foldmarker(optset_T *args)
 {
     char_u	*p;
 
-    p = vim_strchr(*varp, ',');
+    p = vim_strchr(args->os_varp, ',');
     if (p == NULL)
 	return e_comma_required;
-    else if (p == *varp || p[1] == NUL)
+    else if (p == args->os_varp || p[1] == NUL)
 	return e_invalid_argument;
     else if (foldmethodIsMarker(curwin))
 	foldUpdateAll(curwin);
@@ -2204,10 +2280,10 @@ did_set_foldmarker(char_u **varp)
 /*
  * The 'commentstring' option is changed.
  */
-    static char *
-did_set_commentstring(char_u **varp)
+    char *
+did_set_commentstring(optset_T *args)
 {
-    if (**varp != NUL && strstr((char *)*varp, "%s") == NULL)
+    if (*args->os_varp != NUL && strstr((char *)args->os_varp, "%s") == NULL)
 	return e_commentstring_must_be_empty_or_contain_str;
 
     return NULL;
@@ -2216,37 +2292,38 @@ did_set_commentstring(char_u **varp)
 /*
  * The 'foldignore' option is changed.
  */
-    static void
-did_set_foldignore(void)
+    char *
+did_set_foldignore(optset_T *args UNUSED)
 {
     if (foldmethodIsIndent(curwin))
 	foldUpdateAll(curwin);
+    return NULL;
 }
 #endif
 
 /*
  * The 'virtualedit' option is changed.
  */
-    static char *
-did_set_virtualedit(char_u *oldval, int opt_flags)
+    char *
+did_set_virtualedit(optset_T *args)
 {
     char_u		*ve = p_ve;
     unsigned int	*flags = &ve_flags;
 
-    if (opt_flags & OPT_LOCAL)
+    if (args->os_flags & OPT_LOCAL)
     {
 	ve = curwin->w_p_ve;
 	flags = &curwin->w_ve_flags;
     }
 
-    if ((opt_flags & OPT_LOCAL) && *ve == NUL)
+    if ((args->os_flags & OPT_LOCAL) && *ve == NUL)
 	// make the local value empty: use the global value
 	*flags = 0;
     else
     {
 	if (opt_strings_flags(ve, p_ve_values, flags, TRUE) != OK)
 	    return e_invalid_argument;
-	else if (STRCMP(ve, oldval) != 0)
+	else if (STRCMP(ve, args->os_oldval.string) != 0)
 	{
 	    // Recompute cursor position in case the new 've' setting
 	    // changes something.
@@ -2258,12 +2335,12 @@ did_set_virtualedit(char_u *oldval, int 
     return NULL;
 }
 
-#if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)
+#if (defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)) || defined(PROTO)
 /*
  * The 'cscopequickfix' option is changed.
  */
-    static char *
-did_set_cscopequickfix(void)
+    char *
+did_set_cscopequickfix(optset_T *args UNUSED)
 {
     char_u	*p;
 
@@ -2291,32 +2368,34 @@ did_set_cscopequickfix(void)
 /*
  * The 'cinoptions' option is changed.
  */
-    static void
-did_set_cinoptions(void)
+    char *
+did_set_cinoptions(optset_T *args UNUSED)
 {
     // TODO: recognize errors
     parse_cino(curbuf);
+
+    return NULL;
 }
 
 /*
  * The 'lispoptions' option is changed.
  */
-    static char *
-did_set_lispoptions(char_u **varp)
+    char *
+did_set_lispoptions(optset_T *args)
 {
-    if (**varp != NUL && STRCMP(*varp, "expr:0") != 0
-	    && STRCMP(*varp, "expr:1") != 0)
+    if (*args->os_varp != NUL && STRCMP(args->os_varp, "expr:0") != 0
+	    && STRCMP(args->os_varp, "expr:1") != 0)
 	return e_invalid_argument;
 
     return NULL;
 }
 
-#if defined(FEAT_RENDER_OPTIONS)
+#if defined(FEAT_RENDER_OPTIONS) || defined(PROTO)
 /*
  * The 'renderoptions' option is changed.
  */
-    static char *
-did_set_renderoptions(void)
+    char *
+did_set_renderoptions(optset_T *args UNUSED)
 {
     if (!gui_mch_set_rendering_options(p_rop))
 	return e_invalid_argument;
@@ -2347,12 +2426,12 @@ did_set_filetype_or_syntax(
     return NULL;
 }
 
-#ifdef FEAT_TERMINAL
+#if defined(FEAT_TERMINAL) || defined(PROTO)
 /*
  * The 'termwinkey' option is changed.
  */
-    static char *
-did_set_termwinkey(void)
+    char *
+did_set_termwinkey(optset_T *args UNUSED)
 {
     if (*curwin->w_p_twk != NUL
 	    && string_to_key(curwin->w_p_twk, TRUE) == 0)
@@ -2364,8 +2443,8 @@ did_set_termwinkey(void)
 /*
  * The 'termwinsize' option is changed.
  */
-    static char *
-did_set_termwinsize(void)
+    char *
+did_set_termwinsize(optset_T *args UNUSED)
 {
     char_u	*p;
 
@@ -2382,16 +2461,16 @@ did_set_termwinsize(void)
 }
 #endif
 
-#ifdef FEAT_VARTABS
+#if defined(FEAT_VARTABS) || defined(PROTO)
 /*
  * The 'varsofttabstop' option is changed.
  */
-    static char *
-did_set_varsofttabstop(char_u **varp)
+    char *
+did_set_varsofttabstop(optset_T *args)
 {
     char_u *cp;
 
-    if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1]))
+    if (!(args->os_varp[0]) || (args->os_varp[0] == '0' && !(args->os_varp[1])))
     {
 	if (curbuf->b_p_vsts_array)
 	{
@@ -2401,17 +2480,17 @@ did_set_varsofttabstop(char_u **varp)
     }
     else
     {
-	for (cp = *varp; *cp; ++cp)
+	for (cp = args->os_varp; *cp; ++cp)
 	{
 	    if (vim_isdigit(*cp))
 		continue;
-	    if (*cp == ',' && cp > *varp && *(cp-1) != ',')
+	    if (*cp == ',' && cp > args->os_varp && *(cp-1) != ',')
 		continue;
 	    return e_invalid_argument;
 	}
 
 	int *oldarray = curbuf->b_p_vsts_array;
-	if (tabstop_set(*varp, &(curbuf->b_p_vsts_array)) == OK)
+	if (tabstop_set(args->os_varp, &(curbuf->b_p_vsts_array)) == OK)
 	{
 	    if (oldarray)
 		vim_free(oldarray);
@@ -2426,12 +2505,12 @@ did_set_varsofttabstop(char_u **varp)
 /*
  * The 'vartabstop' option is changed.
  */
-    static char *
-did_set_vartabstop(char_u **varp)
+    char *
+did_set_vartabstop(optset_T *args)
 {
     char_u *cp;
 
-    if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1]))
+    if (!(args->os_varp[0]) || (args->os_varp[0] == '0' && !(args->os_varp[1])))
     {
 	if (curbuf->b_p_vts_array)
 	{
@@ -2441,18 +2520,18 @@ did_set_vartabstop(char_u **varp)
     }
     else
     {
-	for (cp = *varp; *cp; ++cp)
+	for (cp = args->os_varp; *cp; ++cp)
 	{
 	    if (vim_isdigit(*cp))
 		continue;
-	    if (*cp == ',' && cp > *varp && *(cp-1) != ',')
+	    if (*cp == ',' && cp > args->os_varp && *(cp-1) != ',')
 		continue;
 	    return e_invalid_argument;
 	}
 
 	int *oldarray = curbuf->b_p_vts_array;
 
-	if (tabstop_set(*varp, &(curbuf->b_p_vts_array)) == OK)
+	if (tabstop_set(args->os_varp, &(curbuf->b_p_vts_array)) == OK)
 	{
 	    vim_free(oldarray);
 # ifdef FEAT_FOLDING
@@ -2468,12 +2547,12 @@ did_set_vartabstop(char_u **varp)
 }
 #endif
 
-#ifdef FEAT_PROP_POPUP
+#if defined(FEAT_PROP_POPUP) || defined(PROTO)
 /*
  * The 'previewpopup' option is changed.
  */
-    static char *
-did_set_previewpopup(void)
+    char *
+did_set_previewpopup(optset_T *args UNUSED)
 {
     if (parse_previewpopup(NULL) == FAIL)
 	return e_invalid_argument;
@@ -2481,12 +2560,12 @@ did_set_previewpopup(void)
     return NULL;
 }
 
-# ifdef FEAT_QUICKFIX
+# if defined(FEAT_QUICKFIX) || defined(PROTO)
 /*
  * The 'completepopup' option is changed.
  */
-    static char *
-did_set_completepopup(void)
+    char *
+did_set_completepopup(optset_T *args UNUSED)
 {
     if (parse_completepopup(NULL) == FAIL)
 	return e_invalid_argument;
@@ -2629,6 +2708,7 @@ did_set_string_option(
     int		opt_idx,		// index in options[] table
     char_u	**varp,			// pointer to the option variable
     char_u	*oldval,		// previous value of the option
+    char_u	*value,			// new value of the option
     char	*errbuf,		// buffer for errors, or NULL
     int		opt_flags,		// OPT_LOCAL and/or OPT_GLOBAL
     int		*value_checked)		// value was checked to be safe, no
@@ -2638,12 +2718,9 @@ did_set_string_option(
     int		did_chartab = FALSE;
     char_u	**gvarp;
     long_u	free_oldval = (get_option_flags(opt_idx) & P_ALLOCED);
-#ifdef FEAT_GUI
-    // set when changing an option that only requires a redraw in the GUI
-    int		redraw_gui_only = FALSE;
-#endif
     int		value_changed = FALSE;
     int		did_swaptcap = FALSE;
+    opt_did_set_cb_T did_set_cb = get_option_did_set_cb(opt_idx);
 
     // Get the global option to compare with, otherwise we would have to check
     // two values for all local options.
@@ -2659,25 +2736,23 @@ did_set_string_option(
     // Check for a "normal" directory or file name in some options.
     else if (check_illegal_path_names(opt_idx, varp))
 	errmsg = e_invalid_argument;
+    else if (did_set_cb != NULL)
+    {
+	optset_T   args;
+
+	args.os_varp = *varp;
+	args.os_flags = opt_flags;
+	args.os_oldval.string = oldval;
+	args.os_newval.string = value;
+	errmsg = did_set_cb(&args);
+    }
     else if (varp == &T_NAME)			// 'term'
 	errmsg = did_set_term(&opt_idx, &free_oldval);
-    else if (gvarp == &p_bkc)			// 'backupcopy'
-	errmsg = did_set_backupcopy(oldval, opt_flags);
-    else if (  varp == &p_bex			// 'backupext'
-	    || varp == &p_pm)			// 'patchmode'
-	errmsg = did_set_backupext_or_patchmode();
-#ifdef FEAT_LINEBREAK
-    else if (varp == &curwin->w_p_briopt)	// 'breakindentopt'
-	errmsg = did_set_breakindentopt();
-#endif
-
     else if (  varp == &p_isi			// 'isident'
 	    || varp == &(curbuf->b_p_isk)	// 'iskeyword'
 	    || varp == &p_isp			// 'isprint'
 	    || varp == &p_isf)			// 'isfname'
 	errmsg = did_set_isopt(&did_chartab);
-    else if (varp == &p_hf)			// 'helpfile'
-	did_set_helpfile();
 #ifdef FEAT_SYN_HL
     else if (  varp == &curwin->w_p_culopt	// 'cursorlineopt'
 	    || gvarp == &curwin->w_allbuf_opt.wo_culopt)
@@ -2685,67 +2760,25 @@ did_set_string_option(
     else if (varp == &curwin->w_p_cc)		// 'colorcolumn'
 	errmsg = check_colorcolumn(curwin);
 #endif
-#ifdef FEAT_MULTI_LANG
-    else if (varp == &p_hlg)			// 'helplang'
-	errmsg = did_set_helplang();
-#endif
-    else if (varp == &p_hl)			// 'highlight'
-	errmsg = did_set_highlight();
     else if (gvarp == &p_nf)			// 'nrformats'
 	errmsg = did_set_opt_strings(*varp, p_nf_values, TRUE);
 #ifdef FEAT_SESSION
-    else if (varp == &p_ssop)			// 'sessionoptions'
-	errmsg = did_set_sessionoptions(oldval);
     else if (varp == &p_vop)			// 'viewoptions'
 	errmsg = did_set_opt_flags(p_vop, p_ssop_values, &vop_flags, TRUE);
 #endif
     else if (varp == &p_sbo)			// 'scrollopt'
 	errmsg = did_set_opt_strings(p_sbo, p_scbopt_values, TRUE);
-    else if (  varp == &p_ambw			// 'ambiwidth'
-	    || varp == &p_emoji)		// 'emoji'
-	errmsg = did_set_ambiwidth();
-    else if (varp == &p_bg)			// 'background'
-	errmsg = did_set_background();
-    else if (varp == &p_wim)			// 'wildmode'
-	errmsg = did_set_wildmode();
     else if (varp == &p_wop)			// 'wildoptions'
 	errmsg = did_set_opt_strings(p_wop, p_wop_values, TRUE);
-#ifdef FEAT_WAK
-    else if (varp == &p_wak)			// 'winaltkeys'
-	errmsg = did_set_winaltkeys();
-#endif
-    else if (varp == &p_ei)			// 'eventignore'
-	errmsg = did_set_eventignore();
-
     else if (  varp == &p_enc			// 'encoding'
 	    || gvarp == &p_fenc			// 'fileencoding'
 	    || varp == &p_tenc			// 'termencoding'
 	    || gvarp == &p_menc)		// 'makeencoding'
 	errmsg = did_set_encoding(varp, gvarp, opt_flags);
-#if defined(FEAT_POSTSCRIPT)
-    else if (varp == &p_penc)			// 'printencoding'
-	did_set_printencoding();
-#endif
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
-    else if (varp == &p_imak)			// 'imactivatekey'
-	errmsg = did_set_imactivatekey();
-#endif
 #ifdef FEAT_KEYMAP
     else if (varp == &curbuf->b_p_keymap)	// 'keymap'
 	errmsg = did_set_keymap(varp, opt_flags, value_checked);
 #endif
-    else if (gvarp == &p_ff)			// 'fileformat'
-	errmsg = did_set_fileformat(varp, oldval, opt_flags);
-    else if (varp == &p_ffs)			// 'fileformats'
-	errmsg = did_set_fileformats();
-#if defined(FEAT_CRYPT)
-    else if (gvarp == &p_key)			// 'cryptkey'
-	did_set_cryptkey(oldval);
-    else if (gvarp == &p_cm)			// 'cryptmethod'
-	errmsg = did_set_cryptmethod(oldval, opt_flags);
-#endif
-    else if (gvarp == &p_mps)			// 'matchpairs'
-	errmsg = did_set_matchpairs(varp);
     else if (gvarp == &p_com)			// 'comments'
 	errmsg = did_set_comments(varp, errbuf);
     else if (  varp == &p_lcs			// global 'listchars'
@@ -2755,10 +2788,6 @@ did_set_string_option(
 	errmsg = set_chars_option(curwin, varp, TRUE);
     else if (varp == &curwin->w_p_fcs)		// local 'fillchars'
 	errmsg = set_chars_option(curwin, varp, TRUE);
-    else if (varp == &p_cedit)			// 'cedit'
-	errmsg = check_cedit();
-    else if (varp == &p_vfile)			// 'verbosefile'
-	errmsg = did_set_verbosefile();
 #ifdef FEAT_VIMINFO
     else if (varp == &p_viminfo)		// 'viminfo'
 	errmsg = did_set_viminfo(errbuf);
@@ -2766,199 +2795,36 @@ did_set_string_option(
     // terminal options
     else if (istermoption_idx(opt_idx) && full_screen)
 	did_set_term_option(varp, &did_swaptcap);
-#ifdef FEAT_LINEBREAK
-    else if (gvarp == &p_sbr)			// 'showbreak'
-	errmsg = did_set_showbreak(varp);
-#endif
-#ifdef FEAT_GUI
-    else if (varp == &p_guifont)		// 'guifont'
-    {
-	errmsg = did_set_guifont(oldval);
-	redraw_gui_only = TRUE;
-    }
-# ifdef FEAT_XFONTSET
-    else if (varp == &p_guifontset)		// 'guifontset'
-    {
-	errmsg = did_set_guifontset();
-	redraw_gui_only = TRUE;
-    }
-# endif
-    else if (varp == &p_guifontwide)		// 'guifontwide'
-    {
-	errmsg = did_set_guifontwide();
-	redraw_gui_only = TRUE;
-    }
-#endif
-#if defined(FEAT_GUI_GTK)
-    else if (varp == &p_guiligatures)		// 'guiligatures'
-    {
-	did_set_guiligatures();
-	redraw_gui_only = TRUE;
-    }
-#endif
 #ifdef CURSOR_SHAPE
     else if (varp == &p_guicursor)		// 'guicursor'
 	errmsg = parse_shape_opt(SHAPE_CURSOR);
 #endif
-#ifdef FEAT_MOUSESHAPE
-    else if (varp == &p_mouseshape)		// 'mouseshape'
-	errmsg = did_set_mouseshape();
-#endif
-#ifdef FEAT_PRINTER
-    else if (varp == &p_popt)			// 'printoptions'
-	errmsg = parse_printoptions();
-# if defined(FEAT_POSTSCRIPT)
-    else if (varp == &p_pmfn)			// 'printmbfont'
-	errmsg = parse_printmbfont();
-# endif
-#endif
-#ifdef FEAT_LANGMAP
-    else if (varp == &p_langmap)		// 'langmap'
-	langmap_set();
-#endif
-#ifdef FEAT_LINEBREAK
-    else if (varp == &p_breakat)		// 'breakat'
-	fill_breakat_flags();
-#endif
-    else if (  varp == &p_titlestring		// 'titlestring'
-	    || varp == &p_iconstring)		// 'iconstring'
-	did_set_titleiconstring(varp);
-#ifdef FEAT_GUI
-    else if (varp == &p_go)			// 'guioptions'
-    {
-	did_set_guioptions(oldval);
-	redraw_gui_only = TRUE;
-    }
-#endif
-#if defined(FEAT_GUI_TABLINE)
-    else if (varp == &p_gtl)			// 'guitablabel'
-    {
-	did_set_guitablabel();
-	redraw_gui_only = TRUE;
-    }
-    else if (varp == &p_gtt)			// 'guitabtooltip'
-	redraw_gui_only = TRUE;
-#endif
-#if defined(UNIX) || defined(VMS)
-    else if (varp == &p_ttym)			// 'ttymouse'
-	errmsg = did_set_ttymouse();
-#endif
-    else if (varp == &p_sel)			// 'selection'
-	errmsg = did_set_selection();
     else if (varp == &p_slm)			// 'selectmode'
 	errmsg = did_set_opt_strings(p_slm, p_slm_values, TRUE);
-#ifdef FEAT_BROWSE
-    else if (varp == &p_bsdir)			// 'browsedir'
-	errmsg = did_set_browsedir();
-#endif
-    else if (varp == &p_km)			// 'keymodel'
-	errmsg = did_set_keymodel();
-    else if (varp == &p_kpc)			// 'keyprotocol'
-	errmsg = did_set_keyprotocol();
-    else if (varp == &p_mousem)			// 'mousemodel'
-	errmsg = did_set_mousemodel();
     else if (varp == &p_swb)			// 'switchbuf'
 	errmsg = did_set_opt_flags(p_swb, p_swb_values, &swb_flags, TRUE);
     else if (varp == &p_spk)			// 'splitkeep'
 	errmsg = did_set_opt_strings(p_spk, p_spk_values, FALSE);
     else if (varp == &p_debug)			// 'debug'
 	errmsg = did_set_opt_strings(p_debug, p_debug_values, TRUE);
-    else if (varp == &p_dy)			// 'display'
-	errmsg = did_set_display();
     else if (varp == &p_ead)			// 'eadirection'
 	errmsg = did_set_opt_strings(p_ead, p_ead_values, FALSE);
-#ifdef FEAT_CLIPBOARD
-    else if (varp == &p_cb)			// 'clipboard'
-	errmsg = check_clipboard_option();
-#endif
-#ifdef FEAT_SPELL
-    else if (varp == &(curwin->w_s->b_p_spf))	// 'spellfile'
-	errmsg = did_set_spellfile(varp);
-    else if (varp == &(curwin->w_s->b_p_spl))	// 'spell'
-	errmsg = did_set_spell(varp);
-    else if (varp == &(curwin->w_s->b_p_spc))	// 'spellcapcheck'
-	errmsg = did_set_spellcapcheck();
-    else if (varp == &(curwin->w_s->b_p_spo))	// 'spelloptions'
-	errmsg = did_set_spelloptions(varp);
-    else if (varp == &p_sps)			// 'spellsuggest'
-	errmsg = did_set_spellsuggest();
-    else if (varp == &p_msm)			// 'mkspellmem'
-	errmsg = did_set_mkspellmem();
-#endif
     else if (gvarp == &p_bh)			// 'bufhidden'
 	errmsg = did_set_opt_strings(curbuf->b_p_bh, p_bufhidden_values,
 								FALSE);
-    else if (gvarp == &p_bt)			// 'buftype'
-	errmsg = did_set_buftype();
-#ifdef FEAT_STL_OPT
-    else if (  gvarp == &p_stl			// 'statusline'
-	    || varp == &p_tal			// 'tabline'
-	    || varp == &p_ruf)			// 'rulerformat'
-	errmsg = did_set_statusline(varp);
-#endif
     else if (gvarp == &p_cpt)			// 'complete'
 	errmsg = did_set_complete(varp, errbuf);
-    else if (varp == &p_cot)			// 'completeopt'
-	errmsg = did_set_completeopt();
-#ifdef BACKSLASH_IN_FILENAME
-    else if (gvarp == &p_csl)			// 'completeslash'
-	errmsg = did_set_completeslash();
-#endif
-#ifdef FEAT_SIGNS
-    else if (varp == &curwin->w_p_scl)		// 'signcolumn'
-	errmsg = did_set_signcolumn(varp, oldval);
-#endif
     else if (varp == &p_sloc)			// 'showcmdloc'
 	errmsg = did_set_opt_strings(p_sloc, p_sloc_values, FALSE);
-#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)
-    else if (varp == &p_toolbar)		// 'toolbar'
-	errmsg = did_set_toolbar();
-#endif
-#if defined(FEAT_TOOLBAR) && defined(FEAT_GUI_GTK)
-    else if (varp == &p_tbis)			// 'toolbariconsize'
-	errmsg = did_set_toolbariconsize();
-#endif
-    else if (varp == &p_pt)			// 'pastetoggle'
-	did_set_pastetoggle();
-    else if (varp == &p_bs)			// 'backspace'
-	errmsg = did_set_backspace();
     else if (varp == &p_bo)			// 'belloff'
 	errmsg = did_set_opt_flags(p_bo, p_bo_values, &bo_flags, TRUE);
-    else if (gvarp == &p_tc)			// 'tagcase'
-	errmsg = did_set_tagcase(opt_flags);
     else if (varp == &p_cmp)			// 'casemap'
 	errmsg = did_set_opt_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE);
-#ifdef FEAT_DIFF
-    else if (varp == &p_dip)			// 'diffopt'
-	errmsg = did_set_diffopt();
-#endif
 #ifdef FEAT_FOLDING
-    else if (gvarp == &curwin->w_allbuf_opt.wo_fdm)	// 'foldmethod'
-	errmsg = did_set_foldmethod(varp);
-    else if (gvarp == &curwin->w_allbuf_opt.wo_fmr)	// 'foldmarker'
-	errmsg = did_set_foldmarker(varp);
-    else if (gvarp == &p_cms)			// 'commentstring'
-	errmsg = did_set_commentstring(varp);
     else if (varp == &p_fdo)			// 'foldopen'
 	errmsg = did_set_opt_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE);
     else if (varp == &p_fcl)			// 'foldclose'
 	errmsg = did_set_opt_strings(p_fcl, p_fcl_values, TRUE);
-    else if (gvarp == &curwin->w_allbuf_opt.wo_fdi)	// 'foldignore'
-	did_set_foldignore();
-#endif
-    else if (gvarp == &p_ve)			// 'virtualedit'
-	errmsg = did_set_virtualedit(oldval, opt_flags);
-#if defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)
-    else if (varp == &p_csqf)			// 'cscopequickfix'
-	errmsg = did_set_cscopequickfix();
-#endif
-    else if (gvarp == &p_cino)			// 'cinoptions'
-	did_set_cinoptions();
-    else if (gvarp == &p_lop)			// 'lispoptions'
-	errmsg = did_set_lispoptions(varp);
-#if defined(FEAT_RENDER_OPTIONS)
-    else if (varp == &p_rop)			// 'renderoptions'
-	errmsg = did_set_renderoptions();
 #endif
     else if (gvarp == &p_ft)			// 'filetype'
 	errmsg = did_set_filetype_or_syntax(varp, oldval, value_checked,
@@ -2969,10 +2835,6 @@ did_set_string_option(
 							&value_changed);
 #endif
 #ifdef FEAT_TERMINAL
-    else if (varp == &curwin->w_p_twk)		// 'termwinkey'
-	errmsg = did_set_termwinkey();
-    else if (varp == &curwin->w_p_tws)		// 'termwinsize'
-	errmsg = did_set_termwinsize();
     else if (varp == &curwin->w_p_wcr)		// 'wincolor'
 	term_update_wincolor(curwin);
 # if defined(MSWIN)
@@ -2980,20 +2842,6 @@ did_set_string_option(
 	errmsg = did_set_opt_strings(p_twt, p_twt_values, FALSE);
 # endif
 #endif
-#ifdef FEAT_VARTABS
-    else if (varp == &(curbuf->b_p_vsts))	// 'varsofttabstop'
-	errmsg = did_set_varsofttabstop(varp);
-    else if (varp == &(curbuf->b_p_vts))	// 'vartabstop'
-	errmsg = did_set_vartabstop(varp);
-#endif
-#ifdef FEAT_PROP_POPUP
-    else if (varp == &p_pvp)			// 'previewpopup'
-	errmsg = did_set_previewpopup();
-# ifdef FEAT_QUICKFIX
-    else if (varp == &p_cpp)			// 'completepopup'
-	errmsg = did_set_completepopup();
-# endif
-#endif
 #ifdef FEAT_EVAL
     else if (
 # ifdef FEAT_BEVAL
@@ -3020,31 +2868,6 @@ did_set_string_option(
 	    varp == &p_ccv)			// 'charconvert'
 	did_set_optexpr(varp);
 #endif
-#ifdef FEAT_COMPL_FUNC
-    else if (gvarp == &p_cfu)			// 'completefunc'
-	errmsg = set_completefunc_option();
-    else if (gvarp == &p_ofu)			// 'omnifunc'
-	errmsg = set_omnifunc_option();
-    else if (gvarp == &p_tsrfu)			// 'thesaurusfunc'
-	errmsg = set_thesaurusfunc_option();
-#endif
-#if defined(FEAT_EVAL) && \
-     (defined(FEAT_XIM) || defined(IME_WITHOUT_XIM) || defined(VIMDLL))
-    else if (gvarp == &p_imaf)			// 'imactivatefunc'
-	errmsg = set_imactivatefunc_option();
-    else if (gvarp == &p_imsf)			// 'imstatusfunc'
-	errmsg = set_imstatusfunc_option();
-#endif
-    else if (varp == &p_opfunc)			// 'operatorfunc'
-	errmsg = set_operatorfunc_option();
-#ifdef FEAT_QUICKFIX
-    else if (varp == &p_qftf)			// 'quickfixtextfunc'
-	errmsg = qf_process_qftf_option();
-#endif
-#ifdef FEAT_EVAL
-    else if (gvarp == &p_tfu)			// 'tagfunc'
-	errmsg = set_tagfunc_option();
-#endif
     else if (varp == &p_ww)			// 'whichwrap'
 	errmsg = did_set_option_listflag(varp, (char_u *)WW_ALL, errbuf);
     else if (varp == &p_shm)			// 'shortmess'
@@ -3143,6 +2966,25 @@ did_set_string_option(
     if ((opt_flags & OPT_NO_REDRAW) == 0)
     {
 #ifdef FEAT_GUI
+	// set when changing an option that only requires a redraw in the GUI
+	int	redraw_gui_only = FALSE;
+
+	if (varp == &p_go			// 'guioptions'
+		|| varp == &p_guifont		// 'guifont'
+# ifdef FEAT_GUI_TABLINE
+		|| varp == &p_gtl		// 'guitablabel'
+		|| varp == &p_gtt		// 'guitabtooltip'
+# endif
+# ifdef FEAT_XFONTSET
+		|| varp == &p_guifontset	// 'guifontset'
+# endif
+		|| varp == &p_guifontwide	// 'guifontwide'
+# ifdef FEAT_GUI_GTK
+		|| varp == &p_guiligatures	// 'guiligatures'
+# endif
+	    )
+	    redraw_gui_only = TRUE;
+
 	// check redraw when it's not a GUI option or the GUI is active.
 	if (!redraw_gui_only || gui.in_use)
 #endif
@@ -3226,9 +3068,8 @@ check_ff_value(char_u *p)
 }
 
 /*
- * Save the acutal shortmess Flags and clear them
- * temporarily to avoid that file messages
- * overwrites any output from the following commands.
+ * Save the actual shortmess Flags and clear them temporarily to avoid that
+ * file messages overwrites any output from the following commands.
  *
  * Caller must make sure to first call save_clear_shm_value() and then
  * restore_shm_value() exactly the same number of times.