comparison src/option.c @ 31924:4789a9d20e7c v9.0.1294

patch 9.0.1294: the set_bool_option() function is too long Commit: https://github.com/vim/vim/commit/80b817b7494b5b162efd2d0d308933f81aef7c45 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Thu Feb 9 22:08:52 2023 +0000 patch 9.0.1294: the set_bool_option() function is too long Problem: The set_bool_option() function is too long. Solution: Move code to separate functions. (Yegappan Lakshmanan, closes #11964)
author Bram Moolenaar <Bram@vim.org>
date Thu, 09 Feb 2023 23:15:03 +0100
parents 440256d03990
children 6072c1d9fe2a
comparison
equal deleted inserted replaced
31923:29fab93b9d07 31924:4789a9d20e7c
2898 reset_v_option_vars(); 2898 reset_v_option_vars();
2899 } 2899 }
2900 #endif 2900 #endif
2901 2901
2902 /* 2902 /*
2903 * Set the value of a boolean option, and take care of side effects. 2903 * Process the updated 'compatible' option value.
2904 * Returns NULL for success, or an error message for an error. 2904 */
2905 static void
2906 did_set_compatible(void)
2907 {
2908 compatible_set();
2909 }
2910
2911 #ifdef FEAT_LANGMAP
2912 /*
2913 * Process the updated 'langremap' option value.
2914 */
2915 static void
2916 did_set_langremap(void)
2917 {
2918 // 'langremap' -> !'langnoremap'
2919 p_lnr = !p_lrm;
2920 }
2921
2922 /*
2923 * Process the updated 'langnoremap' option value.
2924 */
2925 static void
2926 did_set_langnoremap(void)
2927 {
2928 // 'langnoremap' -> !'langremap'
2929 p_lrm = !p_lnr;
2930 }
2931 #endif
2932
2933 #ifdef FEAT_PERSISTENT_UNDO
2934 /*
2935 * Process the updated 'undofile' option value.
2936 */
2937 static void
2938 did_set_undofile(int opt_flags)
2939 {
2940 // Only take action when the option was set. When reset we do not
2941 // delete the undo file, the option may be set again without making
2942 // any changes in between.
2943 if (curbuf->b_p_udf || p_udf)
2944 {
2945 char_u hash[UNDO_HASH_SIZE];
2946 buf_T *save_curbuf = curbuf;
2947
2948 FOR_ALL_BUFFERS(curbuf)
2949 {
2950 // When 'undofile' is set globally: for every buffer, otherwise
2951 // only for the current buffer: Try to read in the undofile,
2952 // if one exists, the buffer wasn't changed and the buffer was
2953 // loaded
2954 if ((curbuf == save_curbuf
2955 || (opt_flags & OPT_GLOBAL) || opt_flags == 0)
2956 && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
2957 {
2958 #ifdef FEAT_CRYPT
2959 if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD)
2960 continue;
2961 #endif
2962 u_compute_hash(hash);
2963 u_read_undo(NULL, hash, curbuf->b_fname);
2964 }
2965 }
2966 curbuf = save_curbuf;
2967 }
2968
2969 }
2970 #endif
2971
2972 /*
2973 * Process the updated 'readonly' option value.
2974 */
2975 static void
2976 did_set_readonly(int opt_flags)
2977 {
2978 // when 'readonly' is reset globally, also reset readonlymode
2979 if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
2980 readonlymode = FALSE;
2981
2982 // when 'readonly' is set may give W10 again
2983 if (curbuf->b_p_ro)
2984 curbuf->b_did_warn = FALSE;
2985
2986 redraw_titles();
2987 }
2988
2989 #ifdef FEAT_GUI
2990 /*
2991 * Process the updated 'mousehide' option value.
2992 */
2993 static void
2994 did_set_mousehide(void)
2995 {
2996 if (!p_mh)
2997 gui_mch_mousehide(FALSE);
2998 }
2999 #endif
3000
3001 /*
3002 * Process the updated 'modifiable' option value.
2905 */ 3003 */
2906 static char * 3004 static char *
2907 set_bool_option( 3005 did_set_modifiable(int *doskip UNUSED)
2908 int opt_idx, // index in options[] table 3006 {
2909 char_u *varp, // pointer to the option variable
2910 int value, // new value
2911 int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL
2912 {
2913 int old_value = *(int *)varp;
2914 #if defined(FEAT_EVAL)
2915 int old_global_value = 0;
2916 #endif
2917 char *errmsg = NULL;
2918
2919 // Disallow changing some options from secure mode
2920 if ((secure
2921 #ifdef HAVE_SANDBOX
2922 || sandbox != 0
2923 #endif
2924 ) && (options[opt_idx].flags & P_SECURE))
2925 return e_not_allowed_here;
2926
2927 #if defined(FEAT_EVAL)
2928 // Save the global value before changing anything. This is needed as for
2929 // a global-only option setting the "local value" in fact sets the global
2930 // value (since there is only one value).
2931 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
2932 old_global_value = *(int *)get_varp_scope(&(options[opt_idx]),
2933 OPT_GLOBAL);
2934 #endif
2935
2936 *(int *)varp = value; // set the new value
2937 #ifdef FEAT_EVAL
2938 // Remember where the option was set.
2939 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
2940 #endif
2941
2942 #ifdef FEAT_GUI
2943 need_mouse_correct = TRUE;
2944 #endif
2945
2946 // May set global value for local option.
2947 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
2948 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
2949
2950 /*
2951 * Handle side effects of changing a bool option.
2952 */
2953
2954 // 'compatible'
2955 if ((int *)varp == &p_cp)
2956 compatible_set();
2957
2958 #ifdef FEAT_LANGMAP
2959 if ((int *)varp == &p_lrm)
2960 // 'langremap' -> !'langnoremap'
2961 p_lnr = !p_lrm;
2962 else if ((int *)varp == &p_lnr)
2963 // 'langnoremap' -> !'langremap'
2964 p_lrm = !p_lnr;
2965 #endif
2966
2967 #ifdef FEAT_PERSISTENT_UNDO
2968 // 'undofile'
2969 else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf)
2970 {
2971 // Only take action when the option was set. When reset we do not
2972 // delete the undo file, the option may be set again without making
2973 // any changes in between.
2974 if (curbuf->b_p_udf || p_udf)
2975 {
2976 char_u hash[UNDO_HASH_SIZE];
2977 buf_T *save_curbuf = curbuf;
2978
2979 FOR_ALL_BUFFERS(curbuf)
2980 {
2981 // When 'undofile' is set globally: for every buffer, otherwise
2982 // only for the current buffer: Try to read in the undofile,
2983 // if one exists, the buffer wasn't changed and the buffer was
2984 // loaded
2985 if ((curbuf == save_curbuf
2986 || (opt_flags & OPT_GLOBAL) || opt_flags == 0)
2987 && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
2988 {
2989 #ifdef FEAT_CRYPT
2990 if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD)
2991 continue;
2992 #endif
2993 u_compute_hash(hash);
2994 u_read_undo(NULL, hash, curbuf->b_fname);
2995 }
2996 }
2997 curbuf = save_curbuf;
2998 }
2999 }
3000 #endif
3001
3002 else if ((int *)varp == &curbuf->b_p_ro)
3003 {
3004 // when 'readonly' is reset globally, also reset readonlymode
3005 if (!curbuf->b_p_ro && (opt_flags & OPT_LOCAL) == 0)
3006 readonlymode = FALSE;
3007
3008 // when 'readonly' is set may give W10 again
3009 if (curbuf->b_p_ro)
3010 curbuf->b_did_warn = FALSE;
3011
3012 redraw_titles();
3013 }
3014
3015 #ifdef FEAT_GUI
3016 else if ((int *)varp == &p_mh)
3017 {
3018 if (!p_mh)
3019 gui_mch_mousehide(FALSE);
3020 }
3021 #endif
3022
3023 // when 'modifiable' is changed, redraw the window title 3007 // when 'modifiable' is changed, redraw the window title
3024 else if ((int *)varp == &curbuf->b_p_ma) 3008
3025 {
3026 # ifdef FEAT_TERMINAL 3009 # ifdef FEAT_TERMINAL
3027 // Cannot set 'modifiable' when in Terminal mode. 3010 // Cannot set 'modifiable' when in Terminal mode.
3028 if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf) 3011 if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf)
3029 && curbuf->b_term != NULL && !term_is_finished(curbuf)))) 3012 && curbuf->b_term != NULL && !term_is_finished(curbuf))))
3030 { 3013 {
3031 curbuf->b_p_ma = FALSE; 3014 curbuf->b_p_ma = FALSE;
3032 return e_cannot_make_terminal_with_running_job_modifiable; 3015 *doskip = TRUE;
3033 } 3016 return e_cannot_make_terminal_with_running_job_modifiable;
3017 }
3034 # endif 3018 # endif
3035 redraw_titles(); 3019 redraw_titles();
3036 } 3020
3037 // redraw the window title and tab page text when 'endoffile', 'endofline', 3021 return NULL;
3038 // 'fixeol' or 'bomb' is changed 3022 }
3039 else if ((int *)varp == &curbuf->b_p_eof 3023
3040 || (int *)varp == &curbuf->b_p_eol 3024 /*
3041 || (int *)varp == &curbuf->b_p_fixeol 3025 * Process the updated 'endoffile' or 'endofline' or 'fixendofline' or 'bomb'
3042 || (int *)varp == &curbuf->b_p_bomb) 3026 * option value.
3043 { 3027 */
3044 redraw_titles(); 3028 static void
3045 } 3029 did_set_eof_eol_fixeol_bomb(void)
3046 3030 {
3031 // redraw the window title and tab page text
3032 redraw_titles();
3033 }
3034
3035 /*
3036 * Process the updated 'binary' option value.
3037 */
3038 static void
3039 did_set_binary(int opt_flags, long old_value)
3040 {
3047 // when 'bin' is set also set some other options 3041 // when 'bin' is set also set some other options
3048 else if ((int *)varp == &curbuf->b_p_bin) 3042 set_options_bin(old_value, curbuf->b_p_bin, opt_flags);
3049 { 3043 redraw_titles();
3050 set_options_bin(old_value, curbuf->b_p_bin, opt_flags); 3044 }
3051 redraw_titles(); 3045
3052 } 3046 /*
3053 3047 * Process the updated 'buflisted' option value.
3048 */
3049 static void
3050 did_set_buflisted(long old_value)
3051 {
3054 // when 'buflisted' changes, trigger autocommands 3052 // when 'buflisted' changes, trigger autocommands
3055 else if ((int *)varp == &curbuf->b_p_bl && old_value != curbuf->b_p_bl) 3053 if (old_value != curbuf->b_p_bl)
3056 {
3057 apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE, 3054 apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
3058 NULL, NULL, TRUE, curbuf); 3055 NULL, NULL, TRUE, curbuf);
3059 } 3056 }
3060 3057
3058 /*
3059 * Process the updated 'swapfile' option value.
3060 */
3061 static void
3062 did_set_swapfile(void)
3063 {
3061 // when 'swf' is set, create swapfile, when reset remove swapfile 3064 // when 'swf' is set, create swapfile, when reset remove swapfile
3062 else if ((int *)varp == &curbuf->b_p_swf) 3065 if (curbuf->b_p_swf && p_uc)
3063 { 3066 ml_open_file(curbuf); // create the swap file
3064 if (curbuf->b_p_swf && p_uc) 3067 else
3065 ml_open_file(curbuf); // create the swap file 3068 // no need to reset curbuf->b_may_swap, ml_open_file() will check
3066 else 3069 // buf->b_p_swf
3067 // no need to reset curbuf->b_may_swap, ml_open_file() will check 3070 mf_close_file(curbuf, TRUE); // remove the swap file
3068 // buf->b_p_swf 3071 }
3069 mf_close_file(curbuf, TRUE); // remove the swap file 3072
3070 } 3073 /*
3074 * Process the updated 'terse' option value.
3075 */
3076 static void
3077 did_set_terse(void)
3078 {
3079 char_u *p;
3071 3080
3072 // when 'terse' is set change 'shortmess' 3081 // when 'terse' is set change 'shortmess'
3073 else if ((int *)varp == &p_terse) 3082 p = vim_strchr(p_shm, SHM_SEARCH);
3074 { 3083
3075 char_u *p; 3084 // insert 's' in p_shm
3076 3085 if (p_terse && p == NULL)
3077 p = vim_strchr(p_shm, SHM_SEARCH); 3086 {
3078 3087 STRCPY(IObuff, p_shm);
3079 // insert 's' in p_shm 3088 STRCAT(IObuff, "s");
3080 if (p_terse && p == NULL) 3089 set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
3081 { 3090 }
3082 STRCPY(IObuff, p_shm); 3091 // remove 's' from p_shm
3083 STRCAT(IObuff, "s"); 3092 else if (!p_terse && p != NULL)
3084 set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0); 3093 STRMOVE(p, p + 1);
3085 } 3094 }
3086 // remove 's' from p_shm 3095
3087 else if (!p_terse && p != NULL) 3096 /*
3088 STRMOVE(p, p + 1); 3097 * Process the updated 'paste' option value.
3089 } 3098 */
3090 3099 static void
3100 did_set_paste(void)
3101 {
3091 // when 'paste' is set or reset also change other options 3102 // when 'paste' is set or reset also change other options
3092 else if ((int *)varp == &p_paste) 3103 paste_option_changed();
3093 { 3104 }
3094 paste_option_changed(); 3105
3095 } 3106 /*
3096 3107 * Process the updated 'insertmode' option value.
3108 */
3109 static void
3110 did_set_insertmode(long old_value)
3111 {
3097 // when 'insertmode' is set from an autocommand need to do work here 3112 // when 'insertmode' is set from an autocommand need to do work here
3098 else if ((int *)varp == &p_im) 3113 if (p_im)
3099 { 3114 {
3100 if (p_im) 3115 if ((State & MODE_INSERT) == 0)
3101 { 3116 need_start_insertmode = TRUE;
3102 if ((State & MODE_INSERT) == 0) 3117 stop_insert_mode = FALSE;
3103 need_start_insertmode = TRUE; 3118 }
3104 stop_insert_mode = FALSE; 3119 // only reset if it was set previously
3105 } 3120 else if (old_value)
3106 // only reset if it was set previously 3121 {
3107 else if (old_value) 3122 need_start_insertmode = FALSE;
3108 { 3123 stop_insert_mode = TRUE;
3109 need_start_insertmode = FALSE; 3124 if (restart_edit != 0 && mode_displayed)
3110 stop_insert_mode = TRUE; 3125 clear_cmdline = TRUE; // remove "(insert)"
3111 if (restart_edit != 0 && mode_displayed) 3126 restart_edit = 0;
3112 clear_cmdline = TRUE; // remove "(insert)" 3127 }
3113 restart_edit = 0; 3128 }
3114 } 3129
3115 } 3130 /*
3116 3131 * Process the updated 'ignorecase' option value.
3132 */
3133 static void
3134 did_set_ignorecase(void)
3135 {
3117 // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw 3136 // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw
3118 else if ((int *)varp == &p_ic && p_hls) 3137 if (p_hls)
3119 {
3120 redraw_all_later(UPD_SOME_VALID); 3138 redraw_all_later(UPD_SOME_VALID);
3121 } 3139 }
3122 3140
3123 #ifdef FEAT_SEARCH_EXTRA 3141 #ifdef FEAT_SEARCH_EXTRA
3142 /*
3143 * Process the updated 'hlsearch' option value.
3144 */
3145 static void
3146 did_set_hlsearch(void)
3147 {
3124 // when 'hlsearch' is set or reset: reset no_hlsearch 3148 // when 'hlsearch' is set or reset: reset no_hlsearch
3125 else if ((int *)varp == &p_hls) 3149 set_no_hlsearch(FALSE);
3126 { 3150 }
3127 set_no_hlsearch(FALSE); 3151 #endif
3128 } 3152
3129 #endif 3153 /*
3130 3154 * Process the updated 'scrollbind' option value.
3155 */
3156 static void
3157 did_set_scrollbind(void)
3158 {
3131 // when 'scrollbind' is set: snapshot the current position to avoid a jump 3159 // when 'scrollbind' is set: snapshot the current position to avoid a jump
3132 // at the end of normal_cmd() 3160 // at the end of normal_cmd()
3133 else if ((int *)varp == &curwin->w_p_scb) 3161 if (curwin->w_p_scb)
3134 { 3162 {
3135 if (curwin->w_p_scb) 3163 do_check_scrollbind(FALSE);
3136 { 3164 curwin->w_scbind_pos = curwin->w_topline;
3137 do_check_scrollbind(FALSE); 3165 }
3138 curwin->w_scbind_pos = curwin->w_topline; 3166 }
3139 } 3167
3140 } 3168 #ifdef FEAT_QUICKFIX
3141 3169 /*
3142 #if defined(FEAT_QUICKFIX) 3170 * Process the updated 'previewwindow' option value.
3171 */
3172 static char *
3173 did_set_previewwindow(int *doskip)
3174 {
3175 if (!curwin->w_p_pvw)
3176 return NULL;
3177
3143 // There can be only one window with 'previewwindow' set. 3178 // There can be only one window with 'previewwindow' set.
3144 else if ((int *)varp == &curwin->w_p_pvw) 3179 win_T *win;
3145 { 3180
3146 if (curwin->w_p_pvw) 3181 FOR_ALL_WINDOWS(win)
3147 { 3182 if (win->w_p_pvw && win != curwin)
3148 win_T *win; 3183 {
3149 3184 curwin->w_p_pvw = FALSE;
3150 FOR_ALL_WINDOWS(win) 3185 *doskip = TRUE;
3151 if (win->w_p_pvw && win != curwin) 3186 return e_preview_window_already_exists;
3152 { 3187 }
3153 curwin->w_p_pvw = FALSE; 3188
3154 return e_preview_window_already_exists; 3189 return NULL;
3155 } 3190 }
3156 } 3191 #endif
3157 } 3192
3158 #endif 3193 /*
3159 3194 * Process the updated 'smoothscroll' option value.
3160 else if ((int *)varp == &curwin->w_p_sms) 3195 */
3161 { 3196 static void
3162 if (!curwin->w_p_sms) 3197 did_set_smoothscroll(void)
3163 { 3198 {
3164 curwin->w_skipcol = 0; 3199 if (!curwin->w_p_sms)
3165 changed_line_abv_curs(); 3200 {
3166 } 3201 curwin->w_skipcol = 0;
3167 } 3202 changed_line_abv_curs();
3168 3203 }
3204 }
3205
3206 /*
3207 * Process the updated 'textmode' option value.
3208 */
3209 static void
3210 did_set_textmode(int opt_flags)
3211 {
3169 // when 'textmode' is set or reset also change 'fileformat' 3212 // when 'textmode' is set or reset also change 'fileformat'
3170 else if ((int *)varp == &curbuf->b_p_tx) 3213 set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags);
3171 { 3214 }
3172 set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, opt_flags); 3215
3173 } 3216 /*
3174 3217 * Process the updated 'textauto' option value.
3218 */
3219 static void
3220 did_set_textauto(int opt_flags)
3221 {
3175 // when 'textauto' is set or reset also change 'fileformats' 3222 // when 'textauto' is set or reset also change 'fileformats'
3176 else if ((int *)varp == &p_ta) 3223 set_string_option_direct((char_u *)"ffs", -1,
3177 { 3224 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
3178 set_string_option_direct((char_u *)"ffs", -1, 3225 OPT_FREE | opt_flags, 0);
3179 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"", 3226 }
3180 OPT_FREE | opt_flags, 0); 3227
3181 } 3228 /*
3182 3229 * Process the updated 'lisp' option value.
3183 /* 3230 */
3184 * When 'lisp' option changes include/exclude '-' in 3231 static void
3185 * keyword characters. 3232 did_set_lisp(void)
3186 */ 3233 {
3187 else if (varp == (char_u *)&(curbuf->b_p_lisp)) 3234 // When 'lisp' option changes include/exclude '-' in keyword characters.
3188 { 3235 (void)buf_init_chartab(curbuf, FALSE); // ignore errors
3189 (void)buf_init_chartab(curbuf, FALSE); // ignore errors 3236 }
3190 } 3237
3191 3238 /*
3239 * Process the updated 'title' or the 'icon' option value.
3240 */
3241 static void
3242 did_set_title_icon(void)
3243 {
3192 // when 'title' changed, may need to change the title; same for 'icon' 3244 // when 'title' changed, may need to change the title; same for 'icon'
3193 else if ((int *)varp == &p_title || (int *)varp == &p_icon) 3245 did_set_title();
3194 { 3246 }
3195 did_set_title(); 3247
3196 } 3248 /*
3197 3249 * Process the updated 'modified' option value.
3198 else if ((int *)varp == &curbuf->b_changed) 3250 */
3199 { 3251 static void
3200 if (!value) 3252 did_set_modified(long value)
3201 save_file_ff(curbuf); // Buffer is unchanged 3253 {
3202 redraw_titles(); 3254 if (!value)
3203 modified_was_set = value; 3255 save_file_ff(curbuf); // Buffer is unchanged
3204 } 3256 redraw_titles();
3257 modified_was_set = value;
3258 }
3205 3259
3206 #ifdef BACKSLASH_IN_FILENAME 3260 #ifdef BACKSLASH_IN_FILENAME
3207 else if ((int *)varp == &p_ssl) 3261 /*
3208 { 3262 * Process the updated 'shellslash' option value.
3209 if (p_ssl) 3263 */
3210 { 3264 static void
3211 psepc = '/'; 3265 did_set_shellslash(void)
3212 psepcN = '\\'; 3266 {
3213 pseps[0] = '/'; 3267 if (p_ssl)
3214 } 3268 {
3215 else 3269 psepc = '/';
3216 { 3270 psepcN = '\\';
3217 psepc = '\\'; 3271 pseps[0] = '/';
3218 psepcN = '/'; 3272 }
3219 pseps[0] = '\\'; 3273 else
3220 } 3274 {
3221 3275 psepc = '\\';
3222 // need to adjust the file name arguments and buffer names. 3276 psepcN = '/';
3223 buflist_slash_adjust(); 3277 pseps[0] = '\\';
3224 alist_slash_adjust(); 3278 }
3279
3280 // need to adjust the file name arguments and buffer names.
3281 buflist_slash_adjust();
3282 alist_slash_adjust();
3225 # ifdef FEAT_EVAL 3283 # ifdef FEAT_EVAL
3226 scriptnames_slash_adjust(); 3284 scriptnames_slash_adjust();
3227 # endif 3285 # endif
3228 } 3286 }
3229 #endif 3287 #endif
3230 3288
3289 /*
3290 * Process the updated 'wrap' option value.
3291 */
3292 static void
3293 did_set_wrap(void)
3294 {
3231 // If 'wrap' is set, set w_leftcol to zero. 3295 // If 'wrap' is set, set w_leftcol to zero.
3232 else if ((int *)varp == &curwin->w_p_wrap) 3296 if (curwin->w_p_wrap)
3233 { 3297 curwin->w_leftcol = 0;
3234 if (curwin->w_p_wrap) 3298 }
3235 curwin->w_leftcol = 0; 3299
3236 } 3300 /*
3237 3301 * Process the updated 'equalalways' option value.
3238 else if ((int *)varp == &p_ea) 3302 */
3239 { 3303 static void
3240 if (p_ea && !old_value) 3304 did_set_equalalways(long old_value)
3241 win_equal(curwin, FALSE, 0); 3305 {
3242 } 3306 if (p_ea && !old_value)
3243 3307 win_equal(curwin, FALSE, 0);
3244 else if ((int *)varp == &p_wiv) 3308 }
3309
3310 /*
3311 * Process the updated 'weirdinvert' option value.
3312 */
3313 static void
3314 did_set_weirdinvert(long old_value)
3315 {
3316 // When 'weirdinvert' changed, set/reset 't_xs'.
3317 // Then set 'weirdinvert' according to value of 't_xs'.
3318 if (p_wiv && !old_value)
3319 T_XS = (char_u *)"y";
3320 else if (!p_wiv && old_value)
3321 T_XS = empty_option;
3322 p_wiv = (*T_XS != NUL);
3323 }
3324
3325 #ifdef FEAT_BEVAL_GUI
3326 /*
3327 * Process the updated 'ballooneval' option value.
3328 */
3329 static void
3330 did_set_ballooneval(long old_value)
3331 {
3332 if (!balloonEvalForTerm)
3333 {
3334 if (p_beval && !old_value)
3335 gui_mch_enable_beval_area(balloonEval);
3336 else if (!p_beval && old_value)
3337 gui_mch_disable_beval_area(balloonEval);
3338 }
3339
3340 }
3341 #endif
3342
3343 #ifdef FEAT_BEVAL_TERM
3344 /*
3345 * Process the updated 'balloonevalterm' option value.
3346 */
3347 static void
3348 did_set_balloonevalterm(void)
3349 {
3350 mch_bevalterm_changed();
3351 }
3352 #endif
3353
3354 #ifdef FEAT_AUTOCHDIR
3355 /*
3356 * Process the updated 'autochdir' option value.
3357 */
3358 static void
3359 did_set_autochdir(void)
3360 {
3361 // Change directories when the 'acd' option is set now.
3362 DO_AUTOCHDIR;
3363 }
3364 #endif
3365
3366 #ifdef FEAT_DIFF
3367 /*
3368 * Process the updated 'diff' option value.
3369 */
3370 static void
3371 did_set_diff(void)
3372 {
3373 // May add or remove the buffer from the list of diff buffers.
3374 diff_buf_adjust(curwin);
3375 # ifdef FEAT_FOLDING
3376 if (foldmethodIsDiff(curwin))
3377 foldUpdateAll(curwin);
3378 # endif
3379 }
3380 #endif
3381
3382 #ifdef HAVE_INPUT_METHOD
3383 /*
3384 * Process the updated 'imdisable' option value.
3385 */
3386 static void
3387 did_set_imdisable(void)
3388 {
3389 // Only de-activate it here, it will be enabled when changing mode.
3390 if (p_imdisable)
3391 im_set_active(FALSE);
3392 else if (State & MODE_INSERT)
3393 // When the option is set from an autocommand, it may need to take
3394 // effect right away.
3395 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
3396 }
3397 #endif
3398
3399 #ifdef FEAT_SPELL
3400 /*
3401 * Process the updated 'spell' option value.
3402 */
3403 static char *
3404 did_set_spell(void)
3405 {
3406 if (curwin->w_p_spell)
3407 return did_set_spelllang(curwin);
3408
3409 return NULL;
3410 }
3411 #endif
3412
3413 #ifdef FEAT_ARABIC
3414 /*
3415 * Process the updated 'arabic' option value.
3416 */
3417 static char *
3418 did_set_arabic(void)
3419 {
3420 char *errmsg = NULL;
3421
3422 if (curwin->w_p_arab)
3245 { 3423 {
3246 /* 3424 /*
3247 * When 'weirdinvert' changed, set/reset 't_xs'. 3425 * 'arabic' is set, handle various sub-settings.
3248 * Then set 'weirdinvert' according to value of 't_xs'.
3249 */ 3426 */
3250 if (p_wiv && !old_value) 3427 if (!p_tbidi)
3251 T_XS = (char_u *)"y"; 3428 {
3252 else if (!p_wiv && old_value) 3429 // set rightleft mode
3253 T_XS = empty_option; 3430 if (!curwin->w_p_rl)
3254 p_wiv = (*T_XS != NUL); 3431 {
3255 } 3432 curwin->w_p_rl = TRUE;
3256 3433 changed_window_setting();
3257 #ifdef FEAT_BEVAL_GUI 3434 }
3258 else if ((int *)varp == &p_beval) 3435
3259 { 3436 // Enable Arabic shaping (major part of what Arabic requires)
3260 if (!balloonEvalForTerm) 3437 if (!p_arshape)
3261 { 3438 {
3262 if (p_beval && !old_value) 3439 p_arshape = TRUE;
3263 gui_mch_enable_beval_area(balloonEval); 3440 redraw_later_clear();
3264 else if (!p_beval && old_value) 3441 }
3265 gui_mch_disable_beval_area(balloonEval); 3442 }
3266 } 3443
3267 } 3444 // Arabic requires a utf-8 encoding, inform the user if it's not
3268 #endif 3445 // set.
3269 #ifdef FEAT_BEVAL_TERM 3446 if (STRCMP(p_enc, "utf-8") != 0)
3270 else if ((int *)varp == &p_bevalterm) 3447 {
3271 { 3448 static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
3272 mch_bevalterm_changed(); 3449
3273 } 3450 msg_source(HL_ATTR(HLF_W));
3274 #endif 3451 msg_attr(_(w_arabic), HL_ATTR(HLF_W));
3275 3452 #ifdef FEAT_EVAL
3276 #ifdef FEAT_AUTOCHDIR 3453 set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
3277 else if ((int *)varp == &p_acd) 3454 #endif
3278 { 3455 }
3279 // Change directories when the 'acd' option is set now. 3456
3280 DO_AUTOCHDIR; 3457 // set 'delcombine'
3281 } 3458 p_deco = TRUE;
3282 #endif 3459
3283 3460 # ifdef FEAT_KEYMAP
3284 #ifdef FEAT_DIFF 3461 // Force-set the necessary keymap for arabic
3285 // 'diff' 3462 errmsg = set_option_value((char_u *)"keymap",
3286 else if ((int *)varp == &curwin->w_p_diff) 3463 0L, (char_u *)"arabic", OPT_LOCAL);
3287 {
3288 // May add or remove the buffer from the list of diff buffers.
3289 diff_buf_adjust(curwin);
3290 # ifdef FEAT_FOLDING
3291 if (foldmethodIsDiff(curwin))
3292 foldUpdateAll(curwin);
3293 # endif 3464 # endif
3294 } 3465 }
3295 #endif 3466 else
3296 3467 {
3297 #ifdef HAVE_INPUT_METHOD 3468 /*
3298 // 'imdisable' 3469 * 'arabic' is reset, handle various sub-settings.
3299 else if ((int *)varp == &p_imdisable) 3470 */
3300 { 3471 if (!p_tbidi)
3301 // Only de-activate it here, it will be enabled when changing mode. 3472 {
3302 if (p_imdisable) 3473 // reset rightleft mode
3303 im_set_active(FALSE); 3474 if (curwin->w_p_rl)
3304 else if (State & MODE_INSERT)
3305 // When the option is set from an autocommand, it may need to take
3306 // effect right away.
3307 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
3308 }
3309 #endif
3310
3311 #ifdef FEAT_SPELL
3312 // 'spell'
3313 else if ((int *)varp == &curwin->w_p_spell)
3314 {
3315 if (curwin->w_p_spell)
3316 errmsg = did_set_spelllang(curwin);
3317 }
3318 #endif
3319
3320 #ifdef FEAT_ARABIC
3321 if ((int *)varp == &curwin->w_p_arab)
3322 {
3323 if (curwin->w_p_arab)
3324 {
3325 /*
3326 * 'arabic' is set, handle various sub-settings.
3327 */
3328 if (!p_tbidi)
3329 { 3475 {
3330 // set rightleft mode 3476 curwin->w_p_rl = FALSE;
3331 if (!curwin->w_p_rl) 3477 changed_window_setting();
3332 {
3333 curwin->w_p_rl = TRUE;
3334 changed_window_setting();
3335 }
3336
3337 // Enable Arabic shaping (major part of what Arabic requires)
3338 if (!p_arshape)
3339 {
3340 p_arshape = TRUE;
3341 redraw_later_clear();
3342 }
3343 } 3478 }
3344 3479
3345 // Arabic requires a utf-8 encoding, inform the user if it's not 3480 // 'arabicshape' isn't reset, it is a global option and
3346 // set. 3481 // another window may still need it "on".
3347 if (STRCMP(p_enc, "utf-8") != 0) 3482 }
3348 { 3483
3349 static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"); 3484 // 'delcombine' isn't reset, it is a global option and another
3350 3485 // window may still want it "on".
3351 msg_source(HL_ATTR(HLF_W));
3352 msg_attr(_(w_arabic), HL_ATTR(HLF_W));
3353 #ifdef FEAT_EVAL
3354 set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
3355 #endif
3356 }
3357
3358 // set 'delcombine'
3359 p_deco = TRUE;
3360 3486
3361 # ifdef FEAT_KEYMAP 3487 # ifdef FEAT_KEYMAP
3362 // Force-set the necessary keymap for arabic 3488 // Revert to the default keymap
3363 errmsg = set_option_value((char_u *)"keymap", 3489 curbuf->b_p_iminsert = B_IMODE_NONE;
3364 0L, (char_u *)"arabic", OPT_LOCAL); 3490 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
3365 # endif 3491 # endif
3366 } 3492 }
3367 else 3493
3368 { 3494 return errmsg;
3369 /* 3495 }
3370 * 'arabic' is reset, handle various sub-settings.
3371 */
3372 if (!p_tbidi)
3373 {
3374 // reset rightleft mode
3375 if (curwin->w_p_rl)
3376 {
3377 curwin->w_p_rl = FALSE;
3378 changed_window_setting();
3379 }
3380
3381 // 'arabicshape' isn't reset, it is a global option and
3382 // another window may still need it "on".
3383 }
3384
3385 // 'delcombine' isn't reset, it is a global option and another
3386 // window may still want it "on".
3387
3388 # ifdef FEAT_KEYMAP
3389 // Revert to the default keymap
3390 curbuf->b_p_iminsert = B_IMODE_NONE;
3391 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
3392 # endif
3393 }
3394 }
3395
3396 #endif 3496 #endif
3397 3497
3398 #if defined(FEAT_SIGNS) && defined(FEAT_GUI) 3498 #if defined(FEAT_SIGNS) && defined(FEAT_GUI)
3399 else if (((int *)varp == &curwin->w_p_nu 3499 /*
3400 || (int *)varp == &curwin->w_p_rnu) 3500 * Process the updated 'number' or 'relativenumber' option value.
3401 && gui.in_use 3501 */
3502 static void
3503 did_set_number_relativenumber(char_u *varp)
3504 {
3505 if (gui.in_use
3402 && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u') 3506 && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u')
3403 && curbuf->b_signlist != NULL) 3507 && curbuf->b_signlist != NULL)
3404 { 3508 {
3405 // If the 'number' or 'relativenumber' options are modified and 3509 // If the 'number' or 'relativenumber' options are modified and
3406 // 'signcolumn' is set to 'number', then clear the screen for a full 3510 // 'signcolumn' is set to 'number', then clear the screen for a full
3409 // 'relativenumber' option is toggled, then don't refresh the screen 3513 // 'relativenumber' option is toggled, then don't refresh the screen
3410 // (optimization). 3514 // (optimization).
3411 if (!(curwin->w_p_nu && ((int *)varp == &curwin->w_p_rnu))) 3515 if (!(curwin->w_p_nu && ((int *)varp == &curwin->w_p_rnu)))
3412 redraw_all_later(UPD_CLEAR); 3516 redraw_all_later(UPD_CLEAR);
3413 } 3517 }
3518 }
3414 #endif 3519 #endif
3415 3520
3416 #ifdef FEAT_TERMGUICOLORS 3521 #ifdef FEAT_TERMGUICOLORS
3417 // 'termguicolors' 3522 static char *
3418 else if ((int *)varp == &p_tgc) 3523 did_set_termguicolors(int *doskip UNUSED)
3419 { 3524 {
3420 # ifdef FEAT_VTP 3525 # ifdef FEAT_VTP
3421 // Do not turn on 'tgc' when 24-bit colors are not supported. 3526 // Do not turn on 'tgc' when 24-bit colors are not supported.
3422 if ( 3527 if (
3423 # ifdef VIMDLL 3528 # ifdef VIMDLL
3424 !gui.in_use && !gui.starting && 3529 !gui.in_use && !gui.starting &&
3425 # endif 3530 # endif
3426 !has_vtp_working()) 3531 !has_vtp_working())
3427 { 3532 {
3428 p_tgc = 0; 3533 p_tgc = 0;
3429 return e_24_bit_colors_are_not_supported_on_this_environment; 3534 *doskip = TRUE;
3430 } 3535 return e_24_bit_colors_are_not_supported_on_this_environment;
3431 if (is_term_win32()) 3536 }
3432 swap_tcap(); 3537 if (is_term_win32())
3538 swap_tcap();
3433 # endif 3539 # endif
3434 # ifdef FEAT_GUI 3540 # ifdef FEAT_GUI
3435 if (!gui.in_use && !gui.starting) 3541 if (!gui.in_use && !gui.starting)
3436 # endif 3542 # endif
3437 highlight_gui_started(); 3543 highlight_gui_started();
3438 # ifdef FEAT_VTP 3544 # ifdef FEAT_VTP
3439 // reset t_Co 3545 // reset t_Co
3440 if (is_term_win32()) 3546 if (is_term_win32())
3441 { 3547 {
3442 control_console_color_rgb(); 3548 control_console_color_rgb();
3443 set_termname(T_NAME); 3549 set_termname(T_NAME);
3444 init_highlight(TRUE, FALSE); 3550 init_highlight(TRUE, FALSE);
3445 } 3551 }
3446 # endif 3552 # endif
3447 # ifdef FEAT_TERMINAL 3553 # ifdef FEAT_TERMINAL
3448 term_update_colors_all(); 3554 term_update_colors_all();
3449 term_update_palette_all(); 3555 term_update_palette_all();
3450 term_update_wincolor_all(); 3556 term_update_wincolor_all();
3451 # endif 3557 # endif
3452 } 3558
3453 #endif 3559 return NULL;
3560 }
3561 #endif
3562
3563 /*
3564 * When some boolean options are changed, need to take some action.
3565 */
3566 static char *
3567 did_set_bool_option(
3568 char_u *varp,
3569 int opt_flags,
3570 long value,
3571 long old_value,
3572 int *doskip)
3573 {
3574 char *errmsg = NULL;
3575
3576 if ((int *)varp == &p_cp) // 'compatible'
3577 did_set_compatible();
3578 #ifdef FEAT_LANGMAP
3579 else if ((int *)varp == &p_lrm) // 'langremap'
3580 did_set_langremap();
3581 else if ((int *)varp == &p_lnr) // 'langnoremap'
3582 did_set_langnoremap();
3583 #endif
3584 #ifdef FEAT_PERSISTENT_UNDO
3585 else if ((int *)varp == &curbuf->b_p_udf // buffer local 'undofile'
3586 || (int *)varp == &p_udf) // 'undofile'
3587 did_set_undofile(opt_flags);
3588 #endif
3589 else if ((int *)varp == &curbuf->b_p_ro) // 'readonly'
3590 did_set_readonly(opt_flags);
3591 #ifdef FEAT_GUI
3592 else if ((int *)varp == &p_mh) // 'mousehide'
3593 did_set_mousehide();
3594 #endif
3595 else if ((int *)varp == &curbuf->b_p_ma)
3596 errmsg = did_set_modifiable(doskip); // 'modifiable'
3597 else if ((int *)varp == &curbuf->b_p_eof // 'endoffile'
3598 || (int *)varp == &curbuf->b_p_eol // 'endofline'
3599 || (int *)varp == &curbuf->b_p_fixeol // 'fixendofline'
3600 || (int *)varp == &curbuf->b_p_bomb) // 'bomb'
3601 did_set_eof_eol_fixeol_bomb();
3602 else if ((int *)varp == &curbuf->b_p_bin) // 'binary'
3603 did_set_binary(opt_flags, old_value);
3604 else if ((int *)varp == &curbuf->b_p_bl) // 'buflisted'
3605 did_set_buflisted(old_value);
3606 else if ((int *)varp == &curbuf->b_p_swf) // 'swapfile'
3607 did_set_swapfile();
3608 else if ((int *)varp == &p_terse) // 'terse'
3609 did_set_terse();
3610 else if ((int *)varp == &p_paste) // 'paste'
3611 did_set_paste();
3612 else if ((int *)varp == &p_im) // 'insertmode'
3613 did_set_insertmode(old_value);
3614 else if ((int *)varp == &p_ic) // 'ignorecase'
3615 did_set_ignorecase();
3616 #ifdef FEAT_SEARCH_EXTRA
3617 else if ((int *)varp == &p_hls) // 'hlsearch'
3618 did_set_hlsearch();
3619 #endif
3620 else if ((int *)varp == &curwin->w_p_scb) // 'scrollbind'
3621 did_set_scrollbind();
3622 #ifdef FEAT_QUICKFIX
3623 else if ((int *)varp == &curwin->w_p_pvw) // 'previewwindow'
3624 errmsg = did_set_previewwindow(doskip);
3625 #endif
3626 else if ((int *)varp == &curwin->w_p_sms) // 'smoothscroll'
3627 did_set_smoothscroll();
3628 else if ((int *)varp == &curbuf->b_p_tx) // 'textmode'
3629 did_set_textmode(opt_flags);
3630 else if ((int *)varp == &p_ta) // 'textauto'
3631 did_set_textauto(opt_flags);
3632 else if (varp == (char_u *)&(curbuf->b_p_lisp)) // 'lisp'
3633 did_set_lisp();
3634 else if ( (int *)varp == &p_title // 'title'
3635 || (int *)varp == &p_icon) // 'icon'
3636 did_set_title_icon();
3637 else if ((int *)varp == &curbuf->b_changed) // 'modified'
3638 did_set_modified(value);
3639 #ifdef BACKSLASH_IN_FILENAME
3640 else if ((int *)varp == &p_ssl) // 'shellslash'
3641 did_set_shellslash();
3642 #endif
3643 else if ((int *)varp == &curwin->w_p_wrap) // 'wrap'
3644 did_set_wrap();
3645 else if ((int *)varp == &p_ea) // 'equalalways'
3646 did_set_equalalways(old_value);
3647 else if ((int *)varp == &p_wiv) // weirdinvert'
3648 did_set_weirdinvert(old_value);
3649 #ifdef FEAT_BEVAL_GUI
3650 else if ((int *)varp == &p_beval) // 'ballooneval'
3651 did_set_ballooneval(old_value);
3652 #endif
3653 #ifdef FEAT_BEVAL_TERM
3654 else if ((int *)varp == &p_bevalterm) // 'balloonevalterm'
3655 did_set_balloonevalterm();
3656 #endif
3657 #ifdef FEAT_AUTOCHDIR
3658 else if ((int *)varp == &p_acd) // 'autochdir'
3659 did_set_autochdir();
3660 #endif
3661 #ifdef FEAT_DIFF
3662 else if ((int *)varp == &curwin->w_p_diff) // 'diff'
3663 did_set_diff();
3664 #endif
3665 #ifdef HAVE_INPUT_METHOD
3666 else if ((int *)varp == &p_imdisable) // 'imdisable'
3667 did_set_imdisable();
3668 #endif
3669 #ifdef FEAT_SPELL
3670 else if ((int *)varp == &curwin->w_p_spell) // 'spell'
3671 errmsg = did_set_spell();
3672 #endif
3673 #ifdef FEAT_ARABIC
3674 else if ((int *)varp == &curwin->w_p_arab) // 'arabic'
3675 errmsg = did_set_arabic();
3676 #endif
3677 #if defined(FEAT_SIGNS) && defined(FEAT_GUI)
3678 else if ( (int *)varp == &curwin->w_p_nu // 'number'
3679 || (int *)varp == &curwin->w_p_rnu) // 'relativenumber'
3680 did_set_number_relativenumber(varp);
3681 #endif
3682 #ifdef FEAT_TERMGUICOLORS
3683 else if ((int *)varp == &p_tgc) // 'termguicolors'
3684 errmsg = did_set_termguicolors(doskip);
3685 #endif
3686
3687 return errmsg;
3688 }
3689
3690 /*
3691 * Set the value of a boolean option, and take care of side effects.
3692 * Returns NULL for success, or an error message for an error.
3693 */
3694 static char *
3695 set_bool_option(
3696 int opt_idx, // index in options[] table
3697 char_u *varp, // pointer to the option variable
3698 int value, // new value
3699 int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL
3700 {
3701 int old_value = *(int *)varp;
3702 #if defined(FEAT_EVAL)
3703 int old_global_value = 0;
3704 #endif
3705 char *errmsg = NULL;
3706
3707 // Disallow changing some options from secure mode
3708 if ((secure
3709 #ifdef HAVE_SANDBOX
3710 || sandbox != 0
3711 #endif
3712 ) && (options[opt_idx].flags & P_SECURE))
3713 return e_not_allowed_here;
3714
3715 #if defined(FEAT_EVAL)
3716 // Save the global value before changing anything. This is needed as for
3717 // a global-only option setting the "local value" in fact sets the global
3718 // value (since there is only one value).
3719 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3720 old_global_value = *(int *)get_varp_scope(&(options[opt_idx]),
3721 OPT_GLOBAL);
3722 #endif
3723
3724 *(int *)varp = value; // set the new value
3725 #ifdef FEAT_EVAL
3726 // Remember where the option was set.
3727 set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
3728 #endif
3729
3730 #ifdef FEAT_GUI
3731 need_mouse_correct = TRUE;
3732 #endif
3733
3734 // May set global value for local option.
3735 if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
3736 *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
3454 3737
3455 /* 3738 /*
3456 * End of handling side effects for bool options. 3739 * Handle side effects of changing a bool option.
3457 */ 3740 */
3741 int doskip = FALSE;
3742 errmsg = did_set_bool_option(varp, opt_flags, value, old_value, &doskip);
3743 if (doskip)
3744 return errmsg;
3458 3745
3459 // after handling side effects, call autocommand 3746 // after handling side effects, call autocommand
3460 3747
3461 options[opt_idx].flags |= P_WAS_SET; 3748 options[opt_idx].flags |= P_WAS_SET;
3462 3749