Patch 9.0.1237
Problem:    Code is indented more than necessary.
Solution:   Use an early return where it makes sense. (Yegappan Lakshmanan,
            closes #11858)
Files:      src/screen.c, src/scriptfile.c, src/search.c, src/session.c,
            src/sign.c, src/sound.c, src/spell.c, src/spellfile.c,
            src/spellsuggest.c, src/strings.c, src/syntax.c


*** ../vim-9.0.1236/src/screen.c        2022-12-15 13:14:17.411527402 +0000
--- src/screen.c        2023-01-23 20:41:57.558588535 +0000
***************
*** 94,113 ****
      void
  conceal_check_cursor_line(int was_concealed)
  {
!     if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin) != was_concealed)
!     {
!       int wcol = curwin->w_wcol;
  
!       need_cursor_line_redraw = TRUE;
!       // Need to recompute cursor column, e.g., when starting Visual mode
!       // without concealing.
!       curs_columns(TRUE);
! 
!       // When concealing now w_wcol will be computed wrong, keep the previous
!       // value, it will be updated in win_line().
!       if (!was_concealed)
!           curwin->w_wcol = wcol;
!     }
  }
  #endif
  
--- 94,113 ----
      void
  conceal_check_cursor_line(int was_concealed)
  {
!     if (curwin->w_p_cole <= 0 || conceal_cursor_line(curwin) == was_concealed)
!       return;
  
!     int wcol = curwin->w_wcol;
! 
!     need_cursor_line_redraw = TRUE;
!     // Need to recompute cursor column, e.g., when starting Visual mode
!     // without concealing.
!     curs_columns(TRUE);
! 
!     // When concealing now w_wcol will be computed wrong, keep the previous
!     // value, it will be updated in win_line().
!     if (!was_concealed)
!       curwin->w_wcol = wcol;
  }
  #endif
  
***************
*** 906,919 ****
      int               hl;
      int               c;
  
!     if (wp->w_vsep_width)
!     {
!       // draw the vertical separator right of this window
!       c = fillchar_vsep(&hl, wp);
!       screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height,
!               W_ENDCOL(wp), W_ENDCOL(wp) + 1,
!               c, ' ', hl);
!     }
  }
  
  /*
--- 906,919 ----
      int               hl;
      int               c;
  
!     if (!wp->w_vsep_width)
!       return;
! 
!     // draw the vertical separator right of this window
!     c = fillchar_vsep(&hl, wp);
!     screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height,
!           W_ENDCOL(wp), W_ENDCOL(wp) + 1,
!           c, ' ', hl);
  }
  
  /*
***************
*** 960,995 ****
      if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP)
        return FALSE;
  
-     {
  #ifdef FEAT_EVAL
!       buf_T   *old_curbuf = curbuf;
!       win_T   *old_curwin = curwin;
!       char_u  *s;
! 
!       curbuf = wp->w_buffer;
!       curwin = wp;
!       STRCPY(buf, "b:keymap_name");   // must be writable
!       ++emsg_skip;
!       s = p = eval_to_string(buf, FALSE, FALSE);
!       --emsg_skip;
!       curbuf = old_curbuf;
!       curwin = old_curwin;
!       if (p == NULL || *p == NUL)
  #endif
!       {
  #ifdef FEAT_KEYMAP
!           if (wp->w_buffer->b_kmap_state & KEYMAP_LOADED)
!               p = wp->w_buffer->b_p_keymap;
!           else
  #endif
!               p = (char_u *)"lang";
!       }
!       if (vim_snprintf((char *)buf, len, (char *)fmt, p) > len - 1)
!           buf[0] = NUL;
  #ifdef FEAT_EVAL
!       vim_free(s);
  #endif
-     }
      return buf[0] != NUL;
  }
  
--- 960,993 ----
      if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP)
        return FALSE;
  
  #ifdef FEAT_EVAL
!     buf_T     *old_curbuf = curbuf;
!     win_T     *old_curwin = curwin;
!     char_u    *s;
! 
!     curbuf = wp->w_buffer;
!     curwin = wp;
!     STRCPY(buf, "b:keymap_name");     // must be writable
!     ++emsg_skip;
!     s = p = eval_to_string(buf, FALSE, FALSE);
!     --emsg_skip;
!     curbuf = old_curbuf;
!     curwin = old_curwin;
!     if (p == NULL || *p == NUL)
  #endif
!     {
  #ifdef FEAT_KEYMAP
!       if (wp->w_buffer->b_kmap_state & KEYMAP_LOADED)
!           p = wp->w_buffer->b_p_keymap;
!       else
  #endif
!           p = (char_u *)"lang";
!     }
!     if (vim_snprintf((char *)buf, len, (char *)fmt, p) > len - 1)
!       buf[0] = NUL;
  #ifdef FEAT_EVAL
!     vim_free(s);
  #endif
      return buf[0] != NUL;
  }
  
***************
*** 1208,1233 ****
      unsigned off;
  
      // safety check
!     if (ScreenLines != NULL && row < screen_Rows && col < screen_Columns)
      {
-       off = LineOffset[row] + col;
-       *attrp = ScreenAttrs[off];
        bytes[0] = ScreenLines[off];
!       bytes[1] = NUL;
! 
!       if (enc_utf8 && ScreenLinesUC[off] != 0)
!           bytes[utfc_char2bytes(off, bytes)] = NUL;
!       else if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
!       {
!           bytes[0] = ScreenLines[off];
!           bytes[1] = ScreenLines2[off];
!           bytes[2] = NUL;
!       }
!       else if (enc_dbcs && MB_BYTE2LEN(bytes[0]) > 1)
!       {
!           bytes[1] = ScreenLines[off + 1];
!           bytes[2] = NUL;
!       }
      }
  }
  
--- 1206,1231 ----
      unsigned off;
  
      // safety check
!     if (ScreenLines == NULL || row >= screen_Rows || col >= screen_Columns)
!       return;
! 
!     off = LineOffset[row] + col;
!     *attrp = ScreenAttrs[off];
!     bytes[0] = ScreenLines[off];
!     bytes[1] = NUL;
! 
!     if (enc_utf8 && ScreenLinesUC[off] != 0)
!       bytes[utfc_char2bytes(off, bytes)] = NUL;
!     else if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
      {
        bytes[0] = ScreenLines[off];
!       bytes[1] = ScreenLines2[off];
!       bytes[2] = NUL;
!     }
!     else if (enc_dbcs && MB_BYTE2LEN(bytes[0]) > 1)
!     {
!       bytes[1] = ScreenLines[off + 1];
!       bytes[2] = NUL;
      }
  }
  
***************
*** 1538,1549 ****
      void
  start_search_hl(void)
  {
!     if (p_hls && !no_hlsearch)
!     {
!       end_search_hl();  // just in case it wasn't called before
!       last_pat_prog(&screen_search_hl.rm);
!       screen_search_hl.attr = HL_ATTR(HLF_L);
!     }
  }
  
  /*
--- 1536,1547 ----
      void
  start_search_hl(void)
  {
!     if (!p_hls || no_hlsearch)
!       return;
! 
!     end_search_hl();  // just in case it wasn't called before
!     last_pat_prog(&screen_search_hl.rm);
!     screen_search_hl.attr = HL_ATTR(HLF_L);
  }
  
  /*
***************
*** 1552,1562 ****
      void
  end_search_hl(void)
  {
!     if (screen_search_hl.rm.regprog != NULL)
!     {
!       vim_regfree(screen_search_hl.rm.regprog);
!       screen_search_hl.rm.regprog = NULL;
!     }
  }
  #endif
  
--- 1550,1560 ----
      void
  end_search_hl(void)
  {
!     if (screen_search_hl.rm.regprog == NULL)
!       return;
! 
!     vim_regfree(screen_search_hl.rm.regprog);
!     screen_search_hl.rm.regprog = NULL;
  }
  #endif
  
***************
*** 1566,1718 ****
      attrentry_T *aep = NULL;
  
      screen_attr = attr;
!     if (full_screen
  #ifdef MSWIN
!                   && termcap_active
  #endif
!                                      )
!     {
  #ifdef FEAT_GUI
!       if (gui.in_use)
!       {
!           char        buf[20];
  
!           // The GUI handles this internally.
!           sprintf(buf, "\033|%dh", attr);
!           OUT_STR(buf);
!       }
!       else
  #endif
!       {
!           if (attr > HL_ALL)                          // special HL attr.
!           {
!               if (IS_CTERM)
!                   aep = syn_cterm_attr2entry(attr);
!               else
!                   aep = syn_term_attr2entry(attr);
!               if (aep == NULL)            // did ":syntax clear"
!                   attr = 0;
!               else
!                   attr = aep->ae_attr;
!           }
  #if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS)
!           if (use_vtp())
!           {
!               guicolor_T  defguifg, defguibg;
!               int         defctermfg, defctermbg;
  
!               // If FG and BG are unset, the color is undefined when
!               // BOLD+INVERSE. Use Normal as the default value.
!               get_default_console_color(&defctermfg, &defctermbg, &defguifg,
!                                                                   &defguibg);
  
!               if (p_tgc)
!               {
!                   if (aep == NULL || COLOR_INVALID(aep->ae_u.cterm.fg_rgb))
!                       term_fg_rgb_color(defguifg);
!                   if (aep == NULL || COLOR_INVALID(aep->ae_u.cterm.bg_rgb))
!                       term_bg_rgb_color(defguibg);
!               }
!               else if (t_colors >= 256)
!               {
!                   if (aep == NULL || aep->ae_u.cterm.fg_color == 0)
!                       term_fg_color(defctermfg);
!                   if (aep == NULL || aep->ae_u.cterm.bg_color == 0)
!                       term_bg_color(defctermbg);
!               }
!           }
  #endif
!           if ((attr & HL_BOLD) && *T_MD != NUL)       // bold
!               out_str(T_MD);
!           else if (aep != NULL && cterm_normal_fg_bold && (
  #ifdef FEAT_TERMGUICOLORS
!                       p_tgc && aep->ae_u.cterm.fg_rgb != CTERMCOLOR
!                         ? aep->ae_u.cterm.fg_rgb != INVALCOLOR
!                         :
! #endif
!                           t_colors > 1 && aep->ae_u.cterm.fg_color))
!               // If the Normal FG color has BOLD attribute and the new HL
!               // has a FG color defined, clear BOLD.
!               out_str(T_ME);
!           if ((attr & HL_STANDOUT) && *T_SO != NUL)   // standout
!               out_str(T_SO);
!           if ((attr & HL_UNDERCURL) && *T_UCS != NUL) // undercurl
!               out_str(T_UCS);
!           if ((attr & HL_UNDERDOUBLE) && *T_USS != NUL) // double underline
!               out_str(T_USS);
!           if ((attr & HL_UNDERDOTTED) && *T_DS != NUL) // dotted underline
!               out_str(T_DS);
!           if ((attr & HL_UNDERDASHED) && *T_CDS != NUL) // dashed underline
!               out_str(T_CDS);
!           if (((attr & HL_UNDERLINE)      // underline or undercurl, etc.
!                       || ((attr & HL_UNDERCURL) && *T_UCS == NUL)
!                       || ((attr & HL_UNDERDOUBLE) && *T_USS == NUL)
!                       || ((attr & HL_UNDERDOTTED) && *T_DS == NUL)
!                       || ((attr & HL_UNDERDASHED) && *T_CDS == NUL))
!                   && *T_US != NUL)
!               out_str(T_US);
!           if ((attr & HL_ITALIC) && *T_CZH != NUL)    // italic
!               out_str(T_CZH);
!           if ((attr & HL_INVERSE) && *T_MR != NUL)    // inverse (reverse)
!               out_str(T_MR);
!           if ((attr & HL_STRIKETHROUGH) && *T_STS != NUL)     // strike
!               out_str(T_STS);
  
!           /*
!            * Output the color or start string after bold etc., in case the
!            * bold etc. override the color setting.
!            */
!           if (aep != NULL)
!           {
  #ifdef FEAT_TERMGUICOLORS
!               // When 'termguicolors' is set but fg or bg is unset,
!               // fall back to the cterm colors.   This helps for SpellBad,
!               // where the GUI uses a red undercurl.
!               if (p_tgc && aep->ae_u.cterm.fg_rgb != CTERMCOLOR)
!               {
!                   if (aep->ae_u.cterm.fg_rgb != INVALCOLOR)
!                       term_fg_rgb_color(aep->ae_u.cterm.fg_rgb);
!               }
!               else
  #endif
!               if (t_colors > 1)
!               {
!                   if (aep->ae_u.cterm.fg_color)
!                       term_fg_color(aep->ae_u.cterm.fg_color - 1);
!               }
  #ifdef FEAT_TERMGUICOLORS
!               if (p_tgc && aep->ae_u.cterm.bg_rgb != CTERMCOLOR)
!               {
!                   if (aep->ae_u.cterm.bg_rgb != INVALCOLOR)
!                       term_bg_rgb_color(aep->ae_u.cterm.bg_rgb);
!               }
!               else
  #endif
!               if (t_colors > 1)
!               {
!                   if (aep->ae_u.cterm.bg_color)
!                       term_bg_color(aep->ae_u.cterm.bg_color - 1);
!               }
  #ifdef FEAT_TERMGUICOLORS
!               if (p_tgc && aep->ae_u.cterm.ul_rgb != CTERMCOLOR)
!               {
!                   if (aep->ae_u.cterm.ul_rgb != INVALCOLOR)
!                       term_ul_rgb_color(aep->ae_u.cterm.ul_rgb);
!               }
!               else
  #endif
!               if (t_colors > 1)
!               {
!                   if (aep->ae_u.cterm.ul_color)
!                       term_ul_color(aep->ae_u.cterm.ul_color - 1);
!               }
! 
!               if (!IS_CTERM)
!               {
!                   if (aep->ae_u.term.start != NULL)
!                       out_str(aep->ae_u.term.start);
!               }
            }
        }
      }
  }
--- 1564,1715 ----
      attrentry_T *aep = NULL;
  
      screen_attr = attr;
!     if (!full_screen
  #ifdef MSWIN
!           || !termcap_active
  #endif
!        )
!       return;
! 
  #ifdef FEAT_GUI
!     if (gui.in_use)
!     {
!       char    buf[20];
  
!       // The GUI handles this internally.
!       sprintf(buf, "\033|%dh", attr);
!       OUT_STR(buf);
!       return;
!     }
  #endif
! 
!     if (attr > HL_ALL)                                // special HL attr.
!     {
!       if (IS_CTERM)
!           aep = syn_cterm_attr2entry(attr);
!       else
!           aep = syn_term_attr2entry(attr);
!       if (aep == NULL)            // did ":syntax clear"
!           attr = 0;
!       else
!           attr = aep->ae_attr;
!     }
  #if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS)
!     if (use_vtp())
!     {
!       guicolor_T  defguifg, defguibg;
!       int         defctermfg, defctermbg;
  
!       // If FG and BG are unset, the color is undefined when
!       // BOLD+INVERSE. Use Normal as the default value.
!       get_default_console_color(&defctermfg, &defctermbg, &defguifg,
!               &defguibg);
  
!       if (p_tgc)
!       {
!           if (aep == NULL || COLOR_INVALID(aep->ae_u.cterm.fg_rgb))
!               term_fg_rgb_color(defguifg);
!           if (aep == NULL || COLOR_INVALID(aep->ae_u.cterm.bg_rgb))
!               term_bg_rgb_color(defguibg);
!       }
!       else if (t_colors >= 256)
!       {
!           if (aep == NULL || aep->ae_u.cterm.fg_color == 0)
!               term_fg_color(defctermfg);
!           if (aep == NULL || aep->ae_u.cterm.bg_color == 0)
!               term_bg_color(defctermbg);
!       }
!     }
  #endif
!     if ((attr & HL_BOLD) && *T_MD != NUL)     // bold
!       out_str(T_MD);
!     else if (aep != NULL && cterm_normal_fg_bold && (
  #ifdef FEAT_TERMGUICOLORS
!               p_tgc && aep->ae_u.cterm.fg_rgb != CTERMCOLOR
!               ? aep->ae_u.cterm.fg_rgb != INVALCOLOR
!               :
! #endif
!               t_colors > 1 && aep->ae_u.cterm.fg_color))
!       // If the Normal FG color has BOLD attribute and the new HL
!       // has a FG color defined, clear BOLD.
!       out_str(T_ME);
!     if ((attr & HL_STANDOUT) && *T_SO != NUL) // standout
!       out_str(T_SO);
!     if ((attr & HL_UNDERCURL) && *T_UCS != NUL) // undercurl
!       out_str(T_UCS);
!     if ((attr & HL_UNDERDOUBLE) && *T_USS != NUL) // double underline
!       out_str(T_USS);
!     if ((attr & HL_UNDERDOTTED) && *T_DS != NUL) // dotted underline
!       out_str(T_DS);
!     if ((attr & HL_UNDERDASHED) && *T_CDS != NUL) // dashed underline
!       out_str(T_CDS);
!     if (((attr & HL_UNDERLINE)            // underline or undercurl, etc.
!               || ((attr & HL_UNDERCURL) && *T_UCS == NUL)
!               || ((attr & HL_UNDERDOUBLE) && *T_USS == NUL)
!               || ((attr & HL_UNDERDOTTED) && *T_DS == NUL)
!               || ((attr & HL_UNDERDASHED) && *T_CDS == NUL))
!           && *T_US != NUL)
!       out_str(T_US);
!     if ((attr & HL_ITALIC) && *T_CZH != NUL)  // italic
!       out_str(T_CZH);
!     if ((attr & HL_INVERSE) && *T_MR != NUL)  // inverse (reverse)
!       out_str(T_MR);
!     if ((attr & HL_STRIKETHROUGH) && *T_STS != NUL)   // strike
!       out_str(T_STS);
  
!     /*
!      * Output the color or start string after bold etc., in case the
!      * bold etc. override the color setting.
!      */
!     if (aep != NULL)
!     {
  #ifdef FEAT_TERMGUICOLORS
!       // When 'termguicolors' is set but fg or bg is unset,
!       // fall back to the cterm colors.   This helps for SpellBad,
!       // where the GUI uses a red undercurl.
!       if (p_tgc && aep->ae_u.cterm.fg_rgb != CTERMCOLOR)
!       {
!           if (aep->ae_u.cterm.fg_rgb != INVALCOLOR)
!               term_fg_rgb_color(aep->ae_u.cterm.fg_rgb);
!       }
!       else
  #endif
!           if (t_colors > 1)
!           {
!               if (aep->ae_u.cterm.fg_color)
!                   term_fg_color(aep->ae_u.cterm.fg_color - 1);
!           }
  #ifdef FEAT_TERMGUICOLORS
!       if (p_tgc && aep->ae_u.cterm.bg_rgb != CTERMCOLOR)
!       {
!           if (aep->ae_u.cterm.bg_rgb != INVALCOLOR)
!               term_bg_rgb_color(aep->ae_u.cterm.bg_rgb);
!       }
!       else
  #endif
!           if (t_colors > 1)
!           {
!               if (aep->ae_u.cterm.bg_color)
!                   term_bg_color(aep->ae_u.cterm.bg_color - 1);
!           }
  #ifdef FEAT_TERMGUICOLORS
!       if (p_tgc && aep->ae_u.cterm.ul_rgb != CTERMCOLOR)
!       {
!           if (aep->ae_u.cterm.ul_rgb != INVALCOLOR)
!               term_ul_rgb_color(aep->ae_u.cterm.ul_rgb);
!       }
!       else
  #endif
!           if (t_colors > 1)
!           {
!               if (aep->ae_u.cterm.ul_color)
!                   term_ul_color(aep->ae_u.cterm.ul_color - 1);
            }
+ 
+       if (!IS_CTERM)
+       {
+           if (aep->ae_u.term.start != NULL)
+               out_str(aep->ae_u.term.start);
        }
      }
  }
***************
*** 1895,1907 ****
      void
  reset_cterm_colors(void)
  {
!     if (IS_CTERM)
!     {
!       // set Normal cterm colors
  #ifdef FEAT_TERMGUICOLORS
!       if (p_tgc ? (cterm_normal_fg_gui_color != INVALCOLOR
!                || cterm_normal_bg_gui_color != INVALCOLOR)
!               : (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0))
  #else
        if (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0)
  #endif
--- 1892,1905 ----
      void
  reset_cterm_colors(void)
  {
!     if (!IS_CTERM)
!       return;
! 
!     // set Normal cterm colors
  #ifdef FEAT_TERMGUICOLORS
!     if (p_tgc ? (cterm_normal_fg_gui_color != INVALCOLOR
!               || cterm_normal_bg_gui_color != INVALCOLOR)
!           : (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0))
  #else
        if (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0)
  #endif
***************
*** 1909,1919 ****
            out_str(T_OP);
            screen_attr = -1;
        }
!       if (cterm_normal_fg_bold)
!       {
!           out_str(T_ME);
!           screen_attr = -1;
!       }
      }
  }
  
--- 1907,1916 ----
            out_str(T_OP);
            screen_attr = -1;
        }
!     if (cterm_normal_fg_bold)
!     {
!       out_str(T_ME);
!       screen_attr = -1;
      }
  }
  
***************
*** 2954,3176 ****
      // Can't use ScreenLines unless initialized
      if (ScreenLines == NULL)
        return;
!     if (col != screen_cur_col || row != screen_cur_row)
      {
!       // Check for valid position.
!       if (row < 0)    // window without text lines?
!           row = 0;
!       if (row >= screen_Rows)
!           row = screen_Rows - 1;
!       if (col >= screen_Columns)
!           col = screen_Columns - 1;
! 
!       // check if no cursor movement is allowed in highlight mode
!       if (screen_attr && *T_MS == NUL)
!           noinvcurs = HIGHL_COST;
!       else
!           noinvcurs = 0;
!       goto_cost = GOTO_COST + noinvcurs;
  
        /*
!        * Plan how to do the positioning:
!        * 1. Use CR to move it to column 0, same row.
!        * 2. Use T_LE to move it a few columns to the left.
!        * 3. Use NL to move a few lines down, column 0.
!        * 4. Move a few columns to the right with T_ND or by writing chars.
!        *
!        * Don't do this if the cursor went beyond the last column, the cursor
!        * position is unknown then (some terminals wrap, some don't )
!        *
!        * First check if the highlighting attributes allow us to write
!        * characters to move the cursor to the right.
         */
!       if (row >= screen_cur_row && screen_cur_col < Columns)
        {
!           /*
!            * If the cursor is in the same row, bigger col, we can use CR
!            * or T_LE.
!            */
!           bs = NULL;                      // init for GCC
!           attr = screen_attr;
!           if (row == screen_cur_row && col < screen_cur_col)
!           {
!               // "le" is preferred over "bc", because "bc" is obsolete
!               if (*T_LE)
!                   bs = T_LE;              // "cursor left"
!               else
!                   bs = T_BC;              // "backspace character (old)
!               if (*bs)
!                   cost = (screen_cur_col - col) * (int)STRLEN(bs);
!               else
!                   cost = 999;
!               if (col + 1 < cost)         // using CR is less characters
!               {
!                   plan = PLAN_CR;
!                   wouldbe_col = 0;
!                   cost = 1;               // CR is just one character
!               }
!               else
!               {
!                   plan = PLAN_LE;
!                   wouldbe_col = col;
!               }
!               if (noinvcurs)              // will stop highlighting
!               {
!                   cost += noinvcurs;
!                   attr = 0;
!               }
            }
  
            /*
!            * If the cursor is above where we want to be, we can use CR LF.
             */
!           else if (row > screen_cur_row)
            {
!               plan = PLAN_NL;
!               wouldbe_col = 0;
!               cost = (row - screen_cur_row) * 2;  // CR LF
!               if (noinvcurs)              // will stop highlighting
                {
                    cost += noinvcurs;
!                   attr = 0;
                }
            }
! 
!           /*
!            * If the cursor is in the same row, smaller col, just use write.
!            */
!           else
            {
!               plan = PLAN_WRITE;
!               wouldbe_col = screen_cur_col;
!               cost = 0;
            }
  
!           /*
!            * Check if any characters that need to be written have the
!            * correct attributes.  Also avoid UTF-8 characters.
!            */
!           i = col - wouldbe_col;
!           if (i > 0)
!               cost += i;
!           if (cost < goto_cost && i > 0)
            {
!               /*
!                * Check if the attributes are correct without additionally
!                * stopping highlighting.
!                */
!               p = ScreenAttrs + LineOffset[row] + wouldbe_col;
!               while (i && *p++ == attr)
!                   --i;
!               if (i != 0)
                {
!                   /*
!                    * Try if it works when highlighting is stopped here.
!                    */
!                   if (*--p == 0)
!                   {
!                       cost += noinvcurs;
!                       while (i && *p++ == 0)
!                           --i;
!                   }
!                   if (i != 0)
!                       cost = 999;     // different attributes, don't do it
                }
!               if (enc_utf8)
                {
!                   // Don't use an UTF-8 char for positioning, it's slow.
!                   for (i = wouldbe_col; i < col; ++i)
!                       if (ScreenLinesUC[LineOffset[row] + i] != 0)
!                       {
!                           cost = 999;
!                           break;
!                       }
                }
            }
  
!           /*
!            * We can do it without term_windgoto()!
!            */
!           if (cost < goto_cost)
            {
!               if (plan == PLAN_LE)
!               {
!                   if (noinvcurs)
!                       screen_stop_highlight();
!                   while (screen_cur_col > col)
!                   {
!                       out_str(bs);
!                       --screen_cur_col;
!                   }
!               }
!               else if (plan == PLAN_CR)
                {
!                   if (noinvcurs)
!                       screen_stop_highlight();
!                   out_char('\r');
!                   screen_cur_col = 0;
                }
!               else if (plan == PLAN_NL)
                {
!                   if (noinvcurs)
!                       screen_stop_highlight();
!                   while (screen_cur_row < row)
!                   {
!                       out_char('\n');
!                       ++screen_cur_row;
!                   }
!                   screen_cur_col = 0;
!               }
  
!               i = col - screen_cur_col;
!               if (i > 0)
!               {
!                   /*
!                    * Use cursor-right if it's one character only.  Avoids
!                    * removing a line of pixels from the last bold char, when
!                    * using the bold trick in the GUI.
!                    */
!                   if (T_ND[0] != NUL && T_ND[1] == NUL)
                    {
!                       while (i-- > 0)
!                           out_char(*T_ND);
!                   }
!                   else
!                   {
!                       int     off;
! 
!                       off = LineOffset[row] + screen_cur_col;
!                       while (i-- > 0)
!                       {
!                           if (ScreenAttrs[off] != screen_attr)
!                               screen_stop_highlight();
!                           out_flush_check();
!                           out_char(ScreenLines[off]);
!                           if (enc_dbcs == DBCS_JPNU
!                                                 && ScreenLines[off] == 0x8e)
!                               out_char(ScreenLines2[off]);
!                           ++off;
!                       }
                    }
                }
            }
        }
!       else
!           cost = 999;
  
!       if (cost >= goto_cost)
!       {
!           if (noinvcurs)
!               screen_stop_highlight();
!           if (row == screen_cur_row && (col > screen_cur_col)
!                                                            && *T_CRI != NUL)
!               term_cursor_right(col - screen_cur_col);
!           else
!               term_windgoto(row, col);
!       }
!       screen_cur_row = row;
!       screen_cur_col = col;
      }
  }
  
  /*
--- 2951,3173 ----
      // Can't use ScreenLines unless initialized
      if (ScreenLines == NULL)
        return;
!     if (col == screen_cur_col && row == screen_cur_row)
!       return;
! 
!     // Check for valid position.
!     if (row < 0)      // window without text lines?
!       row = 0;
!     if (row >= screen_Rows)
!       row = screen_Rows - 1;
!     if (col >= screen_Columns)
!       col = screen_Columns - 1;
! 
!     // check if no cursor movement is allowed in highlight mode
!     if (screen_attr && *T_MS == NUL)
!       noinvcurs = HIGHL_COST;
!     else
!       noinvcurs = 0;
!     goto_cost = GOTO_COST + noinvcurs;
! 
!     /*
!      * Plan how to do the positioning:
!      * 1. Use CR to move it to column 0, same row.
!      * 2. Use T_LE to move it a few columns to the left.
!      * 3. Use NL to move a few lines down, column 0.
!      * 4. Move a few columns to the right with T_ND or by writing chars.
!      *
!      * Don't do this if the cursor went beyond the last column, the cursor
!      * position is unknown then (some terminals wrap, some don't )
!      *
!      * First check if the highlighting attributes allow us to write
!      * characters to move the cursor to the right.
!      */
!     if (row >= screen_cur_row && screen_cur_col < Columns)
      {
!       /*
!        * If the cursor is in the same row, bigger col, we can use CR
!        * or T_LE.
!        */
!       bs = NULL;                          // init for GCC
!       attr = screen_attr;
!       if (row == screen_cur_row && col < screen_cur_col)
!       {
!           // "le" is preferred over "bc", because "bc" is obsolete
!           if (*T_LE)
!               bs = T_LE;                  // "cursor left"
!           else
!               bs = T_BC;                  // "backspace character (old)
!           if (*bs)
!               cost = (screen_cur_col - col) * (int)STRLEN(bs);
!           else
!               cost = 999;
!           if (col + 1 < cost)     // using CR is less characters
!           {
!               plan = PLAN_CR;
!               wouldbe_col = 0;
!               cost = 1;                   // CR is just one character
!           }
!           else
!           {
!               plan = PLAN_LE;
!               wouldbe_col = col;
!           }
!           if (noinvcurs)                  // will stop highlighting
!           {
!               cost += noinvcurs;
!               attr = 0;
!           }
!       }
  
        /*
!        * If the cursor is above where we want to be, we can use CR LF.
         */
!       else if (row > screen_cur_row)
        {
!           plan = PLAN_NL;
!           wouldbe_col = 0;
!           cost = (row - screen_cur_row) * 2;  // CR LF
!           if (noinvcurs)                  // will stop highlighting
!           {
!               cost += noinvcurs;
!               attr = 0;
            }
+       }
  
+       /*
+        * If the cursor is in the same row, smaller col, just use write.
+        */
+       else
+       {
+           plan = PLAN_WRITE;
+           wouldbe_col = screen_cur_col;
+           cost = 0;
+       }
+ 
+       /*
+        * Check if any characters that need to be written have the
+        * correct attributes.  Also avoid UTF-8 characters.
+        */
+       i = col - wouldbe_col;
+       if (i > 0)
+           cost += i;
+       if (cost < goto_cost && i > 0)
+       {
            /*
!            * Check if the attributes are correct without additionally
!            * stopping highlighting.
             */
!           p = ScreenAttrs + LineOffset[row] + wouldbe_col;
!           while (i && *p++ == attr)
!               --i;
!           if (i != 0)
            {
!               /*
!                * Try if it works when highlighting is stopped here.
!                */
!               if (*--p == 0)
                {
                    cost += noinvcurs;
!                   while (i && *p++ == 0)
!                       --i;
                }
+               if (i != 0)
+                   cost = 999; // different attributes, don't do it
            }
!           if (enc_utf8)
            {
!               // Don't use an UTF-8 char for positioning, it's slow.
!               for (i = wouldbe_col; i < col; ++i)
!                   if (ScreenLinesUC[LineOffset[row] + i] != 0)
!                   {
!                       cost = 999;
!                       break;
!                   }
            }
+       }
  
!       /*
!        * We can do it without term_windgoto()!
!        */
!       if (cost < goto_cost)
!       {
!           if (plan == PLAN_LE)
            {
!               if (noinvcurs)
!                   screen_stop_highlight();
!               while (screen_cur_col > col)
                {
!                   out_str(bs);
!                   --screen_cur_col;
                }
!           }
!           else if (plan == PLAN_CR)
!           {
!               if (noinvcurs)
!                   screen_stop_highlight();
!               out_char('\r');
!               screen_cur_col = 0;
!           }
!           else if (plan == PLAN_NL)
!           {
!               if (noinvcurs)
!                   screen_stop_highlight();
!               while (screen_cur_row < row)
                {
!                   out_char('\n');
!                   ++screen_cur_row;
                }
+               screen_cur_col = 0;
            }
  
!           i = col - screen_cur_col;
!           if (i > 0)
            {
!               /*
!                * Use cursor-right if it's one character only.  Avoids
!                * removing a line of pixels from the last bold char, when
!                * using the bold trick in the GUI.
!                */
!               if (T_ND[0] != NUL && T_ND[1] == NUL)
                {
!                   while (i-- > 0)
!                       out_char(*T_ND);
                }
!               else
                {
!                   int off;
  
!                   off = LineOffset[row] + screen_cur_col;
!                   while (i-- > 0)
                    {
!                       if (ScreenAttrs[off] != screen_attr)
!                           screen_stop_highlight();
!                       out_flush_check();
!                       out_char(ScreenLines[off]);
!                       if (enc_dbcs == DBCS_JPNU
!                               && ScreenLines[off] == 0x8e)
!                           out_char(ScreenLines2[off]);
!                       ++off;
                    }
                }
            }
        }
!     }
!     else
!       cost = 999;
  
!     if (cost >= goto_cost)
!     {
!       if (noinvcurs)
!           screen_stop_highlight();
!       if (row == screen_cur_row && (col > screen_cur_col)
!               && *T_CRI != NUL)
!           term_cursor_right(col - screen_cur_col);
!       else
!           term_windgoto(row, col);
      }
+     screen_cur_row = row;
+     screen_cur_col = col;
  }
  
  /*
***************
*** 4222,4234 ****
  recording_mode(int attr)
  {
      msg_puts_attr(_("recording"), attr);
!     if (!shortmess(SHM_RECORDING))
!     {
!       char s[4];
  
!       sprintf(s, " @%c", reg_recording);
!       msg_puts_attr(s, attr);
!     }
  }
  
  /*
--- 4219,4231 ----
  recording_mode(int attr)
  {
      msg_puts_attr(_("recording"), attr);
!     if (shortmess(SHM_RECORDING))
!       return;
  
!     char s[4];
! 
!     sprintf(s, " @%c", reg_recording);
!     msg_puts_attr(s, attr);
  }
  
  /*
*** ../vim-9.0.1236/src/scriptfile.c    2023-01-22 18:38:45.502261340 +0000
--- src/scriptfile.c    2023-01-23 20:41:57.558588535 +0000
***************
*** 56,74 ****
  
      // If memory allocation fails then we'll pop more than we push, eventually
      // at the top level it will be OK again.
!     if (ga_grow(&exestack, 1) == OK)
!     {
!       entry = ((estack_T *)exestack.ga_data) + exestack.ga_len;
!       entry->es_type = type;
!       entry->es_name = name;
!       entry->es_lnum = lnum;
  #ifdef FEAT_EVAL
!       entry->es_info.ufunc = NULL;
  #endif
!       ++exestack.ga_len;
!       return entry;
!     }
!     return NULL;
  }
  
  #if defined(FEAT_EVAL) || defined(PROTO)
--- 56,73 ----
  
      // If memory allocation fails then we'll pop more than we push, eventually
      // at the top level it will be OK again.
!     if (ga_grow(&exestack, 1) != OK)
!       return NULL;
! 
!     entry = ((estack_T *)exestack.ga_data) + exestack.ga_len;
!     entry->es_type = type;
!     entry->es_name = name;
!     entry->es_lnum = lnum;
  #ifdef FEAT_EVAL
!     entry->es_info.ufunc = NULL;
  #endif
!     ++exestack.ga_len;
!     return entry;
  }
  
  #if defined(FEAT_EVAL) || defined(PROTO)
***************
*** 667,678 ****
      char_u  **files;
      int           i;
  
!     if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK)
!     {
!       for (i = 0; i < num_files; ++i)
!           (void)do_source(files[i], FALSE, DOSO_NONE, NULL);
!       FreeWild(num_files, files);
!     }
  }
  
  /*
--- 666,677 ----
      char_u  **files;
      int           i;
  
!     if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) != OK)
!       return;
! 
!     for (i = 0; i < num_files; ++i)
!       (void)do_source(files[i], FALSE, DOSO_NONE, NULL);
!     FreeWild(num_files, files);
  }
  
  /*
***************
*** 2616,2651 ****
      char_u *
  may_prefix_autoload(char_u *name)
  {
!     if (SCRIPT_ID_VALID(current_sctx.sc_sid))
!     {
!       scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
  
!       if (si->sn_autoload_prefix != NULL)
!       {
!           char_u  *basename = name;
!           size_t  len;
!           char_u  *res;
  
!           if (*name == K_SPECIAL)
!           {
!               char_u *p = vim_strchr(name, '_');
  
!               // skip over "<SNR>99_"
!               if (p != NULL)
!                   basename = p + 1;
!           }
  
!           len = STRLEN(si->sn_autoload_prefix) + STRLEN(basename) + 2;
!           res = alloc(len);
!           if (res != NULL)
!           {
!               vim_snprintf((char *)res, len, "%s%s",
!                                            si->sn_autoload_prefix, basename);
!               return res;
!           }
!       }
      }
!     return name;
  }
  
  /*
--- 2615,2648 ----
      char_u *
  may_prefix_autoload(char_u *name)
  {
!     if (!SCRIPT_ID_VALID(current_sctx.sc_sid))
!       return name;
  
!     scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
  
!     if (si->sn_autoload_prefix == NULL)
!       return name;
  
!     char_u  *basename = name;
!     size_t  len;
!     char_u  *res;
  
!     if (*name == K_SPECIAL)
!     {
!       char_u *p = vim_strchr(name, '_');
! 
!       // skip over "<SNR>99_"
!       if (p != NULL)
!           basename = p + 1;
      }
! 
!     len = STRLEN(si->sn_autoload_prefix) + STRLEN(basename) + 2;
!     res = alloc(len);
!     if (res == NULL)
!       return NULL;
! 
!     vim_snprintf((char *)res, len, "%s%s", si->sn_autoload_prefix, basename);
!     return res;
  }
  
  /*
*** ../vim-9.0.1236/src/search.c        2023-01-22 21:14:32.621863614 +0000
--- src/search.c        2023-01-23 20:41:57.562588533 +0000
***************
*** 220,245 ****
       */
      len = (unsigned)STRLEN(s);
      rev = alloc(len + 1);
!     if (rev != NULL)
      {
!       rev_i = len;
!       for (s_i = 0; s_i < len; ++s_i)
        {
!           if (has_mbyte)
!           {
!               int     mb_len;
! 
!               mb_len = (*mb_ptr2len)(s + s_i);
!               rev_i -= mb_len;
!               mch_memmove(rev + rev_i, s + s_i, mb_len);
!               s_i += mb_len - 1;
!           }
!           else
!               rev[--rev_i] = s[s_i];
  
        }
!       rev[len] = NUL;
      }
      return rev;
  }
  #endif
--- 220,245 ----
       */
      len = (unsigned)STRLEN(s);
      rev = alloc(len + 1);
!     if (rev == NULL)
!       return NULL;
! 
!     rev_i = len;
!     for (s_i = 0; s_i < len; ++s_i)
      {
!       if (has_mbyte)
        {
!           int mb_len;
  
+           mb_len = (*mb_ptr2len)(s + s_i);
+           rev_i -= mb_len;
+           mch_memmove(rev + rev_i, s + s_i, mb_len);
+           s_i += mb_len - 1;
        }
!       else
!           rev[--rev_i] = s[s_i];
! 
      }
+     rev[len] = NUL;
      return rev;
  }
  #endif
***************
*** 247,266 ****
      void
  save_re_pat(int idx, char_u *pat, int magic)
  {
!     if (spats[idx].pat != pat)
!     {
!       vim_free(spats[idx].pat);
!       spats[idx].pat = vim_strsave(pat);
!       spats[idx].magic = magic;
!       spats[idx].no_scs = no_smartcase;
!       last_idx = idx;
  #ifdef FEAT_SEARCH_EXTRA
!       // If 'hlsearch' set and search pat changed: need redraw.
!       if (p_hls)
!           redraw_all_later(UPD_SOME_VALID);
!       set_no_hlsearch(FALSE);
  #endif
-     }
  }
  
  /*
--- 247,266 ----
      void
  save_re_pat(int idx, char_u *pat, int magic)
  {
!     if (spats[idx].pat == pat)
!       return;
! 
!     vim_free(spats[idx].pat);
!     spats[idx].pat = vim_strsave(pat);
!     spats[idx].magic = magic;
!     spats[idx].no_scs = no_smartcase;
!     last_idx = idx;
  #ifdef FEAT_SEARCH_EXTRA
!     // If 'hlsearch' set and search pat changed: need redraw.
!     if (p_hls)
!       redraw_all_later(UPD_SOME_VALID);
!     set_no_hlsearch(FALSE);
  #endif
  }
  
  /*
***************
*** 272,315 ****
      void
  save_search_patterns(void)
  {
!     if (save_level++ == 0)
!     {
!       saved_spats[0] = spats[0];
!       if (spats[0].pat != NULL)
!           saved_spats[0].pat = vim_strsave(spats[0].pat);
!       saved_spats[1] = spats[1];
!       if (spats[1].pat != NULL)
!           saved_spats[1].pat = vim_strsave(spats[1].pat);
!       if (mr_pattern == NULL)
!           saved_mr_pattern = NULL;
!       else
!           saved_mr_pattern = vim_strsave(mr_pattern);
  #ifdef FEAT_SEARCH_EXTRA
!       saved_spats_last_idx = last_idx;
!       saved_spats_no_hlsearch = no_hlsearch;
  #endif
-     }
  }
  
      void
  restore_search_patterns(void)
  {
!     if (--save_level == 0)
!     {
!       vim_free(spats[0].pat);
!       spats[0] = saved_spats[0];
  #if defined(FEAT_EVAL)
!       set_vv_searchforward();
  #endif
!       vim_free(spats[1].pat);
!       spats[1] = saved_spats[1];
!       vim_free(mr_pattern);
!       mr_pattern = saved_mr_pattern;
  #ifdef FEAT_SEARCH_EXTRA
!       last_idx = saved_spats_last_idx;
!       set_no_hlsearch(saved_spats_no_hlsearch);
  #endif
-     }
  }
  
  #if defined(EXITFREE) || defined(PROTO)
--- 272,315 ----
      void
  save_search_patterns(void)
  {
!     if (save_level++ != 0)
!       return;
! 
!     saved_spats[0] = spats[0];
!     if (spats[0].pat != NULL)
!       saved_spats[0].pat = vim_strsave(spats[0].pat);
!     saved_spats[1] = spats[1];
!     if (spats[1].pat != NULL)
!       saved_spats[1].pat = vim_strsave(spats[1].pat);
!     if (mr_pattern == NULL)
!       saved_mr_pattern = NULL;
!     else
!       saved_mr_pattern = vim_strsave(mr_pattern);
  #ifdef FEAT_SEARCH_EXTRA
!     saved_spats_last_idx = last_idx;
!     saved_spats_no_hlsearch = no_hlsearch;
  #endif
  }
  
      void
  restore_search_patterns(void)
  {
!     if (--save_level != 0)
!       return;
! 
!     vim_free(spats[0].pat);
!     spats[0] = saved_spats[0];
  #if defined(FEAT_EVAL)
!     set_vv_searchforward();
  #endif
!     vim_free(spats[1].pat);
!     spats[1] = saved_spats[1];
!     vim_free(mr_pattern);
!     mr_pattern = saved_mr_pattern;
  #ifdef FEAT_SEARCH_EXTRA
!     last_idx = saved_spats_last_idx;
!     set_no_hlsearch(saved_spats_no_hlsearch);
  #endif
  }
  
  #if defined(EXITFREE) || defined(PROTO)
***************
*** 2791,2851 ****
        return;
  
      if ((lpos = findmatch(NULL, NUL)) == NULL)            // no match, so beep
-       vim_beep(BO_MATCH);
-     else if (lpos->lnum >= curwin->w_topline && lpos->lnum < 
curwin->w_botline)
      {
!       if (!curwin->w_p_wrap)
!           getvcol(curwin, lpos, NULL, &vcol, NULL);
!       if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol
!                              && vcol < curwin->w_leftcol + curwin->w_width))
!       {
!           mpos = *lpos;    // save the pos, update_screen() may change it
!           save_cursor = curwin->w_cursor;
!           save_so = *so;
!           save_siso = *siso;
!           // Handle "$" in 'cpo': If the ')' is typed on top of the "$",
!           // stop displaying the "$".
!           if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol)
!               dollar_vcol = -1;
!           ++curwin->w_virtcol;        // do display ')' just before "$"
!           update_screen(UPD_VALID);   // show the new char first
  
!           save_dollar_vcol = dollar_vcol;
  #ifdef CURSOR_SHAPE
!           save_state = State;
!           State = MODE_SHOWMATCH;
!           ui_cursor_shape();          // may show different cursor shape
! #endif
!           curwin->w_cursor = mpos;    // move to matching char
!           *so = 0;                    // don't use 'scrolloff' here
!           *siso = 0;                  // don't use 'sidescrolloff' here
!           showruler(FALSE);
!           setcursor();
!           cursor_on();                // make sure that the cursor is shown
!           out_flush_cursor(TRUE, FALSE);
! 
!           // Restore dollar_vcol(), because setcursor() may call curs_rows()
!           // which resets it if the matching position is in a previous line
!           // and has a higher column number.
!           dollar_vcol = save_dollar_vcol;
  
!           /*
!            * brief pause, unless 'm' is present in 'cpo' and a character is
!            * available.
!            */
!           if (vim_strchr(p_cpo, CPO_SHOWMATCH) != NULL)
!               ui_delay(p_mat * 100L + 8, TRUE);
!           else if (!char_avail())
!               ui_delay(p_mat * 100L + 9, FALSE);
!           curwin->w_cursor = save_cursor;     // restore cursor position
!           *so = save_so;
!           *siso = save_siso;
  #ifdef CURSOR_SHAPE
!           State = save_state;
!           ui_cursor_shape();          // may show different cursor shape
  #endif
-       }
-     }
  }
  
  /*
--- 2791,2858 ----
        return;
  
      if ((lpos = findmatch(NULL, NUL)) == NULL)            // no match, so beep
      {
!       vim_beep(BO_MATCH);
!       return;
!     }
! 
!     if (lpos->lnum < curwin->w_topline || lpos->lnum >= curwin->w_botline)
!       return;
! 
!     if (!curwin->w_p_wrap)
!       getvcol(curwin, lpos, NULL, &vcol, NULL);
  
!     int col_visible = (curwin->w_p_wrap
!           || (vcol >= curwin->w_leftcol
!               && vcol < curwin->w_leftcol + curwin->w_width));
!     if (!col_visible)
!       return;
! 
!     mpos = *lpos;    // save the pos, update_screen() may change it
!     save_cursor = curwin->w_cursor;
!     save_so = *so;
!     save_siso = *siso;
!     // Handle "$" in 'cpo': If the ')' is typed on top of the "$",
!     // stop displaying the "$".
!     if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol)
!       dollar_vcol = -1;
!     ++curwin->w_virtcol;      // do display ')' just before "$"
!     update_screen(UPD_VALID); // show the new char first
! 
!     save_dollar_vcol = dollar_vcol;
  #ifdef CURSOR_SHAPE
!     save_state = State;
!     State = MODE_SHOWMATCH;
!     ui_cursor_shape();                // may show different cursor shape
! #endif
!     curwin->w_cursor = mpos;  // move to matching char
!     *so = 0;                  // don't use 'scrolloff' here
!     *siso = 0;                        // don't use 'sidescrolloff' here
!     showruler(FALSE);
!     setcursor();
!     cursor_on();              // make sure that the cursor is shown
!     out_flush_cursor(TRUE, FALSE);
! 
!     // Restore dollar_vcol(), because setcursor() may call curs_rows()
!     // which resets it if the matching position is in a previous line
!     // and has a higher column number.
!     dollar_vcol = save_dollar_vcol;
  
!     /*
!      * brief pause, unless 'm' is present in 'cpo' and a character is
!      * available.
!      */
!     if (vim_strchr(p_cpo, CPO_SHOWMATCH) != NULL)
!       ui_delay(p_mat * 100L + 8, TRUE);
!     else if (!char_avail())
!       ui_delay(p_mat * 100L + 9, FALSE);
!     curwin->w_cursor = save_cursor;   // restore cursor position
!     *so = save_so;
!     *siso = save_siso;
  #ifdef CURSOR_SHAPE
!     State = save_state;
!     ui_cursor_shape();                // may show different cursor shape
  #endif
  }
  
  /*
***************
*** 3101,3160 ****
  
      update_search_stat(dirc, pos, cursor_pos, &stat, recompute, maxcount,
                                                                      timeout);
!     if (stat.cur > 0)
!     {
!       char    t[SEARCH_STAT_BUF_LEN];
!       size_t  len;
  
  #ifdef FEAT_RIGHTLEFT
!       if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
!       {
!           if (stat.incomplete == 1)
!               vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
!           else if (stat.cnt > maxcount && stat.cur > maxcount)
!               vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
!                                                          maxcount, maxcount);
!           else if (stat.cnt > maxcount)
!               vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
!                                                          maxcount, stat.cur);
!           else
!               vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
!                                                          stat.cnt, stat.cur);
!       }
        else
  #endif
!       {
!           if (stat.incomplete == 1)
!               vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
!           else if (stat.cnt > maxcount && stat.cur > maxcount)
!               vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
!                                                          maxcount, maxcount);
!           else if (stat.cnt > maxcount)
!               vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
!                                                          stat.cur, maxcount);
!           else
!               vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
!                                                          stat.cur, stat.cnt);
!       }
  
!       len = STRLEN(t);
!       if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN)
!       {
!           mch_memmove(t + 2, t, len);
!           t[0] = 'W';
!           t[1] = ' ';
!           len += 2;
!       }
  
!       mch_memmove(msgbuf + STRLEN(msgbuf) - len, t, len);
!       if (dirc == '?' && stat.cur == maxcount + 1)
!           stat.cur = -1;
  
!       // keep the message even after redraw, but don't put in history
!       msg_hist_off = TRUE;
!       give_warning(msgbuf, FALSE);
!       msg_hist_off = FALSE;
!     }
  }
  
  /*
--- 3108,3167 ----
  
      update_search_stat(dirc, pos, cursor_pos, &stat, recompute, maxcount,
                                                                      timeout);
!     if (stat.cur <= 0)
!       return;
! 
!     char      t[SEARCH_STAT_BUF_LEN];
!     size_t    len;
  
  #ifdef FEAT_RIGHTLEFT
!     if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
!     {
!       if (stat.incomplete == 1)
!           vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
!       else if (stat.cnt > maxcount && stat.cur > maxcount)
!           vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
!                   maxcount, maxcount);
!       else if (stat.cnt > maxcount)
!           vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]",
!                   maxcount, stat.cur);
        else
+           vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
+                   stat.cnt, stat.cur);
+     }
+     else
  #endif
!     {
!       if (stat.incomplete == 1)
!           vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]");
!       else if (stat.cnt > maxcount && stat.cur > maxcount)
!           vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]",
!                   maxcount, maxcount);
!       else if (stat.cnt > maxcount)
!           vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]",
!                   stat.cur, maxcount);
!       else
!           vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]",
!                   stat.cur, stat.cnt);
!     }
  
!     len = STRLEN(t);
!     if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN)
!     {
!       mch_memmove(t + 2, t, len);
!       t[0] = 'W';
!       t[1] = ' ';
!       len += 2;
!     }
  
!     mch_memmove(msgbuf + STRLEN(msgbuf) - len, t, len);
!     if (dirc == '?' && stat.cur == maxcount + 1)
!       stat.cur = -1;
  
!     // keep the message even after redraw, but don't put in history
!     msg_hist_off = TRUE;
!     give_warning(msgbuf, FALSE);
!     msg_hist_off = FALSE;
  }
  
  /*
*** ../vim-9.0.1236/src/session.c       2022-09-17 21:07:52.099993159 +0100
--- src/session.c       2023-01-23 20:41:57.562588533 +0000
***************
*** 200,240 ****
      frame_T   *frc;
      int               count = 0;
  
!     if (fr->fr_layout != FR_LEAF)
!     {
!       // Find first frame that's not skipped and then create a window for
!       // each following one (first frame is already there).
!       frc = ses_skipframe(fr->fr_child);
!       if (frc != NULL)
!           while ((frc = ses_skipframe(frc->fr_next)) != NULL)
!           {
!               // Make window as big as possible so that we have lots of room
!               // to split.
!               if (put_line(fd, "wincmd _ | wincmd |") == FAIL
!                       || put_line(fd, fr->fr_layout == FR_COL
!                                               ? "split" : "vsplit") == FAIL)
!                   return FAIL;
!               ++count;
!           }
  
!       // Go back to the first window.
!       if (count > 0 && (fprintf(fd, fr->fr_layout == FR_COL
!                       ? "%dwincmd k" : "%dwincmd h", count) < 0
!                                                     || put_eol(fd) == FAIL))
!           return FAIL;
! 
!       // Recursively create frames/windows in each window of this column or
!       // row.
!       frc = ses_skipframe(fr->fr_child);
!       while (frc != NULL)
!       {
!           ses_win_rec(fd, frc);
!           frc = ses_skipframe(frc->fr_next);
!           // Go to next window.
!           if (frc != NULL && put_line(fd, "wincmd w") == FAIL)
                return FAIL;
        }
      }
      return OK;
  }
  
--- 200,241 ----
      frame_T   *frc;
      int               count = 0;
  
!     if (fr->fr_layout == FR_LEAF)
!       return OK;
  
!     // Find first frame that's not skipped and then create a window for
!     // each following one (first frame is already there).
!     frc = ses_skipframe(fr->fr_child);
!     if (frc != NULL)
!       while ((frc = ses_skipframe(frc->fr_next)) != NULL)
!       {
!           // Make window as big as possible so that we have lots of room
!           // to split.
!           if (put_line(fd, "wincmd _ | wincmd |") == FAIL
!                   || put_line(fd, fr->fr_layout == FR_COL
!                       ? "split" : "vsplit") == FAIL)
                return FAIL;
+           ++count;
        }
+ 
+     // Go back to the first window.
+     if (count > 0 && (fprintf(fd, fr->fr_layout == FR_COL
+                   ? "%dwincmd k" : "%dwincmd h", count) < 0
+               || put_eol(fd) == FAIL))
+       return FAIL;
+ 
+     // Recursively create frames/windows in each window of this column or
+     // row.
+     frc = ses_skipframe(fr->fr_child);
+     while (frc != NULL)
+     {
+       ses_win_rec(fd, frc);
+       frc = ses_skipframe(frc->fr_next);
+       // Go to next window.
+       if (frc != NULL && put_line(fd, "wincmd w") == FAIL)
+           return FAIL;
      }
+ 
      return OK;
  }
  
***************
*** 1068,1078 ****
      char_u    *fname;
  
      fname = get_view_file(*eap->arg);
!     if (fname != NULL)
!     {
!       do_source(fname, FALSE, DOSO_NONE, NULL);
!       vim_free(fname);
!     }
  }
  
  # if defined(FEAT_GUI_GNOME) \
--- 1069,1079 ----
      char_u    *fname;
  
      fname = get_view_file(*eap->arg);
!     if (fname == NULL)
!       return;
! 
!     do_source(fname, FALSE, DOSO_NONE, NULL);
!     vim_free(fname);
  }
  
  # if defined(FEAT_GUI_GNOME) \
*** ../vim-9.0.1236/src/sign.c  2022-11-25 16:31:46.968606662 +0000
--- src/sign.c  2023-01-23 20:41:57.562588533 +0000
***************
*** 119,134 ****
      signgroup_T               *group;
  
      hi = hash_find(&sg_table, groupname);
!     if (!HASHITEM_EMPTY(hi))
      {
!       group = HI2SG(hi);
!       group->sg_refcount--;
!       if (group->sg_refcount == 0)
!       {
!           // All the signs in this group are removed
!           hash_remove(&sg_table, hi, "sign remove");
!           vim_free(group);
!       }
      }
  }
  
--- 119,134 ----
      signgroup_T               *group;
  
      hi = hash_find(&sg_table, groupname);
!     if (HASHITEM_EMPTY(hi))
!       return;
! 
!     group = HI2SG(hi);
!     group->sg_refcount--;
!     if (group->sg_refcount == 0)
      {
!       // All the signs in this group are removed
!       hash_remove(&sg_table, hi, "sign remove");
!       vim_free(group);
      }
  }
  
***************
*** 220,267 ****
      sign_entry_T *newsign;
  
      newsign = lalloc_id(sizeof(sign_entry_T), FALSE, aid_insert_sign);
!     if (newsign != NULL)
      {
!       newsign->se_id = id;
!       newsign->se_lnum = lnum;
!       newsign->se_typenr = typenr;
!       if (group != NULL)
        {
!           newsign->se_group = sign_group_ref(group);
!           if (newsign->se_group == NULL)
!           {
!               vim_free(newsign);
!               return;
!           }
        }
!       else
!           newsign->se_group = NULL;
!       newsign->se_priority = prio;
!       newsign->se_next = next;
!       newsign->se_prev = prev;
!       if (next != NULL)
!           next->se_prev = newsign;
  
!       if (prev == NULL)
        {
!           // When adding first sign need to redraw the windows to create the
!           // column for signs.
!           if (buf->b_signlist == NULL)
!           {
!               redraw_buf_later(buf, UPD_NOT_VALID);
!               changed_line_abv_curs();
!           }
  
!           // first sign in signlist
!           buf->b_signlist = newsign;
  #ifdef FEAT_NETBEANS_INTG
!           if (netbeans_active())
!               buf->b_has_sign_column = TRUE;
  #endif
-       }
-       else
-           prev->se_next = newsign;
      }
  }
  
  /*
--- 220,267 ----
      sign_entry_T *newsign;
  
      newsign = lalloc_id(sizeof(sign_entry_T), FALSE, aid_insert_sign);
!     if (newsign == NULL)
!       return;
! 
!     newsign->se_id = id;
!     newsign->se_lnum = lnum;
!     newsign->se_typenr = typenr;
!     if (group != NULL)
      {
!       newsign->se_group = sign_group_ref(group);
!       if (newsign->se_group == NULL)
        {
!           vim_free(newsign);
!           return;
        }
!     }
!     else
!       newsign->se_group = NULL;
!     newsign->se_priority = prio;
!     newsign->se_next = next;
!     newsign->se_prev = prev;
!     if (next != NULL)
!       next->se_prev = newsign;
  
!     if (prev == NULL)
!     {
!       // When adding first sign need to redraw the windows to create the
!       // column for signs.
!       if (buf->b_signlist == NULL)
        {
!           redraw_buf_later(buf, UPD_NOT_VALID);
!           changed_line_abv_curs();
!       }
  
!       // first sign in signlist
!       buf->b_signlist = newsign;
  #ifdef FEAT_NETBEANS_INTG
!       if (netbeans_active())
!           buf->b_has_sign_column = TRUE;
  #endif
      }
+     else
+       prev->se_next = newsign;
  }
  
  /*
*** ../vim-9.0.1236/src/sound.c 2022-12-03 13:52:20.465763544 +0000
--- src/sound.c 2023-01-23 20:41:57.562588533 +0000
***************
*** 54,68 ****
  
      soundcb = ALLOC_ONE(soundcb_T);
      if (soundcb == NULL)
-       free_callback(&callback);
-     else
      {
!       soundcb->snd_next = first_callback;
!       first_callback = soundcb;
!       set_callback(&soundcb->snd_callback, &callback);
!       if (callback.cb_free_name)
!           vim_free(callback.cb_name);
      }
      return soundcb;
  }
  
--- 54,69 ----
  
      soundcb = ALLOC_ONE(soundcb_T);
      if (soundcb == NULL)
      {
!       free_callback(&callback);
!       return NULL;
      }
+ 
+     soundcb->snd_next = first_callback;
+     first_callback = soundcb;
+     set_callback(&soundcb->snd_callback, &callback);
+     if (callback.cb_free_name)
+       vim_free(callback.cb_name);
      return soundcb;
  }
  
***************
*** 195,239 ****
  
      if (context == NULL)
        ca_context_create(&context);
!     if (context != NULL)
      {
!       soundcb_T       *soundcb = get_sound_callback(&argvars[1]);
!       int             res = CA_ERROR_INVALID;
  
!       ++sound_id;
!       if (soundcb == NULL)
!       {
!           res = ca_context_play(context, sound_id,
!                   playfile ? CA_PROP_MEDIA_FILENAME : CA_PROP_EVENT_ID,
!                                                   tv_get_string(&argvars[0]),
!                   CA_PROP_CANBERRA_CACHE_CONTROL, "volatile",
!                   NULL);
!       }
!       else
        {
!           static ca_proplist *proplist = NULL;
! 
!           ca_proplist_create(&proplist);
!           if (proplist != NULL)
!           {
!               if (playfile)
!                   ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME,
!                                          (char *)tv_get_string(&argvars[0]));
!               else
!                   ca_proplist_sets(proplist, CA_PROP_EVENT_ID,
!                                          (char *)tv_get_string(&argvars[0]));
!               ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL,
!                       "volatile");
!               res = ca_context_play_full(context, sound_id, proplist,
!                                                     sound_callback, soundcb);
!               if (res != CA_SUCCESS)
!                   delete_sound_callback(soundcb);
  
!               ca_proplist_destroy(proplist);
!           }
        }
-       rettv->vval.v_number = res == CA_SUCCESS ? sound_id : 0;
      }
  }
  
      void
--- 196,240 ----
  
      if (context == NULL)
        ca_context_create(&context);
!     if (context == NULL)
!       return;
! 
!     soundcb_T *soundcb = get_sound_callback(&argvars[1]);
!     int               res = CA_ERROR_INVALID;
! 
!     ++sound_id;
!     if (soundcb == NULL)
!     {
!       res = ca_context_play(context, sound_id,
!               playfile ? CA_PROP_MEDIA_FILENAME : CA_PROP_EVENT_ID,
!               tv_get_string(&argvars[0]),
!               CA_PROP_CANBERRA_CACHE_CONTROL, "volatile",
!               NULL);
!     }
!     else
      {
!       static ca_proplist *proplist = NULL;
  
!       ca_proplist_create(&proplist);
!       if (proplist != NULL)
        {
!           if (playfile)
!               ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME,
!                       (char *)tv_get_string(&argvars[0]));
!           else
!               ca_proplist_sets(proplist, CA_PROP_EVENT_ID,
!                       (char *)tv_get_string(&argvars[0]));
!           ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL,
!                   "volatile");
!           res = ca_context_play_full(context, sound_id, proplist,
!                   sound_callback, soundcb);
!           if (res != CA_SUCCESS)
!               delete_sound_callback(soundcb);
  
!           ca_proplist_destroy(proplist);
        }
      }
+     rettv->vval.v_number = res == CA_SUCCESS ? sound_id : 0;
  }
  
      void
***************
*** 270,280 ****
      void
  f_sound_clear(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
  {
!     if (context != NULL)
!     {
!       ca_context_destroy(context);
!       context = NULL;
!     }
  }
  
  # if defined(EXITFREE) || defined(PROTO)
--- 271,280 ----
      void
  f_sound_clear(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
  {
!     if (context == NULL)
!       return;
!     ca_context_destroy(context);
!     context = NULL;
  }
  
  # if defined(EXITFREE) || defined(PROTO)
*** ../vim-9.0.1236/src/spell.c 2022-11-14 20:52:11.277268383 +0000
--- src/spell.c 2023-01-23 20:41:57.562588533 +0000
***************
*** 1527,1542 ****
      while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL)
        p = skipwhite(p + 1);
  
!     if (*p != NUL)
      {
!       // Only worth concatenating if there is something else than spaces to
!       // concatenate.
!       n = (int)(p - line) + 1;
!       if (n < maxlen - 1)
!       {
!           vim_memset(buf, ' ', n);
!           vim_strncpy(buf +  n, p, maxlen - 1 - n);
!       }
      }
  }
  
--- 1527,1542 ----
      while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL)
        p = skipwhite(p + 1);
  
!     if (*p == NUL)
!       return;
! 
!     // Only worth concatenating if there is something else than spaces to
!     // concatenate.
!     n = (int)(p - line) + 1;
!     if (n < maxlen - 1)
      {
!       vim_memset(buf, ' ', n);
!       vim_strncpy(buf +  n, p, maxlen - 1 - n);
      }
  }
  
***************
*** 1803,1819 ****
      slang_T   *slang;
  
      slang = spell_load_file(fname, slp->sl_lang, NULL, FALSE);
!     if (slang != NULL)
!     {
!       // When a previously loaded file has NOBREAK also use it for the
!       // ".add" files.
!       if (slp->sl_nobreak && slang->sl_add)
!           slang->sl_nobreak = TRUE;
!       else if (slang->sl_nobreak)
!           slp->sl_nobreak = TRUE;
  
!       slp->sl_slang = slang;
!     }
  }
  
  
--- 1803,1819 ----
      slang_T   *slang;
  
      slang = spell_load_file(fname, slp->sl_lang, NULL, FALSE);
!     if (slang == NULL)
!       return;
  
!     // When a previously loaded file has NOBREAK also use it for the
!     // ".add" files.
!     if (slp->sl_nobreak && slang->sl_add)
!       slang->sl_nobreak = TRUE;
!     else if (slang->sl_nobreak)
!       slp->sl_nobreak = TRUE;
! 
!     slp->sl_slang = slang;
  }
  
  
***************
*** 2444,2456 ****
  {
      char_u    fname[MAXPATHL];
  
!     if (int_wordlist != NULL)
!     {
!       mch_remove(int_wordlist);
!       int_wordlist_spl(fname);
!       mch_remove(fname);
!       VIM_CLEAR(int_wordlist);
!     }
  }
  
  /*
--- 2444,2456 ----
  {
      char_u    fname[MAXPATHL];
  
!     if (int_wordlist == NULL)
!       return;
! 
!     mch_remove(int_wordlist);
!     int_wordlist_spl(fname);
!     mch_remove(fname);
!     VIM_CLEAR(int_wordlist);
  }
  
  /*
***************
*** 2524,2539 ****
      buf_T     *buf;
  
      buf = ALLOC_CLEAR_ONE(buf_T);
!     if (buf != NULL)
!     {
!       buf->b_spell = TRUE;
!       buf->b_p_swf = TRUE;    // may create a swap file
  #ifdef FEAT_CRYPT
!       buf->b_p_key = empty_option;
  #endif
!       ml_open(buf);
!       ml_open_file(buf);      // create swap file now
!     }
      return buf;
  }
  
--- 2524,2539 ----
      buf_T     *buf;
  
      buf = ALLOC_CLEAR_ONE(buf_T);
!     if (buf == NULL)
!       return NULL;
! 
!     buf->b_spell = TRUE;
!     buf->b_p_swf = TRUE;      // may create a swap file
  #ifdef FEAT_CRYPT
!     buf->b_p_key = empty_option;
  #endif
!     ml_open(buf);
!     ml_open_file(buf);        // create swap file now
      return buf;
  }
  
***************
*** 2543,2553 ****
      void
  close_spellbuf(buf_T *buf)
  {
!     if (buf != NULL)
!     {
!       ml_close(buf, TRUE);
!       vim_free(buf);
!     }
  }
  
  /*
--- 2543,2553 ----
      void
  close_spellbuf(buf_T *buf)
  {
!     if (buf == NULL)
!       return;
! 
!     ml_close(buf, TRUE);
!     vim_free(buf);
  }
  
  /*
***************
*** 4404,4418 ****
            errmsg = e_invalid_argument;
      }
  
!     if (errmsg == NULL)
!     {
!       FOR_ALL_WINDOWS(wp)
!           if (wp->w_buffer == curbuf && wp->w_p_spell)
!           {
!               errmsg = did_set_spelllang(wp);
!               break;
!           }
!     }
      return errmsg;
  }
  
--- 4404,4418 ----
            errmsg = e_invalid_argument;
      }
  
!     if (errmsg != NULL)
!       return errmsg;
! 
!     FOR_ALL_WINDOWS(wp)
!       if (wp->w_buffer == curbuf && wp->w_p_spell)
!       {
!           errmsg = did_set_spelllang(wp);
!           break;
!       }
      return errmsg;
  }
  
*** ../vim-9.0.1236/src/spellfile.c     2022-11-25 16:31:46.968606662 +0000
--- src/spellfile.c     2023-01-23 20:41:57.562588533 +0000
***************
*** 1561,1572 ****
      int               i = 0;
  
      res = ALLOC_MULT(int, mb_charlen(s) + 1);
!     if (res != NULL)
!     {
!       for (p = s; *p != NUL; )
!           res[i++] = mb_ptr2char_adv(&p);
!       res[i] = NUL;
!     }
      return res;
  }
  
--- 1561,1572 ----
      int               i = 0;
  
      res = ALLOC_MULT(int, mb_charlen(s) + 1);
!     if (res == NULL)
!       return NULL;
! 
!     for (p = s; *p != NUL; )
!       res[i++] = mb_ptr2char_adv(&p);
!     res[i] = NUL;
      return res;
  }
  
***************
*** 1598,1624 ****
      if (len >= LONG_MAX / (long)sizeof(int))
        // Invalid length, multiply with sizeof(int) would overflow.
        return SP_FORMERROR;
!     if (len > 0)
!     {
!       // Allocate the byte array.
!       bp = alloc(len);
!       if (bp == NULL)
!           return SP_OTHERERROR;
!       *bytsp = bp;
!       if (bytsp_len != NULL)
!           *bytsp_len = len;
! 
!       // Allocate the index array.
!       ip = lalloc_clear(len * sizeof(int), TRUE);
!       if (ip == NULL)
!           return SP_OTHERERROR;
!       *idxsp = ip;
! 
!       // Recursively read the tree and store it in the array.
!       idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
!       if (idx < 0)
!           return idx;
!     }
      return 0;
  }
  
--- 1598,1624 ----
      if (len >= LONG_MAX / (long)sizeof(int))
        // Invalid length, multiply with sizeof(int) would overflow.
        return SP_FORMERROR;
!     if (len <= 0)
!       return 0;
! 
!     // Allocate the byte array.
!     bp = alloc(len);
!     if (bp == NULL)
!       return SP_OTHERERROR;
!     *bytsp = bp;
!     if (bytsp_len != NULL)
!       *bytsp_len = len;
! 
!     // Allocate the index array.
!     ip = lalloc_clear(len * sizeof(int), TRUE);
!     if (ip == NULL)
!       return SP_OTHERERROR;
!     *idxsp = ip;
! 
!     // Recursively read the tree and store it in the array.
!     idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
!     if (idx < 0)
!       return idx;
      return 0;
  }
  
***************
*** 2167,2181 ****
      static void
  spell_print_tree(wordnode_T *root)
  {
!     if (root != NULL)
!     {
!       // Clear the "wn_u1.index" fields, used to remember what has been
!       // done.
!       spell_clear_flags(root);
  
!       // Recursively print the tree.
!       spell_print_node(root, 0);
!     }
  }
  #endif // SPELL_PRINTTREE
  
--- 2167,2180 ----
      static void
  spell_print_tree(wordnode_T *root)
  {
!     if (root == NULL)
!       return;
  
!     // Clear the "wn_u1.index" fields, used to remember what has been done.
!     spell_clear_flags(root);
! 
!     // Recursively print the tree.
!     spell_print_node(root, 0);
  }
  #endif // SPELL_PRINTTREE
  
***************
*** 3429,3443 ****
      fromto_T  *ftp;
      char_u    word[MAXWLEN];
  
!     if (ga_grow(gap, 1) == OK)
!     {
!       ftp = ((fromto_T *)gap->ga_data) + gap->ga_len;
!       (void)spell_casefold(curwin, from, (int)STRLEN(from), word, MAXWLEN);
!       ftp->ft_from = getroom_save(spin, word);
!       (void)spell_casefold(curwin, to, (int)STRLEN(to), word, MAXWLEN);
!       ftp->ft_to = getroom_save(spin, word);
!       ++gap->ga_len;
!     }
  }
  
  /*
--- 3428,3442 ----
      fromto_T  *ftp;
      char_u    word[MAXWLEN];
  
!     if (ga_grow(gap, 1) != OK)
!       return;
! 
!     ftp = ((fromto_T *)gap->ga_data) + gap->ga_len;
!     (void)spell_casefold(curwin, from, (int)STRLEN(from), word, MAXWLEN);
!     ftp->ft_from = getroom_save(spin, word);
!     (void)spell_casefold(curwin, to, (int)STRLEN(to), word, MAXWLEN);
!     ftp->ft_to = getroom_save(spin, word);
!     ++gap->ga_len;
  }
  
  /*
***************
*** 4700,4730 ****
  
      // Skip the root itself, it's not actually used.  The first sibling is the
      // start of the tree.
!     if (root->wn_sibling != NULL)
!     {
!       hash_init(&ht);
!       n = node_compress(spin, root->wn_sibling, &ht, &tot);
  
  #ifndef SPELL_PRINTTREE
!       if (spin->si_verbose || p_verbose > 2)
  #endif
!       {
!           if (tot > 1000000)
!               perc = (tot - n) / (tot / 100);
!           else if (tot == 0)
!               perc = 0;
!           else
!               perc = (tot - n) * 100 / tot;
!           vim_snprintf((char *)IObuff, IOSIZE,
!                      _("Compressed %s: %ld of %ld nodes; %ld (%ld%%) 
remaining"),
!                                                      name, n, tot, tot - n, 
perc);
!           spell_message(spin, IObuff);
!       }
  #ifdef SPELL_PRINTTREE
!       spell_print_tree(root->wn_sibling);
  #endif
!       hash_clear(&ht);
!     }
  }
  
  /*
--- 4699,4729 ----
  
      // Skip the root itself, it's not actually used.  The first sibling is the
      // start of the tree.
!     if (root->wn_sibling == NULL)
!       return;
! 
!     hash_init(&ht);
!     n = node_compress(spin, root->wn_sibling, &ht, &tot);
  
  #ifndef SPELL_PRINTTREE
!     if (spin->si_verbose || p_verbose > 2)
  #endif
!     {
!       if (tot > 1000000)
!           perc = (tot - n) / (tot / 100);
!       else if (tot == 0)
!           perc = 0;
!       else
!           perc = (tot - n) * 100 / tot;
!       vim_snprintf((char *)IObuff, IOSIZE,
!               _("Compressed %s: %ld of %ld nodes; %ld (%ld%%) remaining"),
!               name, n, tot, tot - n, perc);
!       spell_message(spin, IObuff);
!     }
  #ifdef SPELL_PRINTTREE
!     spell_print_tree(root->wn_sibling);
  #endif
!     hash_clear(&ht);
  }
  
  /*
***************
*** 5465,5475 ****
      }
  
      // Expand all the remaining arguments (e.g., $VIMRUNTIME).
!     if (get_arglist_exp(arg, &fcount, &fnames, FALSE) == OK)
!     {
!       mkspell(fcount, fnames, ascii, eap->forceit, FALSE);
!       FreeWild(fcount, fnames);
!     }
  }
  
  /*
--- 5464,5474 ----
      }
  
      // Expand all the remaining arguments (e.g., $VIMRUNTIME).
!     if (get_arglist_exp(arg, &fcount, &fnames, FALSE) != OK)
!       return;
! 
!     mkspell(fcount, fnames, ascii, eap->forceit, FALSE);
!     FreeWild(fcount, fnames);
  }
  
  /*
***************
*** 6392,6461 ****
      int               aspath = FALSE;
      char_u    *lstart = curbuf->b_s.b_p_spl;
  
!     if (*curwin->w_s->b_p_spl != NUL && curwin->w_s->b_langp.ga_len > 0)
!     {
!       buf = alloc(MAXPATHL);
!       if (buf == NULL)
!           return;
  
!       // Find the end of the language name.  Exclude the region.  If there
!       // is a path separator remember the start of the tail.
!       for (lend = curwin->w_s->b_p_spl; *lend != NUL
!                       && vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
!           if (vim_ispathsep(*lend))
!           {
!               aspath = TRUE;
!               lstart = lend + 1;
!           }
  
!       // Loop over all entries in 'runtimepath'.  Use the first one where we
!       // are allowed to write.
!       rtp = p_rtp;
!       while (*rtp != NUL)
        {
            if (aspath)
-               // Use directory of an entry with path, e.g., for
-               // "/dir/lg.utf-8.spl" use "/dir".
                vim_strncpy(buf, curbuf->b_s.b_p_spl,
!                                           lstart - curbuf->b_s.b_p_spl - 1);
            else
!               // Copy the path from 'runtimepath' to buf[].
!               copy_option_part(&rtp, buf, MAXPATHL, ",");
!           if (filewritable(buf) == 2)
!           {
!               // Use the first language name from 'spelllang' and the
!               // encoding used in the first loaded .spl file.
!               if (aspath)
!                   vim_strncpy(buf, curbuf->b_s.b_p_spl,
!                                                 lend - curbuf->b_s.b_p_spl);
!               else
!               {
!                   // Create the "spell" directory if it doesn't exist yet.
!                   l = (int)STRLEN(buf);
!                   vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
!                   if (filewritable(buf) != 2)
!                       vim_mkdir(buf, 0755);
! 
!                   l = (int)STRLEN(buf);
!                   vim_snprintf((char *)buf + l, MAXPATHL - l,
!                                "/%.*s", (int)(lend - lstart), lstart);
!               }
                l = (int)STRLEN(buf);
!               fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
!                                                        ->lp_slang->sl_fname;
!               vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
!                       fname != NULL
!                         && strstr((char *)gettail(fname), ".ascii.") != NULL
!                                      ? (char_u *)"ascii" : spell_enc());
!               set_option_value_give_err((char_u *)"spellfile",
!                                                          0L, buf, OPT_LOCAL);
!               break;
            }
!           aspath = FALSE;
        }
! 
!       vim_free(buf);
      }
  }
  
  
--- 6391,6460 ----
      int               aspath = FALSE;
      char_u    *lstart = curbuf->b_s.b_p_spl;
  
!     if (*curwin->w_s->b_p_spl == NUL || curwin->w_s->b_langp.ga_len <= 0)
!       return;
  
!     buf = alloc(MAXPATHL);
!     if (buf == NULL)
!       return;
  
!     // Find the end of the language name.  Exclude the region.  If there
!     // is a path separator remember the start of the tail.
!     for (lend = curwin->w_s->b_p_spl; *lend != NUL
!           && vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
!       if (vim_ispathsep(*lend))
!       {
!           aspath = TRUE;
!           lstart = lend + 1;
!       }
! 
!     // Loop over all entries in 'runtimepath'.  Use the first one where we
!     // are allowed to write.
!     rtp = p_rtp;
!     while (*rtp != NUL)
!     {
!       if (aspath)
!           // Use directory of an entry with path, e.g., for
!           // "/dir/lg.utf-8.spl" use "/dir".
!           vim_strncpy(buf, curbuf->b_s.b_p_spl,
!                   lstart - curbuf->b_s.b_p_spl - 1);
!       else
!           // Copy the path from 'runtimepath' to buf[].
!           copy_option_part(&rtp, buf, MAXPATHL, ",");
!       if (filewritable(buf) == 2)
        {
+           // Use the first language name from 'spelllang' and the
+           // encoding used in the first loaded .spl file.
            if (aspath)
                vim_strncpy(buf, curbuf->b_s.b_p_spl,
!                       lend - curbuf->b_s.b_p_spl);
            else
!           {
!               // Create the "spell" directory if it doesn't exist yet.
                l = (int)STRLEN(buf);
!               vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
!               if (filewritable(buf) != 2)
!                   vim_mkdir(buf, 0755);
! 
!               l = (int)STRLEN(buf);
!               vim_snprintf((char *)buf + l, MAXPATHL - l,
!                       "/%.*s", (int)(lend - lstart), lstart);
            }
!           l = (int)STRLEN(buf);
!           fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
!               ->lp_slang->sl_fname;
!           vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
!                   fname != NULL
!                   && strstr((char *)gettail(fname), ".ascii.") != NULL
!                   ? (char_u *)"ascii" : spell_enc());
!           set_option_value_give_err((char_u *)"spellfile",
!                   0L, buf, OPT_LOCAL);
!           break;
        }
!       aspath = FALSE;
      }
+ 
+     vim_free(buf);
  }
  
  
*** ../vim-9.0.1236/src/spellsuggest.c  2022-10-13 22:12:07.168673806 +0100
--- src/spellsuggest.c  2023-01-23 20:41:57.562588533 +0000
***************
*** 282,305 ****
      int               newscore;
  
      hi = hash_find(&slang->sl_wordcount, word);
!     if (!HASHITEM_EMPTY(hi))
!     {
!       wc = HI2WC(hi);
!       if (wc->wc_count < SCORE_THRES2)
!           bonus = SCORE_COMMON1;
!       else if (wc->wc_count < SCORE_THRES3)
!           bonus = SCORE_COMMON2;
!       else
!           bonus = SCORE_COMMON3;
!       if (split)
!           newscore = score - bonus / 2;
!       else
!           newscore = score - bonus;
!       if (newscore < 0)
!           return 0;
!       return newscore;
!     }
!     return score;
  }
  
  /*
--- 282,304 ----
      int               newscore;
  
      hi = hash_find(&slang->sl_wordcount, word);
!     if (HASHITEM_EMPTY(hi))
!       return score;
! 
!     wc = HI2WC(hi);
!     if (wc->wc_count < SCORE_THRES2)
!       bonus = SCORE_COMMON1;
!     else if (wc->wc_count < SCORE_THRES3)
!       bonus = SCORE_COMMON2;
!     else
!       bonus = SCORE_COMMON3;
!     if (split)
!       newscore = score - bonus / 2;
!     else
!       newscore = score - bonus;
!     if (newscore < 0)
!       return 0;
!     return newscore;
  }
  
  /*
***************
*** 316,351 ****
      int               first;
      char_u    *p;
  
!     if (flags & WF_KEEPCAP)
!     {
!       // Count the number of UPPER and lower case letters.
!       l = u = 0;
!       first = FALSE;
!       for (p = word; p < end; MB_PTR_ADV(p))
!       {
!           c = PTR2CHAR(p);
!           if (SPELL_ISUPPER(c))
!           {
!               ++u;
!               if (p == word)
!                   first = TRUE;
!           }
!           else
!               ++l;
        }
  
!       // If there are more UPPER than lower case letters suggest an
!       // ALLCAP word.  Otherwise, if the first letter is UPPER then
!       // suggest ONECAP.  Exception: "ALl" most likely should be "All",
!       // require three upper case letters.
!       if (u > l && u > 2)
!           flags |= WF_ALLCAP;
!       else if (first)
!           flags |= WF_ONECAP;
  
-       if (u >= 2 && l >= 2)   // maCARONI maCAroni
-           flags |= WF_MIXCAP;
-     }
      return flags;
  }
  
--- 315,351 ----
      int               first;
      char_u    *p;
  
!     if (!(flags & WF_KEEPCAP))
!       return flags;
! 
!     // Count the number of UPPER and lower case letters.
!     l = u = 0;
!     first = FALSE;
!     for (p = word; p < end; MB_PTR_ADV(p))
!     {
!       c = PTR2CHAR(p);
!       if (SPELL_ISUPPER(c))
!       {
!           ++u;
!           if (p == word)
!               first = TRUE;
        }
+       else
+           ++l;
+     }
  
!     // If there are more UPPER than lower case letters suggest an
!     // ALLCAP word.  Otherwise, if the first letter is UPPER then
!     // suggest ONECAP.  Exception: "ALl" most likely should be "All",
!     // require three upper case letters.
!     if (u > l && u > 2)
!       flags |= WF_ALLCAP;
!     else if (first)
!       flags |= WF_ONECAP;
! 
!     if (u >= 2 && l >= 2)     // maCARONI maCAroni
!       flags |= WF_MIXCAP;
  
      return flags;
  }
  
***************
*** 3692,3703 ****
  
      hash = hash_hash(word);
      hi = hash_lookup(&su->su_banned, word, hash);
!     if (HASHITEM_EMPTY(hi))
!     {
!       s = vim_strsave(word);
!       if (s != NULL)
!           hash_add_item(&su->su_banned, hi, s, hash);
!     }
  }
  
  /*
--- 3692,3702 ----
  
      hash = hash_hash(word);
      hi = hash_lookup(&su->su_banned, word, hash);
!     if (!HASHITEM_EMPTY(hi))          // already present
!       return;
!     s = vim_strsave(word);
!     if (s != NULL)
!       hash_add_item(&su->su_banned, hi, s, hash);
  }
  
  /*
***************
*** 3778,3802 ****
      int               maxscore,
      int               keep)           // nr of suggestions to keep
  {
!     if (gap->ga_len > 0)
      {
!       // Sort the list.
!       qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T),
!                                                                 sug_compare);
! 
!       // Truncate the list to the number of suggestions that will be
!       // displayed.
!       if (gap->ga_len > keep)
!       {
!           int         i;
!           suggest_T   *stp = &SUG(*gap, 0);
! 
!           for (i = keep; i < gap->ga_len; ++i)
!               vim_free(stp[i].st_word);
!           gap->ga_len = keep;
!           if (keep >= 1)
!               return stp[keep - 1].st_score;
!       }
      }
      return maxscore;
  }
--- 3777,3801 ----
      int               maxscore,
      int               keep)           // nr of suggestions to keep
  {
!     if (gap->ga_len <= 0)
!       return maxscore;
! 
!     // Sort the list.
!     qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T),
!           sug_compare);
! 
!     // Truncate the list to the number of suggestions that will be
!     // displayed.
!     if (gap->ga_len > keep)
      {
!       int             i;
!       suggest_T   *stp = &SUG(*gap, 0);
! 
!       for (i = keep; i < gap->ga_len; ++i)
!           vim_free(stp[i].st_word);
!       gap->ga_len = keep;
!       if (keep >= 1)
!           return stp[keep - 1].st_score;
      }
      return maxscore;
  }
*** ../vim-9.0.1236/src/strings.c       2023-01-04 15:56:47.868550539 +0000
--- src/strings.c       2023-01-23 20:41:57.562588533 +0000
***************
*** 42,52 ****
      char_u    *p;
  
      p = alloc(len + 1);
!     if (p != NULL)
!     {
!       STRNCPY(p, string, len);
!       p[len] = NUL;
!     }
      return p;
  }
  
--- 42,52 ----
      char_u    *p;
  
      p = alloc(len + 1);
!     if (p == NULL)
!       return NULL;
! 
!     STRNCPY(p, string, len);
!     p[len] = NUL;
      return p;
  }
  
***************
*** 94,117 ****
        ++length;                       // count an ordinary char
      }
      escaped_string = alloc(length);
!     if (escaped_string != NULL)
      {
!       p2 = escaped_string;
!       for (p = string; *p; p++)
        {
!           if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
!           {
!               mch_memmove(p2, p, (size_t)l);
!               p2 += l;
!               p += l - 1;             // skip multibyte char
!               continue;
!           }
!           if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
!               *p2++ = cc;
!           *p2++ = *p;
        }
!       *p2 = NUL;
      }
      return escaped_string;
  }
  
--- 94,116 ----
        ++length;                       // count an ordinary char
      }
      escaped_string = alloc(length);
!     if (escaped_string == NULL)
!       return NULL;
!     p2 = escaped_string;
!     for (p = string; *p; p++)
      {
!       if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
        {
!           mch_memmove(p2, p, (size_t)l);
!           p2 += l;
!           p += l - 1;         // skip multibyte char
!           continue;
        }
!       if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p)))
!           *p2++ = cc;
!       *p2++ = *p;
      }
+     *p2 = NUL;
      return escaped_string;
  }
  
***************
*** 338,349 ****
      char_u  *p2;
      int           c;
  
!     if (p != NULL)
!     {
!       p2 = p;
!       while ((c = *p2) != NUL)
!           *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20);
!     }
  }
  
  #if defined(FEAT_EVAL) || defined(FEAT_SPELL) || defined(PROTO)
--- 337,348 ----
      char_u  *p2;
      int           c;
  
!     if (p == NULL)
!       return;
! 
!     p2 = p;
!     while ((c = *p2) != NUL)
!       *p2++ = (c < 'a' || c > 'z') ? c : (c - 0x20);
  }
  
  #if defined(FEAT_EVAL) || defined(FEAT_SPELL) || defined(PROTO)
***************
*** 760,774 ****
      size_t  l = str1 == NULL ? 0 : STRLEN(str1);
  
      dest = alloc(l + (str2 == NULL ? 0 : STRLEN(str2)) + 1L);
!     if (dest != NULL)
!     {
!       if (str1 == NULL)
!           *dest = NUL;
!       else
!           STRCPY(dest, str1);
!       if (str2 != NULL)
!           STRCPY(dest + l, str2);
!     }
      return dest;
  }
  
--- 759,772 ----
      size_t  l = str1 == NULL ? 0 : STRLEN(str1);
  
      dest = alloc(l + (str2 == NULL ? 0 : STRLEN(str2)) + 1L);
!     if (dest == NULL)
!       return NULL;
!     if (str1 == NULL)
!       *dest = NUL;
!     else
!       STRCPY(dest, str1);
!     if (str2 != NULL)
!       STRCPY(dest + l, str2);
      return dest;
  }
  
***************
*** 793,819 ****
                ++len;
      }
      s = r = alloc(len);
!     if (r != NULL)
      {
!       if (function)
        {
!           STRCPY(r, "function('");
!           r += 10;
        }
!       else
!           *r++ = '\'';
!       if (str != NULL)
!           for (p = str; *p != NUL; )
!           {
!               if (*p == '\'')
!                   *r++ = '\'';
!               MB_COPY_CHAR(p, r);
!           }
!       *r++ = '\'';
!       if (function)
!           *r++ = ')';
!       *r++ = NUL;
!     }
      return s;
  }
  
--- 791,817 ----
                ++len;
      }
      s = r = alloc(len);
!     if (r == NULL)
!       return NULL;
! 
!     if (function)
      {
!       STRCPY(r, "function('");
!       r += 10;
!     }
!     else
!       *r++ = '\'';
!     if (str != NULL)
!       for (p = str; *p != NUL; )
        {
!           if (*p == '\'')
!               *r++ = '\'';
!           MB_COPY_CHAR(p, r);
        }
!     *r++ = '\'';
!     if (function)
!       *r++ = ')';
!     *r++ = NUL;
      return s;
  }
  
*** ../vim-9.0.1236/src/syntax.c        2023-01-02 18:10:00.019271226 +0000
--- src/syntax.c        2023-01-23 20:41:57.566588532 +0000
***************
*** 855,866 ****
      static void
  save_chartab(char_u *chartab)
  {
!     if (syn_block->b_syn_isk != empty_option)
!     {
!       mch_memmove(chartab, syn_buf->b_chartab, (size_t)32);
!       mch_memmove(syn_buf->b_chartab, syn_win->w_s->b_syn_chartab,
!                                                                 (size_t)32);
!     }
  }
  
      static void
--- 855,865 ----
      static void
  save_chartab(char_u *chartab)
  {
!     if (syn_block->b_syn_isk == empty_option)
!       return;
! 
!     mch_memmove(chartab, syn_buf->b_chartab, (size_t)32);
!     mch_memmove(syn_buf->b_chartab, syn_win->w_s->b_syn_chartab, (size_t)32);
  }
  
      static void
***************
*** 880,898 ****
      int r;
      char_u    buf_chartab[32];  // chartab array for syn iskyeyword
  
!     if (syn_block->b_syn_linecont_prog != NULL)
!     {
!       // use syntax iskeyword option
!       save_chartab(buf_chartab);
!       regmatch.rmm_ic = syn_block->b_syn_linecont_ic;
!       regmatch.regprog = syn_block->b_syn_linecont_prog;
!       r = syn_regexec(&regmatch, lnum, (colnr_T)0,
!                               IF_SYN_TIME(&syn_block->b_syn_linecont_time));
!       syn_block->b_syn_linecont_prog = regmatch.regprog;
!       restore_chartab(buf_chartab);
!       return r;
!     }
!     return FALSE;
  }
  
  /*
--- 879,896 ----
      int r;
      char_u    buf_chartab[32];  // chartab array for syn iskyeyword
  
!     if (syn_block->b_syn_linecont_prog == NULL)
!       return FALSE;
! 
!     // use syntax iskeyword option
!     save_chartab(buf_chartab);
!     regmatch.rmm_ic = syn_block->b_syn_linecont_ic;
!     regmatch.regprog = syn_block->b_syn_linecont_prog;
!     r = syn_regexec(&regmatch, lnum, (colnr_T)0,
!           IF_SYN_TIME(&syn_block->b_syn_linecont_time));
!     syn_block->b_syn_linecont_prog = regmatch.regprog;
!     restore_chartab(buf_chartab);
!     return r;
  }
  
  /*
***************
*** 1030,1043 ****
  {
      synstate_T        *p;
  
!     if (block->b_sst_array != NULL)
!     {
!       FOR_ALL_SYNSTATES(block, p)
!           clear_syn_state(p);
!       VIM_CLEAR(block->b_sst_array);
!       block->b_sst_first = NULL;
!       block->b_sst_len = 0;
!     }
  }
  /*
   * Free b_sst_array[] for buffer "buf".
--- 1028,1041 ----
  {
      synstate_T        *p;
  
!     if (block->b_sst_array == NULL)
!       return;
! 
!     FOR_ALL_SYNSTATES(block, p)
!       clear_syn_state(p);
!     VIM_CLEAR(block->b_sst_array);
!     block->b_sst_first = NULL;
!     block->b_sst_len = 0;
  }
  /*
   * Free b_sst_array[] for buffer "buf".
***************
*** 5437,5447 ****
      int           id = 0;
  
      name = vim_strnsave(linep, len);
!     if (name != NULL)
!     {
!       id = syn_scl_name2id(name);
!       vim_free(name);
!     }
      return id;
  }
  
--- 5435,5445 ----
      int           id = 0;
  
      name = vim_strnsave(linep, len);
!     if (name == NULL)
!       return 0;
! 
!     id = syn_scl_name2id(name);
!     vim_free(name);
      return id;
  }
  
***************
*** 6256,6283 ****
      for (subcmd_end = arg; ASCII_ISALPHA(*subcmd_end); ++subcmd_end)
        ;
      subcmd_name = vim_strnsave(arg, subcmd_end - arg);
!     if (subcmd_name != NULL)
      {
!       if (eap->skip)          // skip error messages for all subcommands
!           ++emsg_skip;
!       for (i = 0; ; ++i)
        {
!           if (subcommands[i].name == NULL)
!           {
!               semsg(_(e_invalid_syntax_subcommand_str), subcmd_name);
!               break;
!           }
!           if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0)
!           {
!               eap->arg = skipwhite(subcmd_end);
!               (subcommands[i].func)(eap, FALSE);
!               break;
!           }
        }
-       vim_free(subcmd_name);
-       if (eap->skip)
-           --emsg_skip;
      }
  }
  
      void
--- 6254,6281 ----
      for (subcmd_end = arg; ASCII_ISALPHA(*subcmd_end); ++subcmd_end)
        ;
      subcmd_name = vim_strnsave(arg, subcmd_end - arg);
!     if (subcmd_name == NULL)
!       return;
! 
!     if (eap->skip)            // skip error messages for all subcommands
!       ++emsg_skip;
!     for (i = 0; ; ++i)
      {
!       if (subcommands[i].name == NULL)
        {
!           semsg(_(e_invalid_syntax_subcommand_str), subcmd_name);
!           break;
!       }
!       if (STRCMP(subcmd_name, (char_u *)subcommands[i].name) == 0)
!       {
!           eap->arg = skipwhite(subcmd_end);
!           (subcommands[i].func)(eap, FALSE);
!           break;
        }
      }
+     vim_free(subcmd_name);
+     if (eap->skip)
+       --emsg_skip;
  }
  
      void
***************
*** 6384,6420 ****
      include_link = 0;
      include_default = 0;
  
      // (part of) subcommand already typed
!     if (*arg != NUL)
!     {
!       p = skiptowhite(arg);
!       if (*p != NUL)              // past first word
!       {
!           xp->xp_pattern = skipwhite(p);
!           if (*skiptowhite(xp->xp_pattern) != NUL)
!               xp->xp_context = EXPAND_NOTHING;
!           else if (STRNICMP(arg, "case", p - arg) == 0)
!               expand_what = EXP_CASE;
!           else if (STRNICMP(arg, "spell", p - arg) == 0)
!               expand_what = EXP_SPELL;
!           else if (STRNICMP(arg, "sync", p - arg) == 0)
!               expand_what = EXP_SYNC;
!           else if (STRNICMP(arg, "list", p - arg) == 0)
!           {
!               p = skipwhite(p);
!               if (*p == '@')
!                   expand_what = EXP_CLUSTER;
!               else
!                   xp->xp_context = EXPAND_HIGHLIGHT;
!           }
!           else if (STRNICMP(arg, "keyword", p - arg) == 0
!                   || STRNICMP(arg, "region", p - arg) == 0
!                   || STRNICMP(arg, "match", p - arg) == 0)
!               xp->xp_context = EXPAND_HIGHLIGHT;
!           else
!               xp->xp_context = EXPAND_NOTHING;
!       }
      }
  }
  
  /*
--- 6382,6419 ----
      include_link = 0;
      include_default = 0;
  
+     if (*arg == NUL)
+       return;
+ 
      // (part of) subcommand already typed
!     p = skiptowhite(arg);
!     if (*p == NUL)
!       return;
! 
!     // past first word
!     xp->xp_pattern = skipwhite(p);
!     if (*skiptowhite(xp->xp_pattern) != NUL)
!       xp->xp_context = EXPAND_NOTHING;
!     else if (STRNICMP(arg, "case", p - arg) == 0)
!       expand_what = EXP_CASE;
!     else if (STRNICMP(arg, "spell", p - arg) == 0)
!       expand_what = EXP_SPELL;
!     else if (STRNICMP(arg, "sync", p - arg) == 0)
!       expand_what = EXP_SYNC;
!     else if (STRNICMP(arg, "list", p - arg) == 0)
!     {
!       p = skipwhite(p);
!       if (*p == '@')
!           expand_what = EXP_CLUSTER;
!       else
!           xp->xp_context = EXPAND_HIGHLIGHT;
      }
+     else if (STRNICMP(arg, "keyword", p - arg) == 0
+           || STRNICMP(arg, "region", p - arg) == 0
+           || STRNICMP(arg, "match", p - arg) == 0)
+       xp->xp_context = EXPAND_HIGHLIGHT;
+     else
+       xp->xp_context = EXPAND_NOTHING;
  }
  
  /*
*** ../vim-9.0.1236/src/version.c       2023-01-23 16:56:52.740404170 +0000
--- src/version.c       2023-01-23 20:43:02.294563069 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1237,
  /**/

-- 
A fine is a tax for doing wrong.  A tax is a fine for doing well.

 /// 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/20230123204655.8F1571C08EE%40moolenaar.net.

Raspunde prin e-mail lui