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 -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20230302144730.B0D151C0F2A%40moolenaar.net.

Raspunde prin e-mail lui