To: vim_dev@googlegroups.com Subject: Patch 9.0.1237 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 "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 "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(®match, 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(®match, 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 -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///