comparison src/option.c @ 32096:e7ab58f57ea3 v9.0.1379

patch 9.0.1379: functions for handling options are not ordered Commit: https://github.com/vim/vim/commit/5284b23e148063648be0ff46c730ca574e3ca9fa Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Sat Mar 4 19:57:32 2023 +0000 patch 9.0.1379: functions for handling options are not ordered Problem: Functions for handling options are not ordered. Solution: Put functions in alphabetical order. (Yegappan Lakshmanan, closes #12101)
author Bram Moolenaar <Bram@vim.org>
date Sat, 04 Mar 2023 21:00:04 +0100
parents 32acf287a9ae
children 39f4126d2a0d
comparison
equal deleted inserted replaced
32095:3b1944008f7e 32096:e7ab58f57ea3
64 static char_u *get_varp(struct vimoption *); 64 static char_u *get_varp(struct vimoption *);
65 static void check_win_options(win_T *win); 65 static void check_win_options(win_T *win);
66 static void option_value2string(struct vimoption *, int scope); 66 static void option_value2string(struct vimoption *, int scope);
67 static void check_winopt(winopt_T *wop); 67 static void check_winopt(winopt_T *wop);
68 static int wc_use_keyname(char_u *varp, long *wcp); 68 static int wc_use_keyname(char_u *varp, long *wcp);
69 static void paste_option_changed(void);
70 static void compatible_set(void); 69 static void compatible_set(void);
71 70
72 /* 71 /*
73 * Initialize the 'shell' option to a default value. 72 * Initialize the 'shell' option to a default value.
74 */ 73 */
3109 NULL, FALSE, NULL); 3108 NULL, FALSE, NULL);
3110 reset_v_option_vars(); 3109 reset_v_option_vars();
3111 } 3110 }
3112 #endif 3111 #endif
3113 3112
3114 /* 3113 #if defined(FEAT_ARABIC) || defined(PROTO)
3115 * Process the updated 'compatible' option value. 3114 /*
3115 * Process the updated 'arabic' option value.
3116 */ 3116 */
3117 char * 3117 char *
3118 did_set_compatible(optset_T *args UNUSED) 3118 did_set_arabic(optset_T *args UNUSED)
3119 { 3119 {
3120 compatible_set(); 3120 char *errmsg = NULL;
3121
3122 if (curwin->w_p_arab)
3123 {
3124 // 'arabic' is set, handle various sub-settings.
3125 if (!p_tbidi)
3126 {
3127 // set rightleft mode
3128 if (!curwin->w_p_rl)
3129 {
3130 curwin->w_p_rl = TRUE;
3131 changed_window_setting();
3132 }
3133
3134 // Enable Arabic shaping (major part of what Arabic requires)
3135 if (!p_arshape)
3136 {
3137 p_arshape = TRUE;
3138 redraw_later_clear();
3139 }
3140 }
3141
3142 // Arabic requires a utf-8 encoding, inform the user if it's not
3143 // set.
3144 if (STRCMP(p_enc, "utf-8") != 0)
3145 {
3146 static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
3147
3148 msg_source(HL_ATTR(HLF_W));
3149 msg_attr(_(w_arabic), HL_ATTR(HLF_W));
3150 #ifdef FEAT_EVAL
3151 set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
3152 #endif
3153 }
3154
3155 // set 'delcombine'
3156 p_deco = TRUE;
3157
3158 # ifdef FEAT_KEYMAP
3159 // Force-set the necessary keymap for arabic
3160 errmsg = set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic",
3161 OPT_LOCAL);
3162 # endif
3163 }
3164 else
3165 {
3166 // 'arabic' is reset, handle various sub-settings.
3167 if (!p_tbidi)
3168 {
3169 // reset rightleft mode
3170 if (curwin->w_p_rl)
3171 {
3172 curwin->w_p_rl = FALSE;
3173 changed_window_setting();
3174 }
3175
3176 // 'arabicshape' isn't reset, it is a global option and
3177 // another window may still need it "on".
3178 }
3179
3180 // 'delcombine' isn't reset, it is a global option and another
3181 // window may still want it "on".
3182
3183 # ifdef FEAT_KEYMAP
3184 // Revert to the default keymap
3185 curbuf->b_p_iminsert = B_IMODE_NONE;
3186 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
3187 # endif
3188 }
3189
3190 return errmsg;
3191 }
3192 #endif
3193
3194 #if defined(FEAT_AUTOCHDIR) || defined(PROTO)
3195 /*
3196 * Process the updated 'autochdir' option value.
3197 */
3198 char *
3199 did_set_autochdir(optset_T *args UNUSED)
3200 {
3201 // Change directories when the 'acd' option is set now.
3202 DO_AUTOCHDIR;
3121 return NULL; 3203 return NULL;
3122 } 3204 }
3123 3205 #endif
3124 #if defined(FEAT_LANGMAP) || defined(PROTO) 3206
3125 /* 3207 #if defined(FEAT_BEVAL_GUI) || defined(PROTO)
3126 * Process the updated 'langremap' option value. 3208 /*
3209 * Process the updated 'ballooneval' option value.
3127 */ 3210 */
3128 char * 3211 char *
3129 did_set_langremap(optset_T *args UNUSED) 3212 did_set_ballooneval(optset_T *args)
3130 { 3213 {
3131 // 'langremap' -> !'langnoremap' 3214 if (balloonEvalForTerm)
3132 p_lnr = !p_lrm; 3215 return NULL;
3216
3217 if (p_beval && !args->os_oldval.boolean)
3218 gui_mch_enable_beval_area(balloonEval);
3219 else if (!p_beval && args->os_oldval.boolean)
3220 gui_mch_disable_beval_area(balloonEval);
3221
3133 return NULL; 3222 return NULL;
3134 } 3223 }
3135 3224 #endif
3136 /* 3225
3137 * Process the updated 'langnoremap' option value. 3226 #if defined(FEAT_BEVAL_TERM) || defined(PROTO)
3227 /*
3228 * Process the updated 'balloonevalterm' option value.
3138 */ 3229 */
3139 char * 3230 char *
3140 did_set_langnoremap(optset_T *args UNUSED) 3231 did_set_balloonevalterm(optset_T *args UNUSED)
3141 { 3232 {
3142 // 'langnoremap' -> !'langremap' 3233 mch_bevalterm_changed();
3143 p_lrm = !p_lnr;
3144 return NULL; 3234 return NULL;
3145 } 3235 }
3146 #endif 3236 #endif
3147
3148 #if defined(FEAT_PERSISTENT_UNDO) || defined(PROTO)
3149 /*
3150 * Process the updated 'undofile' option value.
3151 */
3152 char *
3153 did_set_undofile(optset_T *args)
3154 {
3155 // Only take action when the option was set.
3156 if (!curbuf->b_p_udf && !p_udf)
3157 return NULL;
3158
3159 // When reset we do not delete the undo file, the option may be set again
3160 // without making any changes in between.
3161 char_u hash[UNDO_HASH_SIZE];
3162 buf_T *save_curbuf = curbuf;
3163
3164 FOR_ALL_BUFFERS(curbuf)
3165 {
3166 // When 'undofile' is set globally: for every buffer, otherwise
3167 // only for the current buffer: Try to read in the undofile,
3168 // if one exists, the buffer wasn't changed and the buffer was
3169 // loaded
3170 if ((curbuf == save_curbuf
3171 || (args->os_flags & OPT_GLOBAL)
3172 || args->os_flags == 0)
3173 && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
3174 {
3175 #ifdef FEAT_CRYPT
3176 if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD)
3177 continue;
3178 #endif
3179 u_compute_hash(hash);
3180 u_read_undo(NULL, hash, curbuf->b_fname);
3181 }
3182 }
3183 curbuf = save_curbuf;
3184
3185 return NULL;
3186 }
3187 #endif
3188
3189 /*
3190 * Process the updated 'readonly' option value.
3191 */
3192 char *
3193 did_set_readonly(optset_T *args)
3194 {
3195 // when 'readonly' is reset globally, also reset readonlymode
3196 if (!curbuf->b_p_ro && (args->os_flags & OPT_LOCAL) == 0)
3197 readonlymode = FALSE;
3198
3199 // when 'readonly' is set may give W10 again
3200 if (curbuf->b_p_ro)
3201 curbuf->b_did_warn = FALSE;
3202
3203 redraw_titles();
3204
3205 return NULL;
3206 }
3207
3208 #if defined(FEAT_GUI) || defined(PROTO)
3209 /*
3210 * Process the updated 'mousehide' option value.
3211 */
3212 char *
3213 did_set_mousehide(optset_T *args UNUSED)
3214 {
3215 if (!p_mh)
3216 gui_mch_mousehide(FALSE);
3217 return NULL;
3218 }
3219 #endif
3220
3221 /*
3222 * Process the updated 'modifiable' option value.
3223 */
3224 char *
3225 did_set_modifiable(optset_T *args UNUSED)
3226 {
3227 // when 'modifiable' is changed, redraw the window title
3228
3229 # ifdef FEAT_TERMINAL
3230 // Cannot set 'modifiable' when in Terminal mode.
3231 if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf)
3232 && curbuf->b_term != NULL && !term_is_finished(curbuf))))
3233 {
3234 curbuf->b_p_ma = FALSE;
3235 args->os_doskip = TRUE;
3236 return e_cannot_make_terminal_with_running_job_modifiable;
3237 }
3238 # endif
3239 redraw_titles();
3240
3241 return NULL;
3242 }
3243
3244 /*
3245 * Process the updated 'endoffile' or 'endofline' or 'fixendofline' or 'bomb'
3246 * option value.
3247 */
3248 char *
3249 did_set_eof_eol_fixeol_bomb(optset_T *args UNUSED)
3250 {
3251 // redraw the window title and tab page text
3252 redraw_titles();
3253 return NULL;
3254 }
3255 3237
3256 /* 3238 /*
3257 * Process the updated 'binary' option value. 3239 * Process the updated 'binary' option value.
3258 */ 3240 */
3259 char * 3241 char *
3263 set_options_bin(args->os_oldval.boolean, curbuf->b_p_bin, args->os_flags); 3245 set_options_bin(args->os_oldval.boolean, curbuf->b_p_bin, args->os_flags);
3264 redraw_titles(); 3246 redraw_titles();
3265 3247
3266 return NULL; 3248 return NULL;
3267 } 3249 }
3250
3251 #if defined(FEAT_LINEBREAK) || defined(PROTO)
3252 /*
3253 * Called when the 'breakat' option changes value.
3254 */
3255 char *
3256 did_set_breakat(optset_T *args UNUSED)
3257 {
3258 char_u *p;
3259 int i;
3260
3261 for (i = 0; i < 256; i++)
3262 breakat_flags[i] = FALSE;
3263
3264 if (p_breakat != NULL)
3265 for (p = p_breakat; *p; p++)
3266 breakat_flags[*p] = TRUE;
3267
3268 return NULL;
3269 }
3270 #endif
3268 3271
3269 /* 3272 /*
3270 * Process the updated 'buflisted' option value. 3273 * Process the updated 'buflisted' option value.
3271 */ 3274 */
3272 char * 3275 char *
3276 if (args->os_oldval.boolean != curbuf->b_p_bl) 3279 if (args->os_oldval.boolean != curbuf->b_p_bl)
3277 apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE, 3280 apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE,
3278 NULL, NULL, TRUE, curbuf); 3281 NULL, NULL, TRUE, curbuf);
3279 return NULL; 3282 return NULL;
3280 } 3283 }
3284
3285 /*
3286 * Process the new 'cmdheight' option value.
3287 */
3288 char *
3289 did_set_cmdheight(optset_T *args)
3290 {
3291 long old_value = args->os_oldval.number;
3292 char *errmsg = NULL;
3293
3294 // if p_ch changed value, change the command line height
3295 if (p_ch < 1)
3296 {
3297 errmsg = e_argument_must_be_positive;
3298 p_ch = 1;
3299 }
3300 if (p_ch > Rows - min_rows() + 1)
3301 p_ch = Rows - min_rows() + 1;
3302
3303 // Only compute the new window layout when startup has been
3304 // completed. Otherwise the frame sizes may be wrong.
3305 if ((p_ch != old_value
3306 || tabline_height() + topframe->fr_height != Rows - p_ch)
3307 && full_screen
3308 #ifdef FEAT_GUI
3309 && !gui.starting
3310 #endif
3311 )
3312 command_height();
3313
3314 return errmsg;
3315 }
3316
3317 /*
3318 * Process the updated 'compatible' option value.
3319 */
3320 char *
3321 did_set_compatible(optset_T *args UNUSED)
3322 {
3323 compatible_set();
3324 return NULL;
3325 }
3326
3327 #if defined(FEAT_CONCEAL) || defined(PROTO)
3328 /*
3329 * Process the new 'conceallevel' option value.
3330 */
3331 char *
3332 did_set_conceallevel(optset_T *args UNUSED)
3333 {
3334 char *errmsg = NULL;
3335
3336 if (curwin->w_p_cole < 0)
3337 {
3338 errmsg = e_argument_must_be_positive;
3339 curwin->w_p_cole = 0;
3340 }
3341 else if (curwin->w_p_cole > 3)
3342 {
3343 errmsg = e_invalid_argument;
3344 curwin->w_p_cole = 3;
3345 }
3346
3347 return errmsg;
3348 }
3349 #endif
3350
3351 #if defined(FEAT_DIFF) || defined(PROTO)
3352 /*
3353 * Process the updated 'diff' option value.
3354 */
3355 char *
3356 did_set_diff(optset_T *args UNUSED)
3357 {
3358 // May add or remove the buffer from the list of diff buffers.
3359 diff_buf_adjust(curwin);
3360 # ifdef FEAT_FOLDING
3361 if (foldmethodIsDiff(curwin))
3362 foldUpdateAll(curwin);
3363 # endif
3364 return NULL;
3365 }
3366 #endif
3367
3368 /*
3369 * Process the updated 'endoffile' or 'endofline' or 'fixendofline' or 'bomb'
3370 * option value.
3371 */
3372 char *
3373 did_set_eof_eol_fixeol_bomb(optset_T *args UNUSED)
3374 {
3375 // redraw the window title and tab page text
3376 redraw_titles();
3377 return NULL;
3378 }
3379
3380 /*
3381 * Process the updated 'equalalways' option value.
3382 */
3383 char *
3384 did_set_equalalways(optset_T *args)
3385 {
3386 if (p_ea && !args->os_oldval.boolean)
3387 win_equal(curwin, FALSE, 0);
3388
3389 return NULL;
3390 }
3391
3392 #if defined(FEAT_FOLDING) || defined(PROTO)
3393 /*
3394 * Process the new 'foldcolumn' option value.
3395 */
3396 char *
3397 did_set_foldcolumn(optset_T *args UNUSED)
3398 {
3399 char *errmsg = NULL;
3400
3401 if (curwin->w_p_fdc < 0)
3402 {
3403 errmsg = e_argument_must_be_positive;
3404 curwin->w_p_fdc = 0;
3405 }
3406 else if (curwin->w_p_fdc > 12)
3407 {
3408 errmsg = e_invalid_argument;
3409 curwin->w_p_fdc = 12;
3410 }
3411
3412 return errmsg;
3413 }
3414
3415 /*
3416 * Process the new 'foldlevel' option value.
3417 */
3418 char *
3419 did_set_foldlevel(optset_T *args UNUSED)
3420 {
3421 if (curwin->w_p_fdl < 0)
3422 curwin->w_p_fdl = 0;
3423 newFoldLevel();
3424 return NULL;
3425 }
3426
3427 /*
3428 * Process the new 'foldminlines' option value.
3429 */
3430 char *
3431 did_set_foldminlines(optset_T *args UNUSED)
3432 {
3433 foldUpdateAll(curwin);
3434 return NULL;
3435 }
3436
3437 /*
3438 * Process the new 'foldnestmax' option value.
3439 */
3440 char *
3441 did_set_foldnestmax(optset_T *args UNUSED)
3442 {
3443 if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
3444 foldUpdateAll(curwin);
3445 return NULL;
3446 }
3447 #endif
3448
3449 #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
3450 /*
3451 * Process the updated 'hlsearch' option value.
3452 */
3453 char *
3454 did_set_hlsearch(optset_T *args UNUSED)
3455 {
3456 // when 'hlsearch' is set or reset: reset no_hlsearch
3457 set_no_hlsearch(FALSE);
3458 return NULL;
3459 }
3460 #endif
3461
3462 /*
3463 * Process the updated 'ignorecase' option value.
3464 */
3465 char *
3466 did_set_ignorecase(optset_T *args UNUSED)
3467 {
3468 // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw
3469 if (p_hls)
3470 redraw_all_later(UPD_SOME_VALID);
3471 return NULL;
3472 }
3473
3474 #if defined(HAVE_INPUT_METHOD) || defined(PROTO)
3475 /*
3476 * Process the updated 'imdisable' option value.
3477 */
3478 char *
3479 did_set_imdisable(optset_T *args UNUSED)
3480 {
3481 // Only de-activate it here, it will be enabled when changing mode.
3482 if (p_imdisable)
3483 im_set_active(FALSE);
3484 else if (State & MODE_INSERT)
3485 // When the option is set from an autocommand, it may need to take
3486 // effect right away.
3487 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
3488 return NULL;
3489 }
3490 #endif
3491
3492 /*
3493 * Process the new 'iminsert' option value.
3494 */
3495 char *
3496 did_set_iminsert(optset_T *args UNUSED)
3497 {
3498 char *errmsg = NULL;
3499
3500 if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST)
3501 {
3502 errmsg = e_invalid_argument;
3503 curbuf->b_p_iminsert = B_IMODE_NONE;
3504 }
3505 p_iminsert = curbuf->b_p_iminsert;
3506 if (termcap_active) // don't do this in the alternate screen
3507 showmode();
3508 #if defined(FEAT_KEYMAP)
3509 // Show/unshow value of 'keymap' in status lines.
3510 status_redraw_curbuf();
3511 #endif
3512
3513 return errmsg;
3514 }
3515
3516 /*
3517 * Process the new 'imsearch' option value.
3518 */
3519 char *
3520 did_set_imsearch(optset_T *args UNUSED)
3521 {
3522 char *errmsg = NULL;
3523
3524 if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST)
3525 {
3526 errmsg = e_invalid_argument;
3527 curbuf->b_p_imsearch = B_IMODE_NONE;
3528 }
3529 p_imsearch = curbuf->b_p_imsearch;
3530
3531 return errmsg;
3532 }
3533
3534 #if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) || defined(PROTO)
3535 /*
3536 * Process the new 'imstyle' option value.
3537 */
3538 char *
3539 did_set_imstyle(optset_T *args UNUSED)
3540 {
3541 char *errmsg = NULL;
3542
3543 if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT)
3544 errmsg = e_invalid_argument;
3545
3546 return errmsg;
3547 }
3548 #endif
3549
3550 /*
3551 * Process the updated 'insertmode' option value.
3552 */
3553 char *
3554 did_set_insertmode(optset_T *args)
3555 {
3556 // when 'insertmode' is set from an autocommand need to do work here
3557 if (p_im)
3558 {
3559 if ((State & MODE_INSERT) == 0)
3560 need_start_insertmode = TRUE;
3561 stop_insert_mode = FALSE;
3562 }
3563 // only reset if it was set previously
3564 else if (args->os_oldval.boolean)
3565 {
3566 need_start_insertmode = FALSE;
3567 stop_insert_mode = TRUE;
3568 if (restart_edit != 0 && mode_displayed)
3569 clear_cmdline = TRUE; // remove "(insert)"
3570 restart_edit = 0;
3571 }
3572
3573 return NULL;
3574 }
3575
3576 #if defined(FEAT_LANGMAP) || defined(PROTO)
3577 /*
3578 * Process the updated 'langnoremap' option value.
3579 */
3580 char *
3581 did_set_langnoremap(optset_T *args UNUSED)
3582 {
3583 // 'langnoremap' -> !'langremap'
3584 p_lrm = !p_lnr;
3585 return NULL;
3586 }
3587
3588 /*
3589 * Process the updated 'langremap' option value.
3590 */
3591 char *
3592 did_set_langremap(optset_T *args UNUSED)
3593 {
3594 // 'langremap' -> !'langnoremap'
3595 p_lnr = !p_lrm;
3596 return NULL;
3597 }
3598 #endif
3599
3600 /*
3601 * Process the new 'laststatus' option value.
3602 */
3603 char *
3604 did_set_laststatus(optset_T *args UNUSED)
3605 {
3606 last_status(FALSE); // (re)set last window status line
3607 return NULL;
3608 }
3609
3610 #if defined(FEAT_GUI) || defined(PROTO)
3611 /*
3612 * Process the new 'linespace' option value.
3613 */
3614 char *
3615 did_set_linespace(optset_T *args UNUSED)
3616 {
3617 // Recompute gui.char_height and resize the Vim window to keep the
3618 // same number of lines.
3619 if (gui.in_use && gui_mch_adjust_charheight() == OK)
3620 gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
3621 return NULL;
3622 }
3623 #endif
3624
3625 /*
3626 * Process the updated 'lisp' option value.
3627 */
3628 char *
3629 did_set_lisp(optset_T *args UNUSED)
3630 {
3631 // When 'lisp' option changes include/exclude '-' in keyword characters.
3632 (void)buf_init_chartab(curbuf, FALSE); // ignore errors
3633 return NULL;
3634 }
3635
3636 /*
3637 * Process the new 'maxcombine' option value.
3638 */
3639 char *
3640 did_set_maxcombine(optset_T *args UNUSED)
3641 {
3642 if (p_mco > MAX_MCO)
3643 p_mco = MAX_MCO;
3644 else if (p_mco < 0)
3645 p_mco = 0;
3646 screenclear(); // will re-allocate the screen
3647 return NULL;
3648 }
3649
3650 /*
3651 * Process the updated 'modifiable' option value.
3652 */
3653 char *
3654 did_set_modifiable(optset_T *args UNUSED)
3655 {
3656 // when 'modifiable' is changed, redraw the window title
3657
3658 # ifdef FEAT_TERMINAL
3659 // Cannot set 'modifiable' when in Terminal mode.
3660 if (curbuf->b_p_ma && (term_in_normal_mode() || (bt_terminal(curbuf)
3661 && curbuf->b_term != NULL && !term_is_finished(curbuf))))
3662 {
3663 curbuf->b_p_ma = FALSE;
3664 args->os_doskip = TRUE;
3665 return e_cannot_make_terminal_with_running_job_modifiable;
3666 }
3667 # endif
3668 redraw_titles();
3669
3670 return NULL;
3671 }
3672
3673 /*
3674 * Process the updated 'modified' option value.
3675 */
3676 char *
3677 did_set_modified(optset_T *args)
3678 {
3679 if (!args->os_newval.boolean)
3680 save_file_ff(curbuf); // Buffer is unchanged
3681 redraw_titles();
3682 modified_was_set = args->os_newval.boolean;
3683 return NULL;
3684 }
3685
3686 #if defined(FEAT_GUI) || defined(PROTO)
3687 /*
3688 * Process the updated 'mousehide' option value.
3689 */
3690 char *
3691 did_set_mousehide(optset_T *args UNUSED)
3692 {
3693 if (!p_mh)
3694 gui_mch_mousehide(FALSE);
3695 return NULL;
3696 }
3697 #endif
3698
3699 /*
3700 * Process the updated 'number' or 'relativenumber' option value.
3701 */
3702 char *
3703 did_set_number_relativenumber(optset_T *args UNUSED)
3704 {
3705 #if (defined(FEAT_SIGNS) && defined(FEAT_GUI)) || defined(PROTO)
3706 if (gui.in_use
3707 && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u')
3708 && curbuf->b_signlist != NULL)
3709 {
3710 // If the 'number' or 'relativenumber' options are modified and
3711 // 'signcolumn' is set to 'number', then clear the screen for a full
3712 // refresh. Otherwise the sign icons are not displayed properly in the
3713 // number column. If the 'number' option is set and only the
3714 // 'relativenumber' option is toggled, then don't refresh the screen
3715 // (optimization).
3716 if (!(curwin->w_p_nu && ((int *)args->os_varp == &curwin->w_p_rnu)))
3717 redraw_all_later(UPD_CLEAR);
3718 }
3719 #endif
3720 return NULL;
3721 }
3722
3723 #if defined(FEAT_LINEBREAK) || defined(PROTO)
3724 /*
3725 * Process the new 'numberwidth' option value.
3726 */
3727 char *
3728 did_set_numberwidth(optset_T *args UNUSED)
3729 {
3730 char *errmsg = NULL;
3731
3732 // 'numberwidth' must be positive
3733 if (curwin->w_p_nuw < 1)
3734 {
3735 errmsg = e_argument_must_be_positive;
3736 curwin->w_p_nuw = 1;
3737 }
3738 if (curwin->w_p_nuw > 20)
3739 {
3740 errmsg = e_invalid_argument;
3741 curwin->w_p_nuw = 20;
3742 }
3743 curwin->w_nrwidth_line_count = 0; // trigger a redraw
3744
3745 return errmsg;
3746 }
3747 #endif
3748
3749 /*
3750 * Process the updated 'paste' option value. Called after p_paste was set or
3751 * reset. When 'paste' is set or reset also change other options.
3752 */
3753 char *
3754 did_set_paste(optset_T *args UNUSED)
3755 {
3756 static int old_p_paste = FALSE;
3757 static int save_sm = 0;
3758 static int save_sta = 0;
3759 static int save_ru = 0;
3760 #ifdef FEAT_RIGHTLEFT
3761 static int save_ri = 0;
3762 static int save_hkmap = 0;
3763 #endif
3764 buf_T *buf;
3765
3766 if (p_paste)
3767 {
3768 // Paste switched from off to on.
3769 // Save the current values, so they can be restored later.
3770 if (!old_p_paste)
3771 {
3772 // save options for each buffer
3773 FOR_ALL_BUFFERS(buf)
3774 {
3775 buf->b_p_tw_nopaste = buf->b_p_tw;
3776 buf->b_p_wm_nopaste = buf->b_p_wm;
3777 buf->b_p_sts_nopaste = buf->b_p_sts;
3778 buf->b_p_ai_nopaste = buf->b_p_ai;
3779 buf->b_p_et_nopaste = buf->b_p_et;
3780 #ifdef FEAT_VARTABS
3781 if (buf->b_p_vsts_nopaste)
3782 vim_free(buf->b_p_vsts_nopaste);
3783 buf->b_p_vsts_nopaste =
3784 buf->b_p_vsts && buf->b_p_vsts != empty_option
3785 ? vim_strsave(buf->b_p_vsts) : NULL;
3786 #endif
3787 }
3788
3789 // save global options
3790 save_sm = p_sm;
3791 save_sta = p_sta;
3792 save_ru = p_ru;
3793 #ifdef FEAT_RIGHTLEFT
3794 save_ri = p_ri;
3795 save_hkmap = p_hkmap;
3796 #endif
3797 // save global values for local buffer options
3798 p_ai_nopaste = p_ai;
3799 p_et_nopaste = p_et;
3800 p_sts_nopaste = p_sts;
3801 p_tw_nopaste = p_tw;
3802 p_wm_nopaste = p_wm;
3803 #ifdef FEAT_VARTABS
3804 if (p_vsts_nopaste)
3805 vim_free(p_vsts_nopaste);
3806 p_vsts_nopaste = p_vsts && p_vsts != empty_option
3807 ? vim_strsave(p_vsts) : NULL;
3808 #endif
3809 }
3810
3811 // Always set the option values, also when 'paste' is set when it is
3812 // already on. Set options for each buffer.
3813 FOR_ALL_BUFFERS(buf)
3814 {
3815 buf->b_p_tw = 0; // textwidth is 0
3816 buf->b_p_wm = 0; // wrapmargin is 0
3817 buf->b_p_sts = 0; // softtabstop is 0
3818 buf->b_p_ai = 0; // no auto-indent
3819 buf->b_p_et = 0; // no expandtab
3820 #ifdef FEAT_VARTABS
3821 if (buf->b_p_vsts)
3822 free_string_option(buf->b_p_vsts);
3823 buf->b_p_vsts = empty_option;
3824 VIM_CLEAR(buf->b_p_vsts_array);
3825 #endif
3826 }
3827
3828 // set global options
3829 p_sm = 0; // no showmatch
3830 p_sta = 0; // no smarttab
3831 if (p_ru)
3832 status_redraw_all(); // redraw to remove the ruler
3833 p_ru = 0; // no ruler
3834 #ifdef FEAT_RIGHTLEFT
3835 p_ri = 0; // no reverse insert
3836 p_hkmap = 0; // no Hebrew keyboard
3837 #endif
3838 // set global values for local buffer options
3839 p_tw = 0;
3840 p_wm = 0;
3841 p_sts = 0;
3842 p_ai = 0;
3843 #ifdef FEAT_VARTABS
3844 if (p_vsts)
3845 free_string_option(p_vsts);
3846 p_vsts = empty_option;
3847 #endif
3848 }
3849
3850 // Paste switched from on to off: Restore saved values.
3851 else if (old_p_paste)
3852 {
3853 // restore options for each buffer
3854 FOR_ALL_BUFFERS(buf)
3855 {
3856 buf->b_p_tw = buf->b_p_tw_nopaste;
3857 buf->b_p_wm = buf->b_p_wm_nopaste;
3858 buf->b_p_sts = buf->b_p_sts_nopaste;
3859 buf->b_p_ai = buf->b_p_ai_nopaste;
3860 buf->b_p_et = buf->b_p_et_nopaste;
3861 #ifdef FEAT_VARTABS
3862 if (buf->b_p_vsts)
3863 free_string_option(buf->b_p_vsts);
3864 buf->b_p_vsts = buf->b_p_vsts_nopaste
3865 ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option;
3866 vim_free(buf->b_p_vsts_array);
3867 if (buf->b_p_vsts && buf->b_p_vsts != empty_option)
3868 (void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
3869 else
3870 buf->b_p_vsts_array = NULL;
3871 #endif
3872 }
3873
3874 // restore global options
3875 p_sm = save_sm;
3876 p_sta = save_sta;
3877 if (p_ru != save_ru)
3878 status_redraw_all(); // redraw to draw the ruler
3879 p_ru = save_ru;
3880 #ifdef FEAT_RIGHTLEFT
3881 p_ri = save_ri;
3882 p_hkmap = save_hkmap;
3883 #endif
3884 // set global values for local buffer options
3885 p_ai = p_ai_nopaste;
3886 p_et = p_et_nopaste;
3887 p_sts = p_sts_nopaste;
3888 p_tw = p_tw_nopaste;
3889 p_wm = p_wm_nopaste;
3890 #ifdef FEAT_VARTABS
3891 if (p_vsts)
3892 free_string_option(p_vsts);
3893 p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option;
3894 #endif
3895 }
3896
3897 old_p_paste = p_paste;
3898
3899 return NULL;
3900 }
3901
3902
3903 #ifdef FEAT_QUICKFIX
3904 /*
3905 * Process the updated 'previewwindow' option value.
3906 */
3907 char *
3908 did_set_previewwindow(optset_T *args)
3909 {
3910 if (!curwin->w_p_pvw)
3911 return NULL;
3912
3913 // There can be only one window with 'previewwindow' set.
3914 win_T *win;
3915
3916 FOR_ALL_WINDOWS(win)
3917 if (win->w_p_pvw && win != curwin)
3918 {
3919 curwin->w_p_pvw = FALSE;
3920 args->os_doskip = TRUE;
3921 return e_preview_window_already_exists;
3922 }
3923
3924 return NULL;
3925 }
3926 #endif
3927
3928 #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
3929 /*
3930 * Process the new 'pyxversion' option value.
3931 */
3932 char *
3933 did_set_pyxversion(optset_T *args UNUSED)
3934 {
3935 char *errmsg = NULL;
3936
3937 if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3)
3938 errmsg = e_invalid_argument;
3939
3940 return errmsg;
3941 }
3942 #endif
3943
3944 /*
3945 * Process the updated 'readonly' option value.
3946 */
3947 char *
3948 did_set_readonly(optset_T *args)
3949 {
3950 // when 'readonly' is reset globally, also reset readonlymode
3951 if (!curbuf->b_p_ro && (args->os_flags & OPT_LOCAL) == 0)
3952 readonlymode = FALSE;
3953
3954 // when 'readonly' is set may give W10 again
3955 if (curbuf->b_p_ro)
3956 curbuf->b_did_warn = FALSE;
3957
3958 redraw_titles();
3959
3960 return NULL;
3961 }
3962
3963 /*
3964 * Process the updated 'scrollbind' option value.
3965 */
3966 char *
3967 did_set_scrollbind(optset_T *args UNUSED)
3968 {
3969 // when 'scrollbind' is set: snapshot the current position to avoid a jump
3970 // at the end of normal_cmd()
3971 if (!curwin->w_p_scb)
3972 return NULL;
3973
3974 do_check_scrollbind(FALSE);
3975 curwin->w_scbind_pos = curwin->w_topline;
3976 return NULL;
3977 }
3978
3979 #if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
3980 /*
3981 * Process the updated 'shellslash' option value.
3982 */
3983 char *
3984 did_set_shellslash(optset_T *args UNUSED)
3985 {
3986 if (p_ssl)
3987 {
3988 psepc = '/';
3989 psepcN = '\\';
3990 pseps[0] = '/';
3991 }
3992 else
3993 {
3994 psepc = '\\';
3995 psepcN = '/';
3996 pseps[0] = '\\';
3997 }
3998
3999 // need to adjust the file name arguments and buffer names.
4000 buflist_slash_adjust();
4001 alist_slash_adjust();
4002 # ifdef FEAT_EVAL
4003 scriptnames_slash_adjust();
4004 # endif
4005 return NULL;
4006 }
4007 #endif
4008
4009 /*
4010 * Process the new 'shiftwidth' or the 'tabstop' option value.
4011 */
4012 char *
4013 did_set_shiftwidth_tabstop(optset_T *args)
4014 {
4015 long *pp = (long *)args->os_varp;
4016 char *errmsg = NULL;
4017
4018 if (curbuf->b_p_sw < 0)
4019 {
4020 errmsg = e_argument_must_be_positive;
4021 #ifdef FEAT_VARTABS
4022 // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use.
4023 curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0
4024 ? tabstop_first(curbuf->b_p_vts_array)
4025 : curbuf->b_p_ts;
4026 #else
4027 curbuf->b_p_sw = curbuf->b_p_ts;
4028 #endif
4029 }
4030
4031 #ifdef FEAT_FOLDING
4032 if (foldmethodIsIndent(curwin))
4033 foldUpdateAll(curwin);
4034 #endif
4035 // When 'shiftwidth' changes, or it's zero and 'tabstop' changes:
4036 // parse 'cinoptions'.
4037 if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0)
4038 parse_cino(curbuf);
4039
4040 return errmsg;
4041 }
4042
4043 /*
4044 * Process the new 'showtabline' option value.
4045 */
4046 char *
4047 did_set_showtabline(optset_T *args UNUSED)
4048 {
4049 shell_new_rows(); // recompute window positions and heights
4050 return NULL;
4051 }
4052
4053 /*
4054 * Process the updated 'smoothscroll' option value.
4055 */
4056 char *
4057 did_set_smoothscroll(optset_T *args UNUSED)
4058 {
4059 if (curwin->w_p_sms)
4060 return NULL;
4061
4062 curwin->w_skipcol = 0;
4063 changed_line_abv_curs();
4064 return NULL;
4065 }
4066
4067 #if defined(FEAT_SPELL) || defined(PROTO)
4068 /*
4069 * Process the updated 'spell' option value.
4070 */
4071 char *
4072 did_set_spell(optset_T *args UNUSED)
4073 {
4074 if (curwin->w_p_spell)
4075 return parse_spelllang(curwin);
4076
4077 return NULL;
4078 }
4079 #endif
3281 4080
3282 /* 4081 /*
3283 * Process the updated 'swapfile' option value. 4082 * Process the updated 'swapfile' option value.
3284 */ 4083 */
3285 char * 4084 char *
3293 // buf->b_p_swf 4092 // buf->b_p_swf
3294 mf_close_file(curbuf, TRUE); // remove the swap file 4093 mf_close_file(curbuf, TRUE); // remove the swap file
3295 return NULL; 4094 return NULL;
3296 } 4095 }
3297 4096
3298 /* 4097 #if defined(FEAT_TERMGUICOLORS) || defined(PROTO)
3299 * Process the updated 'terse' option value.
3300 */
3301 char *
3302 did_set_terse(optset_T *args UNUSED)
3303 {
3304 char_u *p;
3305
3306 // when 'terse' is set change 'shortmess'
3307 p = vim_strchr(p_shm, SHM_SEARCH);
3308
3309 // insert 's' in p_shm
3310 if (p_terse && p == NULL)
3311 {
3312 STRCPY(IObuff, p_shm);
3313 STRCAT(IObuff, "s");
3314 set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
3315 }
3316 // remove 's' from p_shm
3317 else if (!p_terse && p != NULL)
3318 STRMOVE(p, p + 1);
3319 return NULL;
3320 }
3321
3322 /*
3323 * Process the updated 'paste' option value.
3324 */
3325 char *
3326 did_set_paste(optset_T *args UNUSED)
3327 {
3328 // when 'paste' is set or reset also change other options
3329 paste_option_changed();
3330 return NULL;
3331 }
3332
3333 /*
3334 * Process the updated 'insertmode' option value.
3335 */
3336 char *
3337 did_set_insertmode(optset_T *args)
3338 {
3339 // when 'insertmode' is set from an autocommand need to do work here
3340 if (p_im)
3341 {
3342 if ((State & MODE_INSERT) == 0)
3343 need_start_insertmode = TRUE;
3344 stop_insert_mode = FALSE;
3345 }
3346 // only reset if it was set previously
3347 else if (args->os_oldval.boolean)
3348 {
3349 need_start_insertmode = FALSE;
3350 stop_insert_mode = TRUE;
3351 if (restart_edit != 0 && mode_displayed)
3352 clear_cmdline = TRUE; // remove "(insert)"
3353 restart_edit = 0;
3354 }
3355
3356 return NULL;
3357 }
3358
3359 /*
3360 * Process the updated 'ignorecase' option value.
3361 */
3362 char *
3363 did_set_ignorecase(optset_T *args UNUSED)
3364 {
3365 // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw
3366 if (p_hls)
3367 redraw_all_later(UPD_SOME_VALID);
3368 return NULL;
3369 }
3370
3371 #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
3372 /*
3373 * Process the updated 'hlsearch' option value.
3374 */
3375 char *
3376 did_set_hlsearch(optset_T *args UNUSED)
3377 {
3378 // when 'hlsearch' is set or reset: reset no_hlsearch
3379 set_no_hlsearch(FALSE);
3380 return NULL;
3381 }
3382 #endif
3383
3384 /*
3385 * Process the updated 'scrollbind' option value.
3386 */
3387 char *
3388 did_set_scrollbind(optset_T *args UNUSED)
3389 {
3390 // when 'scrollbind' is set: snapshot the current position to avoid a jump
3391 // at the end of normal_cmd()
3392 if (!curwin->w_p_scb)
3393 return NULL;
3394
3395 do_check_scrollbind(FALSE);
3396 curwin->w_scbind_pos = curwin->w_topline;
3397 return NULL;
3398 }
3399
3400 #ifdef FEAT_QUICKFIX
3401 /*
3402 * Process the updated 'previewwindow' option value.
3403 */
3404 char *
3405 did_set_previewwindow(optset_T *args)
3406 {
3407 if (!curwin->w_p_pvw)
3408 return NULL;
3409
3410 // There can be only one window with 'previewwindow' set.
3411 win_T *win;
3412
3413 FOR_ALL_WINDOWS(win)
3414 if (win->w_p_pvw && win != curwin)
3415 {
3416 curwin->w_p_pvw = FALSE;
3417 args->os_doskip = TRUE;
3418 return e_preview_window_already_exists;
3419 }
3420
3421 return NULL;
3422 }
3423 #endif
3424
3425 /*
3426 * Process the updated 'smoothscroll' option value.
3427 */
3428 char *
3429 did_set_smoothscroll(optset_T *args UNUSED)
3430 {
3431 if (curwin->w_p_sms)
3432 return NULL;
3433
3434 curwin->w_skipcol = 0;
3435 changed_line_abv_curs();
3436 return NULL;
3437 }
3438
3439 /*
3440 * Process the updated 'textmode' option value.
3441 */
3442 char *
3443 did_set_textmode(optset_T *args)
3444 {
3445 // when 'textmode' is set or reset also change 'fileformat'
3446 set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, args->os_flags);
3447
3448 return NULL;
3449 }
3450
3451 /*
3452 * Process the updated 'textauto' option value.
3453 */
3454 char *
3455 did_set_textauto(optset_T *args)
3456 {
3457 // when 'textauto' is set or reset also change 'fileformats'
3458 set_string_option_direct((char_u *)"ffs", -1,
3459 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
3460 OPT_FREE | args->os_flags, 0);
3461
3462 return NULL;
3463 }
3464
3465 /*
3466 * Process the updated 'lisp' option value.
3467 */
3468 char *
3469 did_set_lisp(optset_T *args UNUSED)
3470 {
3471 // When 'lisp' option changes include/exclude '-' in keyword characters.
3472 (void)buf_init_chartab(curbuf, FALSE); // ignore errors
3473 return NULL;
3474 }
3475
3476 /*
3477 * Process the updated 'title' or the 'icon' option value.
3478 */
3479 char *
3480 did_set_title_icon(optset_T *args UNUSED)
3481 {
3482 // when 'title' changed, may need to change the title; same for 'icon'
3483 did_set_title();
3484 return NULL;
3485 }
3486
3487 /*
3488 * Process the updated 'modified' option value.
3489 */
3490 char *
3491 did_set_modified(optset_T *args)
3492 {
3493 if (!args->os_newval.boolean)
3494 save_file_ff(curbuf); // Buffer is unchanged
3495 redraw_titles();
3496 modified_was_set = args->os_newval.boolean;
3497 return NULL;
3498 }
3499
3500 #if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
3501 /*
3502 * Process the updated 'shellslash' option value.
3503 */
3504 char *
3505 did_set_shellslash(optset_T *args UNUSED)
3506 {
3507 if (p_ssl)
3508 {
3509 psepc = '/';
3510 psepcN = '\\';
3511 pseps[0] = '/';
3512 }
3513 else
3514 {
3515 psepc = '\\';
3516 psepcN = '/';
3517 pseps[0] = '\\';
3518 }
3519
3520 // need to adjust the file name arguments and buffer names.
3521 buflist_slash_adjust();
3522 alist_slash_adjust();
3523 # ifdef FEAT_EVAL
3524 scriptnames_slash_adjust();
3525 # endif
3526 return NULL;
3527 }
3528 #endif
3529
3530 /*
3531 * Process the updated 'wrap' option value.
3532 */
3533 char *
3534 did_set_wrap(optset_T *args UNUSED)
3535 {
3536 // If 'wrap' is set, set w_leftcol to zero.
3537 if (curwin->w_p_wrap)
3538 curwin->w_leftcol = 0;
3539 return NULL;
3540 }
3541
3542 /*
3543 * Process the updated 'equalalways' option value.
3544 */
3545 char *
3546 did_set_equalalways(optset_T *args)
3547 {
3548 if (p_ea && !args->os_oldval.boolean)
3549 win_equal(curwin, FALSE, 0);
3550
3551 return NULL;
3552 }
3553
3554 /*
3555 * Process the updated 'weirdinvert' option value.
3556 */
3557 char *
3558 did_set_weirdinvert(optset_T *args)
3559 {
3560 // When 'weirdinvert' changed, set/reset 't_xs'.
3561 // Then set 'weirdinvert' according to value of 't_xs'.
3562 if (p_wiv && !args->os_oldval.boolean)
3563 T_XS = (char_u *)"y";
3564 else if (!p_wiv && args->os_oldval.boolean)
3565 T_XS = empty_option;
3566 p_wiv = (*T_XS != NUL);
3567
3568 return NULL;
3569 }
3570
3571 #if defined(FEAT_BEVAL_GUI) || defined(PROTO)
3572 /*
3573 * Process the updated 'ballooneval' option value.
3574 */
3575 char *
3576 did_set_ballooneval(optset_T *args)
3577 {
3578 if (balloonEvalForTerm)
3579 return NULL;
3580
3581 if (p_beval && !args->os_oldval.boolean)
3582 gui_mch_enable_beval_area(balloonEval);
3583 else if (!p_beval && args->os_oldval.boolean)
3584 gui_mch_disable_beval_area(balloonEval);
3585
3586 return NULL;
3587 }
3588 #endif
3589
3590 #if defined(FEAT_BEVAL_TERM) || defined(PROTO)
3591 /*
3592 * Process the updated 'balloonevalterm' option value.
3593 */
3594 char *
3595 did_set_balloonevalterm(optset_T *args UNUSED)
3596 {
3597 mch_bevalterm_changed();
3598 return NULL;
3599 }
3600 #endif
3601
3602 #if defined(FEAT_AUTOCHDIR) || defined(PROTO)
3603 /*
3604 * Process the updated 'autochdir' option value.
3605 */
3606 char *
3607 did_set_autochdir(optset_T *args UNUSED)
3608 {
3609 // Change directories when the 'acd' option is set now.
3610 DO_AUTOCHDIR;
3611 return NULL;
3612 }
3613 #endif
3614
3615 #if defined(FEAT_DIFF) || defined(PROTO)
3616 /*
3617 * Process the updated 'diff' option value.
3618 */
3619 char *
3620 did_set_diff(optset_T *args UNUSED)
3621 {
3622 // May add or remove the buffer from the list of diff buffers.
3623 diff_buf_adjust(curwin);
3624 # ifdef FEAT_FOLDING
3625 if (foldmethodIsDiff(curwin))
3626 foldUpdateAll(curwin);
3627 # endif
3628 return NULL;
3629 }
3630 #endif
3631
3632 #if defined(HAVE_INPUT_METHOD) || defined(PROTO)
3633 /*
3634 * Process the updated 'imdisable' option value.
3635 */
3636 char *
3637 did_set_imdisable(optset_T *args UNUSED)
3638 {
3639 // Only de-activate it here, it will be enabled when changing mode.
3640 if (p_imdisable)
3641 im_set_active(FALSE);
3642 else if (State & MODE_INSERT)
3643 // When the option is set from an autocommand, it may need to take
3644 // effect right away.
3645 im_set_active(curbuf->b_p_iminsert == B_IMODE_IM);
3646 return NULL;
3647 }
3648 #endif
3649
3650 #if defined(FEAT_SPELL) || defined(PROTO)
3651 /*
3652 * Process the updated 'spell' option value.
3653 */
3654 char *
3655 did_set_spell(optset_T *args UNUSED)
3656 {
3657 if (curwin->w_p_spell)
3658 return parse_spelllang(curwin);
3659
3660 return NULL;
3661 }
3662 #endif
3663
3664 #if defined(FEAT_ARABIC) || defined(PROTO)
3665 /*
3666 * Process the updated 'arabic' option value.
3667 */
3668 char *
3669 did_set_arabic(optset_T *args UNUSED)
3670 {
3671 char *errmsg = NULL;
3672
3673 if (curwin->w_p_arab)
3674 {
3675 // 'arabic' is set, handle various sub-settings.
3676 if (!p_tbidi)
3677 {
3678 // set rightleft mode
3679 if (!curwin->w_p_rl)
3680 {
3681 curwin->w_p_rl = TRUE;
3682 changed_window_setting();
3683 }
3684
3685 // Enable Arabic shaping (major part of what Arabic requires)
3686 if (!p_arshape)
3687 {
3688 p_arshape = TRUE;
3689 redraw_later_clear();
3690 }
3691 }
3692
3693 // Arabic requires a utf-8 encoding, inform the user if it's not
3694 // set.
3695 if (STRCMP(p_enc, "utf-8") != 0)
3696 {
3697 static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
3698
3699 msg_source(HL_ATTR(HLF_W));
3700 msg_attr(_(w_arabic), HL_ATTR(HLF_W));
3701 #ifdef FEAT_EVAL
3702 set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
3703 #endif
3704 }
3705
3706 // set 'delcombine'
3707 p_deco = TRUE;
3708
3709 # ifdef FEAT_KEYMAP
3710 // Force-set the necessary keymap for arabic
3711 errmsg = set_option_value((char_u *)"keymap",
3712 0L, (char_u *)"arabic", OPT_LOCAL);
3713 # endif
3714 }
3715 else
3716 {
3717 // 'arabic' is reset, handle various sub-settings.
3718 if (!p_tbidi)
3719 {
3720 // reset rightleft mode
3721 if (curwin->w_p_rl)
3722 {
3723 curwin->w_p_rl = FALSE;
3724 changed_window_setting();
3725 }
3726
3727 // 'arabicshape' isn't reset, it is a global option and
3728 // another window may still need it "on".
3729 }
3730
3731 // 'delcombine' isn't reset, it is a global option and another
3732 // window may still want it "on".
3733
3734 # ifdef FEAT_KEYMAP
3735 // Revert to the default keymap
3736 curbuf->b_p_iminsert = B_IMODE_NONE;
3737 curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
3738 # endif
3739 }
3740
3741 return errmsg;
3742 }
3743 #endif
3744
3745 /*
3746 * Process the updated 'number' or 'relativenumber' option value.
3747 */
3748 char *
3749 did_set_number_relativenumber(optset_T *args UNUSED)
3750 {
3751 #if (defined(FEAT_SIGNS) && defined(FEAT_GUI)) || defined(PROTO)
3752 if (gui.in_use
3753 && (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u')
3754 && curbuf->b_signlist != NULL)
3755 {
3756 // If the 'number' or 'relativenumber' options are modified and
3757 // 'signcolumn' is set to 'number', then clear the screen for a full
3758 // refresh. Otherwise the sign icons are not displayed properly in the
3759 // number column. If the 'number' option is set and only the
3760 // 'relativenumber' option is toggled, then don't refresh the screen
3761 // (optimization).
3762 if (!(curwin->w_p_nu && ((int *)args->os_varp == &curwin->w_p_rnu)))
3763 redraw_all_later(UPD_CLEAR);
3764 }
3765 #endif
3766 return NULL;
3767 }
3768
3769 #ifdef FEAT_TERMGUICOLORS
3770 char * 4098 char *
3771 did_set_termguicolors(optset_T *args UNUSED) 4099 did_set_termguicolors(optset_T *args UNUSED)
3772 { 4100 {
3773 # ifdef FEAT_VTP 4101 # ifdef FEAT_VTP
3774 // Do not turn on 'tgc' when 24-bit colors are not supported. 4102 // Do not turn on 'tgc' when 24-bit colors are not supported.
3807 return NULL; 4135 return NULL;
3808 } 4136 }
3809 #endif 4137 #endif
3810 4138
3811 /* 4139 /*
4140 * Process the updated 'terse' option value.
4141 */
4142 char *
4143 did_set_terse(optset_T *args UNUSED)
4144 {
4145 char_u *p;
4146
4147 // when 'terse' is set change 'shortmess'
4148 p = vim_strchr(p_shm, SHM_SEARCH);
4149
4150 // insert 's' in p_shm
4151 if (p_terse && p == NULL)
4152 {
4153 STRCPY(IObuff, p_shm);
4154 STRCAT(IObuff, "s");
4155 set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
4156 }
4157 // remove 's' from p_shm
4158 else if (!p_terse && p != NULL)
4159 STRMOVE(p, p + 1);
4160 return NULL;
4161 }
4162
4163 /*
4164 * Process the updated 'textauto' option value.
4165 */
4166 char *
4167 did_set_textauto(optset_T *args)
4168 {
4169 // when 'textauto' is set or reset also change 'fileformats'
4170 set_string_option_direct((char_u *)"ffs", -1,
4171 p_ta ? (char_u *)DFLT_FFS_VIM : (char_u *)"",
4172 OPT_FREE | args->os_flags, 0);
4173
4174 return NULL;
4175 }
4176
4177 /*
4178 * Process the updated 'textmode' option value.
4179 */
4180 char *
4181 did_set_textmode(optset_T *args)
4182 {
4183 // when 'textmode' is set or reset also change 'fileformat'
4184 set_fileformat(curbuf->b_p_tx ? EOL_DOS : EOL_UNIX, args->os_flags);
4185
4186 return NULL;
4187 }
4188
4189 /*
4190 * Process the new 'textwidth' option value.
4191 */
4192 char *
4193 did_set_textwidth(optset_T *args UNUSED)
4194 {
4195 char *errmsg = NULL;
4196
4197 if (curbuf->b_p_tw < 0)
4198 {
4199 errmsg = e_argument_must_be_positive;
4200 curbuf->b_p_tw = 0;
4201 }
4202 #ifdef FEAT_SYN_HL
4203 {
4204 win_T *wp;
4205 tabpage_T *tp;
4206
4207 FOR_ALL_TAB_WINDOWS(tp, wp)
4208 check_colorcolumn(wp);
4209 }
4210 #endif
4211
4212 return errmsg;
4213 }
4214
4215 /*
4216 * Process the updated 'title' or the 'icon' option value.
4217 */
4218 char *
4219 did_set_title_icon(optset_T *args UNUSED)
4220 {
4221 // when 'title' changed, may need to change the title; same for 'icon'
4222 did_set_title();
4223 return NULL;
4224 }
4225
4226 /*
4227 * Process the new 'titlelen' option value.
4228 */
4229 char *
4230 did_set_titlelen(optset_T *args)
4231 {
4232 long old_value = args->os_oldval.number;
4233 char *errmsg = NULL;
4234
4235 // if 'titlelen' has changed, redraw the title
4236 if (p_titlelen < 0)
4237 {
4238 errmsg = e_argument_must_be_positive;
4239 p_titlelen = 85;
4240 }
4241 if (starting != NO_SCREEN && old_value != p_titlelen)
4242 need_maketitle = TRUE;
4243
4244 return errmsg;
4245 }
4246
4247 #if defined(FEAT_PERSISTENT_UNDO) || defined(PROTO)
4248 /*
4249 * Process the updated 'undofile' option value.
4250 */
4251 char *
4252 did_set_undofile(optset_T *args)
4253 {
4254 // Only take action when the option was set.
4255 if (!curbuf->b_p_udf && !p_udf)
4256 return NULL;
4257
4258 // When reset we do not delete the undo file, the option may be set again
4259 // without making any changes in between.
4260 char_u hash[UNDO_HASH_SIZE];
4261 buf_T *save_curbuf = curbuf;
4262
4263 FOR_ALL_BUFFERS(curbuf)
4264 {
4265 // When 'undofile' is set globally: for every buffer, otherwise
4266 // only for the current buffer: Try to read in the undofile,
4267 // if one exists, the buffer wasn't changed and the buffer was
4268 // loaded
4269 if ((curbuf == save_curbuf
4270 || (args->os_flags & OPT_GLOBAL)
4271 || args->os_flags == 0)
4272 && !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
4273 {
4274 #ifdef FEAT_CRYPT
4275 if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD)
4276 continue;
4277 #endif
4278 u_compute_hash(hash);
4279 u_read_undo(NULL, hash, curbuf->b_fname);
4280 }
4281 }
4282 curbuf = save_curbuf;
4283
4284 return NULL;
4285 }
4286 #endif
4287
4288 /*
4289 * Process the new global 'undolevels' option value.
4290 */
4291 static void
4292 update_global_undolevels(long value, long old_value)
4293 {
4294 // sync undo before 'undolevels' changes
4295
4296 // use the old value, otherwise u_sync() may not work properly
4297 p_ul = old_value;
4298 u_sync(TRUE);
4299 p_ul = value;
4300 }
4301
4302 /*
4303 * Process the new buffer local 'undolevels' option value.
4304 */
4305 static void
4306 update_buflocal_undolevels(long value, long old_value)
4307 {
4308 // use the old value, otherwise u_sync() may not work properly
4309 curbuf->b_p_ul = old_value;
4310 u_sync(TRUE);
4311 curbuf->b_p_ul = value;
4312 }
4313
4314 /*
4315 * Process the new 'undolevels' option value.
4316 */
4317 char *
4318 did_set_undolevels(optset_T *args)
4319 {
4320 long *pp = (long *)args->os_varp;
4321
4322 if (pp == &p_ul) // global 'undolevels'
4323 update_global_undolevels(args->os_newval.number,
4324 args->os_oldval.number);
4325 else if (pp == &curbuf->b_p_ul) // buffer local 'undolevels'
4326 update_buflocal_undolevels(args->os_newval.number,
4327 args->os_oldval.number);
4328
4329 return NULL;
4330 }
4331
4332 /*
4333 * Process the new 'updatecount' option value.
4334 */
4335 char *
4336 did_set_updatecount(optset_T *args)
4337 {
4338 long old_value = args->os_oldval.number;
4339 char *errmsg = NULL;
4340
4341 // when 'updatecount' changes from zero to non-zero, open swap files
4342 if (p_uc < 0)
4343 {
4344 errmsg = e_argument_must_be_positive;
4345 p_uc = 100;
4346 }
4347 if (p_uc && !old_value)
4348 ml_open_files();
4349
4350 return errmsg;
4351 }
4352
4353 /*
4354 * Process the updated 'weirdinvert' option value.
4355 */
4356 char *
4357 did_set_weirdinvert(optset_T *args)
4358 {
4359 // When 'weirdinvert' changed, set/reset 't_xs'.
4360 // Then set 'weirdinvert' according to value of 't_xs'.
4361 if (p_wiv && !args->os_oldval.boolean)
4362 T_XS = (char_u *)"y";
4363 else if (!p_wiv && args->os_oldval.boolean)
4364 T_XS = empty_option;
4365 p_wiv = (*T_XS != NUL);
4366
4367 return NULL;
4368 }
4369
4370 /*
4371 * Process the new 'window' option value.
4372 */
4373 char *
4374 did_set_window(optset_T *args UNUSED)
4375 {
4376 if (p_window < 1)
4377 p_window = 1;
4378 else if (p_window >= Rows)
4379 p_window = Rows - 1;
4380 return NULL;
4381 }
4382
4383 /*
4384 * Process the new 'winheight' or the 'helpheight' option value.
4385 */
4386 char *
4387 did_set_winheight_helpheight(optset_T *args)
4388 {
4389 long *pp = (long *)args->os_varp;
4390 char *errmsg = NULL;
4391
4392 if (p_wh < 1)
4393 {
4394 errmsg = e_argument_must_be_positive;
4395 p_wh = 1;
4396 }
4397 if (p_wmh > p_wh)
4398 {
4399 errmsg = e_winheight_cannot_be_smaller_than_winminheight;
4400 p_wh = p_wmh;
4401 }
4402 if (p_hh < 0)
4403 {
4404 errmsg = e_argument_must_be_positive;
4405 p_hh = 0;
4406 }
4407
4408 // Change window height NOW
4409 if (!ONE_WINDOW)
4410 {
4411 if (pp == &p_wh && curwin->w_height < p_wh)
4412 win_setheight((int)p_wh);
4413 if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
4414 win_setheight((int)p_hh);
4415 }
4416
4417 return errmsg;
4418 }
4419
4420 /*
4421 * Process the new 'winminheight' option value.
4422 */
4423 char *
4424 did_set_winminheight(optset_T *args UNUSED)
4425 {
4426 char *errmsg = NULL;
4427
4428 if (p_wmh < 0)
4429 {
4430 errmsg = e_argument_must_be_positive;
4431 p_wmh = 0;
4432 }
4433 if (p_wmh > p_wh)
4434 {
4435 errmsg = e_winheight_cannot_be_smaller_than_winminheight;
4436 p_wmh = p_wh;
4437 }
4438 win_setminheight();
4439
4440 return errmsg;
4441 }
4442
4443 /*
4444 * Process the new 'winminwidth' option value.
4445 */
4446 char *
4447 did_set_winminwidth(optset_T *args UNUSED)
4448 {
4449 char *errmsg = NULL;
4450
4451 if (p_wmw < 0)
4452 {
4453 errmsg = e_argument_must_be_positive;
4454 p_wmw = 0;
4455 }
4456 if (p_wmw > p_wiw)
4457 {
4458 errmsg = e_winwidth_cannot_be_smaller_than_winminwidth;
4459 p_wmw = p_wiw;
4460 }
4461 win_setminwidth();
4462
4463 return errmsg;
4464 }
4465
4466 /*
4467 * Process the new 'winwidth' option value.
4468 */
4469 char *
4470 did_set_winwidth(optset_T *args UNUSED)
4471 {
4472 char *errmsg = NULL;
4473
4474 if (p_wiw < 1)
4475 {
4476 errmsg = e_argument_must_be_positive;
4477 p_wiw = 1;
4478 }
4479 if (p_wmw > p_wiw)
4480 {
4481 errmsg = e_winwidth_cannot_be_smaller_than_winminwidth;
4482 p_wiw = p_wmw;
4483 }
4484
4485 // Change window width NOW
4486 if (!ONE_WINDOW && curwin->w_width < p_wiw)
4487 win_setwidth((int)p_wiw);
4488
4489 return errmsg;
4490 }
4491
4492 /*
4493 * Process the updated 'wrap' option value.
4494 */
4495 char *
4496 did_set_wrap(optset_T *args UNUSED)
4497 {
4498 // If 'wrap' is set, set w_leftcol to zero.
4499 if (curwin->w_p_wrap)
4500 curwin->w_leftcol = 0;
4501 return NULL;
4502 }
4503
4504 /*
3812 * Set the value of a boolean option, and take care of side effects. 4505 * Set the value of a boolean option, and take care of side effects.
3813 * Returns NULL for success, or an error message for an error. 4506 * Returns NULL for success, or an error message for an error.
3814 */ 4507 */
3815 static char * 4508 static char *
3816 set_bool_option( 4509 set_bool_option(
3859 // Handle side effects of changing a bool option. 4552 // Handle side effects of changing a bool option.
3860 if (options[opt_idx].opt_did_set_cb != NULL) 4553 if (options[opt_idx].opt_did_set_cb != NULL)
3861 { 4554 {
3862 optset_T args; 4555 optset_T args;
3863 4556
4557 CLEAR_FIELD(args);
3864 args.os_varp = varp; 4558 args.os_varp = varp;
3865 args.os_flags = opt_flags; 4559 args.os_flags = opt_flags;
3866 args.os_oldval.boolean = old_value; 4560 args.os_oldval.boolean = old_value;
3867 args.os_newval.boolean = value; 4561 args.os_newval.boolean = value;
3868 args.os_doskip = FALSE;
3869 args.os_errbuf = NULL; 4562 args.os_errbuf = NULL;
3870 errmsg = options[opt_idx].opt_did_set_cb(&args); 4563 errmsg = options[opt_idx].opt_did_set_cb(&args);
3871 if (args.os_doskip) 4564 if (args.os_doskip)
3872 return errmsg; 4565 return errmsg;
3873 } 4566 }
3890 4583
3891 if ((opt_flags & OPT_NO_REDRAW) == 0) 4584 if ((opt_flags & OPT_NO_REDRAW) == 0)
3892 check_redraw(options[opt_idx].flags); 4585 check_redraw(options[opt_idx].flags);
3893 4586
3894 return errmsg; 4587 return errmsg;
3895 }
3896
3897 /*
3898 * Process the new 'winheight' or the 'helpheight' option value.
3899 */
3900 char *
3901 did_set_winheight_helpheight(optset_T *args)
3902 {
3903 long *pp = (long *)args->os_varp;
3904 char *errmsg = NULL;
3905
3906 if (p_wh < 1)
3907 {
3908 errmsg = e_argument_must_be_positive;
3909 p_wh = 1;
3910 }
3911 if (p_wmh > p_wh)
3912 {
3913 errmsg = e_winheight_cannot_be_smaller_than_winminheight;
3914 p_wh = p_wmh;
3915 }
3916 if (p_hh < 0)
3917 {
3918 errmsg = e_argument_must_be_positive;
3919 p_hh = 0;
3920 }
3921
3922 // Change window height NOW
3923 if (!ONE_WINDOW)
3924 {
3925 if (pp == &p_wh && curwin->w_height < p_wh)
3926 win_setheight((int)p_wh);
3927 if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
3928 win_setheight((int)p_hh);
3929 }
3930
3931 return errmsg;
3932 }
3933
3934 /*
3935 * Process the new 'winminheight' option value.
3936 */
3937 char *
3938 did_set_winminheight(optset_T *args UNUSED)
3939 {
3940 char *errmsg = NULL;
3941
3942 if (p_wmh < 0)
3943 {
3944 errmsg = e_argument_must_be_positive;
3945 p_wmh = 0;
3946 }
3947 if (p_wmh > p_wh)
3948 {
3949 errmsg = e_winheight_cannot_be_smaller_than_winminheight;
3950 p_wmh = p_wh;
3951 }
3952 win_setminheight();
3953
3954 return errmsg;
3955 }
3956
3957 /*
3958 * Process the new 'winwidth' option value.
3959 */
3960 char *
3961 did_set_winwidth(optset_T *args UNUSED)
3962 {
3963 char *errmsg = NULL;
3964
3965 if (p_wiw < 1)
3966 {
3967 errmsg = e_argument_must_be_positive;
3968 p_wiw = 1;
3969 }
3970 if (p_wmw > p_wiw)
3971 {
3972 errmsg = e_winwidth_cannot_be_smaller_than_winminwidth;
3973 p_wiw = p_wmw;
3974 }
3975
3976 // Change window width NOW
3977 if (!ONE_WINDOW && curwin->w_width < p_wiw)
3978 win_setwidth((int)p_wiw);
3979
3980 return errmsg;
3981 }
3982
3983 /*
3984 * Process the new 'winminwidth' option value.
3985 */
3986 char *
3987 did_set_winminwidth(optset_T *args UNUSED)
3988 {
3989 char *errmsg = NULL;
3990
3991 if (p_wmw < 0)
3992 {
3993 errmsg = e_argument_must_be_positive;
3994 p_wmw = 0;
3995 }
3996 if (p_wmw > p_wiw)
3997 {
3998 errmsg = e_winwidth_cannot_be_smaller_than_winminwidth;
3999 p_wmw = p_wiw;
4000 }
4001 win_setminwidth();
4002
4003 return errmsg;
4004 }
4005
4006 /*
4007 * Process the new 'laststatus' option value.
4008 */
4009 char *
4010 did_set_laststatus(optset_T *args UNUSED)
4011 {
4012 last_status(FALSE); // (re)set last window status line
4013 return NULL;
4014 }
4015
4016 /*
4017 * Process the new 'showtabline' option value.
4018 */
4019 char *
4020 did_set_showtabline(optset_T *args UNUSED)
4021 {
4022 shell_new_rows(); // recompute window positions and heights
4023 return NULL;
4024 }
4025
4026 #if defined(FEAT_GUI) || defined(PROTO)
4027 /*
4028 * Process the new 'linespace' option value.
4029 */
4030 char *
4031 did_set_linespace(optset_T *args UNUSED)
4032 {
4033 // Recompute gui.char_height and resize the Vim window to keep the
4034 // same number of lines.
4035 if (gui.in_use && gui_mch_adjust_charheight() == OK)
4036 gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
4037 return NULL;
4038 }
4039 #endif
4040
4041 #if defined(FEAT_FOLDING) || defined(PROTO)
4042 /*
4043 * Process the new 'foldlevel' option value.
4044 */
4045 char *
4046 did_set_foldlevel(optset_T *args UNUSED)
4047 {
4048 if (curwin->w_p_fdl < 0)
4049 curwin->w_p_fdl = 0;
4050 newFoldLevel();
4051 return NULL;
4052 }
4053
4054 /*
4055 * Process the new 'foldminlines' option value.
4056 */
4057 char *
4058 did_set_foldminlines(optset_T *args UNUSED)
4059 {
4060 foldUpdateAll(curwin);
4061 return NULL;
4062 }
4063
4064 /*
4065 * Process the new 'foldnestmax' option value.
4066 */
4067 char *
4068 did_set_foldnestmax(optset_T *args UNUSED)
4069 {
4070 if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
4071 foldUpdateAll(curwin);
4072 return NULL;
4073 }
4074
4075 /*
4076 * Process the new 'foldcolumn' option value.
4077 */
4078 char *
4079 did_set_foldcolumn(optset_T *args UNUSED)
4080 {
4081 char *errmsg = NULL;
4082
4083 if (curwin->w_p_fdc < 0)
4084 {
4085 errmsg = e_argument_must_be_positive;
4086 curwin->w_p_fdc = 0;
4087 }
4088 else if (curwin->w_p_fdc > 12)
4089 {
4090 errmsg = e_invalid_argument;
4091 curwin->w_p_fdc = 12;
4092 }
4093
4094 return errmsg;
4095 }
4096 #endif
4097
4098 /*
4099 * Process the new 'shiftwidth' or the 'tabstop' option value.
4100 */
4101 char *
4102 did_set_shiftwidth_tabstop(optset_T *args)
4103 {
4104 long *pp = (long *)args->os_varp;
4105 char *errmsg = NULL;
4106
4107 if (curbuf->b_p_sw < 0)
4108 {
4109 errmsg = e_argument_must_be_positive;
4110 #ifdef FEAT_VARTABS
4111 // Use the first 'vartabstop' value, or 'tabstop' if vts isn't in use.
4112 curbuf->b_p_sw = tabstop_count(curbuf->b_p_vts_array) > 0
4113 ? tabstop_first(curbuf->b_p_vts_array)
4114 : curbuf->b_p_ts;
4115 #else
4116 curbuf->b_p_sw = curbuf->b_p_ts;
4117 #endif
4118 }
4119
4120 #ifdef FEAT_FOLDING
4121 if (foldmethodIsIndent(curwin))
4122 foldUpdateAll(curwin);
4123 #endif
4124 // When 'shiftwidth' changes, or it's zero and 'tabstop' changes:
4125 // parse 'cinoptions'.
4126 if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0)
4127 parse_cino(curbuf);
4128
4129 return errmsg;
4130 }
4131
4132 /*
4133 * Process the new 'maxcombine' option value.
4134 */
4135 char *
4136 did_set_maxcombine(optset_T *args UNUSED)
4137 {
4138 if (p_mco > MAX_MCO)
4139 p_mco = MAX_MCO;
4140 else if (p_mco < 0)
4141 p_mco = 0;
4142 screenclear(); // will re-allocate the screen
4143 return NULL;
4144 }
4145
4146 /*
4147 * Process the new 'iminsert' option value.
4148 */
4149 char *
4150 did_set_iminsert(optset_T *args UNUSED)
4151 {
4152 char *errmsg = NULL;
4153
4154 if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST)
4155 {
4156 errmsg = e_invalid_argument;
4157 curbuf->b_p_iminsert = B_IMODE_NONE;
4158 }
4159 p_iminsert = curbuf->b_p_iminsert;
4160 if (termcap_active) // don't do this in the alternate screen
4161 showmode();
4162 #if defined(FEAT_KEYMAP)
4163 // Show/unshow value of 'keymap' in status lines.
4164 status_redraw_curbuf();
4165 #endif
4166
4167 return errmsg;
4168 }
4169
4170 #if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) || defined(PROTO)
4171 /*
4172 * Process the new 'imstyle' option value.
4173 */
4174 char *
4175 did_set_imstyle(optset_T *args UNUSED)
4176 {
4177 char *errmsg = NULL;
4178
4179 if (p_imst != IM_ON_THE_SPOT && p_imst != IM_OVER_THE_SPOT)
4180 errmsg = e_invalid_argument;
4181
4182 return errmsg;
4183 }
4184 #endif
4185
4186 /*
4187 * Process the new 'window' option value.
4188 */
4189 char *
4190 did_set_window(optset_T *args UNUSED)
4191 {
4192 if (p_window < 1)
4193 p_window = 1;
4194 else if (p_window >= Rows)
4195 p_window = Rows - 1;
4196 return NULL;
4197 }
4198
4199 /*
4200 * Process the new 'imsearch' option value.
4201 */
4202 char *
4203 did_set_imsearch(optset_T *args UNUSED)
4204 {
4205 char *errmsg = NULL;
4206
4207 if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST)
4208 {
4209 errmsg = e_invalid_argument;
4210 curbuf->b_p_imsearch = B_IMODE_NONE;
4211 }
4212 p_imsearch = curbuf->b_p_imsearch;
4213
4214 return errmsg;
4215 }
4216
4217 /*
4218 * Process the new 'titlelen' option value.
4219 */
4220 char *
4221 did_set_titlelen(optset_T *args)
4222 {
4223 long old_value = args->os_oldval.number;
4224 char *errmsg = NULL;
4225
4226 // if 'titlelen' has changed, redraw the title
4227 if (p_titlelen < 0)
4228 {
4229 errmsg = e_argument_must_be_positive;
4230 p_titlelen = 85;
4231 }
4232 if (starting != NO_SCREEN && old_value != p_titlelen)
4233 need_maketitle = TRUE;
4234
4235 return errmsg;
4236 }
4237
4238 /*
4239 * Process the new 'cmdheight' option value.
4240 */
4241 char *
4242 did_set_cmdheight(optset_T *args)
4243 {
4244 long old_value = args->os_oldval.number;
4245 char *errmsg = NULL;
4246
4247 // if p_ch changed value, change the command line height
4248 if (p_ch < 1)
4249 {
4250 errmsg = e_argument_must_be_positive;
4251 p_ch = 1;
4252 }
4253 if (p_ch > Rows - min_rows() + 1)
4254 p_ch = Rows - min_rows() + 1;
4255
4256 // Only compute the new window layout when startup has been
4257 // completed. Otherwise the frame sizes may be wrong.
4258 if ((p_ch != old_value
4259 || tabline_height() + topframe->fr_height != Rows - p_ch)
4260 && full_screen
4261 #ifdef FEAT_GUI
4262 && !gui.starting
4263 #endif
4264 )
4265 command_height();
4266
4267 return errmsg;
4268 }
4269
4270 /*
4271 * Process the new 'updatecount' option value.
4272 */
4273 char *
4274 did_set_updatecount(optset_T *args)
4275 {
4276 long old_value = args->os_oldval.number;
4277 char *errmsg = NULL;
4278
4279 // when 'updatecount' changes from zero to non-zero, open swap files
4280 if (p_uc < 0)
4281 {
4282 errmsg = e_argument_must_be_positive;
4283 p_uc = 100;
4284 }
4285 if (p_uc && !old_value)
4286 ml_open_files();
4287
4288 return errmsg;
4289 }
4290
4291 #if defined(FEAT_CONCEAL) || defined(PROTO)
4292 /*
4293 * Process the new 'conceallevel' option value.
4294 */
4295 char *
4296 did_set_conceallevel(optset_T *args UNUSED)
4297 {
4298 char *errmsg = NULL;
4299
4300 if (curwin->w_p_cole < 0)
4301 {
4302 errmsg = e_argument_must_be_positive;
4303 curwin->w_p_cole = 0;
4304 }
4305 else if (curwin->w_p_cole > 3)
4306 {
4307 errmsg = e_invalid_argument;
4308 curwin->w_p_cole = 3;
4309 }
4310
4311 return errmsg;
4312 }
4313 #endif
4314
4315 #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
4316 /*
4317 * Process the new 'pyxversion' option value.
4318 */
4319 char *
4320 did_set_pyxversion(optset_T *args UNUSED)
4321 {
4322 char *errmsg = NULL;
4323
4324 if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3)
4325 errmsg = e_invalid_argument;
4326
4327 return errmsg;
4328 }
4329 #endif
4330
4331 /*
4332 * Process the new global 'undolevels' option value.
4333 */
4334 static void
4335 did_set_global_undolevels(long value, long old_value)
4336 {
4337 // sync undo before 'undolevels' changes
4338
4339 // use the old value, otherwise u_sync() may not work properly
4340 p_ul = old_value;
4341 u_sync(TRUE);
4342 p_ul = value;
4343 }
4344
4345 /*
4346 * Process the new buffer local 'undolevels' option value.
4347 */
4348 static void
4349 did_set_buflocal_undolevels(long value, long old_value)
4350 {
4351 // use the old value, otherwise u_sync() may not work properly
4352 curbuf->b_p_ul = old_value;
4353 u_sync(TRUE);
4354 curbuf->b_p_ul = value;
4355 }
4356
4357 #if defined(FEAT_LINEBREAK) || defined(PROTO)
4358 /*
4359 * Process the new 'numberwidth' option value.
4360 */
4361 char *
4362 did_set_numberwidth(optset_T *args UNUSED)
4363 {
4364 char *errmsg = NULL;
4365
4366 // 'numberwidth' must be positive
4367 if (curwin->w_p_nuw < 1)
4368 {
4369 errmsg = e_argument_must_be_positive;
4370 curwin->w_p_nuw = 1;
4371 }
4372 if (curwin->w_p_nuw > 20)
4373 {
4374 errmsg = e_invalid_argument;
4375 curwin->w_p_nuw = 20;
4376 }
4377 curwin->w_nrwidth_line_count = 0; // trigger a redraw
4378
4379 return errmsg;
4380 }
4381 #endif
4382
4383 /*
4384 * Process the new 'textwidth' option value.
4385 */
4386 char *
4387 did_set_textwidth(optset_T *args UNUSED)
4388 {
4389 char *errmsg = NULL;
4390
4391 if (curbuf->b_p_tw < 0)
4392 {
4393 errmsg = e_argument_must_be_positive;
4394 curbuf->b_p_tw = 0;
4395 }
4396 #ifdef FEAT_SYN_HL
4397 {
4398 win_T *wp;
4399 tabpage_T *tp;
4400
4401 FOR_ALL_TAB_WINDOWS(tp, wp)
4402 check_colorcolumn(wp);
4403 }
4404 #endif
4405
4406 return errmsg;
4407 }
4408
4409 /*
4410 * Process the new 'undolevels' option value.
4411 */
4412 char *
4413 did_set_undolevels(optset_T *args)
4414 {
4415 long *pp = (long *)args->os_varp;
4416
4417 if (pp == &p_ul) // global 'undolevels'
4418 did_set_global_undolevels(args->os_newval.number,
4419 args->os_oldval.number);
4420 else if (pp == &curbuf->b_p_ul) // buffer local 'undolevels'
4421 did_set_buflocal_undolevels(args->os_newval.number,
4422 args->os_oldval.number);
4423
4424 return NULL;
4425 } 4588 }
4426 4589
4427 /* 4590 /*
4428 * Check the bounds of numeric options. 4591 * Check the bounds of numeric options.
4429 */ 4592 */
4630 // new value. 4793 // new value.
4631 if (options[opt_idx].opt_did_set_cb != NULL) 4794 if (options[opt_idx].opt_did_set_cb != NULL)
4632 { 4795 {
4633 optset_T args; 4796 optset_T args;
4634 4797
4798 CLEAR_FIELD(args);
4635 args.os_varp = varp; 4799 args.os_varp = varp;
4636 args.os_flags = opt_flags; 4800 args.os_flags = opt_flags;
4637 args.os_oldval.number = old_value; 4801 args.os_oldval.number = old_value;
4638 args.os_newval.number = value; 4802 args.os_newval.number = value;
4639 args.os_errbuf = NULL; 4803 args.os_errbuf = NULL;
7654 || (vim_strchr(p_shm, 'a') != NULL 7818 || (vim_strchr(p_shm, 'a') != NULL
7655 && vim_strchr((char_u *)SHM_A, x) != NULL)); 7819 && vim_strchr((char_u *)SHM_A, x) != NULL));
7656 } 7820 }
7657 7821
7658 /* 7822 /*
7659 * paste_option_changed() - Called after p_paste was set or reset.
7660 */
7661 static void
7662 paste_option_changed(void)
7663 {
7664 static int old_p_paste = FALSE;
7665 static int save_sm = 0;
7666 static int save_sta = 0;
7667 static int save_ru = 0;
7668 #ifdef FEAT_RIGHTLEFT
7669 static int save_ri = 0;
7670 static int save_hkmap = 0;
7671 #endif
7672 buf_T *buf;
7673
7674 if (p_paste)
7675 {
7676 // Paste switched from off to on.
7677 // Save the current values, so they can be restored later.
7678 if (!old_p_paste)
7679 {
7680 // save options for each buffer
7681 FOR_ALL_BUFFERS(buf)
7682 {
7683 buf->b_p_tw_nopaste = buf->b_p_tw;
7684 buf->b_p_wm_nopaste = buf->b_p_wm;
7685 buf->b_p_sts_nopaste = buf->b_p_sts;
7686 buf->b_p_ai_nopaste = buf->b_p_ai;
7687 buf->b_p_et_nopaste = buf->b_p_et;
7688 #ifdef FEAT_VARTABS
7689 if (buf->b_p_vsts_nopaste)
7690 vim_free(buf->b_p_vsts_nopaste);
7691 buf->b_p_vsts_nopaste =
7692 buf->b_p_vsts && buf->b_p_vsts != empty_option
7693 ? vim_strsave(buf->b_p_vsts) : NULL;
7694 #endif
7695 }
7696
7697 // save global options
7698 save_sm = p_sm;
7699 save_sta = p_sta;
7700 save_ru = p_ru;
7701 #ifdef FEAT_RIGHTLEFT
7702 save_ri = p_ri;
7703 save_hkmap = p_hkmap;
7704 #endif
7705 // save global values for local buffer options
7706 p_ai_nopaste = p_ai;
7707 p_et_nopaste = p_et;
7708 p_sts_nopaste = p_sts;
7709 p_tw_nopaste = p_tw;
7710 p_wm_nopaste = p_wm;
7711 #ifdef FEAT_VARTABS
7712 if (p_vsts_nopaste)
7713 vim_free(p_vsts_nopaste);
7714 p_vsts_nopaste = p_vsts && p_vsts != empty_option
7715 ? vim_strsave(p_vsts) : NULL;
7716 #endif
7717 }
7718
7719 // Always set the option values, also when 'paste' is set when it is
7720 // already on. Set options for each buffer.
7721 FOR_ALL_BUFFERS(buf)
7722 {
7723 buf->b_p_tw = 0; // textwidth is 0
7724 buf->b_p_wm = 0; // wrapmargin is 0
7725 buf->b_p_sts = 0; // softtabstop is 0
7726 buf->b_p_ai = 0; // no auto-indent
7727 buf->b_p_et = 0; // no expandtab
7728 #ifdef FEAT_VARTABS
7729 if (buf->b_p_vsts)
7730 free_string_option(buf->b_p_vsts);
7731 buf->b_p_vsts = empty_option;
7732 VIM_CLEAR(buf->b_p_vsts_array);
7733 #endif
7734 }
7735
7736 // set global options
7737 p_sm = 0; // no showmatch
7738 p_sta = 0; // no smarttab
7739 if (p_ru)
7740 status_redraw_all(); // redraw to remove the ruler
7741 p_ru = 0; // no ruler
7742 #ifdef FEAT_RIGHTLEFT
7743 p_ri = 0; // no reverse insert
7744 p_hkmap = 0; // no Hebrew keyboard
7745 #endif
7746 // set global values for local buffer options
7747 p_tw = 0;
7748 p_wm = 0;
7749 p_sts = 0;
7750 p_ai = 0;
7751 #ifdef FEAT_VARTABS
7752 if (p_vsts)
7753 free_string_option(p_vsts);
7754 p_vsts = empty_option;
7755 #endif
7756 }
7757
7758 // Paste switched from on to off: Restore saved values.
7759 else if (old_p_paste)
7760 {
7761 // restore options for each buffer
7762 FOR_ALL_BUFFERS(buf)
7763 {
7764 buf->b_p_tw = buf->b_p_tw_nopaste;
7765 buf->b_p_wm = buf->b_p_wm_nopaste;
7766 buf->b_p_sts = buf->b_p_sts_nopaste;
7767 buf->b_p_ai = buf->b_p_ai_nopaste;
7768 buf->b_p_et = buf->b_p_et_nopaste;
7769 #ifdef FEAT_VARTABS
7770 if (buf->b_p_vsts)
7771 free_string_option(buf->b_p_vsts);
7772 buf->b_p_vsts = buf->b_p_vsts_nopaste
7773 ? vim_strsave(buf->b_p_vsts_nopaste) : empty_option;
7774 vim_free(buf->b_p_vsts_array);
7775 if (buf->b_p_vsts && buf->b_p_vsts != empty_option)
7776 (void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
7777 else
7778 buf->b_p_vsts_array = NULL;
7779 #endif
7780 }
7781
7782 // restore global options
7783 p_sm = save_sm;
7784 p_sta = save_sta;
7785 if (p_ru != save_ru)
7786 status_redraw_all(); // redraw to draw the ruler
7787 p_ru = save_ru;
7788 #ifdef FEAT_RIGHTLEFT
7789 p_ri = save_ri;
7790 p_hkmap = save_hkmap;
7791 #endif
7792 // set global values for local buffer options
7793 p_ai = p_ai_nopaste;
7794 p_et = p_et_nopaste;
7795 p_sts = p_sts_nopaste;
7796 p_tw = p_tw_nopaste;
7797 p_wm = p_wm_nopaste;
7798 #ifdef FEAT_VARTABS
7799 if (p_vsts)
7800 free_string_option(p_vsts);
7801 p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option;
7802 #endif
7803 }
7804
7805 old_p_paste = p_paste;
7806 }
7807
7808 /*
7809 * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found. 7823 * vimrc_found() - Called when a ".vimrc" or "VIMINIT" has been found.
7810 * 7824 *
7811 * Reset 'compatible' and set the values for options that didn't get set yet 7825 * Reset 'compatible' and set the values for options that didn't get set yet
7812 * to the Vim defaults. 7826 * to the Vim defaults.
7813 * Don't do this if the 'compatible' option has been set or reset before. 7827 * Don't do this if the 'compatible' option has been set or reset before.
7916 || (!(options[opt_idx].flags & P_VI_DEF) && !p_cp)) 7930 || (!(options[opt_idx].flags & P_VI_DEF) && !p_cp))
7917 set_option_default(opt_idx, OPT_FREE, p_cp); 7931 set_option_default(opt_idx, OPT_FREE, p_cp);
7918 didset_options(); 7932 didset_options();
7919 didset_options2(); 7933 didset_options2();
7920 } 7934 }
7921
7922 #if defined(FEAT_LINEBREAK) || defined(PROTO)
7923
7924 /*
7925 * Called when the 'breakat' option changes value.
7926 */
7927 char *
7928 did_set_breakat(optset_T *args UNUSED)
7929 {
7930 char_u *p;
7931 int i;
7932
7933 for (i = 0; i < 256; i++)
7934 breakat_flags[i] = FALSE;
7935
7936 if (p_breakat != NULL)
7937 for (p = p_breakat; *p; p++)
7938 breakat_flags[*p] = TRUE;
7939
7940 return NULL;
7941 }
7942 #endif
7943 7935
7944 /* 7936 /*
7945 * Check if backspacing over something is allowed. 7937 * Check if backspacing over something is allowed.
7946 */ 7938 */
7947 int 7939 int