To: vim_dev@googlegroups.com Subject: Patch 9.0.1369 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1369 Problem: Still some "else if" constructs for setting options. Solution: Add a few more functions for handling options. (Yegappan Lakshmanan, closes #12090) Files: src/option.c, src/optiondefs.h, src/optionstr.c, src/proto/optionstr.pro, src/screen.c, src/proto/screen.pro, src/testdir/test_options.vim *** ../vim-9.0.1368/src/option.c 2023-02-25 11:59:28.866874078 +0000 --- src/option.c 2023-03-02 14:41:39.588615253 +0000 *************** *** 916,945 **** { int idx; ! /* ! * 'scroll' defaults to half the window height. The stored default is zero, ! * which results in the actual value computed from the window height. ! */ idx = findoption((char_u *)"scroll"); if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) set_option_default(idx, OPT_LOCAL, p_cp); comp_col(); ! /* ! * 'window' is only for backwards compatibility with Vi. ! * Default is Rows - 1. ! */ if (!option_was_set((char_u *)"window")) p_window = Rows - 1; set_number_default("window", Rows - 1); // For DOS console the default is always black. #if !((defined(MSWIN)) && !defined(FEAT_GUI)) ! /* ! * If 'background' wasn't set by the user, try guessing the value, ! * depending on the terminal name. Only need to check for terminals ! * with a dark background, that can handle color. ! */ idx = findoption((char_u *)"bg"); if (idx >= 0 && !(options[idx].flags & P_WAS_SET) && *term_bg_default() == 'd') --- 916,939 ---- { int idx; ! // 'scroll' defaults to half the window height. The stored default is zero, ! // which results in the actual value computed from the window height. idx = findoption((char_u *)"scroll"); if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) set_option_default(idx, OPT_LOCAL, p_cp); comp_col(); ! // 'window' is only for backwards compatibility with Vi. ! // Default is Rows - 1. if (!option_was_set((char_u *)"window")) p_window = Rows - 1; set_number_default("window", Rows - 1); // For DOS console the default is always black. #if !((defined(MSWIN)) && !defined(FEAT_GUI)) ! // If 'background' wasn't set by the user, try guessing the value, ! // depending on the terminal name. Only need to check for terminals ! // with a dark background, that can handle color. idx = findoption((char_u *)"bg"); if (idx >= 0 && !(options[idx].flags & P_WAS_SET) && *term_bg_default() == 'd') *************** *** 997,1006 **** p = get_isolated_shell_name(); if (p != NULL) { ! /* ! * Default for p_sp is "| tee", for p_srr is ">". ! * For known shells it is changed here to include stderr. ! */ if ( fnamecmp(p, "csh") == 0 || fnamecmp(p, "tcsh") == 0 # if defined(MSWIN) // also check with .exe extension --- 991,998 ---- p = get_isolated_shell_name(); if (p != NULL) { ! // Default for p_sp is "| tee", for p_srr is ">". ! // For known shells it is changed here to include stderr. if ( fnamecmp(p, "csh") == 0 || fnamecmp(p, "tcsh") == 0 # if defined(MSWIN) // also check with .exe extension *************** *** 1251,1261 **** int idx1; long val; ! /* ! * If GUI is (going to be) used, we can always set the window title and ! * icon name. Saves a bit of time, because the X11 display server does ! * not need to be contacted. ! */ idx1 = findoption((char_u *)"title"); if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) { --- 1243,1251 ---- int idx1; long val; ! // If GUI is (going to be) used, we can always set the window title and ! // icon name. Saves a bit of time, because the X11 display server does ! // not need to be contacted. idx1 = findoption((char_u *)"title"); if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) { *************** *** 1387,1395 **** int nextchar; // next non-white char after option name len = 0; ! /* ! * The two characters after "t_" may not be alphanumeric. ! */ if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) len = 4; else --- 1377,1383 ---- int nextchar; // next non-white char after option name len = 0; ! // The two characters after "t_" may not be alphanumeric. if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) len = 4; else *************** *** 2075,2085 **** if (opt_idx < 0 || varp == NULL) return NULL; // "cannot happen" ! /* ! * ":set opt!": invert ! * ":set opt&": reset to default value ! * ":set opt<": reset to global value ! */ if (nextchar == '!') value = *(int *)(varp) ^ 1; else if (nextchar == '&') --- 2063,2071 ---- if (opt_idx < 0 || varp == NULL) return NULL; // "cannot happen" ! // ":set opt!": invert ! // ":set opt&": reset to default value ! // ":set opt<": reset to global value if (nextchar == '!') value = *(int *)(varp) ^ 1; else if (nextchar == '&') *************** *** 2095,2104 **** } else { ! /* ! * ":set invopt": invert ! * ":set opt" or ":set noopt": set or reset ! */ if (nextchar != NUL && !VIM_ISWHITE(afterchar)) return e_trailing_characters; if (prefix == PREFIX_INV) --- 2081,2088 ---- } else { ! // ":set invopt": invert ! // ":set opt" or ":set noopt": set or reset if (nextchar != NUL && !VIM_ISWHITE(afterchar)) return e_trailing_characters; if (prefix == PREFIX_INV) *************** *** 2453,2470 **** } } ! /* ! * Allow '=' and ':' for historical reasons (MSDOS command.com). ! * Allows only one '=' character per "set" command line. grrr. (jw) ! */ if (nextchar == '?' || (prefix == PREFIX_NONE && vim_strchr((char_u *)"=:&<", nextchar) == NULL && !(flags & P_BOOL))) { ! /* ! * print value ! */ if (*did_show) msg_putchar('\n'); // cursor below last one else --- 2437,2450 ---- } } ! // Allow '=' and ':' for historical reasons (MSDOS command.com). ! // Allows only one '=' character per "set" command line. grrr. (jw) if (nextchar == '?' || (prefix == PREFIX_NONE && vim_strchr((char_u *)"=:&<", nextchar) == NULL && !(flags & P_BOOL))) { ! // print value if (*did_show) msg_putchar('\n'); // cursor below last one else *************** *** 2557,2566 **** if (STRNCMP(arg, "all", 3) == 0 && !ASCII_ISALPHA(arg[3]) && !(opt_flags & OPT_MODELINE)) { ! /* ! * ":set all" show all options. ! * ":set all&" set all options to their default value. ! */ arg += 3; if (*arg == '&') { --- 2537,2544 ---- if (STRNCMP(arg, "all", 3) == 0 && !ASCII_ISALPHA(arg[3]) && !(opt_flags & OPT_MODELINE)) { ! // ":set all" show all options. ! // ":set all&" set all options to their default value. arg += 3; if (*arg == '&') { *************** *** 2597,2608 **** if (stopopteval) break; ! /* ! * Advance to next argument. ! * - skip until a blank found, taking care of backslashes ! * - skip blanks ! * - skip one "=val" argument (for hidden options ":set gfn =xx") ! */ for (i = 0; i < 2 ; ++i) { while (*arg != NUL && !VIM_ISWHITE(*arg)) --- 2575,2584 ---- if (stopopteval) break; ! // Advance to next argument. ! // - skip until a blank found, taking care of backslashes ! // - skip blanks ! // - skip one "=val" argument (for hidden options ":set gfn =xx") for (i = 0; i < 2 ; ++i) { while (*arg != NUL && !VIM_ISWHITE(*arg)) *************** *** 2727,2736 **** int newval, int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL { ! /* ! * The option values that are changed when 'bin' changes are ! * copied when 'bin is set and restored when 'bin' is reset. ! */ if (newval) { if (!oldval) // switched on --- 2703,2710 ---- int newval, int opt_flags) // OPT_LOCAL and/or OPT_GLOBAL { ! // The option values that are changed when 'bin' changes are ! // copied when 'bin is set and restored when 'bin' is reset. if (newval) { if (!oldval) // switched on *************** *** 2865,2874 **** check_opt_wim(); // Parse default for 'listchars'. ! (void)set_chars_option(curwin, &curwin->w_p_lcs, TRUE); // Parse default for 'fillchars'. ! (void)set_chars_option(curwin, &curwin->w_p_fcs, TRUE); #ifdef FEAT_CLIPBOARD // Parse default for 'clipboard' --- 2839,2848 ---- check_opt_wim(); // Parse default for 'listchars'. ! (void)set_listchars_option(curwin, curwin->w_p_lcs, TRUE); // Parse default for 'fillchars'. ! (void)set_fillchars_option(curwin, curwin->w_p_fcs, TRUE); #ifdef FEAT_CLIPBOARD // Parse default for 'clipboard' *************** *** 3698,3706 **** if (curwin->w_p_arab) { ! /* ! * 'arabic' is set, handle various sub-settings. ! */ if (!p_tbidi) { // set rightleft mode --- 3672,3678 ---- if (curwin->w_p_arab) { ! // 'arabic' is set, handle various sub-settings. if (!p_tbidi) { // set rightleft mode *************** *** 3742,3750 **** } else { ! /* ! * 'arabic' is reset, handle various sub-settings. ! */ if (!p_tbidi) { // reset rightleft mode --- 3714,3720 ---- } else { ! // 'arabic' is reset, handle various sub-settings. if (!p_tbidi) { // reset rightleft mode *************** *** 3886,3894 **** if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value; ! /* ! * Handle side effects of changing a bool option. ! */ if (options[opt_idx].opt_did_set_cb != NULL) { optset_T args; --- 3856,3862 ---- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value; ! // Handle side effects of changing a bool option. if (options[opt_idx].opt_did_set_cb != NULL) { optset_T args; *************** *** 4491,4500 **** } limit_screen_size(); ! /* ! * If the screen (shell) height has been changed, assume it is the ! * physical screenheight. ! */ if (old_Rows != Rows || old_Columns != Columns) { // Changing the screen size is not allowed while updating the screen. --- 4459,4466 ---- } limit_screen_size(); ! // If the screen (shell) height has been changed, assume it is the ! // physical screenheight. if (old_Rows != Rows || old_Columns != Columns) { // Changing the screen size is not allowed while updating the screen. *************** *** 4736,4746 **** static short quick_tab[27] = {0, 0}; // quick access table int is_term_opt; ! /* ! * For first call: Initialize the quick-access table. ! * It contains the index for the first option that starts with a certain ! * letter. There are 26 letters, plus the first "t_" option. ! */ if (quick_tab[1] == 0) { p = options[0].fullname; --- 4702,4710 ---- static short quick_tab[27] = {0, 0}; // quick access table int is_term_opt; ! // For first call: Initialize the quick-access table. ! // It contains the index for the first option that starts with a certain ! // letter. There are 26 letters, plus the first "t_" option. if (quick_tab[1] == 0) { p = options[0].fullname; *************** *** 4757,4765 **** } } ! /* ! * Check for name starting with an illegal character. ! */ if (arg[0] < 'a' || arg[0] > 'z') return -1; --- 4721,4727 ---- } } ! // Check for name starting with an illegal character. if (arg[0] < 'a' || arg[0] > 'z') return -1; *************** *** 5369,5378 **** int modifiers; char_u *arg = arg_arg; ! /* ! * Don't use get_special_key_code() for t_xx, we don't want it to call ! * add_termcap_entry(). ! */ if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) key = TERMCAP2KEY(arg[2], arg[3]); else if (has_lt) --- 5331,5338 ---- int modifiers; char_u *arg = arg_arg; ! // Don't use get_special_key_code() for t_xx, we don't want it to call ! // add_termcap_entry(). if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) key = TERMCAP2KEY(arg[2], arg[3]); else if (has_lt) *************** *** 5426,5442 **** else msg_puts_title(_("\n--- Options ---")); ! /* ! * Do the loop two times: ! * 1. display the short items ! * 2. display the long items (only strings and numbers) ! * When "opt_flags" has OPT_ONECOLUMN do everything in run 2. ! */ for (run = 1; run <= 2 && !got_int; ++run) { ! /* ! * collect the items in items[] ! */ item_count = 0; for (p = &options[0]; p->fullname != NULL; p++) { --- 5386,5398 ---- else msg_puts_title(_("\n--- Options ---")); ! // Do the loop two times: ! // 1. display the short items ! // 2. display the long items (only strings and numbers) ! // When "opt_flags" has OPT_ONECOLUMN do everything in run 2. for (run = 1; run <= 2 && !got_int; ++run) { ! // collect the items in items[] item_count = 0; for (p = &options[0]; p->fullname != NULL; p++) { *************** *** 5473,5481 **** } } ! /* ! * display the items ! */ if (run == 1) { cols = (Columns + GAP - 3) / INC; --- 5429,5435 ---- } } ! // display the items if (run == 1) { cols = (Columns + GAP - 3) / INC; *************** *** 5863,5873 **** void clear_termoptions(void) { ! /* ! * Reset a few things before clearing the old options. This may cause ! * outputting a few things that the terminal doesn't understand, but the ! * screen will be cleared later, so this is OK. ! */ mch_setmouse(FALSE); // switch mouse off mch_restore_title(SAVE_RESTORE_BOTH); // restore window titles #if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI) --- 5817,5825 ---- void clear_termoptions(void) { ! // Reset a few things before clearing the old options. This may cause ! // outputting a few things that the terminal doesn't understand, but the ! // screen will be cleared later, so this is OK. mch_setmouse(FALSE); // switch mouse off mch_restore_title(SAVE_RESTORE_BOTH); // restore window titles #if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI) *************** *** 6083,6094 **** break; case PV_LCS: clear_string_option(&((win_T *)from)->w_p_lcs); ! set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs, TRUE); redraw_later(UPD_NOT_VALID); break; case PV_FCS: clear_string_option(&((win_T *)from)->w_p_fcs); ! set_chars_option((win_T *)from, &((win_T *)from)->w_p_fcs, TRUE); redraw_later(UPD_NOT_VALID); break; case PV_VE: --- 6035,6046 ---- break; case PV_LCS: clear_string_option(&((win_T *)from)->w_p_lcs); ! set_listchars_option((win_T *)from, ((win_T *)from)->w_p_lcs, TRUE); redraw_later(UPD_NOT_VALID); break; case PV_FCS: clear_string_option(&((win_T *)from)->w_p_fcs); ! set_fillchars_option((win_T *)from, ((win_T *)from)->w_p_fcs, TRUE); redraw_later(UPD_NOT_VALID); break; case PV_VE: *************** *** 6494,6501 **** fill_culopt_flags(NULL, wp); check_colorcolumn(wp); #endif ! set_chars_option(wp, &wp->w_p_lcs, TRUE); ! set_chars_option(wp, &wp->w_p_fcs, TRUE); } static char_u * --- 6446,6453 ---- fill_culopt_flags(NULL, wp); check_colorcolumn(wp); #endif ! set_listchars_option(wp, wp->w_p_lcs, TRUE); ! set_fillchars_option(wp, wp->w_p_fcs, TRUE); } static char_u * *************** *** 6753,6762 **** int dont_do_help; int did_isk = FALSE; ! /* ! * Skip this when the option defaults have not been set yet. Happens when ! * main() allocates the first buffer. ! */ if (p_cpo != NULL) { /* --- 6705,6712 ---- int dont_do_help; int did_isk = FALSE; ! // Skip this when the option defaults have not been set yet. Happens when ! // main() allocates the first buffer. if (p_cpo != NULL) { /* *************** *** 6793,6802 **** save_p_isk = buf->b_p_isk; buf->b_p_isk = NULL; } ! /* ! * Always free the allocated strings. If not already initialized, ! * reset 'readonly' and copy 'fileformat'. ! */ if (!buf->b_p_initialized) { free_buf_options(buf, TRUE); --- 6743,6750 ---- save_p_isk = buf->b_p_isk; buf->b_p_isk = NULL; } ! // Always free the allocated strings. If not already initialized, ! // reset 'readonly' and copy 'fileformat'. if (!buf->b_p_initialized) { free_buf_options(buf, TRUE); *************** *** 7027,7038 **** buf->b_p_lw = empty_option; buf->b_p_menc = empty_option; ! /* ! * Don't copy the options set by ex_help(), use the saved values, ! * when going from a help buffer to a non-help buffer. ! * Don't touch these at all when BCO_NOHELP is used and going from ! * or to a help buffer. ! */ if (dont_do_help) { buf->b_p_isk = save_p_isk; --- 6975,6984 ---- buf->b_p_lw = empty_option; buf->b_p_menc = empty_option; ! // Don't copy the options set by ex_help(), use the saved values, ! // when going from a help buffer to a non-help buffer. ! // Don't touch these at all when BCO_NOHELP is used and going from ! // or to a help buffer. if (dont_do_help) { buf->b_p_isk = save_p_isk; *************** *** 7066,7075 **** } } ! /* ! * When the options should be copied (ignoring BCO_ALWAYS), set the ! * flag that indicates that the options have been initialized. ! */ if (should_copy) buf->b_p_initialized = TRUE; } --- 7012,7019 ---- } } ! // When the options should be copied (ignoring BCO_ALWAYS), set the ! // flag that indicates that the options have been initialized. if (should_copy) buf->b_p_initialized = TRUE; } *************** *** 7484,7492 **** } } ! /* ! * Check terminal key codes, these are not in the option table ! */ if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0) { for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++) --- 7428,7434 ---- } } ! // Check terminal key codes, these are not in the option table if (xp->xp_context != EXPAND_BOOL_SETTINGS && num_normal == 0) { for (opt_idx = 0; (str = get_termcode(opt_idx)) != NULL; opt_idx++) *************** *** 7530,7538 **** } } ! /* ! * Check special key names. ! */ regmatch->rm_ic = TRUE; // ignore case here for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++) { --- 7472,7478 ---- } } ! // Check special key names. regmatch->rm_ic = TRUE; // ignore case here for (opt_idx = 0; (str = get_key_name(opt_idx)) != NULL; opt_idx++) { *************** *** 7597,7605 **** if (*matches == NULL) return FAIL; ! /* ! * For a terminal key code expand_option_idx is < 0. ! */ if (expand_option_idx < 0) { var = find_termcode(expand_option_name + 2); --- 7537,7543 ---- if (*matches == NULL) return FAIL; ! // For a terminal key code expand_option_idx is < 0. if (expand_option_idx < 0) { var = find_termcode(expand_option_name + 2); *************** *** 7735,7744 **** if (p_paste) { ! /* ! * Paste switched from off to on. ! * Save the current values, so they can be restored later. ! */ if (!old_p_paste) { // save options for each buffer --- 7673,7680 ---- if (p_paste) { ! // Paste switched from off to on. ! // Save the current values, so they can be restored later. if (!old_p_paste) { // save options for each buffer *************** *** 7780,7790 **** #endif } ! /* ! * Always set the option values, also when 'paste' is set when it is ! * already on. ! */ ! // set options for each buffer FOR_ALL_BUFFERS(buf) { buf->b_p_tw = 0; // textwidth is 0 --- 7716,7723 ---- #endif } ! // Always set the option values, also when 'paste' is set when it is ! // already on. Set options for each buffer. FOR_ALL_BUFFERS(buf) { buf->b_p_tw = 0; // textwidth is 0 *************** *** 7822,7830 **** #endif } ! /* ! * Paste switched from on to off: Restore saved values. ! */ else if (old_p_paste) { // restore options for each buffer --- 7755,7761 ---- #endif } ! // Paste switched from on to off: Restore saved values. else if (old_p_paste) { // restore options for each buffer *** ../vim-9.0.1368/src/optiondefs.h 2023-02-27 12:47:44.107282452 +0000 --- src/optiondefs.h 2023-03-02 14:41:39.588615253 +0000 *************** *** 944,950 **** {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"fillchars", "fcs", P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP, ! (char_u *)&p_fcs, PV_FCS, NULL, {(char_u *)"vert:|,fold:-,eob:~,lastline:@", (char_u *)0L} SCTX_INIT}, --- 944,950 ---- {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"fillchars", "fcs", P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP, ! (char_u *)&p_fcs, PV_FCS, did_set_chars_option, {(char_u *)"vert:|,fold:-,eob:~,lastline:@", (char_u *)0L} SCTX_INIT}, *************** *** 1575,1581 **** (char_u *)VAR_WIN, PV_LIST, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"listchars", "lcs", P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP, ! (char_u *)&p_lcs, PV_LCS, NULL, {(char_u *)"eol:$", (char_u *)0L} SCTX_INIT}, {"loadplugins", "lpl", P_BOOL|P_VI_DEF, (char_u *)&p_lpl, PV_NONE, NULL, --- 1575,1581 ---- (char_u *)VAR_WIN, PV_LIST, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"listchars", "lcs", P_STRING|P_VI_DEF|P_RALL|P_ONECOMMA|P_NODUP, ! (char_u *)&p_lcs, PV_LCS, did_set_chars_option, {(char_u *)"eol:$", (char_u *)0L} SCTX_INIT}, {"loadplugins", "lpl", P_BOOL|P_VI_DEF, (char_u *)&p_lpl, PV_NONE, NULL, *** ../vim-9.0.1368/src/optionstr.c 2023-03-01 12:44:02.692086925 +0000 --- src/optionstr.c 2023-03-02 14:41:39.588615253 +0000 *************** *** 891,896 **** --- 891,967 ---- } /* + * The global 'listchars' or 'fillchars' option is changed. + */ + static char * + did_set_global_listfillchars(char_u *val, int opt_lcs, int opt_flags) + { + char *errmsg = NULL; + char_u **local_ptr = opt_lcs ? &curwin->w_p_lcs : &curwin->w_p_fcs; + + // only apply the global value to "curwin" when it does not have a + // local value + if (opt_lcs) + errmsg = set_listchars_option(curwin, val, + **local_ptr == NUL || !(opt_flags & OPT_GLOBAL)); + else + errmsg = set_fillchars_option(curwin, val, + **local_ptr == NUL || !(opt_flags & OPT_GLOBAL)); + if (errmsg != NULL) + return errmsg; + + tabpage_T *tp; + win_T *wp; + + // If the current window is set to use the global + // 'listchars'/'fillchars' value, clear the window-local value. + if (!(opt_flags & OPT_GLOBAL)) + clear_string_option(local_ptr); + FOR_ALL_TAB_WINDOWS(tp, wp) + { + // If the current window has a local value need to apply it + // again, it was changed when setting the global value. + // If no error was returned above, we don't expect an error + // here, so ignore the return value. + if (opt_lcs) + { + if (*wp->w_p_lcs == NUL) + (void)set_listchars_option(wp, wp->w_p_lcs, TRUE); + } + else + { + if (*wp->w_p_fcs == NUL) + (void)set_fillchars_option(wp, wp->w_p_fcs, TRUE); + } + } + + redraw_all_later(UPD_NOT_VALID); + + return NULL; + } + + /* + * The 'fillchars' option or the 'listchars' option is changed. + */ + char * + did_set_chars_option(optset_T *args) + { + char *errmsg = NULL; + + if ( args->os_varp == p_lcs // global 'listchars' + || args->os_varp == p_fcs) // global 'fillchars' + errmsg = did_set_global_listfillchars(args->os_varp, + args->os_varp == p_lcs, + args->os_flags); + else if (args->os_varp == curwin->w_p_lcs) // local 'listchars' + errmsg = set_listchars_option(curwin, args->os_varp, TRUE); + else if (args->os_varp == curwin->w_p_fcs) // local 'fillchars' + errmsg = set_fillchars_option(curwin, args->os_varp, TRUE); + + return errmsg; + } + + /* * The 'cinoptions' option is changed. */ char * *************** *** 1504,1549 **** args->os_errbuf); } - /* - * The global 'listchars' or 'fillchars' option is changed. - */ - static char * - did_set_global_listfillchars(char_u **varp, int opt_flags) - { - char *errmsg = NULL; - char_u **local_ptr = varp == &p_lcs - ? &curwin->w_p_lcs : &curwin->w_p_fcs; - - // only apply the global value to "curwin" when it does not have a - // local value - errmsg = set_chars_option(curwin, varp, - **local_ptr == NUL || !(opt_flags & OPT_GLOBAL)); - if (errmsg != NULL) - return errmsg; - - tabpage_T *tp; - win_T *wp; - - // If the current window is set to use the global - // 'listchars'/'fillchars' value, clear the window-local value. - if (!(opt_flags & OPT_GLOBAL)) - clear_string_option(local_ptr); - FOR_ALL_TAB_WINDOWS(tp, wp) - { - // If the current window has a local value need to apply it - // again, it was changed when setting the global value. - // If no error was returned above, we don't expect an error - // here, so ignore the return value. - local_ptr = varp == &p_lcs ? &wp->w_p_lcs : &wp->w_p_fcs; - if (**local_ptr == NUL) - (void)set_chars_option(wp, local_ptr, TRUE); - } - - redraw_all_later(UPD_NOT_VALID); - - return NULL; - } - #if defined(CURSOR_SHAPE) || defined(PROTO) /* * The 'guicursor' option is changed. --- 1575,1580 ---- *************** *** 3106,3118 **** || varp == &p_tenc // 'termencoding' || gvarp == &p_menc) // 'makeencoding' errmsg = did_set_encoding(varp, gvarp, opt_flags); - else if ( varp == &p_lcs // global 'listchars' - || varp == &p_fcs) // global 'fillchars' - errmsg = did_set_global_listfillchars(varp, opt_flags); - else if (varp == &curwin->w_p_lcs) // local 'listchars' - errmsg = set_chars_option(curwin, varp, TRUE); - else if (varp == &curwin->w_p_fcs) // local 'fillchars' - errmsg = set_chars_option(curwin, varp, TRUE); // terminal options else if (istermoption_idx(opt_idx) && full_screen) did_set_term_option(varp, &did_swaptcap); --- 3137,3142 ---- *** ../vim-9.0.1368/src/proto/optionstr.pro 2023-03-01 12:44:02.692086925 +0000 --- src/proto/optionstr.pro 2023-03-02 14:43:28.868695112 +0000 *************** *** 20,25 **** --- 20,26 ---- char *did_set_bufhidden(optset_T *args); char *did_set_buftype(optset_T *args); char *did_set_casemap(optset_T *args); + char *did_set_chars_option(optset_T *args); char *did_set_cinoptions(optset_T *args); char *did_set_colorcolumn(optset_T *args); char *did_set_comments(optset_T *args); *** ../vim-9.0.1368/src/screen.c 2023-02-21 14:27:34.524360386 +0000 --- src/screen.c 2023-03-02 14:41:39.588615253 +0000 *************** *** 4655,4667 **** /* * Handle setting 'listchars' or 'fillchars'. ! * "varp" points to either the global or the window-local value. * When "apply" is FALSE do not store the flags, only check for errors. * Assume monocell characters. * Returns error message, NULL if it's OK. */ ! char * ! set_chars_option(win_T *wp, char_u **varp, int apply) { int round, i, len, len2, entries; char_u *p, *s; --- 4655,4668 ---- /* * Handle setting 'listchars' or 'fillchars'. ! * "val" points to either the global or the window-local value. ! * "opt_lcs" is TRUE for "listchars" and FALSE for "fillchars". * When "apply" is FALSE do not store the flags, only check for errors. * Assume monocell characters. * Returns error message, NULL if it's OK. */ ! static char * ! set_chars_option(win_T *wp, char_u *val, int opt_lcs, int apply) { int round, i, len, len2, entries; char_u *p, *s; *************** *** 4670,4677 **** char_u *last_lmultispace = NULL; // Last occurrence of "leadmultispace:" int multispace_len = 0; // Length of lcs-multispace string int lead_multispace_len = 0; // Length of lcs-leadmultispace string ! int is_listchars = (varp == &p_lcs || varp == &wp->w_p_lcs); ! char_u *value = *varp; struct charstab { --- 4671,4678 ---- char_u *last_lmultispace = NULL; // Last occurrence of "leadmultispace:" int multispace_len = 0; // Length of lcs-multispace string int lead_multispace_len = 0; // Length of lcs-leadmultispace string ! int is_listchars = opt_lcs; ! char_u *value = val; struct charstab { *************** *** 4718,4731 **** tab = lcstab; CLEAR_FIELD(lcs_chars); entries = ARRAY_LENGTH(lcstab); ! if (varp == &wp->w_p_lcs && wp->w_p_lcs[0] == NUL) ! value = p_lcs; // local value is empty, us the global value } else { tab = filltab; entries = ARRAY_LENGTH(filltab); ! if (varp == &wp->w_p_fcs && wp->w_p_fcs[0] == NUL) value = p_fcs; // local value is empty, us the global value } --- 4719,4732 ---- tab = lcstab; CLEAR_FIELD(lcs_chars); entries = ARRAY_LENGTH(lcstab); ! if (opt_lcs && wp->w_p_lcs[0] == NUL) ! value = p_lcs; // local value is empty, use the global value } else { tab = filltab; entries = ARRAY_LENGTH(filltab); ! if (!opt_lcs && wp->w_p_fcs[0] == NUL) value = p_fcs; // local value is empty, us the global value } *************** *** 4935,4940 **** --- 4936,4959 ---- } /* + * Handle the new value of 'fillchars'. + */ + char * + set_fillchars_option(win_T *wp, char_u *val, int apply) + { + return set_chars_option(wp, val, FALSE, apply); + } + + /* + * Handle the new value of 'listchars'. + */ + char * + set_listchars_option(win_T *wp, char_u *val, int apply) + { + return set_chars_option(wp, val, TRUE, apply); + } + + /* * Check all global and local values of 'listchars' and 'fillchars'. * Return an untranslated error messages if any of them is invalid, NULL * otherwise. *************** *** 4945,4959 **** tabpage_T *tp; win_T *wp; ! if (set_chars_option(curwin, &p_lcs, FALSE) != NULL) return e_conflicts_with_value_of_listchars; ! if (set_chars_option(curwin, &p_fcs, FALSE) != NULL) return e_conflicts_with_value_of_fillchars; FOR_ALL_TAB_WINDOWS(tp, wp) { ! if (set_chars_option(wp, &wp->w_p_lcs, FALSE) != NULL) return e_conflicts_with_value_of_listchars; ! if (set_chars_option(wp, &wp->w_p_fcs, FALSE) != NULL) return e_conflicts_with_value_of_fillchars; } return NULL; --- 4964,4978 ---- tabpage_T *tp; win_T *wp; ! if (set_listchars_option(curwin, p_lcs, FALSE) != NULL) return e_conflicts_with_value_of_listchars; ! if (set_fillchars_option(curwin, p_fcs, FALSE) != NULL) return e_conflicts_with_value_of_fillchars; FOR_ALL_TAB_WINDOWS(tp, wp) { ! if (set_listchars_option(wp, wp->w_p_lcs, FALSE) != NULL) return e_conflicts_with_value_of_listchars; ! if (set_fillchars_option(wp, wp->w_p_fcs, FALSE) != NULL) return e_conflicts_with_value_of_fillchars; } return NULL; *** ../vim-9.0.1368/src/proto/screen.pro 2022-11-12 17:44:08.268849881 +0000 --- src/proto/screen.pro 2023-03-02 14:43:18.400687452 +0000 *************** *** 55,60 **** int number_width(win_T *wp); int screen_screencol(void); int screen_screenrow(void); ! char *set_chars_option(win_T *wp, char_u **varp, int apply); char *check_chars_options(void); /* vim: set ft=c : */ --- 55,61 ---- int number_width(win_T *wp); int screen_screencol(void); int screen_screenrow(void); ! char *set_fillchars_option(win_T *wp, char_u *val, int apply); ! char *set_listchars_option(win_T *wp, char_u *val, int apply); char *check_chars_options(void); /* vim: set ft=c : */ *** ../vim-9.0.1368/src/testdir/test_options.vim 2023-02-27 12:47:44.107282452 +0000 --- src/testdir/test_options.vim 2023-03-02 14:41:39.588615253 +0000 *************** *** 1640,1657 **** if has('win32') && has('terminal') call add(optlist, ['termwintype', 'winpty', 'a123']) endif ! if has('+toolbar') call add(optlist, ['toolbar', 'text', 'a123']) call add(optlist, ['toolbariconsize', 'medium', 'a123']) endif ! if has('+mouse') call add(optlist, ['ttymouse', 'xterm', 'a123']) endif ! if has('+vartabs') call add(optlist, ['varsofttabstop', '12', 'a123']) call add(optlist, ['vartabstop', '4,20', '4,']) endif ! if has('gui') call add(optlist, ['winaltkeys', 'no', 'a123']) endif for opt in optlist --- 1640,1657 ---- if has('win32') && has('terminal') call add(optlist, ['termwintype', 'winpty', 'a123']) endif ! if exists('+toolbar') call add(optlist, ['toolbar', 'text', 'a123']) call add(optlist, ['toolbariconsize', 'medium', 'a123']) endif ! if exists('+ttymouse') && !has('gui') call add(optlist, ['ttymouse', 'xterm', 'a123']) endif ! if exists('+vartabs') call add(optlist, ['varsofttabstop', '12', 'a123']) call add(optlist, ['vartabstop', '4,20', '4,']) endif ! if exists('+winaltkeys') call add(optlist, ['winaltkeys', 'no', 'a123']) endif for opt in optlist *** ../vim-9.0.1368/src/version.c 2023-03-02 12:51:15.074678591 +0000 --- src/version.c 2023-03-02 14:43:06.560678771 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1369, /**/ -- Your mouse has moved. Windows must be restarted for the change to take effect. Reboot now? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///