]> granicus.if.org Git - vim/commitdiff
patch 9.0.1294: the set_bool_option() function is too long v9.0.1294
authorYegappan Lakshmanan <yegappan@yahoo.com>
Thu, 9 Feb 2023 22:08:52 +0000 (22:08 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 9 Feb 2023 22:08:52 +0000 (22:08 +0000)
Problem:    The set_bool_option() function is too long.
Solution:   Move code to separate functions. (Yegappan Lakshmanan,
            closes #11964)

src/option.c
src/version.c

index 6d860511560c6e64dd83b55fde2dc637d1287847..c95082d4e712830e9caea0c1894ad18e5cf5dd52 100644 (file)
@@ -2900,505 +2900,609 @@ apply_optionset_autocmd(
 #endif
 
 /*
- * 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 updated 'compatible' 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
+    static void
+did_set_compatible(void)
 {
-    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
-
-    *(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
-
-#ifdef FEAT_GUI
-    need_mouse_correct = TRUE;
-#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.
-     */
-
-    // 'compatible'
-    if ((int *)varp == &p_cp)
-       compatible_set();
+    compatible_set();
+}
 
 #ifdef FEAT_LANGMAP
-    if ((int *)varp == &p_lrm)
-       // 'langremap' -> !'langnoremap'
-       p_lnr = !p_lrm;
-    else if ((int *)varp == &p_lnr)
-       // 'langnoremap' -> !'langremap'
-       p_lrm = !p_lnr;
+/*
+ * Process the updated 'langremap' option value.
+ */
+    static void
+did_set_langremap(void)
+{
+    // 'langremap' -> !'langnoremap'
+    p_lnr = !p_lrm;
+}
+
+/*
+ * Process the updated 'langnoremap' option value.
+ */
+    static void
+did_set_langnoremap(void)
+{
+    // 'langnoremap' -> !'langremap'
+    p_lrm = !p_lnr;
+}
 #endif
 
 #ifdef FEAT_PERSISTENT_UNDO
-    // 'undofile'
-    else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf)
+/*
+ * Process the updated 'undofile' option value.
+ */
+    static void
+did_set_undofile(int opt_flags)
+{
+    // Only take action when the option was set. When reset we do not
+    // delete the undo file, the option may be set again without making
+    // any changes in between.
+    if (curbuf->b_p_udf || p_udf)
     {
-       // Only take action when the option was set. When reset we do not
-       // delete the undo file, the option may be set again without making
-       // any changes in between.
-       if (curbuf->b_p_udf || p_udf)
-       {
-           char_u      hash[UNDO_HASH_SIZE];
-           buf_T       *save_curbuf = curbuf;
+       char_u  hash[UNDO_HASH_SIZE];
+       buf_T   *save_curbuf = curbuf;
 
-           FOR_ALL_BUFFERS(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
+                       || (opt_flags & OPT_GLOBAL) || opt_flags == 0)
+                   && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
            {
-               // 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
-                               || (opt_flags & OPT_GLOBAL) || opt_flags == 0)
-                       && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
-               {
 #ifdef FEAT_CRYPT
-                   if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD)
-                       continue;
+               if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD)
+                   continue;
 #endif
-                   u_compute_hash(hash);
-                   u_read_undo(NULL, hash, curbuf->b_fname);
-               }
+               u_compute_hash(hash);
+               u_read_undo(NULL, hash, curbuf->b_fname);
            }
-           curbuf = save_curbuf;
        }
+       curbuf = save_curbuf;
     }
+
+}
 #endif
 
-    else if ((int *)varp == &curbuf->b_p_ro)
-    {
-       // when 'readonly' is reset globally, also reset readonlymode
-       if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
-           readonlymode = FALSE;
+/*
+ * Process the updated 'readonly' option value.
+ */
+    static void
+did_set_readonly(int opt_flags)
+{
+    // when 'readonly' is reset globally, also reset readonlymode
+    if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
+       readonlymode = FALSE;
 
-       // when 'readonly' is set may give W10 again
-       if (curbuf->b_p_ro)
-           curbuf->b_did_warn = FALSE;
+    // when 'readonly' is set may give W10 again
+    if (curbuf->b_p_ro)
+       curbuf->b_did_warn = FALSE;
 
-       redraw_titles();
-    }
+    redraw_titles();
+}
 
 #ifdef FEAT_GUI
-    else if ((int *)varp == &p_mh)
-    {
-       if (!p_mh)
-           gui_mch_mousehide(FALSE);
-    }
+/*
+ * Process the updated 'mousehide' option value.
+ */
+    static void
+did_set_mousehide(void)
+{
+    if (!p_mh)
+       gui_mch_mousehide(FALSE);
+}
 #endif
 
+/*
+ * Process the updated 'modifiable' option value.
+ */
+    static char *
+did_set_modifiable(int *doskip UNUSED)
+{
     // when 'modifiable' is changed, redraw the window title
-    else if ((int *)varp == &curbuf->b_p_ma)
-    {
+
 # 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;
-           return e_cannot_make_terminal_with_running_job_modifiable;
-       }
-# endif
-       redraw_titles();
-    }
-    // redraw the window title and tab page text when 'endoffile', 'endofline',
-    // 'fixeol' or 'bomb' is changed
-    else if ((int *)varp == &curbuf->b_p_eof
-           || (int *)varp == &curbuf->b_p_eol
-           || (int *)varp == &curbuf->b_p_fixeol
-           || (int *)varp == &curbuf->b_p_bomb)
+    // 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))))
     {
-       redraw_titles();
+       curbuf->b_p_ma = FALSE;
+       *doskip = TRUE;
+       return e_cannot_make_terminal_with_running_job_modifiable;
     }
+# endif
+    redraw_titles();
+
+    return NULL;
+}
+
+/*
+ * Process the updated 'endoffile' or 'endofline' or 'fixendofline' or 'bomb'
+ * option value.
+ */
+    static void
+did_set_eof_eol_fixeol_bomb(void)
+{
+    // redraw the window title and tab page text
+    redraw_titles();
+}
 
+/*
+ * Process the updated 'binary' option value.
+ */
+    static void
+did_set_binary(int opt_flags, long old_value)
+{
     // when 'bin' is set also set some other options
-    else if ((int *)varp == &curbuf->b_p_bin)
-    {
-       set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
-       redraw_titles();
-    }
+    set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
+    redraw_titles();
+}
 
+/*
+ * Process the updated 'buflisted' option value.
+ */
+    static void
+did_set_buflisted(long old_value)
+{
     // when 'buflisted' changes, trigger autocommands
-    else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl)
-    {
+    if (old_value != curbuf->b_p_bl)
        apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
-                                                   NULL, NULL, TRUE, curbuf);
-    }
+                                               NULL, NULL, TRUE, curbuf);
+}
 
+/*
+ * Process the updated 'swapfile' option value.
+ */
+    static void
+did_set_swapfile(void)
+{
     // when 'swf' is set, create swapfile, when reset remove swapfile
-    else if ((int *)varp == &curbuf->b_p_swf)
-    {
-       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
-    }
+    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
+}
 
-    // when 'terse' is set change 'shortmess'
-    else if ((int *)varp == &p_terse)
-    {
-       char_u  *p;
+/*
+ * Process the updated 'terse' option value.
+ */
+    static void
+did_set_terse(void)
+{
+    char_u     *p;
 
-       p = vim_strchr(p_shm, SHM_SEARCH);
+    // 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);
+    // 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);
+}
 
+/*
+ * Process the updated 'paste' option value.
+ */
+    static void
+did_set_paste(void)
+{
     // when 'paste' is set or reset also change other options
-    else if ((int *)varp == &p_paste)
-    {
-       paste_option_changed();
-    }
+    paste_option_changed();
+}
 
+/*
+ * Process the updated 'insertmode' option value.
+ */
+    static void
+did_set_insertmode(long old_value)
+{
     // when 'insertmode' is set from an autocommand need to do work here
-    else if ((int *)varp == &p_im)
+    if (p_im)
     {
-       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 (old_value)
-       {
-           need_start_insertmode = FALSE;
-           stop_insert_mode = TRUE;
-           if (restart_edit != 0 && mode_displayed)
-               clear_cmdline = TRUE;   // remove "(insert)"
-           restart_edit = 0;
-       }
+       if ((State & MODE_INSERT) == 0)
+           need_start_insertmode = TRUE;
+       stop_insert_mode = FALSE;
+    }
+    // only reset if it was set previously
+    else if (old_value)
+    {
+       need_start_insertmode = FALSE;
+       stop_insert_mode = TRUE;
+       if (restart_edit != 0 && mode_displayed)
+           clear_cmdline = TRUE;       // remove "(insert)"
+       restart_edit = 0;
     }
+}
 
+/*
+ * Process the updated 'ignorecase' option value.
+ */
+    static void
+did_set_ignorecase(void)
+{
     // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw
-    else if ((int *)varp == &p_ic && p_hls)
-    {
+    if (p_hls)
        redraw_all_later(UPD_SOME_VALID);
-    }
+}
 
 #ifdef FEAT_SEARCH_EXTRA
+/*
+ * Process the updated 'hlsearch' option value.
+ */
+    static void
+did_set_hlsearch(void)
+{
     // when 'hlsearch' is set or reset: reset no_hlsearch
-    else if ((int *)varp == &p_hls)
-    {
-       set_no_hlsearch(FALSE);
-    }
+    set_no_hlsearch(FALSE);
+}
 #endif
 
+/*
+ * Process the updated 'scrollbind' option value.
+ */
+    static void
+did_set_scrollbind(void)
+{
     // when 'scrollbind' is set: snapshot the current position to avoid a jump
     // at the end of normal_cmd()
-    else if ((int *)varp == &curwin->w_p_scb)
+    if (curwin->w_p_scb)
     {
-       if (curwin->w_p_scb)
-       {
-           do_check_scrollbind(FALSE);
-           curwin->w_scbind_pos = curwin->w_topline;
-       }
+       do_check_scrollbind(FALSE);
+       curwin->w_scbind_pos = curwin->w_topline;
     }
+}
+
+#ifdef FEAT_QUICKFIX
+/*
+ * Process the updated 'previewwindow' option value.
+ */
+    static char *
+did_set_previewwindow(int *doskip)
+{
+    if (!curwin->w_p_pvw)
+       return NULL;
 
-#if defined(FEAT_QUICKFIX)
     // There can be only one window with 'previewwindow' set.
-    else if ((int *)varp == &curwin->w_p_pvw)
-    {
-       if (curwin->w_p_pvw)
-       {
-           win_T       *win;
+    win_T      *win;
 
-           FOR_ALL_WINDOWS(win)
-               if (win->w_p_pvw && win != curwin)
-               {
-                   curwin->w_p_pvw = FALSE;
-                   return e_preview_window_already_exists;
-               }
+    FOR_ALL_WINDOWS(win)
+       if (win->w_p_pvw && win != curwin)
+       {
+           curwin->w_p_pvw = FALSE;
+           *doskip = TRUE;
+           return e_preview_window_already_exists;
        }
-    }
+
+    return NULL;
+}
 #endif
 
-    else if ((int *)varp == &curwin->w_p_sms)
+/*
+ * Process the updated 'smoothscroll' option value.
+ */
+    static void
+did_set_smoothscroll(void)
+{
+    if (!curwin->w_p_sms)
     {
-       if (!curwin->w_p_sms)
-       {
-           curwin->w_skipcol = 0;
-           changed_line_abv_curs();
-       }
+       curwin->w_skipcol = 0;
+       changed_line_abv_curs();
     }
+}
 
+/*
+ * Process the updated 'textmode' option value.
+ */
+    static void
+did_set_textmode(int opt_flags)
+{
     // when 'textmode' is set or reset also change 'fileformat'
-    else if ((int *)varp == &curbuf->b_p_tx)
-    {
-       set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
-    }
+    set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
+}
 
+/*
+ * Process the updated 'textauto' option value.
+ */
+    static void
+did_set_textauto(int opt_flags)
+{
     // when 'textauto' is set or reset also change 'fileformats'
-    else if ((int *)varp == &p_ta)
-    {
-       set_string_option_direct((char_u *)"ffs", -1,
-                                p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
-                                                    OPT_FREE | opt_flags, 0);
-    }
+    set_string_option_direct((char_u *)"ffs", -1,
+                               p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
+                               OPT_FREE | opt_flags, 0);
+}
 
-    /*
-     * When 'lisp' option changes include/exclude '-' in
-     * keyword characters.
-     */
-    else if (varp == (char_u *)&(curbuf->b_p_lisp))
-    {
-       (void)buf_init_chartab(curbuf, FALSE);      // ignore errors
-    }
+/*
+ * Process the updated 'lisp' option value.
+ */
+    static void
+did_set_lisp(void)
+{
+    // When 'lisp' option changes include/exclude '-' in keyword characters.
+    (void)buf_init_chartab(curbuf, FALSE);         // ignore errors
+}
 
+/*
+ * Process the updated 'title' or the 'icon' option value.
+ */
+    static void
+did_set_title_icon(void)
+{
     // when 'title' changed, may need to change the title; same for 'icon'
-    else if ((int *)varp == &p_title || (int *)varp == &p_icon)
-    {
-       did_set_title();
-    }
+    did_set_title();
+}
 
-    else if ((int *)varp == &curbuf->b_changed)
-    {
-       if (!value)
-           save_file_ff(curbuf);       // Buffer is unchanged
-       redraw_titles();
-       modified_was_set = value;
-    }
+/*
+ * Process the updated 'modified' option value.
+ */
+    static void
+did_set_modified(long value)
+{
+    if (!value)
+       save_file_ff(curbuf);   // Buffer is unchanged
+    redraw_titles();
+    modified_was_set = value;
+}
 
 #ifdef BACKSLASH_IN_FILENAME
-    else if ((int *)varp == &p_ssl)
+/*
+ * Process the updated 'shellslash' option value.
+ */
+    static void
+did_set_shellslash(void)
+{
+    if (p_ssl)
     {
-       if (p_ssl)
-       {
-           psepc = '/';
-           psepcN = '\\';
-           pseps[0] = '/';
-       }
-       else
-       {
-           psepc = '\\';
-           psepcN = '/';
-           pseps[0] = '\\';
-       }
+       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();
+    // need to adjust the file name arguments and buffer names.
+    buflist_slash_adjust();
+    alist_slash_adjust();
 # ifdef FEAT_EVAL
-       scriptnames_slash_adjust();
+    scriptnames_slash_adjust();
 # endif
-    }
+}
 #endif
 
+/*
+ * Process the updated 'wrap' option value.
+ */
+    static void
+did_set_wrap(void)
+{
     // If 'wrap' is set, set w_leftcol to zero.
-    else if ((int *)varp == &curwin->w_p_wrap)
-    {
-       if (curwin->w_p_wrap)
-           curwin->w_leftcol = 0;
-    }
+    if (curwin->w_p_wrap)
+       curwin->w_leftcol = 0;
+}
 
-    else if ((int *)varp == &p_ea)
-    {
-       if (p_ea && !old_value)
-           win_equal(curwin, FALSE, 0);
-    }
+/*
+ * Process the updated 'equalalways' option value.
+ */
+    static void
+did_set_equalalways(long old_value)
+{
+    if (p_ea && !old_value)
+       win_equal(curwin, FALSE, 0);
+}
 
-    else if ((int *)varp == &p_wiv)
-    {
-       /*
-        * When 'weirdinvert' changed, set/reset 't_xs'.
-        * Then set 'weirdinvert' according to value of 't_xs'.
-        */
-       if (p_wiv && !old_value)
-           T_XS = (char_u *)"y";
-       else if (!p_wiv && old_value)
-           T_XS = empty_option;
-       p_wiv = (*T_XS != NUL);
-    }
+/*
+ * Process the updated 'weirdinvert' option value.
+ */
+    static void
+did_set_weirdinvert(long old_value)
+{
+    // When 'weirdinvert' changed, set/reset 't_xs'.
+    // Then set 'weirdinvert' according to value of 't_xs'.
+    if (p_wiv && !old_value)
+       T_XS = (char_u *)"y";
+    else if (!p_wiv && old_value)
+       T_XS = empty_option;
+    p_wiv = (*T_XS != NUL);
+}
 
 #ifdef FEAT_BEVAL_GUI
-    else if ((int *)varp == &p_beval)
+/*
+ * Process the updated 'ballooneval' option value.
+ */
+    static void
+did_set_ballooneval(long old_value)
+{
+    if (!balloonEvalForTerm)
     {
-       if (!balloonEvalForTerm)
-       {
-           if (p_beval && !old_value)
-               gui_mch_enable_beval_area(balloonEval);
-           else if (!p_beval && old_value)
-               gui_mch_disable_beval_area(balloonEval);
-       }
+       if (p_beval && !old_value)
+           gui_mch_enable_beval_area(balloonEval);
+       else if (!p_beval && old_value)
+           gui_mch_disable_beval_area(balloonEval);
     }
+
+}
 #endif
+
 #ifdef FEAT_BEVAL_TERM
-    else if ((int *)varp == &p_bevalterm)
-    {
-       mch_bevalterm_changed();
-    }
+/*
+ * Process the updated 'balloonevalterm' option value.
+ */
+    static void
+did_set_balloonevalterm(void)
+{
+    mch_bevalterm_changed();
+}
 #endif
 
 #ifdef FEAT_AUTOCHDIR
-    else if ((int *)varp == &p_acd)
-    {
-       // Change directories when the 'acd' option is set now.
-       DO_AUTOCHDIR;
-    }
+/*
+ * Process the updated 'autochdir' option value.
+ */
+    static void
+did_set_autochdir(void)
+{
+    // Change directories when the 'acd' option is set now.
+    DO_AUTOCHDIR;
+}
 #endif
 
 #ifdef FEAT_DIFF
-    // 'diff'
-    else if ((int *)varp == &curwin->w_p_diff)
-    {
-       // May add or remove the buffer from the list of diff buffers.
-       diff_buf_adjust(curwin);
+/*
+ * Process the updated 'diff' option value.
+ */
+    static void
+did_set_diff(void)
+{
+    // May add or remove the buffer from the list of diff buffers.
+    diff_buf_adjust(curwin);
 # ifdef FEAT_FOLDING
-       if (foldmethodIsDiff(curwin))
-           foldUpdateAll(curwin);
+    if (foldmethodIsDiff(curwin))
+       foldUpdateAll(curwin);
 # endif
-    }
+}
 #endif
 
 #ifdef HAVE_INPUT_METHOD
-    // 'imdisable'
-    else if ((int *)varp == &p_imdisable)
-    {
-       // 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);
-    }
+/*
+ * Process the updated 'imdisable' option value.
+ */
+    static void
+did_set_imdisable(void)
+{
+    // 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);
+}
 #endif
 
 #ifdef FEAT_SPELL
-    // 'spell'
-    else if ((int *)varp == &curwin->w_p_spell)
-    {
-       if (curwin->w_p_spell)
-           errmsg = did_set_spelllang(curwin);
-    }
+/*
+ * Process the updated 'spell' option value.
+ */
+    static char *
+did_set_spell(void)
+{
+    if (curwin->w_p_spell)
+       return did_set_spelllang(curwin);
+
+    return NULL;
+}
 #endif
 
 #ifdef FEAT_ARABIC
-    if ((int *)varp == &curwin->w_p_arab)
+/*
+ * Process the updated 'arabic' option value.
+ */
+    static char *
+did_set_arabic(void)
+{
+    char *errmsg = NULL;
+
+    if (curwin->w_p_arab)
     {
-       if (curwin->w_p_arab)
+       /*
+        * 'arabic' is set, handle various sub-settings.
+        */
+       if (!p_tbidi)
        {
-           /*
-            * 'arabic' is set, handle various sub-settings.
-            */
-           if (!p_tbidi)
+           // set rightleft mode
+           if (!curwin->w_p_rl)
            {
-               // set rightleft mode
-               if (!curwin->w_p_rl)
-               {
-                   curwin->w_p_rl = TRUE;
-                   changed_window_setting();
-               }
-
-               // Enable Arabic shaping (major part of what Arabic requires)
-               if (!p_arshape)
-               {
-                   p_arshape = TRUE;
-                   redraw_later_clear();
-               }
+               curwin->w_p_rl = TRUE;
+               changed_window_setting();
            }
 
-           // Arabic requires a utf-8 encoding, inform the user if it's not
-           // set.
-           if (STRCMP(p_enc, "utf-8") != 0)
+           // Enable Arabic shaping (major part of what Arabic requires)
+           if (!p_arshape)
            {
-               static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
+               p_arshape = TRUE;
+               redraw_later_clear();
+           }
+       }
+
+       // 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'");
 
-               msg_source(HL_ATTR(HLF_W));
-               msg_attr(_(w_arabic), HL_ATTR(HLF_W));
+           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_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
 #endif
-           }
+       }
 
-           // set 'delcombine'
-           p_deco = TRUE;
+       // 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);
+       // Force-set the necessary keymap for arabic
+       errmsg = set_option_value((char_u *)"keymap",
+               0L, (char_u *)"arabic", OPT_LOCAL);
 # endif
-       }
-       else
+    }
+    else
+    {
+       /*
+        * 'arabic' is reset, handle various sub-settings.
+        */
+       if (!p_tbidi)
        {
-           /*
-            * 'arabic' is reset, handle various sub-settings.
-            */
-           if (!p_tbidi)
+           // reset rightleft mode
+           if (curwin->w_p_rl)
            {
-               // 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".
+               curwin->w_p_rl = FALSE;
+               changed_window_setting();
            }
 
-           // 'delcombine' isn't reset, it is a global option and another
-           // window may still want it "on".
+           // '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;
+       // Revert to the default keymap
+       curbuf->b_p_iminsert = B_IMODE_NONE;
+       curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
 # endif
-       }
     }
 
+    return errmsg;
+}
 #endif
 
 #if defined(FEAT_SIGNS) && defined(FEAT_GUI)
-    else if (((int *)varp == &curwin->w_p_nu
-               || (int *)varp == &curwin->w_p_rnu)
-           && gui.in_use
+/*
+ * Process the updated 'number' or 'relativenumber' option value.
+ */
+    static void
+did_set_number_relativenumber(char_u *varp)
+{
+    if (gui.in_use
            && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u')
            && curbuf->b_signlist != NULL)
     {
@@ -3411,50 +3515,233 @@ set_bool_option(
        if (!(curwin->w_p_nu && ((int *)varp == &curwin->w_p_rnu)))
            redraw_all_later(UPD_CLEAR);
     }
+}
 #endif
 
 #ifdef FEAT_TERMGUICOLORS
-    // 'termguicolors'
-    else if ((int *)varp == &p_tgc)
-    {
+    static char *
+did_set_termguicolors(int *doskip UNUSED)
+{
 # ifdef FEAT_VTP
-       // Do not turn on 'tgc' when 24-bit colors are not supported.
-       if (
+    // 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;
-           return e_24_bit_colors_are_not_supported_on_this_environment;
-       }
-       if (is_term_win32())
-           swap_tcap();
+    {
+       p_tgc = 0;
+       *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)
+    if (!gui.in_use && !gui.starting)
 # endif
-           highlight_gui_started();
+       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);
-       }
+    // 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();
+    term_update_colors_all();
+    term_update_palette_all();
+    term_update_wincolor_all();
 # endif
-    }
+
+    return NULL;
+}
 #endif
 
+/*
+ * When some boolean options are changed, need to take some action.
+ */
+    static char *
+did_set_bool_option(
+    char_u     *varp,
+    int                opt_flags,
+    long       value,
+    long       old_value,
+    int                *doskip)
+{
+    char *errmsg = NULL;
+
+    if ((int *)varp == &p_cp)                  // 'compatible'
+       did_set_compatible();
+#ifdef FEAT_LANGMAP
+    else if ((int *)varp == &p_lrm)            // 'langremap'
+       did_set_langremap();
+    else if ((int *)varp == &p_lnr)            // 'langnoremap'
+       did_set_langnoremap();
+#endif
+#ifdef FEAT_PERSISTENT_UNDO
+    else if ((int *)varp == &curbuf->b_p_udf   // buffer local 'undofile'
+           || (int *)varp == &p_udf)           // 'undofile'
+       did_set_undofile(opt_flags);
+#endif
+    else if ((int *)varp == &curbuf->b_p_ro)   // 'readonly'
+       did_set_readonly(opt_flags);
+#ifdef FEAT_GUI
+    else if ((int *)varp == &p_mh)             // 'mousehide'
+       did_set_mousehide();
+#endif
+    else if ((int *)varp == &curbuf->b_p_ma)
+       errmsg = did_set_modifiable(doskip);    // 'modifiable'
+    else if ((int *)varp == &curbuf->b_p_eof   // 'endoffile'
+           || (int *)varp == &curbuf->b_p_eol  // 'endofline'
+           || (int *)varp == &curbuf->b_p_fixeol       // 'fixendofline'
+           || (int *)varp == &curbuf->b_p_bomb)        // 'bomb'
+       did_set_eof_eol_fixeol_bomb();
+    else if ((int *)varp == &curbuf->b_p_bin)  // 'binary'
+       did_set_binary(opt_flags, old_value);
+    else if ((int *)varp == &curbuf->b_p_bl)   // 'buflisted'
+       did_set_buflisted(old_value);
+    else if ((int *)varp == &curbuf->b_p_swf)  // 'swapfile'
+       did_set_swapfile();
+    else if ((int *)varp == &p_terse)          // 'terse'
+       did_set_terse();
+    else if ((int *)varp == &p_paste)          // 'paste'
+       did_set_paste();
+    else if ((int *)varp == &p_im)             // 'insertmode'
+       did_set_insertmode(old_value);
+    else if ((int *)varp == &p_ic)             // 'ignorecase'
+       did_set_ignorecase();
+#ifdef FEAT_SEARCH_EXTRA
+    else if ((int *)varp == &p_hls)            // 'hlsearch'
+       did_set_hlsearch();
+#endif
+    else if ((int *)varp == &curwin->w_p_scb)  // 'scrollbind'
+       did_set_scrollbind();
+#ifdef FEAT_QUICKFIX
+    else if ((int *)varp == &curwin->w_p_pvw)  // 'previewwindow'
+       errmsg = did_set_previewwindow(doskip);
+#endif
+    else if ((int *)varp == &curwin->w_p_sms)  // 'smoothscroll'
+       did_set_smoothscroll();
+    else if ((int *)varp == &curbuf->b_p_tx)   // 'textmode'
+       did_set_textmode(opt_flags);
+    else if ((int *)varp == &p_ta)             // 'textauto'
+       did_set_textauto(opt_flags);
+    else if (varp == (char_u *)&(curbuf->b_p_lisp))    // 'lisp'
+       did_set_lisp();
+    else if (  (int *)varp == &p_title         // 'title'
+           || (int *)varp == &p_icon)          // 'icon'
+       did_set_title_icon();
+    else if ((int *)varp == &curbuf->b_changed)        // 'modified'
+       did_set_modified(value);
+#ifdef BACKSLASH_IN_FILENAME
+    else if ((int *)varp == &p_ssl)            // 'shellslash'
+       did_set_shellslash();
+#endif
+    else if ((int *)varp == &curwin->w_p_wrap) // 'wrap'
+       did_set_wrap();
+    else if ((int *)varp == &p_ea)             // 'equalalways'
+       did_set_equalalways(old_value);
+    else if ((int *)varp == &p_wiv)            // weirdinvert'
+       did_set_weirdinvert(old_value);
+#ifdef FEAT_BEVAL_GUI
+    else if ((int *)varp == &p_beval)          // 'ballooneval'
+       did_set_ballooneval(old_value);
+#endif
+#ifdef FEAT_BEVAL_TERM
+    else if ((int *)varp == &p_bevalterm)      // 'balloonevalterm'
+       did_set_balloonevalterm();
+#endif
+#ifdef FEAT_AUTOCHDIR
+    else if ((int *)varp == &p_acd)            // 'autochdir'
+       did_set_autochdir();
+#endif
+#ifdef FEAT_DIFF
+    else if ((int *)varp == &curwin->w_p_diff) // 'diff'
+       did_set_diff();
+#endif
+#ifdef HAVE_INPUT_METHOD
+    else if ((int *)varp == &p_imdisable)      // 'imdisable'
+       did_set_imdisable();
+#endif
+#ifdef FEAT_SPELL
+    else if ((int *)varp == &curwin->w_p_spell)        // 'spell'
+       errmsg = did_set_spell();
+#endif
+#ifdef FEAT_ARABIC
+    else if ((int *)varp == &curwin->w_p_arab) // 'arabic'
+       errmsg = did_set_arabic();
+#endif
+#if defined(FEAT_SIGNS) && defined(FEAT_GUI)
+    else if (  (int *)varp == &curwin->w_p_nu  // 'number'
+           || (int *)varp == &curwin->w_p_rnu) // 'relativenumber'
+       did_set_number_relativenumber(varp);
+#endif
+#ifdef FEAT_TERMGUICOLORS
+    else if ((int *)varp == &p_tgc)            // 'termguicolors'
+       errmsg = did_set_termguicolors(doskip);
+#endif
+
+    return errmsg;
+}
+
+/*
+ * 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 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
+{
+    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
+
+    *(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
+
+#ifdef FEAT_GUI
+    need_mouse_correct = TRUE;
+#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;
+
     /*
-     * End of handling side effects for bool options.
+     * Handle side effects of changing a bool option.
      */
+    int doskip = FALSE;
+    errmsg = did_set_bool_option(varp, opt_flags, value, old_value, &doskip);
+    if (doskip)
+       return errmsg;
 
     // after handling side effects, call autocommand
 
index cc4345d42aa70f11c3e349cff97ea73bab8df8c0..e3563c62a85a1656beea9a912b3443fbb00823e7 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1294,
 /**/
     1293,
 /**/