From 147f65373ecb5a5582d4cc0eb41ebc9a303181cc Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 15 Jan 2022 07:47:13 +0800 Subject: vim-patch:8.2.4091: virtcol is recomputed for statusline unnecessarily Problem: Virtcol is recomputed for statusline unnecessarily. Solution: Just use "w_virtcol". (closes vim/vim#9523) https://github.com/vim/vim/commit/0f112052acaeffd75b7eb001eeb8a246ad12a276 --- src/nvim/buffer.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index abd22fba26..4157651a7e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4001,14 +4001,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use case STL_VIRTCOL: case STL_VIRTCOL_ALT: { - // In list mode virtcol needs to be recomputed - colnr_T virtcol = wp->w_virtcol; - if (wp->w_p_list && wp->w_p_lcs_chars.tab1 == NUL) { - wp->w_p_list = false; - getvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL); - wp->w_p_list = true; - } - virtcol++; + colnr_T virtcol = wp->w_virtcol + 1; // Don't display %V if it's the same as %c. if (opt == STL_VIRTCOL_ALT && (virtcol == (colnr_T)(!(State & INSERT) && empty_line -- cgit From be15ac06badbea6b11390ad7d9c2ddd4aea73480 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 16 Jan 2022 18:44:28 +0800 Subject: feat(statusline): support multibyte fillchar This includes a partial port of Vim patch 8.2.2569 and some changes to nvim_eval_statusline() to allow a multibyte fillchar. Literally every line of C code touched by that patch has been refactored in Nvim, and that patch contains some irrelevant foldcolumn tests I'm not sure how to port (as Nvim's foldcolumn behavior has diverged from Vim's). --- src/nvim/buffer.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index abd22fba26..9a02dff23b 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3418,7 +3418,7 @@ typedef enum { /// /// @return The final width of the statusline int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use_sandbox, - char_u fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab) + int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab) { static size_t stl_items_len = 20; // Initial value, grows as needed. static stl_item_t *stl_items = NULL; @@ -3461,9 +3461,6 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (fillchar == 0) { fillchar = ' '; - } else if (utf_char2len(fillchar) > 1) { - // Can't handle a multi-byte fill character yet. - fillchar = '-'; } // The cursor in windows other than the current one isn't always @@ -3661,7 +3658,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use out_p = out_p - n + 1; // Fill up space left over by half a double-wide char. while (++group_len < stl_items[stl_groupitems[groupdepth]].minwid) { - *out_p++ = fillchar; + MB_CHAR2BYTES(fillchar, out_p); } // } @@ -3684,14 +3681,14 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (min_group_width < 0) { min_group_width = 0 - min_group_width; while (group_len++ < min_group_width && out_p < out_end_p) { - *out_p++ = fillchar; + MB_CHAR2BYTES(fillchar, out_p); } // If the group is right-aligned, shift everything to the right and // prepend with filler characters. } else { // { Move the group to the right - memmove(t + min_group_width - group_len, t, (size_t)(out_p - t)); - group_len = min_group_width - group_len; + group_len = (min_group_width - group_len) * utf_char2len(fillchar); + memmove(t + group_len, t, (size_t)(out_p - t)); if (out_p + group_len >= (out_end_p + 1)) { group_len = (long)(out_end_p - out_p); } @@ -3705,7 +3702,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // Prepend the fill characters for (; group_len > 0; group_len--) { - *t++ = fillchar; + MB_CHAR2BYTES(fillchar, t); } } } @@ -4237,7 +4234,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (l + 1 == minwid && fillchar == '-' && ascii_isdigit(*t)) { *out_p++ = ' '; } else { - *out_p++ = fillchar; + MB_CHAR2BYTES(fillchar, out_p); } } minwid = 0; @@ -4248,20 +4245,21 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } // { Copy the string text into the output buffer - while (*t && out_p < out_end_p) { - *out_p++ = *t++; + for (; *t && out_p < out_end_p; t++) { // Change a space by fillchar, unless fillchar is '-' and a // digit follows. - if (fillable && out_p[-1] == ' ' - && (!ascii_isdigit(*t) || fillchar != '-')) { - out_p[-1] = fillchar; + if (fillable && *t == ' ' + && (!ascii_isdigit(*(t + 1)) || fillchar != '-')) { + MB_CHAR2BYTES(fillchar, out_p); + } else { + *out_p++ = *t; } } // } // For left-aligned items, fill any remaining space with the fillchar for (; l < minwid && out_p < out_end_p; l++) { - *out_p++ = fillchar; + MB_CHAR2BYTES(fillchar, out_p); } // Otherwise if the item is a number, copy that to the output buffer. @@ -4454,7 +4452,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // Fill up for half a double-wide character. while (++width < maxwidth) { - *trunc_p++ = fillchar; + MB_CHAR2BYTES(fillchar, trunc_p); *trunc_p = NUL; } // } @@ -4505,13 +4503,13 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use standard_spaces * (num_separators - 1); for (int i = 0; i < num_separators; i++) { - int dislocation = (i == (num_separators - 1)) - ? final_spaces : standard_spaces; + int dislocation = (i == (num_separators - 1)) ? final_spaces : standard_spaces; + dislocation *= utf_char2len(fillchar); char_u *start = stl_items[stl_separator_locations[i]].start; char_u *seploc = start + dislocation; STRMOVE(seploc, start); - for (char_u *s = start; s < seploc; s++) { - *s = fillchar; + for (char_u *s = start; s < seploc; ) { + MB_CHAR2BYTES(fillchar, s); } for (int item_idx = stl_separator_locations[i] + 1; -- cgit From d224957d30654dfa7fac7732b81f6a1b495a418b Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 19 Jan 2022 22:07:37 -0500 Subject: fix(coverity/188749): nullify pointer to fix use-after-free --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index abd22fba26..0248d42f58 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4351,7 +4351,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // Only free the string buffer if we allocated it. // Note: This is not needed if `str` is pointing at `tmp` if (opt == STL_VIM_EXPR) { - xfree(str); + XFREE_CLEAR(str); } if (num >= 0 || (!itemisflag && str && *str)) { -- cgit From 2fa1b4cbff06b6dabc6d59df585953e9220e5007 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 21 Jan 2022 05:14:40 +0800 Subject: vim-patch:8.2.4166: undo synced when switching buffer in another window Problem: Undo synced when switching buffer in another window. Solution: Do not sync undo when not needed. (closes vim/vim#9575) https://github.com/vim/vim/commit/e615db06046312e74886fa1ef98feb5a9db2a7c3 --- src/nvim/buffer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index abd22fba26..83c95da4f7 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1454,7 +1454,10 @@ void set_curbuf(buf_T *buf, int action) } if (bufref_valid(&prevbufref) && !aborting()) { win_T *previouswin = curwin; - if (prevbuf == curbuf) { + // Do not sync when in Insert mode and the buffer is open in + // another window, might be a timer doing something in another + // window. + if (prevbuf == curbuf && ((State & INSERT) == 0 || curbuf->b_nwindows <= 1)) { u_sync(false); } close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, -- cgit From 15c9d88bb70b8ee9bdcf3c6fe7debc01a1ee5f36 Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sat, 29 Jan 2022 05:27:29 +0000 Subject: vim-patch:8.2.4245: ":retab 0" may cause illegal memory access Problem: ":retab 0" may cause illegal memory access. Solution: Limit the value of 'tabstop' to 10000. https://github.com/vim/vim/commit/652dee448618589de5528a9e9a36995803f5557a ex_retab change is N/A (+vartabs always available). Nvim's set_num_option validation logic was refactored, hence why it looks different from Vim's. Also use XFREE_CLEAR in other places. --- src/nvim/buffer.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index eee5a0b46c..52a7db3be2 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1899,10 +1899,8 @@ void free_buf_options(buf_T *buf, int free_p_ff) clear_string_option(&buf->b_p_flp); clear_string_option(&buf->b_p_isk); clear_string_option(&buf->b_p_vsts); - xfree(buf->b_p_vsts_nopaste); - buf->b_p_vsts_nopaste = NULL; - xfree(buf->b_p_vsts_array); - buf->b_p_vsts_array = NULL; + XFREE_CLEAR(buf->b_p_vsts_nopaste); + XFREE_CLEAR(buf->b_p_vsts_array); clear_string_option(&buf->b_p_vts); XFREE_CLEAR(buf->b_p_vts_array); clear_string_option(&buf->b_p_keymap); -- cgit From ff81725ff03e8885df3c292162acfb6305fda14f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 9 Feb 2022 09:52:57 +0800 Subject: refactor(mbyte.c): add const qualifiers This only touches functions that do not return a pointer. Also add a note about the differences between mb_head_off() and utf_head_off(). --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index bb8483f644..96ddd9a2f5 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3327,7 +3327,7 @@ void maketitle(void) len = (int)STRLEN(buf_p); if (len > 100) { len -= 100; - len += (*mb_tail_off)(buf_p, buf_p + len) + 1; + len += mb_tail_off(buf_p, buf_p + len) + 1; buf_p += len; } STRCPY(icon_str, buf_p); -- cgit From 85ae04dbfd405343b10c400d40e95334a44cc978 Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Sat, 17 Apr 2021 17:33:59 -0400 Subject: fix: close floating windows when calling win_close() --- src/nvim/buffer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 96ddd9a2f5..a9addc0e68 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -846,7 +846,7 @@ void goto_buffer(exarg_T *eap, int start, int dir, int count) enter_cleanup(&cs); // Quitting means closing the split window, nothing else. - win_close(curwin, true); + win_close(curwin, true, false); swap_exists_action = SEA_NONE; swap_exists_did_quit = true; @@ -1237,7 +1237,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) while (buf == curbuf && !(curwin->w_closing || curwin->w_buffer->b_locked > 0) && (!ONE_WINDOW || first_tabpage->tp_next != NULL)) { - if (win_close(curwin, false) == FAIL) { + if (win_close(curwin, false, false) == FAIL) { break; } } @@ -4822,7 +4822,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) && (first_tabpage->tp_next == NULL || !had_tab)) { use_firstwin = true; } else { - win_close(wp, !buf_hide(buf) && !bufIsChanged(buf)); + win_close(wp, !buf_hide(buf) && !bufIsChanged(buf), false); // check if autocommands removed the next window if (!win_valid(wpnext)) { // start all over... @@ -5013,7 +5013,7 @@ void ex_buffer_all(exarg_T *eap) && !ONE_WINDOW && !(wp->w_closing || wp->w_buffer->b_locked > 0)) { - win_close(wp, false); + win_close(wp, false, false); wpnext = firstwin; // just in case an autocommand does // something strange with windows tpnext = first_tabpage; // start all over... @@ -5094,7 +5094,7 @@ void ex_buffer_all(exarg_T *eap) enter_cleanup(&cs); // User selected Quit at ATTENTION prompt; close this window. - win_close(curwin, true); + win_close(curwin, true, false); open_wins--; swap_exists_action = SEA_NONE; swap_exists_did_quit = true; @@ -5136,7 +5136,7 @@ void ex_buffer_all(exarg_T *eap) // BufWrite Autocommands made the window invalid, start over wp = lastwin; } else if (r) { - win_close(wp, !buf_hide(wp->w_buffer)); + win_close(wp, !buf_hide(wp->w_buffer), false); open_wins--; wp = lastwin; } else { -- cgit From 612696bedc8f178cb08645dfb056f01efacf5122 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 12 Feb 2022 06:36:17 +0800 Subject: vim-patch:8.1.2073: when editing a buffer 'colorcolumn' may not work Problem: When editing a buffer 'colorcolumn' may not work. Solution: Set the buffer before copying option values. Call check_colorcolumn() after copying window options. https://github.com/vim/vim/commit/010ee9657acf1a9f799079d718998c94e50ccadc --- src/nvim/buffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index a9addc0e68..ee704bd1bd 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1497,6 +1497,11 @@ void set_curbuf(buf_T *buf, int action) */ void enter_buffer(buf_T *buf) { + // Get the buffer in the current window. + curwin->w_buffer = buf; + curbuf = buf; + curbuf->b_nwindows++; + // Copy buffer and window local option values. Not for a help buffer. buf_copy_options(buf, BCO_ENTER | BCO_NOHELP); if (!buf->b_help) { @@ -1507,11 +1512,6 @@ void enter_buffer(buf_T *buf) } foldUpdateAll(curwin); // update folds (later). - // Get the buffer in the current window. - curwin->w_buffer = buf; - curbuf = buf; - curbuf->b_nwindows++; - if (curwin->w_p_diff) { diff_buf_add(curbuf); } -- cgit From 50250542c346473dd3a91ce63cd989033dae4471 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sat, 12 Feb 2022 17:12:09 +0000 Subject: refactor(signs): more efficient signcol calc When iterating signs to calculate the sign column, stop iterating when we reach the maximum configured from 'signcolumn'. --- src/nvim/buffer.c | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ee704bd1bd..38b045b31c 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5455,30 +5455,43 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp) return false; } -int buf_signcols(buf_T *buf) +static int buf_signcols_inner(buf_T *buf, int maximum) { - if (!buf->b_signcols_valid) { - sign_entry_T *sign; // a sign in the sign list - int signcols = 0; - int linesum = 0; - linenr_T curline = 0; - - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->se_lnum > curline) { - if (linesum > signcols) { - signcols = linesum; + sign_entry_T *sign; // a sign in the sign list + int signcols = 0; + int linesum = 0; + linenr_T curline = 0; + + FOR_ALL_SIGNS_IN_BUF(buf, sign) { + if (sign->se_lnum > curline) { + if (linesum > signcols) { + signcols = linesum; + if (signcols >= maximum) { + return maximum; } - curline = sign->se_lnum; - linesum = 0; - } - if (sign->se_has_text_or_icon) { - linesum++; } + curline = sign->se_lnum; + linesum = 0; + } + if (sign->se_has_text_or_icon) { + linesum++; } - if (linesum > signcols) { - signcols = linesum; + } + + if (linesum > signcols) { + signcols = linesum; + if (signcols >= maximum) { + return maximum; } + } + + return signcols; +} +int buf_signcols(buf_T *buf, int maximum) +{ + if (!buf->b_signcols_valid) { + int signcols = buf_signcols_inner(buf, maximum); // Check if we need to redraw if (signcols != buf->b_signcols) { buf->b_signcols = signcols; -- cgit From dcefd48c1b7023bb1dce25bf9f6cfce47edbe993 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 14 Feb 2022 18:56:30 +0800 Subject: vim-patch:8.2.0156: various typos in source files and tests Problem: Various typos in source files and tests. Solution: Fix the typos. (Emir Sari, closes vim/vim#5532) https://github.com/vim/vim/commit/4b96df5a017a04141c4e901b1fc5704a3ca48099 --- src/nvim/buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 38b045b31c..19e5bb69f3 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1441,7 +1441,7 @@ void set_curbuf(buf_T *buf, int action) set_bufref(&prevbufref, prevbuf); set_bufref(&newbufref, buf); - // Autocommands may delete the curren buffer and/or the buffer we want to go + // Autocommands may delete the current buffer and/or the buffer we want to go // to. In those cases don't close the buffer. if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf) || (bufref_valid(&prevbufref) && bufref_valid(&newbufref) @@ -1454,6 +1454,7 @@ void set_curbuf(buf_T *buf, int action) } if (bufref_valid(&prevbufref) && !aborting()) { win_T *previouswin = curwin; + // Do not sync when in Insert mode and the buffer is open in // another window, might be a timer doing something in another // window. -- cgit From 73cc729dbc156c5882e1db96b35913d4df48c7ba Mon Sep 17 00:00:00 2001 From: Sean Dewar Date: Sat, 19 Feb 2022 14:22:32 +0000 Subject: vim-patch:8.2.4419: illegal memory access when using 20 highlights Problem: Illegal memory access when using exactly 20 highlights. Solution: Add one more item in the array. (Brandon Richardson, closes vim/vim#9800) https://github.com/vim/vim/commit/a493b6506b67887a1cc2d1c00a896598c3b2d445 --- src/nvim/buffer.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 38b045b31c..aada11bc9e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3438,8 +3438,12 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (stl_items == NULL) { stl_items = xmalloc(sizeof(stl_item_t) * stl_items_len); stl_groupitems = xmalloc(sizeof(int) * stl_items_len); - stl_hltab = xmalloc(sizeof(stl_hlrec_t) * stl_items_len); - stl_tabtab = xmalloc(sizeof(StlClickRecord) * stl_items_len); + + // Allocate one more, because the last element is used to indicate the + // end of the list. + stl_hltab = xmalloc(sizeof(stl_hlrec_t) * (stl_items_len + 1)); + stl_tabtab = xmalloc(sizeof(StlClickRecord) * (stl_items_len + 1)); + stl_separator_locations = xmalloc(sizeof(int) * stl_items_len); } @@ -3514,8 +3518,8 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use stl_items = xrealloc(stl_items, sizeof(stl_item_t) * new_len); stl_groupitems = xrealloc(stl_groupitems, sizeof(int) * new_len); - stl_hltab = xrealloc(stl_hltab, sizeof(stl_hlrec_t) * new_len); - stl_tabtab = xrealloc(stl_tabtab, sizeof(StlClickRecord) * new_len); + stl_hltab = xrealloc(stl_hltab, sizeof(stl_hlrec_t) * (new_len + 1)); + stl_tabtab = xrealloc(stl_tabtab, sizeof(StlClickRecord) * (new_len + 1)); stl_separator_locations = xrealloc(stl_separator_locations, sizeof(int) * new_len); -- cgit From e67cd22c38493d4dff90f6afa17bfeacd0ba953d Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sun, 20 Feb 2022 17:26:39 +0000 Subject: fix(signcol): handle edge case with maximum value 50250542 failed to consider that the maximum passed to buf_signcols is window scoped whereas the signcols value is buffer scoped. This can lead to a bug where the signcolumn becomes incorrect if: - global signcolumn is set to auto:N - signcolumn in a window is changed locally to auto:M where M > N - the buffer has a line with M or greater signs. --- src/nvim/buffer.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index dd40623af2..9e82b4e80b 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5495,11 +5495,19 @@ static int buf_signcols_inner(buf_T *buf, int maximum) int buf_signcols(buf_T *buf, int maximum) { + // The maximum can be determined from 'signcolumn' which is window scoped so + // need to invalidate signcols if the maximum is greater than the previous + // maximum. + if (maximum > buf->b_signcols_max) { + buf->b_signcols_valid = false; + } + if (!buf->b_signcols_valid) { int signcols = buf_signcols_inner(buf, maximum); // Check if we need to redraw if (signcols != buf->b_signcols) { buf->b_signcols = signcols; + buf->b_signcols_max = maximum; redraw_buf_later(buf, NOT_VALID); } -- cgit From 30e4cc3b3f2133e9a7170da9da8175832681f39a Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Mon, 3 Jan 2022 12:22:13 +0000 Subject: feat(decorations): support signs Add the following options to extmarks: - sign_text - sign_hl_group - number_hl_group - line_hl_group - cursorline_hl_group Note: ranges are unsupported and decorations are only applied to start_row --- src/nvim/buffer.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 9e82b4e80b..084e18c6cb 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -36,6 +36,7 @@ #include "nvim/cursor.h" #include "nvim/diff.h" #include "nvim/digraph.h" +#include "nvim/decoration.h" #include "nvim/eval.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" @@ -5469,6 +5470,11 @@ static int buf_signcols_inner(buf_T *buf, int maximum) FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->se_lnum > curline) { + // Counted all signs, now add extmark signs + if (curline > 0) { + linesum += decor_signcols(buf, &decor_state, (int)curline-1, (int)curline-1, + maximum-linesum); + } if (linesum > signcols) { signcols = linesum; if (signcols >= maximum) { @@ -5483,6 +5489,19 @@ static int buf_signcols_inner(buf_T *buf, int maximum) } } + if (curline > 0) { + linesum += decor_signcols(buf, &decor_state, (int)curline-1, (int)curline-1, maximum-linesum); + } + if (linesum > signcols) { + signcols = linesum; + if (signcols >= maximum) { + return maximum; + } + } + + // Check extmarks between signs + linesum = decor_signcols(buf, &decor_state, 0, (int)buf->b_ml.ml_line_count-1, maximum); + if (linesum > signcols) { signcols = linesum; if (signcols >= maximum) { -- cgit From 8e7446b3cbc5c82706f41d701239fa18ab5b2808 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sun, 6 Mar 2022 21:45:26 +0000 Subject: refactor(signcol): smarter invalidation (#17533) Previously b_signcols was invalidated whenever a sign was added/removed or when a buffer line was added/removed. This change introduces a sentinel linenr_T into the buffer state which is a line number used to determine the signcolumn. With this information, we can invalidate the signcolumn less often. Now the signcolumn is only invalidated when a sign or line at the sentinel line number is removed. --- src/nvim/buffer.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 10 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 084e18c6cb..2bd14e2103 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1737,7 +1737,7 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl buf = xcalloc(1, sizeof(buf_T)); // init b: variables buf->b_vars = tv_dict_alloc(); - buf->b_signcols_valid = false; + buf->b_signcols.valid = false; init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE); buf_init_changedtick(buf); } @@ -5468,6 +5468,8 @@ static int buf_signcols_inner(buf_T *buf, int maximum) int linesum = 0; linenr_T curline = 0; + buf->b_signcols.sentinel = 0; + FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->se_lnum > curline) { // Counted all signs, now add extmark signs @@ -5475,13 +5477,14 @@ static int buf_signcols_inner(buf_T *buf, int maximum) linesum += decor_signcols(buf, &decor_state, (int)curline-1, (int)curline-1, maximum-linesum); } + curline = sign->se_lnum; if (linesum > signcols) { signcols = linesum; + buf->b_signcols.sentinel = curline; if (signcols >= maximum) { return maximum; } } - curline = sign->se_lnum; linesum = 0; } if (sign->se_has_text_or_icon) { @@ -5504,6 +5507,7 @@ static int buf_signcols_inner(buf_T *buf, int maximum) if (linesum > signcols) { signcols = linesum; + buf->b_signcols.sentinel = curline; if (signcols >= maximum) { return maximum; } @@ -5512,28 +5516,96 @@ static int buf_signcols_inner(buf_T *buf, int maximum) return signcols; } +/// Invalidate the signcolumn if needed after deleting +/// signs between line1 and line2 (inclusive). +/// +/// @param buf buffer to check +/// @param line1 start of region being deleted +/// @param line2 end of region being deleted +void buf_signcols_del_check(buf_T *buf, linenr_T line1, linenr_T line2) +{ + if (!buf->b_signcols.valid) { + return; + } + + if (!buf->b_signcols.sentinel) { + buf->b_signcols.valid = false; + return; + } + + linenr_T sent = buf->b_signcols.sentinel; + + if (sent >= line1 && sent <= line2) { + // Only invalidate when removing signs at the sentinel line. + buf->b_signcols.valid = false; + } +} + +/// Re-calculate the signcolumn after adding a sign. +/// +/// @param buf buffer to check +/// @param added sign being added +void buf_signcols_add_check(buf_T *buf, sign_entry_T *added) +{ + if (!buf->b_signcols.valid) { + return; + } + + if (!added || !buf->b_signcols.sentinel) { + buf->b_signcols.valid = false; + return; + } + + if (added->se_lnum == buf->b_signcols.sentinel) { + if (buf->b_signcols.size == buf->b_signcols.max) { + buf->b_signcols.max++; + } + buf->b_signcols.size++; + return; + } + + sign_entry_T *s; + + // Get first sign for added lnum + for (s = added; s->se_prev && s->se_lnum == s->se_prev->se_lnum; s = s->se_prev) {} + + // Count signs for lnum + int linesum = 1; + for (; s->se_next && s->se_lnum == s->se_next->se_lnum; s = s->se_next) { + linesum++; + } + linesum += decor_signcols(buf, &decor_state, (int)s->se_lnum-1, (int)s->se_lnum-1, + SIGN_SHOW_MAX-linesum); + + if (linesum > buf->b_signcols.size) { + buf->b_signcols.size = linesum; + buf->b_signcols.max = linesum; + buf->b_signcols.sentinel = added->se_lnum; + } +} + int buf_signcols(buf_T *buf, int maximum) { // The maximum can be determined from 'signcolumn' which is window scoped so // need to invalidate signcols if the maximum is greater than the previous // maximum. - if (maximum > buf->b_signcols_max) { - buf->b_signcols_valid = false; + if (maximum > buf->b_signcols.max) { + buf->b_signcols.valid = false; } - if (!buf->b_signcols_valid) { + if (!buf->b_signcols.valid) { int signcols = buf_signcols_inner(buf, maximum); // Check if we need to redraw - if (signcols != buf->b_signcols) { - buf->b_signcols = signcols; - buf->b_signcols_max = maximum; + if (signcols != buf->b_signcols.size) { + buf->b_signcols.size = signcols; + buf->b_signcols.max = maximum; redraw_buf_later(buf, NOT_VALID); } - buf->b_signcols_valid = true; + buf->b_signcols.valid = true; } - return buf->b_signcols; + return buf->b_signcols.size; } // Get "buf->b_fname", use "[No Name]" if it is NULL. -- cgit From 9ff4acbb36c8a914b48b85e345ddb11cc01277ac Mon Sep 17 00:00:00 2001 From: Dundar Göc Date: Thu, 10 Mar 2022 17:34:41 +0100 Subject: refactor: fix all clint warnings from buffer.c --- src/nvim/buffer.c | 437 ++++++++++++++++++++++-------------------------------- 1 file changed, 179 insertions(+), 258 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 2bd14e2103..2e2459aecf 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -34,9 +34,9 @@ #include "nvim/channel.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/decoration.h" #include "nvim/diff.h" #include "nvim/digraph.h" -#include "nvim/decoration.h" #include "nvim/eval.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" @@ -223,7 +223,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) || (S_ISCHR(perm) && is_dev_fd_file(curbuf->b_ffname)) # endif - )) { + )) { // NOLINT(whitespace/parens) read_fifo = true; } if (read_fifo) { @@ -401,7 +401,7 @@ bool buf_valid(buf_T *buf) /// there to be only one window with this buffer. e.g. when /// ":quit" is supposed to close the window but autocommands /// close all other windows. -/// @returns true when we got to the end and b_nwindows was decremented. +/// @return true when we got to the end and b_nwindows was decremented. bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) { bool unload_buf = (action != 0); @@ -587,9 +587,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) // No need to check `unload_buf`: in that case the function returned above. buf_updates_unload(buf, false); - /* - * Remove the buffer from the list. - */ + // Remove the buffer from the list. if (wipe_buf) { if (buf->b_sfname != buf->b_ffname) { XFREE_CLEAR(buf->b_sfname); @@ -737,10 +735,8 @@ void buf_freeall(buf_T *buf, int flags) buf->b_flags &= ~BF_READERR; // a read error is no longer relevant } -/* - * Free a buffer structure and the things it contains related to the buffer - * itself (not the file, that must have been done already). - */ +/// Free a buffer structure and the things it contains related to the buffer +/// itself (not the file, that must have been done already). static void free_buffer(buf_T *buf) { pmap_del(handle_T)(&buffer_handles, buf->b_fnum); @@ -813,9 +809,7 @@ static void free_buffer_stuff(buf_T *buf, int free_flags) buf_updates_unload(buf, false); } -/* - * Free the b_wininfo list for buffer "buf". - */ +/// Free the b_wininfo list for buffer "buf". static void clear_wininfo(buf_T *buf) { wininfo_T *wip; @@ -827,9 +821,7 @@ static void clear_wininfo(buf_T *buf) } } -/* - * Go to another buffer. Handles the result of the ATTENTION dialog. - */ +/// Go to another buffer. Handles the result of the ATTENTION dialog. void goto_buffer(exarg_T *eap, int start, int dir, int count) { bufref_T old_curbuf; @@ -1033,10 +1025,8 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end } -/* - * Make the current buffer empty. - * Used when it is wiped out and it's the last buffer. - */ +/// Make the current buffer empty. +/// Used when it is wiped out and it's the last buffer. static int empty_curbuf(int close_others, int forceit, int action) { int retval; @@ -1410,15 +1400,15 @@ int do_buffer(int action, int start, int dir, int count, int forceit) } -/* - * Set current buffer to "buf". Executes autocommands and closes current - * buffer. "action" tells how to close the current buffer: - * DOBUF_GOTO free or hide it - * DOBUF_SPLIT nothing - * DOBUF_UNLOAD unload it - * DOBUF_DEL delete it - * DOBUF_WIPE wipe it out - */ +/// Set current buffer to "buf". Executes autocommands and closes current +/// buffer. +/// +/// @param action tells how to close the current buffer: +/// DOBUF_GOTO free or hide it +/// DOBUF_SPLIT nothing +/// DOBUF_UNLOAD unload it +/// DOBUF_DEL delete it +/// DOBUF_WIPE wipe it out void set_curbuf(buf_T *buf, int action) { buf_T *prevbuf; @@ -1478,9 +1468,7 @@ void set_curbuf(buf_T *buf, int action) // An autocommand may have deleted "buf", already entered it (e.g., when // it did ":bunload") or aborted the script processing! // If curwin->w_buffer is null, enter_buffer() will make it valid again - if ((buf_valid(buf) && buf != curbuf - && !aborting() - ) || curwin->w_buffer == NULL) { + if ((buf_valid(buf) && buf != curbuf && !aborting()) || curwin->w_buffer == NULL) { enter_buffer(buf); if (old_tw != curbuf->b_p_tw) { check_colorcolumn(curwin); @@ -1492,11 +1480,9 @@ void set_curbuf(buf_T *buf, int action) } } -/* - * Enter a new current buffer. - * Old curbuf must have been abandoned already! This also means "curbuf" may - * be pointing to freed memory. - */ +/// Enter a new current buffer. +/// Old curbuf must have been abandoned already! This also means "curbuf" may +/// be pointing to freed memory. void enter_buffer(buf_T *buf) { // Get the buffer in the current window. @@ -1583,8 +1569,8 @@ void enter_buffer(buf_T *buf) redraw_later(curwin, NOT_VALID); } -// Change to the directory of the current buffer. -// Don't do this while still starting up. +/// Change to the directory of the current buffer. +/// Don't do this while still starting up. void do_autochdir(void) { if (p_acd) { @@ -1661,7 +1647,7 @@ static inline void buf_init_changedtick(buf_T *const buf) /// @param flags BLN_ defines /// @param bufnr /// -/// @return pointer to the buffer +/// @return pointer to the buffer buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int flags) { char_u *ffname = ffname_arg; @@ -1703,14 +1689,12 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl return buf; } - /* - * If the current buffer has no name and no contents, use the current - * buffer. Otherwise: Need to allocate a new buffer structure. - * - * This is the ONLY place where a new buffer structure is allocated! - * (A spell file buffer is allocated in spell.c, but that's not a normal - * buffer.) - */ + // If the current buffer has no name and no contents, use the current + // buffer. Otherwise: Need to allocate a new buffer structure. + // + // This is the ONLY place where a new buffer structure is allocated! + // (A spell file buffer is allocated in spell.c, but that's not a normal + // buffer.) buf = NULL; if ((flags & BLN_CURBUF) && curbuf_reusable()) { assert(curbuf != NULL); @@ -1781,9 +1765,7 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl // need to reload lmaps and set b:keymap_name curbuf->b_kmap_state |= KEYMAP_INIT; } else { - /* - * put new buffer at the end of the buffer list - */ + // put new buffer at the end of the buffer list buf->b_next = NULL; if (firstbuf == NULL) { // buffer list is empty buf->b_prev = NULL; @@ -1875,11 +1857,9 @@ bool curbuf_reusable(void) && !curbufIsChanged()); } -/* - * Free the memory for the options of a buffer. - * If "free_p_ff" is true also free 'fileformat', 'buftype' and - * 'fileencoding'. - */ +/// Free the memory for the options of a buffer. +/// If "free_p_ff" is true also free 'fileformat', 'buftype' and +/// 'fileencoding'. void free_buf_options(buf_T *buf, int free_p_ff) { if (free_p_ff) { @@ -2039,7 +2019,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) return FAIL; } -// Go to the last known line number for the current buffer. +/// Go to the last known line number for the current buffer. void buflist_getfpos(void) { pos_T *fpos; @@ -2059,10 +2039,9 @@ void buflist_getfpos(void) } } -/* - * Find file in buffer list by name (it has to be for the current window). - * Returns NULL if not found. - */ +/// Find file in buffer list by name (it has to be for the current window). +/// +/// @return buffer or NULL if not found buf_T *buflist_findname_exp(char_u *fname) { char_u *ffname; @@ -2076,7 +2055,7 @@ buf_T *buflist_findname_exp(char_u *fname) #else false #endif - ); + ); // NOLINT(whitespace/parens) if (ffname != NULL) { buf = buflist_findname(ffname); xfree(ffname); @@ -2084,12 +2063,11 @@ buf_T *buflist_findname_exp(char_u *fname) return buf; } -/* - * Find file in buffer list by name (it has to be for the current window). - * "ffname" must have a full path. - * Skips dummy buffers. - * Returns NULL if not found. - */ +/// Find file in buffer list by name (it has to be for the current window). +/// "ffname" must have a full path. +/// Skips dummy buffers. +/// +/// @return buffer or NULL if not found buf_T *buflist_findname(char_u *ffname) { FileID file_id; @@ -2097,11 +2075,10 @@ buf_T *buflist_findname(char_u *ffname) return buflist_findname_file_id(ffname, &file_id, file_id_valid); } -/* - * Same as buflist_findname(), but pass the FileID structure to avoid - * getting it twice for the same file. - * Returns NULL if not found. - */ +/// Same as buflist_findname(), but pass the FileID structure to avoid +/// getting it twice for the same file. +/// +/// @return buffer or NULL if not found static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id, bool file_id_valid) { // Start at the last buffer, expect to find a match sooner. @@ -2115,13 +2092,13 @@ static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id, bool fil } /// Find file in buffer list by a regexp pattern. -/// Return fnum of the found buffer. -/// Return < 0 for error. /// /// @param pattern_end pointer to first char after pattern /// @param unlisted find unlisted buffers /// @param diffmode find diff-mode buffers only /// @param curtab_only find buffers in current tab only +/// +/// @return fnum of the found buffer or < 0 for error. int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlisted, bool diffmode, bool curtab_only) FUNC_ATTR_NONNULL_ARG(1) @@ -2145,7 +2122,6 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlis match = -1; } } else { - // // Try four ways of matching a listed buffer: // attempt == 0: without '^' or '$' (at any position) // attempt == 1: with '^' at start (only at position 0) @@ -2153,7 +2129,6 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlis // attempt == 3: with '^' at start and '$' at end (only full match) // Repeat this for finding an unlisted buffer if there was no matching // listed buffer. - // pat = file_pat_to_reg_pat(pattern, pattern_end, NULL, false); if (pat == NULL) { @@ -2251,11 +2226,10 @@ static int buf_time_compare(const void *s1, const void *s2) return buf1->b_last_used > buf2->b_last_used ? -1 : 1; } -/* - * Find all buffer names that match. - * For command line expansion of ":buf" and ":sbuf". - * Return OK if matches found, FAIL otherwise. - */ +/// Find all buffer names that match. +/// For command line expansion of ":buf" and ":sbuf". +/// +/// @return OK if matches found, FAIL otherwise. int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) { int count = 0; @@ -2379,7 +2353,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) /// Check for a match on the file name for buffer "buf" with regprog "prog". /// -/// @param ignore_case When true, ignore case. Use 'fic' otherwise. +/// @param ignore_case When true, ignore case. Use 'fic' otherwise. static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) { // First try the short file name, then the long file name. @@ -2392,8 +2366,9 @@ static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) /// Try matching the regexp in "prog" with file name "name". /// -/// @param ignore_case When true, ignore case. Use 'fileignorecase' otherwise. -/// @return "name" when there is a match, NULL when not. +/// @param ignore_case When true, ignore case. Use 'fileignorecase' otherwise. +/// +/// @return "name" when there is a match, NULL when not. static char_u *fname_match(regmatch_T *rmp, char_u *name, bool ignore_case) { char_u *match = NULL; @@ -2528,12 +2503,13 @@ static bool wininfo_other_tab_diff(wininfo_T *wip) return false; } -// Find info for the current window in buffer "buf". -// If not found, return the info for the most recently used window. -// When "need_options" is true skip entries where wi_optset is false. -// When "skip_diff_buffer" is true avoid windows with 'diff' set that is in -// another tab page. -// Returns NULL when there isn't any info. +/// Find info for the current window in buffer "buf". +/// If not found, return the info for the most recently used window. +/// +/// @param need_options when true, skip entries where wi_optset is false. +/// @param skip_diff_buffer when true, avoid windows with 'diff' set that is in another tab page. +/// +/// @return NULL when there isn't any info. static wininfo_T *find_wininfo(buf_T *buf, bool need_options, bool skip_diff_buffer) FUNC_ATTR_NONNULL_ALL { @@ -2570,12 +2546,10 @@ static wininfo_T *find_wininfo(buf_T *buf, bool need_options, bool skip_diff_buf return wip; } -/* - * Reset the local window options to the values last used in this window. - * If the buffer wasn't used in this window before, use the values from - * the most recently used window. If the values were never set, use the - * global values for the window. - */ +/// Reset the local window options to the values last used in this window. +/// If the buffer wasn't used in this window before, use the values from +/// the most recently used window. If the values were never set, use the +/// global values for the window. void get_winopts(buf_T *buf) { clear_winopt(&curwin->w_onebuf_opt); @@ -2610,11 +2584,10 @@ void get_winopts(buf_T *buf) didset_window_options(curwin); } -/* - * Find the position (lnum and col) for the buffer 'buf' for the current - * window. - * Returns a pointer to no_position if no position is found. - */ +/// Find the position (lnum and col) for the buffer 'buf' for the current +/// window. +/// +/// @return a pointer to no_position if no position is found. pos_T *buflist_findfpos(buf_T *buf) { static pos_T no_position = { 1, 0, 0 }; @@ -2623,15 +2596,13 @@ pos_T *buflist_findfpos(buf_T *buf) return (wip == NULL) ? &no_position : &(wip->wi_fpos); } -/* - * Find the lnum for the buffer 'buf' for the current window. - */ +/// Find the lnum for the buffer 'buf' for the current window. linenr_T buflist_findlnum(buf_T *buf) { return buflist_findfpos(buf)->lnum; } -// List all known file names (for :files and :buffers command). +/// List all known file names (for :files and :buffers command). void buflist_list(exarg_T *eap) { buf_T *buf = firstbuf; @@ -2659,8 +2630,7 @@ void buflist_list(exarg_T *eap) for (; buf != NULL && !got_int; buf = buflist_data != NULL - ? (++p < buflist_data + buflist.ga_len ? *p : NULL) - : buf->b_next) { + ? (++p < buflist_data + buflist.ga_len ? *p : NULL) : buf->b_next) { const bool is_terminal = buf->terminal; const bool job_running = buf->terminal && terminal_running(buf->terminal); @@ -2723,10 +2693,8 @@ void buflist_list(exarg_T *eap) if (vim_strchr(eap->arg, 't') && buf->b_last_used) { undo_fmt_time(IObuff + len, (size_t)(IOSIZE - len), buf->b_last_used); } else { - vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), - _("line %" PRId64), - buf == curbuf ? (int64_t)curwin->w_cursor.lnum - : (int64_t)buflist_findlnum(buf)); + vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), _("line %" PRId64), + buf == curbuf ? (int64_t)curwin->w_cursor.lnum : (int64_t)buflist_findlnum(buf)); } msg_outtrans(IObuff); @@ -2738,12 +2706,11 @@ void buflist_list(exarg_T *eap) } } -/* - * Get file name and line number for file 'fnum'. - * Used by DoOneCmd() for translating '%' and '#'. - * Used by insert_reg() and cmdline_paste() for '#' register. - * Return FAIL if not found, OK for success. - */ +/// Get file name and line number for file 'fnum'. +/// Used by DoOneCmd() for translating '%' and '#'. +/// Used by insert_reg() and cmdline_paste() for '#' register. +/// +/// @return FAIL if not found, OK for success. int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum) { buf_T *buf; @@ -2829,10 +2796,8 @@ int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) return OK; } -/* - * Crude way of changing the name of a buffer. Use with care! - * The name should be relative to the current directory. - */ +/// Crude way of changing the name of a buffer. Use with care! +/// The name should be relative to the current directory. void buf_set_name(int fnum, char_u *name) { buf_T *buf; @@ -2852,15 +2817,10 @@ void buf_set_name(int fnum, char_u *name) } } -/* - * Take care of what needs to be done when the name of buffer "buf" has - * changed. - */ +/// Take care of what needs to be done when the name of buffer "buf" has changed. void buf_name_changed(buf_T *buf) { - /* - * If the file name changed, also change the name of the swapfile - */ + // If the file name changed, also change the name of the swapfile if (buf->b_ml.ml_mfp != NULL) { ml_setname(buf); } @@ -2874,12 +2834,11 @@ void buf_name_changed(buf_T *buf) ml_timestamp(buf); // reset timestamp } -/* - * set alternate file name for current window - * - * Used by do_one_cmd(), do_write() and do_ecmd(). - * Return the buffer. - */ +/// Set alternate file name for current window +/// +/// Used by do_one_cmd(), do_write() and do_ecmd(). +/// +/// @return the buffer. buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum) { buf_T *buf; @@ -2910,12 +2869,10 @@ char_u *getaltfname(bool errmsg) return fname; } -/* - * Add a file name to the buflist and return its number. - * Uses same flags as buflist_new(), except BLN_DUMMY. - * - * used by qf_init(), main() and doarglist() - */ +/// Add a file name to the buflist and return its number. +/// Uses same flags as buflist_new(), except BLN_DUMMY. +/// +/// Used by qf_init(), main() and doarglist() int buflist_add(char_u *fname, int flags) { buf_T *buf; @@ -2928,9 +2885,7 @@ int buflist_add(char_u *fname, int flags) } #if defined(BACKSLASH_IN_FILENAME) -/* - * Adjust slashes in file names. Called after 'shellslash' was set. - */ +/// Adjust slashes in file names. Called after 'shellslash' was set. void buflist_slash_adjust(void) { FOR_ALL_BUFFERS(bp) { @@ -2945,10 +2900,8 @@ void buflist_slash_adjust(void) #endif -/* - * Set alternate cursor position for the current buffer and window "win". - * Also save the local window option values. - */ +/// Set alternate cursor position for the current buffer and window "win". +/// Also save the local window option values. void buflist_altfpos(win_T *win) { buflist_setfpos(curbuf, win, win->w_cursor.lnum, win->w_cursor.col, true); @@ -3011,8 +2964,8 @@ static bool otherfile_buf(buf_T *buf, char_u *ffname, FileID *file_id_p, bool fi return true; } -// Set file_id for a buffer. -// Must always be called when b_fname is changed! +/// Set file_id for a buffer. +/// Must always be called when b_fname is changed! void buf_set_file_id(buf_T *buf) { FileID file_id; @@ -3152,7 +3105,7 @@ static char_u *lasttitle = NULL; static char_u *lasticon = NULL; -// Put the title name in the title bar and icon of the window. +/// Put the title name in the title bar and icon of the window. void maketitle(void) { char_u *title_str = NULL; @@ -3350,8 +3303,8 @@ void maketitle(void) /// /// @param str desired title string /// @param[in,out] last current title string -// -/// @return true if resettitle() is to be called. +/// +/// @return true if resettitle() is to be called. static bool value_change(char_u *str, char_u **last) FUNC_ATTR_WARN_UNUSED_RESULT { @@ -3408,18 +3361,18 @@ typedef enum { /// If maxwidth is not zero, the string will be filled at any middle marker /// or truncated if too long, fillchar is used for all whitespace. /// -/// @param wp The window to build a statusline for -/// @param out The output buffer to write the statusline to -/// Note: This should not be NameBuff -/// @param outlen The length of the output buffer -/// @param fmt The statusline format string -/// @param use_sandbox Use a sandboxed environment when evaluating fmt -/// @param fillchar Character to use when filling empty space in the statusline -/// @param maxwidth The maximum width to make the statusline -/// @param hltab HL attributes (can be NULL) -/// @param tabtab Tab clicks definition (can be NULL). +/// @param wp The window to build a statusline for +/// @param out The output buffer to write the statusline to +/// Note: This should not be NameBuff +/// @param outlen The length of the output buffer +/// @param fmt The statusline format string +/// @param use_sandbox Use a sandboxed environment when evaluating fmt +/// @param fillchar Character to use when filling empty space in the statusline +/// @param maxwidth The maximum width to make the statusline +/// @param hltab HL attributes (can be NULL) +/// @param tabtab Tab clicks definition (can be NULL). /// -/// @return The final width of the statusline +/// @return The final width of the statusline int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use_sandbox, int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab) { @@ -3681,8 +3634,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } } // If the group is shorter than the minimum width, add padding characters. - } else if ( - abs(stl_items[stl_groupitems[groupdepth]].minwid) > group_len) { + } else if (abs(stl_items[stl_groupitems[groupdepth]].minwid) > group_len) { long min_group_width = stl_items[stl_groupitems[groupdepth]].minwid; // If the group is left-aligned, add characters to the right. if (min_group_width < 0) { @@ -4508,7 +4460,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use char_u *start = stl_items[stl_separator_locations[i]].start; char_u *seploc = start + dislocation; STRMOVE(seploc, start); - for (char_u *s = start; s < seploc; ) { + for (char_u *s = start; s < seploc;) { MB_CHAR2BYTES(fillchar, s); } @@ -4582,12 +4534,10 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } return width; -} +} // NOLINT(readability/fn_size) -/* - * Get relative cursor position in window into "buf[buflen]", in the form 99%, - * using "Top", "Bot" or "All" when appropriate. - */ +/// Get relative cursor position in window into "buf[buflen]", in the form 99%, +/// using "Top", "Bot" or "All" when appropriate. void get_rel_pos(win_T *wp, char_u *buf, int buflen) { // Need at least 3 chars for writing. @@ -4624,7 +4574,7 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen) /// @param buflen length of the string buffer /// @param add_file if true, add "file" before the arg number /// -/// @return true if it was appended. +/// @return true if it was appended. static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) FUNC_ATTR_NONNULL_ALL { @@ -4653,12 +4603,12 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) return true; } -// Make "*ffname" a full file name, set "*sfname" to "*ffname" if not NULL. -// "*ffname" becomes a pointer to allocated memory (or NULL). -// When resolving a link both "*sfname" and "*ffname" will point to the same -// allocated memory. -// The "*ffname" and "*sfname" pointer values on call will not be freed. -// Note that the resulting "*ffname" pointer should be considered not allocated. +/// Make "*ffname" a full file name, set "*sfname" to "*ffname" if not NULL. +/// "*ffname" becomes a pointer to allocated memory (or NULL). +/// When resolving a link both "*sfname" and "*ffname" will point to the same +/// allocated memory. +/// The "*ffname" and "*sfname" pointer values on call will not be freed. +/// Note that the resulting "*ffname" pointer should be considered not allocated. void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) { if (*ffname == NULL) { // no file name given, nothing to do @@ -4682,9 +4632,7 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) #endif } -/* - * Get the file name for an argument list entry. - */ +/// Get the file name for an argument list entry. char_u *alist_name(aentry_T *aep) { buf_T *bp; @@ -4726,8 +4674,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) assert(firstwin != NULL); // satisfy coverity if (ARGCOUNT <= 0) { - /* Don't give an error message. We don't want it when the ":all" - * command is in the .vimrc. */ + // Don't give an error message. We don't want it when the ":all" command is in the .vimrc. return; } setpcmark(); @@ -4735,9 +4682,9 @@ void do_arg_all(int count, int forceit, int keep_tabs) opened_len = ARGCOUNT; opened = xcalloc((size_t)opened_len, 1); - /* Autocommands may do anything to the argument list. Make sure it's not - * freed while we are working here by "locking" it. We still have to - * watch out for its size to be changed. */ + // Autocommands may do anything to the argument list. Make sure it's not + // freed while we are working here by "locking" it. We still have to + // watch out for its size to be changed. alist = curwin->w_alist; alist->al_refcount++; @@ -4745,13 +4692,11 @@ void do_arg_all(int count, int forceit, int keep_tabs) old_curtab = curtab; - /* - * Try closing all windows that are not in the argument list. - * Also close windows that are not full width; - * When 'hidden' or "forceit" set the buffer becomes hidden. - * Windows that have a changed buffer and can't be hidden won't be closed. - * When the ":tab" modifier was used do this for all tab pages. - */ + // Try closing all windows that are not in the argument list. + // Also close windows that are not full width; + // When 'hidden' or "forceit" set the buffer becomes hidden. + // Windows that have a changed buffer and can't be hidden won't be closed. + // When the ":tab" modifier was used do this for all tab pages. if (had_tab > 0) { goto_tabpage_tp(first_tabpage, true, true); } @@ -4796,8 +4741,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) } if (wp->w_alist != alist) { - /* Use the current argument list for all windows - * containing a file from it. */ + // Use the current argument list for all windows containing a file from it. alist_unlink(wp->w_alist); wp->w_alist = alist; wp->w_alist->al_refcount++; @@ -4811,8 +4755,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) if (i == opened_len && !keep_tabs) { // close this window if (buf_hide(buf) || forceit || buf->b_nwindows > 1 || !bufIsChanged(buf)) { - /* If the buffer was changed, and we would like to hide it, - * try autowriting. */ + // If the buffer was changed, and we would like to hide it, try autowriting. if (!buf_hide(buf) && buf->b_nwindows <= 1 && bufIsChanged(buf)) { bufref_T bufref; set_bufref(&bufref, buf); @@ -4851,10 +4794,8 @@ void do_arg_all(int count, int forceit, int keep_tabs) goto_tabpage_tp(tpnext, true, true); } - /* - * Open a window for files in the argument list that don't have one. - * ARGCOUNT may change while doing this, because of autocommands. - */ + // Open a window for files in the argument list that don't have one. + // ARGCOUNT may change while doing this, because of autocommands. if (count > opened_len || count <= 0) { count = opened_len; } @@ -4909,9 +4850,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) autocmd_no_leave--; } - /* - * edit file "i" - */ + // edit file "i" curwin->w_arg_idx = i; if (i == 0) { new_curwin = curwin; @@ -4963,15 +4902,13 @@ void do_arg_all(int count, int forceit, int keep_tabs) xfree(opened); } -/// @return true if "buf" is a prompt buffer. +/// @return true if "buf" is a prompt buffer. bool bt_prompt(buf_T *buf) { return buf != NULL && buf->b_p_bt[0] == 'p'; } -/* - * Open a window for a number of buffers. - */ +/// Open a window for a number of buffers. void ex_buffer_all(exarg_T *eap) { buf_T *buf; @@ -4999,10 +4936,8 @@ void ex_buffer_all(exarg_T *eap) setpcmark(); - /* - * Close superfluous windows (two windows for the same buffer). - * Also close windows that are not full-width. - */ + // Close superfluous windows (two windows for the same buffer). + // Also close windows that are not full-width. if (had_tab > 0) { goto_tabpage_tp(first_tabpage, true, true); } @@ -5036,7 +4971,6 @@ void ex_buffer_all(exarg_T *eap) goto_tabpage_tp(tpnext, true, true); } - // // Go through the buffer list. When a buffer doesn't have a window yet, // open one. Otherwise move the window to the right position. // Watch out for autocommands that delete buffers or windows! @@ -5132,9 +5066,7 @@ void ex_buffer_all(exarg_T *eap) win_enter(firstwin, false); // back to first window autocmd_no_leave--; - /* - * Close superfluous windows. - */ + // Close superfluous windows. for (wp = lastwin; open_wins > count;) { r = (buf_hide(wp->w_buffer) || !bufIsChanged(wp->w_buffer) || autowrite(wp->w_buffer, false) == OK); @@ -5155,15 +5087,13 @@ void ex_buffer_all(exarg_T *eap) } -/* - * do_modelines() - process mode lines for the current file - * - * "flags" can be: - * OPT_WINONLY only set options local to window - * OPT_NOWIN don't set options local to window - * - * Returns immediately if the "ml" option isn't set. - */ +/// do_modelines() - process mode lines for the current file +/// +/// @param flags +/// OPT_WINONLY only set options local to window +/// OPT_NOWIN don't set options local to window +/// +/// Returns immediately if the "ml" option isn't set. void do_modelines(int flags) { linenr_T lnum; @@ -5269,10 +5199,8 @@ static int chk_modeline(linenr_T lnum, int flags) break; } - /* - * Find end of set command: ':' or end of line. - * Skip over "\:", replacing it with ":". - */ + // Find end of set command: ':' or end of line. + // Skip over "\:", replacing it with ":". for (e = s; *e != ':' && *e != NUL; e++) { if (e[0] == '\\' && e[1] == ':') { STRMOVE(e, e + 1); @@ -5282,13 +5210,11 @@ static int chk_modeline(linenr_T lnum, int flags) end = true; } - /* - * If there is a "set" command, require a terminating ':' and - * ignore the stuff after the ':'. - * "vi:set opt opt opt: foo" -- foo not interpreted - * "vi:opt opt opt: foo" -- foo interpreted - * Accept "se" for compatibility with Elvis. - */ + // If there is a "set" command, require a terminating ':' and + // ignore the stuff after the ':'. + // "vi:set opt opt opt: foo" -- foo not interpreted + // "vi:opt opt opt: foo" -- foo interpreted + // Accept "se" for compatibility with Elvis. if (STRNCMP(s, "set ", (size_t)4) == 0 || STRNCMP(s, "se ", (size_t)3) == 0) { if (*e != ':') { // no terminating ':'? @@ -5327,36 +5253,36 @@ static int chk_modeline(linenr_T lnum, int flags) return retval; } -// Return true if "buf" is a help buffer. +/// @return true if "buf" is a help buffer. bool bt_help(const buf_T *const buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return buf != NULL && buf->b_help; } -// Return true if "buf" is a normal buffer, 'buftype' is empty. +/// @return true if "buf" is a normal buffer, 'buftype' is empty. bool bt_normal(const buf_T *const buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return buf != NULL && buf->b_p_bt[0] == NUL; } -// Return true if "buf" is the quickfix buffer. +/// @return true if "buf" is the quickfix buffer. bool bt_quickfix(const buf_T *const buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return buf != NULL && buf->b_p_bt[0] == 'q'; } -// Return true if "buf" is a terminal buffer. +/// @return true if "buf" is a terminal buffer. bool bt_terminal(const buf_T *const buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return buf != NULL && buf->b_p_bt[0] == 't'; } -// Return true if "buf" is a "nofile", "acwrite", "terminal" or "prompt" -// buffer. This means the buffer name is not a file name. +/// @return true if "buf" is a "nofile", "acwrite", "terminal" or "prompt" / +/// buffer. This means the buffer name is not a file name. bool bt_nofile(const buf_T *const buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { @@ -5366,8 +5292,8 @@ bool bt_nofile(const buf_T *const buf) || buf->b_p_bt[0] == 'p'); } -// Return true if "buf" is a "nowrite", "nofile", "terminal" or "prompt" -// buffer. +/// @return true if "buf" is a "nowrite", "nofile", "terminal" or "prompt" +/// buffer. bool bt_dontwrite(const buf_T *const buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { @@ -5386,8 +5312,8 @@ bool bt_dontwrite_msg(const buf_T *const buf) return false; } -// Return true if the buffer should be hidden, according to 'hidden', ":hide" -// and 'bufhidden'. +/// @return true if the buffer should be hidden, according to 'hidden', ":hide" +/// and 'bufhidden'. bool buf_hide(const buf_T *const buf) { // 'bufhidden' overrules 'hidden' and ":hide", check it first @@ -5402,10 +5328,8 @@ bool buf_hide(const buf_T *const buf) return p_hid || cmdmod.hide; } -/* - * Return special buffer name. - * Returns NULL when the buffer has a normal file name. - */ +/// @return special buffer name or +/// NULL when the buffer has a normal file name. char_u *buf_spname(buf_T *buf) { if (bt_quickfix(buf)) { @@ -5446,7 +5370,7 @@ char_u *buf_spname(buf_T *buf) /// @param[out] wp stores the found window /// @param[out] tp stores the found tabpage /// -/// @return true if a window was found for the buffer. +/// @return true if a window was found for the buffer. bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp) { *wp = NULL; @@ -5608,7 +5532,7 @@ int buf_signcols(buf_T *buf, int maximum) return buf->b_signcols.size; } -// Get "buf->b_fname", use "[No Name]" if it is NULL. +/// Get "buf->b_fname", use "[No Name]" if it is NULL. char_u *buf_get_fname(const buf_T *buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { @@ -5618,9 +5542,7 @@ char_u *buf_get_fname(const buf_T *buf) return buf->b_fname; } -/* - * Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed. - */ +/// Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed. void set_buflisted(int on) { if (on != curbuf->b_p_bl) { @@ -5638,7 +5560,7 @@ void set_buflisted(int on) /// /// @param buf buffer to check /// -/// @return true if the buffer's contents have changed +/// @return true if the buffer's contents have changed bool buf_contents_changed(buf_T *buf) FUNC_ATTR_NONNULL_ALL { @@ -5719,4 +5641,3 @@ void buf_open_scratch(handle_T bufnr, char *bufname) set_option_value("swf", 0L, NULL, OPT_LOCAL); RESET_BINDING(curwin); } - -- cgit From 8ba8f1a01808c881a32dd8936bb8fb26c9fbd4e8 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sat, 12 Mar 2022 16:25:21 +0000 Subject: fix(signcol): always trigger a redraw Whenever we change the size of the buffer signcol value, always trigger a redraw. Fixes: #17693 --- src/nvim/buffer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 2e2459aecf..402bd2c6de 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5485,6 +5485,7 @@ void buf_signcols_add_check(buf_T *buf, sign_entry_T *added) buf->b_signcols.max++; } buf->b_signcols.size++; + redraw_buf_later(buf, NOT_VALID); return; } @@ -5505,6 +5506,7 @@ void buf_signcols_add_check(buf_T *buf, sign_entry_T *added) buf->b_signcols.size = linesum; buf->b_signcols.max = linesum; buf->b_signcols.sentinel = added->se_lnum; + redraw_buf_later(buf, NOT_VALID); } } -- cgit From 91ac0088e1a8bdf189bf96066eb8e0d8e632ceac Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 10 Oct 2020 13:11:34 -0400 Subject: vim-patch:8.1.0877: new buffer used every time the quickfix window is opened Problem: New buffer used every time the quickfix window is opened. Solution: Reuse the buffer. (Yegappan Lakshmanan, closes vim/vim#3902) https://github.com/vim/vim/commit/ee8188fc74a7cf9ee7acb634b2bb7a032d0cb24c --- src/nvim/buffer.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 2e2459aecf..3fdc111b6f 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5333,16 +5333,12 @@ bool buf_hide(const buf_T *const buf) char_u *buf_spname(buf_T *buf) { if (bt_quickfix(buf)) { - win_T *win; - tabpage_T *tp; - - // For location list window, w_llist_ref points to the location list. - // For quickfix window, w_llist_ref is NULL. - if (find_win_for_buf(buf, &win, &tp) && win->w_llist_ref != NULL) { - return (char_u *)_(msg_loclist); - } else { + // Differentiate between the quickfix and location list buffers using + // the buffer number stored in the global quickfix stack. + if (buf->b_fnum == qf_stack_get_bufnr()) { return (char_u *)_(msg_qflist); } + return (char_u *)_(msg_loclist); } // There is no _file_ when 'buftype' is "nofile", b_sfname // contains the name as specified by the user. -- cgit From 5ab122917474b3f9e88be4ee88bc6d627980cfe0 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Sun, 30 Jan 2022 11:57:41 +0600 Subject: feat: add support for global statusline Ref: #9342 Adds the option to have a single global statusline for the current window at the bottom of the screen instead of a statusline at the bottom of every window. Enabled by setting `laststatus = 3`. Due to the fact that statuslines at the bottom of windows are removed when global statusline is enabled, horizontal separators are used instead to separate horizontal splits. The horizontal separator character is configurable through the`horiz` item in `'fillchars'`. Separator connector characters are also used to connect the horizontal and vertical separators together, which are also configurable through the `horizup`, `horizdown`, `vertleft`, `vertright` and `verthoriz` items in `fillchars`. The window separators are highlighted using the `WinSeparator` highlight group, which supersedes `VertSplit` and is linked to `VertSplit` by default in order to maintain backwards compatibility. --- src/nvim/buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 38b045b31c..493c011ad6 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5006,8 +5006,8 @@ void ex_buffer_all(exarg_T *eap) wpnext = wp->w_next; if ((wp->w_buffer->b_nwindows > 1 || ((cmdmod.split & WSP_VERT) - ? wp->w_height + wp->w_status_height < Rows - p_ch - - tabline_height() + ? wp->w_height + wp->w_hsep_height + wp->w_status_height < Rows - p_ch + - tabline_height() - global_stl_height() : wp->w_width != Columns) || (had_tab > 0 && wp != firstwin)) && !ONE_WINDOW -- cgit From 00effff56944d5b59440dcdb5e3496d49a76d3e2 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 18 Mar 2022 04:47:08 +0000 Subject: vim-patch:8.1.1693: syntax coloring and highlighting is in one big file (#17721) Problem: Syntax coloring and highlighting is in one big file. Solution: Move the highlighting to a separate file. (Yegappan Lakshmanan, closes vim/vim#4674) https://github.com/vim/vim/commit/f9cc9f209ede9f15959e4c2351e970477c139614 Name the new file highlight_group.c instead. Co-authored-by: zeertzjq --- src/nvim/buffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index bfaee82311..dbb471a532 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -51,6 +51,7 @@ #include "nvim/getchar.h" #include "nvim/hashtab.h" #include "nvim/highlight.h" +#include "nvim/highlight_group.h" #include "nvim/indent.h" #include "nvim/indent_c.h" #include "nvim/main.h" -- cgit From 3fdb7b528d9d066ccce8b1cb5d2225c338acfbb8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 21 Mar 2022 23:38:48 +0800 Subject: fix(float): handle buffer deletion with floating windows --- src/nvim/buffer.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 1293edb1da..1fe80dc24c 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1042,6 +1042,10 @@ static int empty_curbuf(int close_others, int forceit, int action) set_bufref(&bufref, buf); if (close_others) { + if (curwin->w_floating) { + // Last window must be non-floating. + curwin = firstwin; + } // Close any other windows on this buffer, then make it empty. close_windows(buf, true); } @@ -1224,11 +1228,12 @@ int do_buffer(int action, int start, int dir, int count, int forceit) } // If the deleted buffer is the current one, close the current window - // (unless it's the only window). Repeat this so long as we end up in - // a window with this buffer. + // (unless it's the only non-floating window). + // When the autocommand window is involved win_close() may need to print an error message. + // Repeat this so long as we end up in a window with this buffer. while (buf == curbuf && !(curwin->w_closing || curwin->w_buffer->b_locked > 0) - && (!ONE_WINDOW || first_tabpage->tp_next != NULL)) { + && (lastwin == aucmd_win || !last_window(curwin))) { if (win_close(curwin, false, false) == FAIL) { break; } -- cgit From ff82b2785f161fc14ff6bd8eae497f37ecd14564 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 24 Mar 2022 11:56:22 +0800 Subject: fix(float): don't always switch window when deleting last listed buffer (#17836) --- src/nvim/buffer.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 1fe80dc24c..7fc880fb41 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1043,8 +1043,20 @@ static int empty_curbuf(int close_others, int forceit, int action) if (close_others) { if (curwin->w_floating) { - // Last window must be non-floating. - curwin = firstwin; + bool can_close_all_others = false; + for (win_T *wp = firstwin; !wp->w_floating; wp = wp->w_next) { + if (wp->w_buffer != curbuf) { + // Found another non-floating window with a different (probably unlisted) buffer. + // Closing all other windows with the this buffer is fine in this case. + can_close_all_others = true; + break; + } + } + if (!can_close_all_others) { + // Closing all other windows with this buffer will close all non-floating windows. + // Move to a non-floating window then. + curwin = firstwin; + } } // Close any other windows on this buffer, then make it empty. close_windows(buf, true); -- cgit From a72f338d76c871869712518df862c85d1df25f54 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 24 Mar 2022 14:53:20 +0800 Subject: fix(float): do not switch window before deleting last listed buffer (#17840) Just allow close_windows() to close the current window instead. This fixes wrong working directory or autocommands not being triggered. --- src/nvim/buffer.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7fc880fb41..f200f16a5f 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1042,24 +1042,24 @@ static int empty_curbuf(int close_others, int forceit, int action) set_bufref(&bufref, buf); if (close_others) { + bool can_close_all_others = true; if (curwin->w_floating) { - bool can_close_all_others = false; + // Closing all other windows with this buffer may leave only floating windows. + can_close_all_others = false; for (win_T *wp = firstwin; !wp->w_floating; wp = wp->w_next) { if (wp->w_buffer != curbuf) { // Found another non-floating window with a different (probably unlisted) buffer. - // Closing all other windows with the this buffer is fine in this case. + // Closing all other windows with this buffer is fine in this case. can_close_all_others = true; break; } } - if (!can_close_all_others) { - // Closing all other windows with this buffer will close all non-floating windows. - // Move to a non-floating window then. - curwin = firstwin; - } } - // Close any other windows on this buffer, then make it empty. - close_windows(buf, true); + // If it is fine to close all other windows with this buffer, keep the current window and + // close any other windows with this buffer, then make it empty. + // Otherwise close_windows() will refuse to close the last non-floating window, so allow it + // to close the current window instead. + close_windows(buf, can_close_all_others); } setpcmark(); -- cgit From 19bbc43947a75b0279f9697f5830a238af337c5b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 24 Mar 2022 12:29:26 +0800 Subject: vim-patch:8.2.4281: using freed memory with :lopen and :bwipe Problem: Using freed memory with :lopen and :bwipe. Solution: Do not use a wiped out buffer. https://github.com/vim/vim/commit/9b4a80a66544f2782040b641498754bcb5b8d461 Cherry-pick some indent changes from patch 8.2.1432. --- src/nvim/buffer.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index f200f16a5f..8d042525d3 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1486,8 +1486,15 @@ void set_curbuf(buf_T *buf, int action) // An autocommand may have deleted "buf", already entered it (e.g., when // it did ":bunload") or aborted the script processing! // If curwin->w_buffer is null, enter_buffer() will make it valid again - if ((buf_valid(buf) && buf != curbuf && !aborting()) || curwin->w_buffer == NULL) { - enter_buffer(buf); + bool valid = buf_valid(buf); + if ((valid && buf != curbuf && !aborting()) || curwin->w_buffer == NULL) { + // If the buffer is not valid but curwin->w_buffer is NULL we must + // enter some buffer. Using the last one is hopefully OK. + if (!valid) { + enter_buffer(lastbuf); + } else { + enter_buffer(buf); + } if (old_tw != curbuf->b_p_tw) { check_colorcolumn(curwin); } -- cgit From d8b4f3e3b83d5a0fd5d844da34da23c88dc9c4c5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 24 Mar 2022 12:39:31 +0800 Subject: vim-patch:8.2.4327: may end up with no current buffer Problem: May end up with no current buffer. Solution: When deleting the current buffer to not pick a quickfix buffer as the new current buffer. https://github.com/vim/vim/commit/e3537aec2f8d6470010547af28dcbd83d41461b8 The test cannot be ported as-is because Nvim doesn't support "-Z" command line argument. Just use only "--clean" instead. --- src/nvim/buffer.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 8d042525d3..4ca752e747 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1284,8 +1284,10 @@ int do_buffer(int action, int start, int dir, int count, int forceit) while (jumpidx != curwin->w_jumplistidx) { buf = buflist_findnr(curwin->w_jumplist[jumpidx].fmark.fnum); if (buf != NULL) { - if (buf == curbuf || !buf->b_p_bl) { - buf = NULL; // skip current and unlisted bufs + // Skip current and unlisted bufs. Also skip a quickfix + // buffer, it might be deleted soon. + if (buf == curbuf || !buf->b_p_bl || bt_quickfix(buf)) { + buf = NULL; } else if (buf->b_ml.ml_mfp == NULL) { // skip unloaded buf, but may keep it for later if (bp == NULL) { @@ -1323,7 +1325,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) continue; } // in non-help buffer, try to skip help buffers, and vv - if (buf->b_help == curbuf->b_help && buf->b_p_bl) { + if (buf->b_help == curbuf->b_help && buf->b_p_bl && !bt_quickfix(buf)) { if (buf->b_ml.ml_mfp != NULL) { // found loaded buffer break; } @@ -1343,7 +1345,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) } if (buf == NULL) { // No loaded buffer, find listed one FOR_ALL_BUFFERS(buf2) { - if (buf2->b_p_bl && buf2 != curbuf) { + if (buf2->b_p_bl && buf2 != curbuf && !bt_quickfix(buf2)) { buf = buf2; break; } @@ -1355,6 +1357,9 @@ int do_buffer(int action, int start, int dir, int count, int forceit) } else { buf = curbuf->b_prev; } + if (bt_quickfix(buf)) { + buf = NULL; + } } } -- cgit From f4f18a983305d3cf8a6028333e9b99e86283032b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 27 Mar 2022 08:57:57 +0800 Subject: vim-patch:8.2.4631: crash when switching window in BufWipeout autocommand Problem: Crash when switching window in BufWipeout autocommand. Solution: Put any buffer in the window to avoid it being NULL. (closes vim/vim#10024) https://github.com/vim/vim/commit/347538fad0c503249ebdedd5884c2081257c9f61 win_init_empty() cannot be made static because it is used in autocmd.c --- src/nvim/buffer.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4ca752e747..bf592a626d 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -590,6 +590,10 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) // Remove the buffer from the list. if (wipe_buf) { + // Do not wipe out the buffer if it is used in a window. + if (buf->b_nwindows > 0) { + return false; + } if (buf->b_sfname != buf->b_ffname) { XFREE_CLEAR(buf->b_sfname); } else { -- cgit From 44b59d1a696b35d2520dbea2de3aab01e740a7ca Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Apr 2022 21:46:07 +0800 Subject: vim-patch:8.2.0004: get E685 and E931 if buffer reload is interrupted Problem: Get E685 and E931 if buffer reload is interrupted. Solution: Do not abort deleting a dummy buffer. (closes vim/vim#5361) https://github.com/vim/vim/commit/a6e8f888e7fc31b8ab7233509254fb2e2fe4089f --- src/nvim/buffer.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index bf592a626d..4ec23244cd 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -174,7 +174,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) if (ml_open(curbuf) == FAIL) { // There MUST be a memfile, otherwise we can't do anything // If we can't create one for the current buffer, take another buffer - close_buffer(NULL, curbuf, 0, false); + close_buffer(NULL, curbuf, 0, false, false); curbuf = NULL; FOR_ALL_BUFFERS(buf) { @@ -402,8 +402,10 @@ bool buf_valid(buf_T *buf) /// there to be only one window with this buffer. e.g. when /// ":quit" is supposed to close the window but autocommands /// close all other windows. +/// @param ignore_abort +/// If true, don't abort even when aborting() returns true. /// @return true when we got to the end and b_nwindows was decremented. -bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) +bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool ignore_abort) { bool unload_buf = (action != 0); bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE); @@ -494,7 +496,8 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) return false; } } - if (aborting()) { // autocmds may abort script processing + // autocmds may abort script processing + if (!ignore_abort && aborting()) { return false; } } @@ -552,14 +555,16 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) buf->b_nwindows = nwindows; - buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0)); + buf_freeall(buf, ((del_buf ? BFA_DEL : 0) + + (wipe_buf ? BFA_WIPE : 0) + + (ignore_abort ? BFA_IGNORE_ABORT : 0))); if (!bufref_valid(&bufref)) { // Autocommands may have deleted the buffer. return false; } - if (aborting()) { - // Autocmds may abort script processing. + // autocmds may abort script processing. + if (!ignore_abort && aborting()) { return false; } @@ -660,9 +665,10 @@ void buf_clear(void) /// buf_freeall() - free all things allocated for a buffer that are related to /// the file. Careful: get here with "curwin" NULL when exiting. /// -/// @param flags BFA_DEL buffer is going to be deleted -/// BFA_WIPE buffer is going to be wiped out -/// BFA_KEEP_UNDO do not free undo information +/// @param flags BFA_DEL buffer is going to be deleted +/// BFA_WIPE buffer is going to be wiped out +/// BFA_KEEP_UNDO do not free undo information +/// BFA_IGNORE_ABORT don't abort even when aborting() returns true void buf_freeall(buf_T *buf, int flags) { bool is_curbuf = (buf == curbuf); @@ -706,7 +712,8 @@ void buf_freeall(buf_T *buf, int flags) goto_tabpage_win(the_curtab, the_curwin); unblock_autocmds(); } - if (aborting()) { // autocmds may abort script processing + // autocmds may abort script processing + if ((flags & BFA_IGNORE_ABORT) == 0 && aborting()) { return; } @@ -877,7 +884,7 @@ void handle_swap_exists(bufref_T *old_curbuf) // open a new, empty buffer. swap_exists_action = SEA_NONE; // don't want it again swap_exists_did_quit = true; - close_buffer(curwin, curbuf, DOBUF_UNLOAD, false); + close_buffer(curwin, curbuf, DOBUF_UNLOAD, false, false); if (old_curbuf == NULL || !bufref_valid(old_curbuf) || old_curbuf->br_buf == curbuf) { @@ -1074,7 +1081,7 @@ static int empty_curbuf(int close_others, int forceit, int action) // the old one. But do_ecmd() may have done that already, check // if the buffer still exists. if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) { - close_buffer(NULL, buf, action, false); + close_buffer(NULL, buf, action, false, false); } if (!close_others) { @@ -1259,7 +1266,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) if (buf != curbuf) { close_windows(buf, false); if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) { - close_buffer(NULL, buf, action, false); + close_buffer(NULL, buf, action, false, false); } return OK; } @@ -1485,7 +1492,7 @@ void set_curbuf(buf_T *buf, int action) ? action : (action == DOBUF_GOTO && !buf_hide(prevbuf) && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, - false); + false, false); if (curwin != previouswin && win_valid(previouswin)) { // autocommands changed curwin, Grr! curwin = previouswin; @@ -2805,7 +2812,7 @@ int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) return FAIL; } // delete from the list - close_buffer(NULL, obuf, DOBUF_WIPE, false); + close_buffer(NULL, obuf, DOBUF_WIPE, false, false); } sfname = vim_strsave(sfname); #ifdef USE_FNAME_CASE @@ -5650,7 +5657,7 @@ void wipe_buffer(buf_T *buf, bool aucmd) // Don't trigger BufDelete autocommands here. block_autocmds(); } - close_buffer(NULL, buf, DOBUF_WIPE, false); + close_buffer(NULL, buf, DOBUF_WIPE, false, true); if (!aucmd) { unblock_autocmds(); } -- cgit From 45f62464d3e1f39e74fca627e27eea106ffe46ef Mon Sep 17 00:00:00 2001 From: Tom Praschan <13141438+tom-anders@users.noreply.github.com> Date: Thu, 7 Apr 2022 16:14:02 +0200 Subject: vim-patch:8.2.4702: C++ scope labels are hard-coded Problem: C++ scope labels are hard-coded. Solution: Add 'cinscopedecls' to define the labels. (Tom Praschan, closes vim/vim#10109) https://github.com/vim/vim/commit/3506cf34c17c5eae6c2d1317db1fcd5a8493c288 --- src/nvim/buffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index bf592a626d..b65fa77660 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1938,6 +1938,7 @@ void free_buf_options(buf_T *buf, int free_p_ff) clear_string_option(&buf->b_p_cink); clear_string_option(&buf->b_p_cino); clear_string_option(&buf->b_p_cinw); + clear_string_option(&buf->b_p_cinsd); clear_string_option(&buf->b_p_cpt); clear_string_option(&buf->b_p_cfu); clear_string_option(&buf->b_p_ofu); -- cgit From 3f2e9298bdd971a4d2baa298aff7c6f2c2c1ad1a Mon Sep 17 00:00:00 2001 From: Charlie Groves Date: Fri, 15 Apr 2022 21:58:48 -0400 Subject: chore: remove vestigial sfname freeing (#18123) This freeing is necessary in Vim since the alloc can fail. Since we're using xcalloc, that's not possible and the freeing will never run. --- src/nvim/buffer.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4948e2bb69..4d914acea4 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1775,19 +1775,6 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl clear_wininfo(buf); buf->b_wininfo = xcalloc(1, sizeof(wininfo_T)); - if (ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL)) { - if (buf->b_sfname != buf->b_ffname) { - XFREE_CLEAR(buf->b_sfname); - } else { - buf->b_sfname = NULL; - } - XFREE_CLEAR(buf->b_ffname); - if (buf != curbuf) { - free_buffer(buf); - } - return NULL; - } - if (buf == curbuf) { // free all things allocated for this buffer buf_freeall(buf, 0); -- cgit From 9b10b4cc6463d901b893ad2d522c629d066607d5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 20 Apr 2022 10:26:33 +0800 Subject: vim-patch:8.1.1756: autocommand that splits window messes up window layout Problem: Autocommand that splits window messes up window layout. Solution: Disallow splitting a window while closing one. In ":all" give an error when moving a window will not work. https://github.com/vim/vim/commit/1417c766f55e5959b31da488417b7d9b141404af Expected error number was changed to E242 in Vim in patch 8.2.1183, and patch 8.2.2420 (which has already been ported) made the test no longer throw E249 in Vim, so just use E242 in the test. --- src/nvim/buffer.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4d914acea4..78426568b4 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4855,6 +4855,10 @@ void do_arg_all(int count, int forceit, int keep_tabs) if (keep_tabs) { new_curwin = wp; new_curtab = curtab; + } else if (wp->w_frame->fr_parent != curwin->w_frame->fr_parent) { + emsg(_("E249: window layout changed unexpectedly")); + i = count; + break; } else { win_move_after(wp, curwin); } -- cgit From 1664e3d4bcc122e6a3b064a3fe20fdc163f6ae9d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 20 Apr 2022 10:05:02 +0800 Subject: vim-patch:8.2.2476: using freed memory when splitting window while closing buffer Problem: Using freed memory when using an autocommand to split a window while a buffer is being closed. Solution: Disallow splitting when the buffer has b_locked_split set. https://github.com/vim/vim/commit/983d83ff1cd796ff321074335fa53fbe7ac45a46 Put the error message in window.c. Cherry-pick a memory leak fix from Vim patch 8.2.0399. Test still fails. --- src/nvim/buffer.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 78426568b4..628e398fd4 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -466,6 +466,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i // When the buffer is no longer in a window, trigger BufWinLeave if (buf->b_nwindows == 1) { buf->b_locked++; + buf->b_locked_split++; if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false, buf) && !bufref_valid(&bufref)) { // Autocommands deleted the buffer. @@ -473,6 +474,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i return false; } buf->b_locked--; + buf->b_locked_split--; if (abort_if_last && last_nonfloat(win)) { // Autocommands made this the only window. emsg(_(e_auabort)); @@ -483,6 +485,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i // BufHidden if (!unload_buf) { buf->b_locked++; + buf->b_locked_split++; if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false, buf) && !bufref_valid(&bufref)) { // Autocommands deleted the buffer. @@ -490,6 +493,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i return false; } buf->b_locked--; + buf->b_locked_split--; if (abort_if_last && last_nonfloat(win)) { // Autocommands made this the only window. emsg(_(e_auabort)); @@ -678,6 +682,7 @@ void buf_freeall(buf_T *buf, int flags) // Make sure the buffer isn't closed by autocommands. buf->b_locked++; + buf->b_locked_split++; bufref_T bufref; set_bufref(&bufref, buf); @@ -703,6 +708,7 @@ void buf_freeall(buf_T *buf, int flags) return; } buf->b_locked--; + buf->b_locked_split--; // If the buffer was in curwin and the window has changed, go back to that // window, if it still exists. This avoids that ":edit x" triggering a @@ -1466,8 +1472,8 @@ void set_curbuf(buf_T *buf, int action) set_bufref(&prevbufref, prevbuf); set_bufref(&newbufref, buf); - // Autocommands may delete the current buffer and/or the buffer we want to go - // to. In those cases don't close the buffer. + // Autocommands may delete the current buffer and/or the buffer we want to + // go to. In those cases don't close the buffer. if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf) || (bufref_valid(&prevbufref) && bufref_valid(&newbufref) && !aborting())) { -- cgit From f531fb97ff5009d2ac279a83da9b9e911c350c89 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 20 Apr 2022 11:11:39 +0800 Subject: vim-patch:8.2.4791: events triggered in different order when reusing buffer Problem: Autocmd events triggered in different order when reusing an empty buffer. Solution: Call buff_freeall() earlier. (Charlie Groves, closes vim/vim#10198) https://github.com/vim/vim/commit/fef4485ef58d5937b170c6dc69431359469fc9cd Test failure becomes very strange. --- src/nvim/buffer.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 628e398fd4..30bd37fe7f 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1748,21 +1748,14 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl buf = curbuf; // It's like this buffer is deleted. Watch out for autocommands that // change curbuf! If that happens, allocate a new buffer anyway. - if (curbuf->b_p_bl) { - apply_autocmds(EVENT_BUFDELETE, NULL, NULL, false, curbuf); - } - if (buf == curbuf) { - apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, false, curbuf); + buf_freeall(buf, BFA_WIPE | BFA_DEL); + if (buf != curbuf) { // autocommands deleted the buffer! + return NULL; } if (aborting()) { // autocmds may abort script processing xfree(ffname); return NULL; } - if (buf == curbuf) { - // Make sure 'bufhidden' and 'buftype' are empty - clear_string_option(&buf->b_p_bh); - clear_string_option(&buf->b_p_bt); - } } if (buf != curbuf || curbuf == NULL) { buf = xcalloc(1, sizeof(buf_T)); @@ -1782,14 +1775,6 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl buf->b_wininfo = xcalloc(1, sizeof(wininfo_T)); if (buf == curbuf) { - // free all things allocated for this buffer - buf_freeall(buf, 0); - if (buf != curbuf) { // autocommands deleted the buffer! - return NULL; - } - if (aborting()) { // autocmds may abort script processing - return NULL; - } free_buffer_stuff(buf, kBffInitChangedtick); // delete local vars et al. // Init the options. -- cgit From c58219413514caf035ac52eb85b84b1ff31d4722 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Mon, 25 Apr 2022 04:12:47 +0200 Subject: refactor: add pure attribute to pure functions (#18165) This will allow the compilers that support the pure attribute to make further optimizations. --- src/nvim/buffer.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 30bd37fe7f..633575bce7 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -357,6 +357,7 @@ void set_bufref(bufref_T *bufref, buf_T *buf) /// /// @param bufref Buffer reference to check for. bool bufref_valid(bufref_T *bufref) + FUNC_ATTR_PURE { return bufref->br_buf_free_count == buf_free_count ? true @@ -2100,6 +2101,7 @@ buf_T *buflist_findname(char_u *ffname) /// /// @return buffer or NULL if not found static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id, bool file_id_valid) + FUNC_ATTR_PURE { // Start at the last buffer, expect to find a match sooner. FOR_ALL_BUFFERS_BACKWARDS(buf) { @@ -2531,7 +2533,7 @@ static bool wininfo_other_tab_diff(wininfo_T *wip) /// /// @return NULL when there isn't any info. static wininfo_T *find_wininfo(buf_T *buf, bool need_options, bool skip_diff_buffer) - FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE { wininfo_T *wip; @@ -2609,6 +2611,7 @@ void get_winopts(buf_T *buf) /// /// @return a pointer to no_position if no position is found. pos_T *buflist_findfpos(buf_T *buf) + FUNC_ATTR_PURE { static pos_T no_position = { 1, 0, 0 }; @@ -2618,6 +2621,7 @@ pos_T *buflist_findfpos(buf_T *buf) /// Find the lnum for the buffer 'buf' for the current window. linenr_T buflist_findlnum(buf_T *buf) + FUNC_ATTR_PURE { return buflist_findfpos(buf)->lnum; } @@ -4928,6 +4932,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) /// @return true if "buf" is a prompt buffer. bool bt_prompt(buf_T *buf) + FUNC_ATTR_PURE { return buf != NULL && buf->b_p_bt[0] == 'p'; } @@ -5339,6 +5344,7 @@ bool bt_dontwrite_msg(const buf_T *const buf) /// @return true if the buffer should be hidden, according to 'hidden', ":hide" /// and 'bufhidden'. bool buf_hide(const buf_T *const buf) + FUNC_ATTR_PURE { // 'bufhidden' overrules 'hidden' and ":hide", check it first switch (buf->b_p_bh[0]) { -- cgit From 0648100fed65cbe8efe774ae997ab841cae01872 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Mon, 25 Apr 2022 04:18:43 +0200 Subject: refactor: convert macros to all-caps (#17895) Closes https://github.com/neovim/neovim/issues/6297 --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 633575bce7..5d2d1cebde 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2955,7 +2955,7 @@ static bool otherfile_buf(buf_T *buf, char_u *ffname, FileID *file_id_p, bool fi if (ffname == NULL || *ffname == NUL || buf->b_ffname == NULL) { return true; } - if (fnamecmp(ffname, buf->b_ffname) == 0) { + if (FNAMECMP(ffname, buf->b_ffname) == 0) { return false; } { -- cgit From 2dddc86a42a77bd099a031165e57add84b9b0e82 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Mon, 25 Apr 2022 08:44:18 -0600 Subject: fix: show autocmd output when F is in shortmess (#18251) The default value of including F in 'shortmess' has the unfortunate side effect of hiding output from autocommands. This is a common source of confusion and often leads people to think their autocommands are not working when they are. There is a small snippet in the docs for 'shortmess' indicating that the F flag suppresses autocmd output, but it's not easy to find if you don't already know to look for it. This commit removes that behavior of the F flag to make it only suppress file info when opening a new file. --- src/nvim/buffer.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 5d2d1cebde..8840813b84 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -109,6 +109,7 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags) { int retval = OK; linenr_T line_count; + bool silent = shortmess(SHM_FILEINFO); // Read from the buffer which the text is already filled in and append at // the end. This makes it possible to retry when 'fileformat' or @@ -117,7 +118,7 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags) retval = readfile(read_stdin ? NULL : curbuf->b_ffname, read_stdin ? NULL : curbuf->b_fname, line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap, - flags | READ_BUFFER); + flags | READ_BUFFER, silent); if (retval == OK) { // Delete the binary lines. while (--line_count >= 0) { @@ -162,6 +163,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) bufref_T old_curbuf; long old_tw = curbuf->b_p_tw; int read_fifo = false; + bool silent = shortmess(SHM_FILEINFO); // The 'readonly' flag is only set when BF_NEVERLOADED is being reset. // When re-entering the same buffer, it should not change, because the @@ -212,7 +214,6 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) curwin->w_valid = 0; if (curbuf->b_ffname != NULL) { - int old_msg_silent = msg_silent; #ifdef UNIX int save_bin = curbuf->b_p_bin; int perm; @@ -231,13 +232,10 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) curbuf->b_p_bin = true; } #endif - if (shortmess(SHM_FILEINFO)) { - msg_silent = 1; - } retval = readfile(curbuf->b_ffname, curbuf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, - flags | READ_NEW | (read_fifo ? READ_FIFO : 0)); + flags | READ_NEW | (read_fifo ? READ_FIFO : 0), silent); #ifdef UNIX if (read_fifo) { curbuf->b_p_bin = save_bin; @@ -246,7 +244,6 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) } } #endif - msg_silent = old_msg_silent; // Help buffer is filtered. if (bt_help(curbuf)) { @@ -262,7 +259,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) curbuf->b_p_bin = true; retval = readfile(NULL, NULL, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, NULL, - flags | (READ_NEW + READ_STDIN)); + flags | (READ_NEW + READ_STDIN), silent); curbuf->b_p_bin = save_bin; if (retval == OK) { retval = read_buffer(true, eap, flags); @@ -903,14 +900,7 @@ void handle_swap_exists(bufref_T *old_curbuf) buf = old_curbuf->br_buf; } if (buf != NULL) { - int old_msg_silent = msg_silent; - - if (shortmess(SHM_FILEINFO)) { - msg_silent = 1; // prevent fileinfo message - } enter_buffer(buf); - // restore msg_silent, so that the command line will be shown - msg_silent = old_msg_silent; if (old_tw != curbuf->b_p_tw) { check_colorcolumn(curwin); @@ -5611,7 +5601,7 @@ bool buf_contents_changed(buf_T *buf) if (ml_open(curbuf) == OK && readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, - &ea, READ_NEW | READ_DUMMY) == OK) { + &ea, READ_NEW | READ_DUMMY, false) == OK) { // compare the two files line by line if (buf->b_ml.ml_line_count == curbuf->b_ml.ml_line_count) { differ = false; -- cgit From 0d41c4dee126b6d93ee8ed82302af47df9a50576 Mon Sep 17 00:00:00 2001 From: kylo252 <59826753+kylo252@users.noreply.github.com> Date: Wed, 27 Apr 2022 06:38:12 +0200 Subject: refactor(build): remove unused includes #17078 Remove unused includes in src/nvim/buffer.c|h using the IWYU library. Yet another step towards #6371 and #549 --- src/nvim/buffer.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 8840813b84..99a24464a8 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -25,7 +25,6 @@ #include #include "nvim/api/private/helpers.h" -#include "nvim/api/vim.h" #include "nvim/ascii.h" #include "nvim/assert.h" #include "nvim/buffer.h" @@ -50,7 +49,6 @@ #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/hashtab.h" -#include "nvim/highlight.h" #include "nvim/highlight_group.h" #include "nvim/indent.h" #include "nvim/indent_c.h" @@ -64,13 +62,11 @@ #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/time.h" -#include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/plines.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" -#include "nvim/shada.h" #include "nvim/sign.h" #include "nvim/spell.h" #include "nvim/strings.h" -- cgit From eef8de4df0247157e57f306062b1b86e01a41454 Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Fri, 29 Apr 2022 13:53:42 +0200 Subject: refactor(uncrustify): change rules to better align with the style guide Add space around arithmetic operators '+' and '-'. Remove space between back-to-back parentheses, i.e. ')(' vs. ') ('. Remove space between '((' or '))' of control statements. Add space between ')' and '{' of control statements. Remove space between function name and '(' on function declaration. Collapse empty blocks between '{' and '}'. Remove newline at the end of the file. Remove newline between 'enum' and '{'. Remove newline between '}' and ')' in a function invocation. Remove newline between '}' and 'while' of 'do' statement. --- src/nvim/buffer.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 99a24464a8..5786a73f43 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2343,9 +2343,9 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) // if the current buffer is first in the list, place it at the end if (matches[0].buf == curbuf) { for (int i = 1; i < count; i++) { - (*file)[i-1] = matches[i].match; + (*file)[i - 1] = matches[i].match; } - (*file)[count-1] = matches[0].match; + (*file)[count - 1] = matches[0].match; } else { for (int i = 0; i < count; i++) { (*file)[i] = matches[i].match; @@ -5410,8 +5410,8 @@ static int buf_signcols_inner(buf_T *buf, int maximum) if (sign->se_lnum > curline) { // Counted all signs, now add extmark signs if (curline > 0) { - linesum += decor_signcols(buf, &decor_state, (int)curline-1, (int)curline-1, - maximum-linesum); + linesum += decor_signcols(buf, &decor_state, (int)curline - 1, (int)curline - 1, + maximum - linesum); } curline = sign->se_lnum; if (linesum > signcols) { @@ -5429,7 +5429,8 @@ static int buf_signcols_inner(buf_T *buf, int maximum) } if (curline > 0) { - linesum += decor_signcols(buf, &decor_state, (int)curline-1, (int)curline-1, maximum-linesum); + linesum += decor_signcols(buf, &decor_state, (int)curline - 1, (int)curline - 1, + maximum - linesum); } if (linesum > signcols) { signcols = linesum; @@ -5439,7 +5440,7 @@ static int buf_signcols_inner(buf_T *buf, int maximum) } // Check extmarks between signs - linesum = decor_signcols(buf, &decor_state, 0, (int)buf->b_ml.ml_line_count-1, maximum); + linesum = decor_signcols(buf, &decor_state, 0, (int)buf->b_ml.ml_line_count - 1, maximum); if (linesum > signcols) { signcols = linesum; @@ -5511,8 +5512,8 @@ void buf_signcols_add_check(buf_T *buf, sign_entry_T *added) for (; s->se_next && s->se_lnum == s->se_next->se_lnum; s = s->se_next) { linesum++; } - linesum += decor_signcols(buf, &decor_state, (int)s->se_lnum-1, (int)s->se_lnum-1, - SIGN_SHOW_MAX-linesum); + linesum += decor_signcols(buf, &decor_state, (int)s->se_lnum - 1, (int)s->se_lnum - 1, + SIGN_SHOW_MAX - linesum); if (linesum > buf->b_signcols.size) { buf->b_signcols.size = linesum; -- cgit From af782a630633ffe0cb082bda974b24d4f577313e Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Sat, 30 Apr 2022 20:28:04 +0200 Subject: refactor: replace char_u variables and functions with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 5786a73f43..c70d845c42 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4870,7 +4870,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) new_curwin = curwin; new_curtab = curtab; } - (void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL, ECMD_ONE, + (void)do_ecmd(0, (char *)alist_name(&AARGLIST(alist)[i]), NULL, NULL, ECMD_ONE, ((buf_hide(curwin->w_buffer) || bufIsChanged(curwin->w_buffer)) ? ECMD_HIDE : 0) + ECMD_OLDBUF, -- cgit From b9bdd0f61e5e7365c07aadbc3f796556b6d85fdf Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Sun, 1 May 2022 11:18:17 +0200 Subject: refactor: replace char_u variables and functions with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index c70d845c42..14ed9921a0 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3421,7 +3421,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use }; set_var(S_LEN("g:statusline_winid"), &tv, false); - usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox); + usefmt = (char_u *)eval_to_string_safe((char *)fmt + 2, NULL, use_sandbox); if (usefmt == NULL) { usefmt = fmt; } @@ -3878,9 +3878,9 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // Store the current buffer number as a string variable vim_snprintf(buf_tmp, sizeof(buf_tmp), "%d", curbuf->b_fnum); - set_internal_string_var("g:actual_curbuf", (char_u *)buf_tmp); + set_internal_string_var("g:actual_curbuf", buf_tmp); vim_snprintf((char *)win_tmp, sizeof(win_tmp), "%d", curwin->handle); - set_internal_string_var("g:actual_curwin", win_tmp); + set_internal_string_var("g:actual_curwin", (char *)win_tmp); buf_T *const save_curbuf = curbuf; win_T *const save_curwin = curwin; @@ -3893,7 +3893,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } // Note: The result stored in `t` is unused. - str = (char *)eval_to_string_safe(out_p, &t, use_sandbox); + str = eval_to_string_safe((char *)out_p, (char **)&t, use_sandbox); curwin = save_curwin; curbuf = save_curbuf; -- cgit From 5576d30e89153c817fb1a8d23c30cfc0432bc7c6 Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Tue, 3 May 2022 11:06:27 +0200 Subject: refactor: replace char_u variables and functions with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 14ed9921a0..1ae1811772 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2622,7 +2622,7 @@ void buflist_list(exarg_T *eap) garray_T buflist; buf_T **buflist_data = NULL; - if (vim_strchr(eap->arg, 't')) { + if (vim_strchr((char_u *)eap->arg, 't')) { ga_init(&buflist, sizeof(buf_T *), 50); for (buf = firstbuf; buf != NULL; buf = buf->b_next) { ga_grow(&buflist, 1); @@ -2645,21 +2645,21 @@ void buflist_list(exarg_T *eap) const bool job_running = buf->terminal && terminal_running(buf->terminal); // skip unspecified buffers - if ((!buf->b_p_bl && !eap->forceit && !vim_strchr(eap->arg, 'u')) - || (vim_strchr(eap->arg, 'u') && buf->b_p_bl) - || (vim_strchr(eap->arg, '+') + if ((!buf->b_p_bl && !eap->forceit && !vim_strchr((char_u *)eap->arg, 'u')) + || (vim_strchr((char_u *)eap->arg, 'u') && buf->b_p_bl) + || (vim_strchr((char_u *)eap->arg, '+') && ((buf->b_flags & BF_READERR) || !bufIsChanged(buf))) - || (vim_strchr(eap->arg, 'a') + || (vim_strchr((char_u *)eap->arg, 'a') && (buf->b_ml.ml_mfp == NULL || buf->b_nwindows == 0)) - || (vim_strchr(eap->arg, 'h') + || (vim_strchr((char_u *)eap->arg, 'h') && (buf->b_ml.ml_mfp == NULL || buf->b_nwindows != 0)) - || (vim_strchr(eap->arg, 'R') && (!is_terminal || !job_running)) - || (vim_strchr(eap->arg, 'F') && (!is_terminal || job_running)) - || (vim_strchr(eap->arg, '-') && buf->b_p_ma) - || (vim_strchr(eap->arg, '=') && !buf->b_p_ro) - || (vim_strchr(eap->arg, 'x') && !(buf->b_flags & BF_READERR)) - || (vim_strchr(eap->arg, '%') && buf != curbuf) - || (vim_strchr(eap->arg, '#') + || (vim_strchr((char_u *)eap->arg, 'R') && (!is_terminal || !job_running)) + || (vim_strchr((char_u *)eap->arg, 'F') && (!is_terminal || job_running)) + || (vim_strchr((char_u *)eap->arg, '-') && buf->b_p_ma) + || (vim_strchr((char_u *)eap->arg, '=') && !buf->b_p_ro) + || (vim_strchr((char_u *)eap->arg, 'x') && !(buf->b_flags & BF_READERR)) + || (vim_strchr((char_u *)eap->arg, '%') && buf != curbuf) + || (vim_strchr((char_u *)eap->arg, '#') && (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) { continue; } @@ -2700,7 +2700,7 @@ void buflist_list(exarg_T *eap) do { IObuff[len++] = ' '; } while (--i > 0 && len < IOSIZE - 18); - if (vim_strchr(eap->arg, 't') && buf->b_last_used) { + if (vim_strchr((char_u *)eap->arg, 't') && buf->b_last_used) { undo_fmt_time(IObuff + len, (size_t)(IOSIZE - len), buf->b_last_used); } else { vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), _("line %" PRId64), -- cgit From d0897243f6a6bb802fc9622486afd69eb65fa6d5 Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Fri, 6 May 2022 17:40:52 +0200 Subject: build(clint): remove "function size is too large" warning This warning is essentially only triggered for ported vim functions. It's unlikely that we'll refactor vim functions solely based on their size since it'd mean we'd greatly deviate from vim, which is a high cost when it comes to importing the vim patches. Thus, this warning only serves as an annoyance and should be removed. --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 1ae1811772..9759bdb46e 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4544,7 +4544,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } return width; -} // NOLINT(readability/fn_size) +} /// Get relative cursor position in window into "buf[buflen]", in the form 99%, /// using "Top", "Bot" or "All" when appropriate. -- cgit From 2a378e6e82cececb12339f2df51ffe107039d867 Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Wed, 4 May 2022 22:35:50 +0200 Subject: refactor: replace char_u variables and functions with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 1ae1811772..2e30f7f8ec 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3456,7 +3456,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use wp->w_cursor.coladd = 0; byteval = 0; } else { - byteval = utf_ptr2char(line_ptr + wp->w_cursor.col); + byteval = utf_ptr2char((char *)line_ptr + wp->w_cursor.col); } int groupdepth = 0; @@ -3616,7 +3616,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use long n = 0; while (group_len >= stl_items[stl_groupitems[groupdepth]].maxwid) { group_len -= ptr2cells(t + n); - n += utfc_ptr2len(t + n); + n += utfc_ptr2len((char *)t + n); } // } @@ -4176,7 +4176,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (l > maxwid) { while (l >= maxwid) { l -= ptr2cells(t); - t += utfc_ptr2len(t); + t += utfc_ptr2len((char *)t); } // Early out if there isn't enough room for the truncation marker @@ -4374,7 +4374,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // Note: Only advance the pointer if the next // character will fit in the available output space - trunc_p += utfc_ptr2len(trunc_p); + trunc_p += utfc_ptr2len((char *)trunc_p); } // Ignore any items in the statusline that occur after @@ -4396,7 +4396,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use long trunc_len = 0; while (width >= maxwidth) { width -= ptr2cells(trunc_p + trunc_len); - trunc_len += utfc_ptr2len(trunc_p + trunc_len); + trunc_len += utfc_ptr2len((char *)trunc_p + trunc_len); } // } -- cgit From e31b32a293f6ba8708499a176234f8be1df6a145 Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Thu, 5 May 2022 13:36:14 +0200 Subject: refactor: replace char_u variables and functions with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 96 +++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 49 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 9839f499eb..107f61919a 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -979,7 +979,7 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end break; } } else { // addr_count == 1 - arg = skipwhite(arg); + arg = (char_u *)skipwhite((char *)arg); if (*arg == NUL) { break; } @@ -3151,8 +3151,8 @@ void maketitle(void) use_sandbox = was_set_insecurely(curwin, "titlestring", 0); called_emsg = false; - build_stl_str_hl(curwin, (char_u *)buf, sizeof(buf), - p_titlestring, use_sandbox, + build_stl_str_hl(curwin, buf, sizeof(buf), + (char *)p_titlestring, use_sandbox, 0, maxlen, NULL, NULL); title_str = (char_u *)buf; if (called_emsg) { @@ -3269,8 +3269,8 @@ void maketitle(void) use_sandbox = was_set_insecurely(curwin, "iconstring", 0); called_emsg = false; - build_stl_str_hl(curwin, icon_str, sizeof(buf), - p_iconstring, use_sandbox, + build_stl_str_hl(curwin, (char *)icon_str, sizeof(buf), + (char *)p_iconstring, use_sandbox, 0, 0, NULL, NULL); if (called_emsg) { set_string_option_direct("iconstring", -1, @@ -3383,8 +3383,8 @@ typedef enum { /// @param tabtab Tab clicks definition (can be NULL). /// /// @return The final width of the statusline -int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use_sandbox, - int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab) +int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_sandbox, int fillchar, + int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab) { static size_t stl_items_len = 20; // Initial value, grows as needed. static stl_item_t *stl_items = NULL; @@ -3395,8 +3395,8 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use #define TMPLEN 70 char buf_tmp[TMPLEN]; - char_u win_tmp[TMPLEN]; - char_u *usefmt = fmt; + char win_tmp[TMPLEN]; + char *usefmt = fmt; const int save_must_redraw = must_redraw; const int save_redr_type = curwin->w_redr_type; @@ -3421,7 +3421,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use }; set_var(S_LEN("g:statusline_winid"), &tv, false); - usefmt = (char_u *)eval_to_string_safe((char *)fmt + 2, NULL, use_sandbox); + usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox); if (usefmt == NULL) { usefmt = fmt; } @@ -3467,17 +3467,17 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use bool prevchar_isitem = false; // out_p is the current position in the output buffer - char_u *out_p = out; + char *out_p = out; // out_end_p is the last valid character in the output buffer // Note: The null termination character must occur here or earlier, // so any user-visible characters must occur before here. - char_u *out_end_p = (out + outlen) - 1; + char *out_end_p = (out + outlen) - 1; // Proceed character by character through the statusline format string // fmt_p is the current position in the input buffer - for (char_u *fmt_p = usefmt; *fmt_p;) { + for (char *fmt_p = usefmt; *fmt_p;) { if (curitem == (int)stl_items_len) { size_t new_len = stl_items_len * 3 / 2; @@ -3534,7 +3534,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use continue; } stl_items[curitem].type = Separate; - stl_items[curitem++].start = out_p; + stl_items[curitem++].start = (char_u *)out_p; continue; } @@ -3542,7 +3542,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (*fmt_p == STL_TRUNCMARK) { fmt_p++; stl_items[curitem].type = Trunc; - stl_items[curitem++].start = out_p; + stl_items[curitem++].start = (char_u *)out_p; continue; } @@ -3591,7 +3591,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } if (n == curitem && group_start_userhl == group_end_userhl) { // empty group - out_p = t; + out_p = (char *)t; group_len = 0; for (n = stl_groupitems[groupdepth] + 1; n < curitem; n++) { // do not use the highlighting from the removed group @@ -3601,7 +3601,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // adjust the start position of TabPage to the next // item position if (stl_items[n].type == TabPage) { - stl_items[n].start = out_p; + stl_items[n].start = (char_u *)out_p; } } } @@ -3624,7 +3624,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use *t = '<'; // { Move the truncated output - memmove(t + 1, t + n, (size_t)(out_p - (t + n))); + memmove(t + 1, t + n, (size_t)((char_u *)out_p - (t + n))); out_p = out_p - n + 1; // Fill up space left over by half a double-wide char. while (++group_len < stl_items[stl_groupitems[groupdepth]].minwid) { @@ -3657,7 +3657,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } else { // { Move the group to the right group_len = (min_group_width - group_len) * utf_char2len(fillchar); - memmove(t + group_len, t, (size_t)(out_p - t)); + memmove(t + group_len, t, (size_t)((char_u *)out_p - t)); if (out_p + group_len >= (out_end_p + 1)) { group_len = (long)(out_end_p - out_p); } @@ -3696,14 +3696,14 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // The first digit group is the item's min width if (ascii_isdigit(*fmt_p)) { - minwid = getdigits_int(&fmt_p, false, 0); + minwid = getdigits_int((char_u **)&fmt_p, false, 0); } // User highlight groups override the min width field // to denote the styling to use. if (*fmt_p == STL_USER_HL) { stl_items[curitem].type = Highlight; - stl_items[curitem].start = out_p; + stl_items[curitem].start = (char_u *)out_p; stl_items[curitem].minwid = minwid > 9 ? 1 : minwid; fmt_p++; curitem++; @@ -3749,7 +3749,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } } stl_items[curitem].type = TabPage; - stl_items[curitem].start = out_p; + stl_items[curitem].start = (char_u *)out_p; stl_items[curitem].minwid = minwid; fmt_p++; curitem++; @@ -3758,7 +3758,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (*fmt_p == STL_CLICK_FUNC) { fmt_p++; - char *t = (char *)fmt_p; + char *t = fmt_p; while (*fmt_p != STL_CLICK_FUNC && *fmt_p) { fmt_p++; } @@ -3766,8 +3766,8 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use break; } stl_items[curitem].type = ClickFunc; - stl_items[curitem].start = out_p; - stl_items[curitem].cmd = xmemdupz(t, (size_t)(((char *)fmt_p - t))); + stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].cmd = xmemdupz(t, (size_t)(fmt_p - t)); stl_items[curitem].minwid = minwid; fmt_p++; curitem++; @@ -3779,7 +3779,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (*fmt_p == '.') { fmt_p++; if (ascii_isdigit(*fmt_p)) { - maxwid = getdigits_int(&fmt_p, false, 50); + maxwid = getdigits_int((char_u **)&fmt_p, false, 50); } } @@ -3791,7 +3791,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (*fmt_p == '(') { stl_groupitems[groupdepth++] = curitem; stl_items[curitem].type = Group; - stl_items[curitem].start = out_p; + stl_items[curitem].start = (char_u *)out_p; stl_items[curitem].minwid = minwid; stl_items[curitem].maxwid = maxwid; fmt_p++; @@ -3814,7 +3814,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } // The status line item type - char_u opt = *fmt_p++; + char opt = *fmt_p++; // OK - now for the real work NumberBase base = kNumBaseDecimal; @@ -3845,7 +3845,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use break; case STL_VIM_EXPR: // '{' { - char_u *block_start = fmt_p - 1; + char *block_start = fmt_p - 1; int reevaluate = (*fmt_p == '%'); itemisflag = true; @@ -3855,7 +3855,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // Attempt to copy the expression to evaluate into // the output buffer as a null-terminated string. - char_u *t = out_p; + char *t = out_p; while ((*fmt_p != '}' || (reevaluate && fmt_p[-1] != '%')) && *fmt_p != NUL && out_p < out_end_p) { *out_p++ = *fmt_p++; @@ -3893,7 +3893,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } // Note: The result stored in `t` is unused. - str = eval_to_string_safe((char *)out_p, (char **)&t, use_sandbox); + str = eval_to_string_safe(out_p, &t, use_sandbox); curwin = save_curwin; curbuf = save_curbuf; @@ -3943,7 +3943,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use xfree(usefmt); } XFREE_CLEAR(str); - usefmt = new_fmt; + usefmt = (char *)new_fmt; fmt_p = usefmt + parsed_usefmt; evaldepth++; continue; @@ -4125,7 +4125,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use case STL_HIGHLIGHT: { // { The name of the highlight is surrounded by `#` - char_u *t = fmt_p; + char *t = fmt_p; while (*fmt_p != '#' && *fmt_p != NUL) { fmt_p++; } @@ -4134,8 +4134,8 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // Create a highlight item based on the name if (*fmt_p == '#') { stl_items[curitem].type = Highlight; - stl_items[curitem].start = out_p; - stl_items[curitem].minwid = -syn_name2id_len(t, (size_t)(fmt_p - t)); + stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].minwid = -syn_name2id_len((char_u *)t, (size_t)(fmt_p - t)); curitem++; fmt_p++; } @@ -4146,14 +4146,14 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // If we made it this far, the item is normal and starts at // our current position in the output buffer. // Non-normal items would have `continued`. - stl_items[curitem].start = out_p; + stl_items[curitem].start = (char_u *)out_p; stl_items[curitem].type = Normal; // Copy the item string into the output buffer if (str != NULL && *str) { // { Skip the leading `,` or ` ` if the item is a flag // and the proper conditions are met - char_u *t = (char_u *)str; + char *t = str; if (itemisflag) { if ((t[0] && t[1]) && ((!prevchar_isitem && *t == ',') @@ -4164,7 +4164,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use } // } - long l = vim_strsize(t); + long l = vim_strsize((char_u *)t); // If this item is non-empty, record that the last thing // we put in the output buffer was an item @@ -4175,8 +4175,8 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // If the item is too wide, truncate it from the beginning if (l > maxwid) { while (l >= maxwid) { - l -= ptr2cells(t); - t += utfc_ptr2len((char *)t); + l -= ptr2cells((char_u *)t); + t += utfc_ptr2len(t); } // Early out if there isn't enough room for the truncation marker @@ -4292,11 +4292,9 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use *++t = 0; // } - vim_snprintf((char *)out_p, remaining_buf_len, (char *)nstr, - 0, num, n); + vim_snprintf(out_p, remaining_buf_len, (char *)nstr, 0, num, n); } else { - vim_snprintf((char *)out_p, remaining_buf_len, (char *)nstr, - minwid, num); + vim_snprintf(out_p, remaining_buf_len, (char *)nstr, minwid, num); } // Advance the output buffer position to the end of the @@ -4333,7 +4331,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // We have now processed the entire statusline format string. // What follows is post-processing to handle alignment and highlighting. - int width = vim_strsize(out); + int width = vim_strsize((char_u *)out); if (maxwidth > 0 && width > maxwidth) { // Result is too long, must truncate somewhere. int item_idx = 0; @@ -4341,7 +4339,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use // If there are no items, truncate from beginning if (itemcnt == 0) { - trunc_p = out; + trunc_p = (char_u *)out; // Otherwise, look for the truncation item } else { @@ -4364,7 +4362,7 @@ int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use if (width - vim_strsize(trunc_p) >= maxwidth) { // Walk from the beginning of the // string to find the last character that will fit. - trunc_p = out; + trunc_p = (char_u *)out; width = 0; for (;;) { width += ptr2cells(trunc_p); @@ -5179,7 +5177,7 @@ static int chk_modeline(linenr_T lnum, int flags) if (*e == ':' && (s[0] != 'V' - || STRNCMP(skipwhite(e + 1), "set", 3) == 0) + || STRNCMP(skipwhite((char *)e + 1), "set", 3) == 0) && (s[3] == ':' || (VIM_VERSION_100 >= vers && isdigit(s[3])) || (VIM_VERSION_100 < vers && s[3] == '<') @@ -5209,7 +5207,7 @@ static int chk_modeline(linenr_T lnum, int flags) end = false; while (end == false) { - s = skipwhite(s); + s = (char_u *)skipwhite((char *)s); if (*s == NUL) { break; } -- cgit From 9aa5647e686e5420e5b9b51828ec7d55631f98ed Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 10 May 2022 07:58:58 +0800 Subject: vim-patch:8.2.4911: the mode #defines are not clearly named (#18499) Problem: The mode #defines are not clearly named. Solution: Prepend MODE_. Renumber them to put the mapped modes first. https://github.com/vim/vim/commit/249591057b4840785c50e41dd850efb8a8faf435 A hunk from the patch depends on patch 8.2.4861, which hasn't been ported yet, but that should be easy to notice. --- src/nvim/buffer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 107f61919a..8a56a08aaa 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1476,7 +1476,7 @@ void set_curbuf(buf_T *buf, int action) // Do not sync when in Insert mode and the buffer is open in // another window, might be a timer doing something in another // window. - if (prevbuf == curbuf && ((State & INSERT) == 0 || curbuf->b_nwindows <= 1)) { + if (prevbuf == curbuf && ((State & MODE_INSERT) == 0 || curbuf->b_nwindows <= 1)) { u_sync(false); } close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, @@ -3961,8 +3961,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san break; case STL_COLUMN: - num = !(State & INSERT) && empty_line - ? 0 : (int)wp->w_cursor.col + 1; + num = (State & MODE_INSERT) == 0 && empty_line ? 0 : (int)wp->w_cursor.col + 1; break; case STL_VIRTCOL: @@ -3970,7 +3969,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san colnr_T virtcol = wp->w_virtcol + 1; // Don't display %V if it's the same as %c. if (opt == STL_VIRTCOL_ALT - && (virtcol == (colnr_T)(!(State & INSERT) && empty_line + && (virtcol == (colnr_T)((State & MODE_INSERT) == 0 && empty_line ? 0 : (int)wp->w_cursor.col + 1))) { break; } @@ -4028,7 +4027,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL, false); num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0 ? - 0L : l + 1 + (!(State & INSERT) && empty_line ? + 0L : l + 1 + ((State & MODE_INSERT) == 0 && empty_line ? 0 : (int)wp->w_cursor.col); break; } -- cgit From 406c2e35b3efb72aac3fb7c174253b3397b77eb1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 10 May 2022 07:38:44 +0800 Subject: vim-patch:8.2.4929: off-by-one error in in statusline item Problem: Off-by-one error in in statusline item. Solution: Subtrace one less. (closes vim/vim#10394, closes vim/vim#5599) https://github.com/vim/vim/commit/57ff52677bf5ba1651281ffe40505df8feba4a36 --- src/nvim/buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 8a56a08aaa..ab804cc42f 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3635,7 +3635,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // correct the start of the items for the truncation for (int idx = stl_groupitems[groupdepth] + 1; idx < curitem; idx++) { // Shift everything back by the number of removed bytes - stl_items[idx].start -= n; + // Minus one for the leading '<' added above. + stl_items[idx].start -= n - 1; // If the item was partially or completely truncated, set its // start to the start of the group -- cgit From 0019886a84c7dfdaf452c8a715f26eb87c697b1b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 11 May 2022 19:07:31 +0800 Subject: vim-patch:8.2.4901: NULL pointer access when using invalid pattern Problem: NULL pointer access when using invalid pattern. Solution: Check for failed regexp program. https://github.com/vim/vim/commit/8e4b76da1d7e987d43ca960dfbc372d1c617466f --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ab804cc42f..f9ad16e357 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2387,7 +2387,7 @@ static char_u *fname_match(regmatch_T *rmp, char_u *name, bool ignore_case) rmp->rm_ic = p_fic || ignore_case; if (vim_regexec(rmp, name, (colnr_T)0)) { match = name; - } else { + } else if (rmp->regprog != NULL) { // Replace $(HOME) with '~' and try matching again. p = home_replace_save(NULL, name); if (vim_regexec(rmp, p, (colnr_T)0)) { -- cgit From 6f52bc5dee23e85d07eb7a32d4cbea633f9939ef Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 11 May 2022 19:10:18 +0800 Subject: vim-patch:8.2.4938: crash when matching buffer with invalid pattern Problem: Crash when matching buffer with invalid pattern. Solution: Check for NULL regprog. https://github.com/vim/vim/commit/a59f2dfd0cf9ee1a584d3de5b7c2d47648e79060 --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index f9ad16e357..2c9f997ac1 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2366,7 +2366,7 @@ static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) { // First try the short file name, then the long file name. char_u *match = fname_match(rmp, buf->b_sfname, ignore_case); - if (match == NULL) { + if (match == NULL && rmp->regprog != NULL) { match = fname_match(rmp, buf->b_ffname, ignore_case); } return match; -- cgit From 85aae12a6dea48621ea2d24a946b3e7b86f9014d Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Sun, 8 May 2022 14:43:16 +0200 Subject: refactor: replace char_u variables and functions with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ab804cc42f..30e5edb4d0 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -111,8 +111,8 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags) // the end. This makes it possible to retry when 'fileformat' or // 'fileencoding' was guessed wrong. line_count = curbuf->b_ml.ml_line_count; - retval = readfile(read_stdin ? NULL : curbuf->b_ffname, - read_stdin ? NULL : curbuf->b_fname, + retval = readfile(read_stdin ? NULL : (char *)curbuf->b_ffname, + read_stdin ? NULL : (char *)curbuf->b_fname, line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap, flags | READ_BUFFER, silent); if (retval == OK) { @@ -229,7 +229,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) } #endif - retval = readfile(curbuf->b_ffname, curbuf->b_fname, + retval = readfile((char *)curbuf->b_ffname, (char *)curbuf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, flags | READ_NEW | (read_fifo ? READ_FIFO : 0), silent); #ifdef UNIX @@ -3175,7 +3175,7 @@ void maketitle(void) SPACE_FOR_FNAME + 1); buf_p += MIN(size, SPACE_FOR_FNAME); } else { - buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname), + buf_p += transstr_buf((const char *)path_tail((char *)curbuf->b_fname), buf_p, SPACE_FOR_FNAME + 1, true); } @@ -3285,7 +3285,7 @@ void maketitle(void) if (buf_spname(curbuf) != NULL) { buf_p = buf_spname(curbuf); } else { // use file name only in icon - buf_p = path_tail(curbuf->b_ffname); + buf_p = (char_u *)path_tail((char *)curbuf->b_ffname); } *icon_str = NUL; // Truncate name at 100 bytes. @@ -3841,7 +3841,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (opt != STL_FILENAME) { str = (char *)NameBuff; } else { - str = (char *)path_tail(NameBuff); + str = path_tail((char *)NameBuff); } break; case STL_VIM_EXPR: // '{' @@ -3909,7 +3909,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Check if the evaluated result is a number. // If so, convert the number to an int and free the string. if (str != NULL && *str != 0) { - if (*skipdigits((char_u *)str) == NUL) { + if (*skipdigits(str) == NUL) { num = atoi(str); XFREE_CLEAR(str); itemisflag = false; @@ -5201,9 +5201,9 @@ static int chk_modeline(linenr_T lnum, int flags) s = linecopy = vim_strsave(s); // copy the line, it will change save_sourcing_lnum = sourcing_lnum; - save_sourcing_name = sourcing_name; + save_sourcing_name = (char_u *)sourcing_name; sourcing_lnum = lnum; // prepare for emsg() - sourcing_name = (char_u *)"modelines"; + sourcing_name = "modelines"; end = false; while (end == false) { @@ -5259,7 +5259,7 @@ static int chk_modeline(linenr_T lnum, int flags) } sourcing_lnum = save_sourcing_lnum; - sourcing_name = save_sourcing_name; + sourcing_name = (char *)save_sourcing_name; xfree(linecopy); @@ -5594,7 +5594,7 @@ bool buf_contents_changed(buf_T *buf) aucmd_prepbuf(&aco, newbuf); if (ml_open(curbuf) == OK - && readfile(buf->b_ffname, buf->b_fname, + && readfile((char *)buf->b_ffname, (char *)buf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, &ea, READ_NEW | READ_DUMMY, false) == OK) { // compare the two files line by line -- cgit From f0148de7907ec297647816d51c79745be729439e Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Mon, 9 May 2022 11:49:32 +0200 Subject: refactor: replace char_u variables and functions with char Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 75 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 38 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 18c8a2c250..4b1aea5720 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -112,7 +112,7 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags) // 'fileencoding' was guessed wrong. line_count = curbuf->b_ml.ml_line_count; retval = readfile(read_stdin ? NULL : (char *)curbuf->b_ffname, - read_stdin ? NULL : (char *)curbuf->b_fname, + read_stdin ? NULL : curbuf->b_fname, line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap, flags | READ_BUFFER, silent); if (retval == OK) { @@ -229,7 +229,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) } #endif - retval = readfile((char *)curbuf->b_ffname, (char *)curbuf->b_fname, + retval = readfile((char *)curbuf->b_ffname, curbuf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, flags | READ_NEW | (read_fifo ? READ_FIFO : 0), silent); #ifdef UNIX @@ -1219,8 +1219,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) return FAIL; } } else { - semsg(_("E89: %s will be killed (add ! to override)"), - (char *)buf->b_fname); + semsg(_("E89: %s will be killed (add ! to override)"), buf->b_fname); return FAIL; } } @@ -1803,7 +1802,7 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl hash_init(&buf->b_s.b_keywtab); hash_init(&buf->b_s.b_keywtab_ic); - buf->b_fname = buf->b_sfname; + buf->b_fname = (char *)buf->b_sfname; if (!file_id_valid) { buf->file_id_valid = false; } else { @@ -2113,10 +2112,10 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlis { int match = -1; int find_listed; - char_u *pat; - char_u *patend; + char *pat; + char *patend; int attempt; - char_u *p; + char *p; int toggledollar; if (pattern_end == pattern + 1 && (*pattern == '%' || *pattern == '#')) { @@ -2138,7 +2137,7 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlis // Repeat this for finding an unlisted buffer if there was no matching // listed buffer. - pat = file_pat_to_reg_pat(pattern, pattern_end, NULL, false); + pat = file_pat_to_reg_pat((char *)pattern, (char *)pattern_end, NULL, false); if (pat == NULL) { return -1; } @@ -2271,7 +2270,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) } regmatch_T regmatch; - regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC); + regmatch.regprog = vim_regcomp((char *)patc + attempt * 11, RE_MAGIC); if (regmatch.regprog == NULL) { if (patc != pat) { xfree(patc); @@ -2426,7 +2425,7 @@ char_u *buflist_nr2name(int n, int fullname, int helptail) return NULL; } return home_replace_save(helptail ? buf : NULL, - fullname ? buf->b_ffname : buf->b_fname); + fullname ? buf->b_ffname : (char_u *)buf->b_fname); } /// Set the line and column numbers for the given buffer and window @@ -2622,7 +2621,7 @@ void buflist_list(exarg_T *eap) garray_T buflist; buf_T **buflist_data = NULL; - if (vim_strchr((char_u *)eap->arg, 't')) { + if (vim_strchr(eap->arg, 't')) { ga_init(&buflist, sizeof(buf_T *), 50); for (buf = firstbuf; buf != NULL; buf = buf->b_next) { ga_grow(&buflist, 1); @@ -2645,28 +2644,28 @@ void buflist_list(exarg_T *eap) const bool job_running = buf->terminal && terminal_running(buf->terminal); // skip unspecified buffers - if ((!buf->b_p_bl && !eap->forceit && !vim_strchr((char_u *)eap->arg, 'u')) - || (vim_strchr((char_u *)eap->arg, 'u') && buf->b_p_bl) - || (vim_strchr((char_u *)eap->arg, '+') + if ((!buf->b_p_bl && !eap->forceit && !vim_strchr(eap->arg, 'u')) + || (vim_strchr(eap->arg, 'u') && buf->b_p_bl) + || (vim_strchr(eap->arg, '+') && ((buf->b_flags & BF_READERR) || !bufIsChanged(buf))) - || (vim_strchr((char_u *)eap->arg, 'a') + || (vim_strchr(eap->arg, 'a') && (buf->b_ml.ml_mfp == NULL || buf->b_nwindows == 0)) - || (vim_strchr((char_u *)eap->arg, 'h') + || (vim_strchr(eap->arg, 'h') && (buf->b_ml.ml_mfp == NULL || buf->b_nwindows != 0)) - || (vim_strchr((char_u *)eap->arg, 'R') && (!is_terminal || !job_running)) - || (vim_strchr((char_u *)eap->arg, 'F') && (!is_terminal || job_running)) - || (vim_strchr((char_u *)eap->arg, '-') && buf->b_p_ma) - || (vim_strchr((char_u *)eap->arg, '=') && !buf->b_p_ro) - || (vim_strchr((char_u *)eap->arg, 'x') && !(buf->b_flags & BF_READERR)) - || (vim_strchr((char_u *)eap->arg, '%') && buf != curbuf) - || (vim_strchr((char_u *)eap->arg, '#') + || (vim_strchr(eap->arg, 'R') && (!is_terminal || !job_running)) + || (vim_strchr(eap->arg, 'F') && (!is_terminal || job_running)) + || (vim_strchr(eap->arg, '-') && buf->b_p_ma) + || (vim_strchr(eap->arg, '=') && !buf->b_p_ro) + || (vim_strchr(eap->arg, 'x') && !(buf->b_flags & BF_READERR)) + || (vim_strchr(eap->arg, '%') && buf != curbuf) + || (vim_strchr(eap->arg, '#') && (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) { continue; } if (buf_spname(buf) != NULL) { STRLCPY(NameBuff, buf_spname(buf), MAXPATHL); } else { - home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, true); + home_replace(buf, (char_u *)buf->b_fname, NameBuff, MAXPATHL, true); } if (message_filtered(NameBuff)) { @@ -2700,7 +2699,7 @@ void buflist_list(exarg_T *eap) do { IObuff[len++] = ' '; } while (--i > 0 && len < IOSIZE - 18); - if (vim_strchr((char_u *)eap->arg, 't') && buf->b_last_used) { + if (vim_strchr(eap->arg, 't') && buf->b_last_used) { undo_fmt_time(IObuff + len, (size_t)(IOSIZE - len), buf->b_last_used); } else { vim_snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), _("line %" PRId64), @@ -2730,7 +2729,7 @@ int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum) return FAIL; } - *fname = buf->b_fname; + *fname = (char_u *)buf->b_fname; *lnum = buflist_findlnum(buf); return OK; @@ -2794,7 +2793,7 @@ int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) buf->b_ffname = ffname; buf->b_sfname = sfname; } - buf->b_fname = buf->b_sfname; + buf->b_fname = (char *)buf->b_sfname; if (!file_id_valid) { buf->file_id_valid = false; } else { @@ -2823,7 +2822,7 @@ void buf_set_name(int fnum, char_u *name) // Allocate ffname and expand into full path. Also resolves .lnk // files on Win32. fname_expand(buf, &buf->b_ffname, &buf->b_sfname); - buf->b_fname = buf->b_sfname; + buf->b_fname = (char *)buf->b_sfname; } } @@ -2980,7 +2979,7 @@ void buf_set_file_id(buf_T *buf) { FileID file_id; if (buf->b_fname != NULL - && os_fileid((char *)buf->b_fname, &file_id)) { + && os_fileid(buf->b_fname, &file_id)) { buf->file_id_valid = true; buf->file_id = file_id; } else { @@ -3023,7 +3022,7 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate) STRLCPY(p, buf_spname(curbuf), IOSIZE - (p - buffer)); } else { if (!fullname && curbuf->b_fname != NULL) { - name = curbuf->b_fname; + name = (char_u *)curbuf->b_fname; } else { name = curbuf->b_ffname; } @@ -3175,7 +3174,7 @@ void maketitle(void) SPACE_FOR_FNAME + 1); buf_p += MIN(size, SPACE_FOR_FNAME); } else { - buf_p += transstr_buf((const char *)path_tail((char *)curbuf->b_fname), + buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname), buf_p, SPACE_FOR_FNAME + 1, true); } @@ -3834,7 +3833,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san STRLCPY(NameBuff, buf_spname(wp->w_buffer), MAXPATHL); } else { char_u *t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname - : wp->w_buffer->b_fname; + : (char_u *)wp->w_buffer->b_fname; home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, true); } trans_characters(NameBuff, MAXPATHL); @@ -4650,7 +4649,7 @@ char_u *alist_name(aentry_T *aep) if (bp == NULL || bp->b_fname == NULL) { return aep->ae_fname; } - return bp->b_fname; + return (char_u *)bp->b_fname; } /// do_arg_all(): Open up to 'count' windows, one for each argument. @@ -5234,7 +5233,7 @@ static int chk_modeline(linenr_T lnum, int flags) break; } end = true; - s = vim_strchr(s, ' ') + 1; + s = (char_u *)vim_strchr((char *)s, ' ') + 1; } *e = NUL; // truncate the set command @@ -5358,7 +5357,7 @@ char_u *buf_spname(buf_T *buf) // contains the name as specified by the user. if (bt_nofile(buf)) { if (buf->b_fname != NULL) { - return buf->b_fname; + return (char_u *)buf->b_fname; } if (bt_prompt(buf)) { return (char_u *)_("[Prompt]"); @@ -5552,7 +5551,7 @@ char_u *buf_get_fname(const buf_T *buf) if (buf->b_fname == NULL) { return (char_u *)_("[No Name]"); } - return buf->b_fname; + return (char_u *)buf->b_fname; } /// Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed. @@ -5594,7 +5593,7 @@ bool buf_contents_changed(buf_T *buf) aucmd_prepbuf(&aco, newbuf); if (ml_open(curbuf) == OK - && readfile((char *)buf->b_ffname, (char *)buf->b_fname, + && readfile((char *)buf->b_ffname, buf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, &ea, READ_NEW | READ_DUMMY, false) == OK) { // compare the two files line by line -- cgit From 9fec6dc9a25b5cf9c9a444ac2bd0728e8af3229e Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 25 May 2022 20:31:14 +0200 Subject: refactor(uncrustify): set maximum number of consecutive newlines to 2 (#18695) --- src/nvim/buffer.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4b1aea5720..4c3f1308b3 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1025,11 +1025,9 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end } } - return errormsg; } - /// Make the current buffer empty. /// Used when it is wiped out and it's the last buffer. static int empty_curbuf(int close_others, int forceit, int action) @@ -1180,7 +1178,6 @@ int do_buffer(int action, int start, int dir, int count, int forceit) return FAIL; } - // delete buffer "buf" from memory and/or the list if (unload) { int forward; @@ -1425,7 +1422,6 @@ int do_buffer(int action, int start, int dir, int count, int forceit) return OK; } - /// Set current buffer to "buf". Executes autocommands and closes current /// buffer. /// @@ -1585,7 +1581,6 @@ void enter_buffer(buf_T *buf) scroll_cursor_halfway(false); // redisplay at correct position } - // Change directories when the 'acd' option is set. do_autochdir(); @@ -1932,7 +1927,6 @@ void free_buf_options(buf_T *buf, int free_p_ff) clear_string_option(&buf->b_p_menc); } - /// Get alternate file "n". /// Set linenr to "lnum" or altfpos.lnum if "lnum" == 0. /// Also set cursor column to altfpos.col if 'startofline' is not set. @@ -2357,7 +2351,6 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) return count == 0 ? FAIL : OK; } - /// Check for a match on the file name for buffer "buf" with regprog "prog". /// /// @param ignore_case When true, ignore case. Use 'fic' otherwise. @@ -2491,7 +2484,6 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T } } - /// Check that "wip" has 'diff' set and the diff is only for another tab page. /// That's because a diff is local to a tab page. static bool wininfo_other_tab_diff(wininfo_T *wip) @@ -3113,7 +3105,6 @@ void col_print(char_u *buf, size_t buflen, int col, int vcol) static char_u *lasttitle = NULL; static char_u *lasticon = NULL; - /// Put the title name in the title bar and icon of the window. void maketitle(void) { @@ -3331,7 +3322,6 @@ static bool value_change(char_u *str, char_u **last) return false; } - /// Set current window title void resettitle(void) { @@ -3356,7 +3346,6 @@ typedef enum { kNumBaseHexadecimal = 16, } NumberBase; - /// Build a string from the status line items in "fmt". /// Return length of string in screen cells. /// @@ -3473,7 +3462,6 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // so any user-visible characters must occur before here. char *out_end_p = (out + outlen) - 1; - // Proceed character by character through the statusline format string // fmt_p is the current position in the input buffer for (char *fmt_p = usefmt; *fmt_p;) { @@ -3915,7 +3903,6 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } } - // If the output of the expression needs to be evaluated // replace the %{} block with the result of evaluation if (reevaluate && str != NULL && *str != 0 @@ -4698,7 +4685,6 @@ void do_arg_all(int count, int forceit, int keep_tabs) old_curwin = curwin; old_curtab = curtab; - // Try closing all windows that are not in the argument list. // Also close windows that are not full width; // When 'hidden' or "forceit" set the buffer becomes hidden. @@ -4947,7 +4933,6 @@ void ex_buffer_all(exarg_T *eap) setpcmark(); - // Close superfluous windows (two windows for the same buffer). // Also close windows that are not full-width. if (had_tab > 0) { @@ -5098,7 +5083,6 @@ void ex_buffer_all(exarg_T *eap) } } - /// do_modelines() - process mode lines for the current file /// /// @param flags -- cgit From 429c40cce3fce3b5391afef8208d65a80a316018 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 13 Jun 2022 06:02:00 +0800 Subject: fix(buffer): disable buffer-updates before removing from window #18933 There can be other places that access window buffer info (e.g. `tabpagebuflist()`), so checking `w_closing` in `win_findbuf()` doesn't solve the crash in all cases, and may also cause Nvim's behavior to diverge from Vim. Fix #14998 --- src/nvim/buffer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4c3f1308b3..921cd20943 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -575,6 +575,10 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i return false; } + // Disable buffer-updates for the current buffer. + // No need to check `unload_buf`: in that case the function returned above. + buf_updates_unload(buf, false); + if (win != NULL // Avoid bogus clang warning. && win_valid_any_tab(win) && win->w_buffer == buf) { @@ -587,10 +591,6 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i buf->b_nwindows--; } - // Disable buffer-updates for the current buffer. - // No need to check `unload_buf`: in that case the function returned above. - buf_updates_unload(buf, false); - // Remove the buffer from the list. if (wipe_buf) { // Do not wipe out the buffer if it is used in a window. -- cgit From 6130b4a84b41b71f4c0c58093a29585c6c67ff16 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 13 Jun 2022 20:20:34 +0800 Subject: vim-patch:8.2.1898: command modifier parsing always uses global cmdmod Problem: Command modifier parsing always uses global cmdmod. Solution: Pass in cmdmod_T to use. Rename struct fields consistently. https://github.com/vim/vim/commit/e10044015841711b989f9a898d427bcc1fdb4c32 --- src/nvim/buffer.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 921cd20943..4fb3f66349 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1191,7 +1191,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) } if (!forceit && bufIsChanged(buf)) { - if ((p_confirm || cmdmod.confirm) && p_write) { + if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) && p_write) { dialog_changed(buf, false); if (!bufref_valid(&bufref)) { // Autocommand deleted buffer, oops! It's not changed now. @@ -1211,7 +1211,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) } if (!forceit && buf->terminal && terminal_running(buf->terminal)) { - if (p_confirm || cmdmod.confirm) { + if (p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) { if (!dialog_close_terminal(buf)) { return FAIL; } @@ -1393,7 +1393,7 @@ int do_buffer(int action, int start, int dir, int count, int forceit) // Check if the current buffer may be abandoned. if (action == DOBUF_GOTO && !can_abandon(curbuf, forceit)) { - if ((p_confirm || cmdmod.confirm) && p_write) { + if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) && p_write) { bufref_T bufref; set_bufref(&bufref, buf); dialog_changed(curbuf, false); @@ -1439,7 +1439,7 @@ void set_curbuf(buf_T *buf, int action) long old_tw = curbuf->b_p_tw; setpcmark(); - if (!cmdmod.keepalt) { + if ((cmdmod.cmod_flags & CMOD_KEEPALT) == 0) { curwin->w_alt_fnum = curbuf->b_fnum; // remember alternate file } buflist_altfpos(curwin); // remember curpos @@ -2846,7 +2846,7 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum) // Create a buffer. 'buflisted' is not set if it's a new buffer buf = buflist_new(ffname, sfname, lnum, 0); - if (buf != NULL && !cmdmod.keepalt) { + if (buf != NULL && (cmdmod.cmod_flags & CMOD_KEEPALT) == 0) { curwin->w_alt_fnum = buf->b_fnum; } return buf; @@ -4659,7 +4659,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) alist_T *alist; // argument list to be used buf_T *buf; tabpage_T *tpnext; - int had_tab = cmdmod.tab; + int had_tab = cmdmod.cmod_tab; win_T *old_curwin, *last_curwin; tabpage_T *old_curtab, *last_curtab; win_T *new_curwin = NULL; @@ -4870,7 +4870,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) // When ":tab" was used open a new tab for a new window repeatedly. if (had_tab > 0 && tabpage_index(NULL) <= p_tpm) { - cmdmod.tab = 9999; + cmdmod.cmod_tab = 9999; } } @@ -4917,7 +4917,7 @@ void ex_buffer_all(exarg_T *eap) int r; long count; // Maximum number of windows to open. int all; // When true also load inactive buffers. - int had_tab = cmdmod.tab; + int had_tab = cmdmod.cmod_tab; tabpage_T *tpnext; if (eap->addr_count == 0) { // make as many windows as possible @@ -4943,7 +4943,7 @@ void ex_buffer_all(exarg_T *eap) for (wp = firstwin; wp != NULL; wp = wpnext) { wpnext = wp->w_next; if ((wp->w_buffer->b_nwindows > 1 - || ((cmdmod.split & WSP_VERT) + || ((cmdmod.cmod_split & WSP_VERT) ? wp->w_height + wp->w_hsep_height + wp->w_status_height < Rows - p_ch - tabline_height() - global_stl_height() : wp->w_width != Columns) @@ -5056,7 +5056,7 @@ void ex_buffer_all(exarg_T *eap) } // When ":tab" was used open a new tab for a new window repeatedly. if (had_tab > 0 && tabpage_index(NULL) <= p_tpm) { - cmdmod.tab = 9999; + cmdmod.cmod_tab = 9999; } } autocmd_no_enter--; @@ -5322,7 +5322,7 @@ bool buf_hide(const buf_T *const buf) case 'h': return true; // "hide" } - return p_hid || cmdmod.hide; + return p_hid || (cmdmod.cmod_flags & CMOD_HIDE); } /// @return special buffer name or -- cgit From ff6b8f54359037790b300cb06a025f84f11d829a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 18 Jun 2022 18:53:12 +0200 Subject: fix(terminal): coverity USE_AFTER_FREE #18978 Problem: Coverity reports use after free: *** CID 352784: Memory - illegal accesses (USE_AFTER_FREE) /src/nvim/buffer.c: 1508 in set_curbuf() 1502 if (old_tw != curbuf->b_p_tw) { 1503 check_colorcolumn(curwin); 1504 } 1505 } 1506 1507 if (bufref_valid(&prevbufref) && prevbuf->terminal != NULL) { >>> CID 352784: Memory - illegal accesses (USE_AFTER_FREE) >>> Calling "terminal_check_size" dereferences freed pointer "prevbuf->terminal". 1508 terminal_check_size(prevbuf->terminal); 1509 } 1510 } 1511 1512 /// Enter a new current buffer. 1513 /// Old curbuf must have been abandoned already! This also means "curbuf" may Solution: Change terminal_destroy and terminal_close to set caller storage to NULL, similar to XFREE_CLEAR. This aligns with the pattern found already in: terminal_destroy e897ccad3eb1e term_delayed_free 3e59c1e20d605 --- src/nvim/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4fb3f66349..f13f6e35ea 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -527,7 +527,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i } if (buf->terminal) { - terminal_close(buf->terminal, -1); + terminal_close(&buf->terminal, -1); } // Always remove the buffer when there is no file name. -- cgit From 7718b758461265d8966468c104ce5454538471e2 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 23 Jun 2022 21:17:11 +0800 Subject: refactor: move some mapping-related code to a separate file (#19061) This marks the following Vim patches as ported: vim-patch:8.1.1785: map functionality mixed with character input Problem: Map functionality mixed with character input. Solution: Move the map functionality to a separate file. (Yegappan Lakshmanan, closes vim/vim#4740) Graduate the +localmap feature. https://github.com/vim/vim/commit/b66bab381c8ba71fd6e92327d1d34c6f8a65f2a7 vim-patch:8.2.3643: header for source file is outdated Problem: Header for source file is outdated. Solution: Make the header more accurate. (closes vim/vim#9186) https://github.com/vim/vim/commit/a3f83feb63eae5464a620ae793c002eb45f7a838 Also cherry-pick a change for mappings from patch 8.2.0807. Rename map_clear_mode() to do_mapclear(). --- src/nvim/buffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index f13f6e35ea..85e34e910d 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -53,6 +53,7 @@ #include "nvim/indent.h" #include "nvim/indent_c.h" #include "nvim/main.h" +#include "nvim/mapping.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memory.h" -- cgit From 014a88799a1d175ad121c520c9cc5bd0bb2d8813 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Tue, 28 Jun 2022 11:31:54 +0200 Subject: refactor: replace char_u #18429 Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 369 ++++++++++++++++++++++++++---------------------------- 1 file changed, 179 insertions(+), 190 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 85e34e910d..46adb55746 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -948,7 +948,7 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end int deleted = 0; // number of buffers deleted char *errormsg = NULL; // return value int bnr; // buffer number - char_u *p; + char *p; if (addr_count == 0) { (void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit); @@ -985,13 +985,12 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end break; } if (!ascii_isdigit(*arg)) { - p = skiptowhite_esc(arg); - bnr = buflist_findpat(arg, p, command == DOBUF_WIPE, - false, false); + p = (char *)skiptowhite_esc(arg); + bnr = buflist_findpat(arg, (char_u *)p, command == DOBUF_WIPE, false, false); if (bnr < 0) { // failed break; } - arg = p; + arg = (char_u *)p; } else { bnr = getdigits_int(&arg, false, 0); } @@ -1679,8 +1678,8 @@ static inline void buf_init_changedtick(buf_T *const buf) /// @return pointer to the buffer buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int flags) { - char_u *ffname = ffname_arg; - char_u *sfname = sfname_arg; + char *ffname = (char *)ffname_arg; + char *sfname = (char *)sfname_arg; buf_T *buf; fname_expand(curbuf, &ffname, &sfname); // will allocate ffname @@ -1690,11 +1689,9 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl // We can use inode numbers when the file exists. Works better // for hard links. FileID file_id; - bool file_id_valid = (sfname != NULL - && os_fileid((char *)sfname, &file_id)); + bool file_id_valid = (sfname != NULL && os_fileid(sfname, &file_id)); if (ffname != NULL && !(flags & (BLN_DUMMY | BLN_NEW)) - && (buf = buflist_findname_file_id(ffname, &file_id, - file_id_valid)) != NULL) { + && (buf = buflist_findname_file_id(ffname, &file_id, file_id_valid)) != NULL) { xfree(ffname); if (lnum != 0) { buflist_setfpos(buf, (flags & BLN_NOCURWIN) ? NULL : curwin, @@ -1749,8 +1746,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl } if (ffname != NULL) { - buf->b_ffname = ffname; - buf->b_sfname = vim_strsave(sfname); + buf->b_ffname = (char_u *)ffname; + buf->b_sfname = vim_strsave((char_u *)sfname); } clear_wininfo(buf); @@ -2045,20 +2042,20 @@ void buflist_getfpos(void) /// @return buffer or NULL if not found buf_T *buflist_findname_exp(char_u *fname) { - char_u *ffname; + char *ffname; buf_T *buf = NULL; // First make the name into a full path name - ffname = (char_u *)FullName_save((char *)fname, + ffname = FullName_save((char *)fname, #ifdef UNIX - // force expansion, get rid of symbolic links - true + // force expansion, get rid of symbolic links + true #else - false + false #endif - ); // NOLINT(whitespace/parens) + ); // NOLINT(whitespace/parens) if (ffname != NULL) { - buf = buflist_findname(ffname); + buf = buflist_findname((char_u *)ffname); xfree(ffname); } return buf; @@ -2073,14 +2070,14 @@ buf_T *buflist_findname(char_u *ffname) { FileID file_id; bool file_id_valid = os_fileid((char *)ffname, &file_id); - return buflist_findname_file_id(ffname, &file_id, file_id_valid); + return buflist_findname_file_id((char *)ffname, &file_id, file_id_valid); } /// Same as buflist_findname(), but pass the FileID structure to avoid /// getting it twice for the same file. /// /// @return buffer or NULL if not found -static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id, bool file_id_valid) +static buf_T *buflist_findname_file_id(char *ffname, FileID *file_id, bool file_id_valid) FUNC_ATTR_PURE { // Start at the last buffer, expect to find a match sooner. @@ -2213,7 +2210,7 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlis typedef struct { buf_T *buf; - char_u *match; + char *match; } bufmatch_T; /// Compare functions for qsort() below, that compares b_last_used. @@ -2236,9 +2233,9 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) { int count = 0; int round; - char_u *p; + char *p; int attempt; - char_u *patc; + char *patc; bufmatch_T *matches = NULL; *num_file = 0; // return values in case of FAIL @@ -2254,20 +2251,20 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) STRCPY(patc, "\\(^\\|[\\/]\\)"); STRCPY(patc + 11, pat + 1); } else { - patc = pat; + patc = (char *)pat; } // attempt == 0: try match with '\<', match at start of word // attempt == 1: try match without '\<', match anywhere for (attempt = 0; attempt <= 1; attempt++) { - if (attempt > 0 && patc == pat) { + if (attempt > 0 && (char_u *)patc == pat) { break; // there was no anchor, no need to try again } regmatch_T regmatch; - regmatch.regprog = vim_regcomp((char *)patc + attempt * 11, RE_MAGIC); + regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC); if (regmatch.regprog == NULL) { - if (patc != pat) { + if ((char_u *)patc != pat) { xfree(patc); } return FAIL; @@ -2294,16 +2291,16 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) count++; } else { if (options & WILD_HOME_REPLACE) { - p = home_replace_save(buf, p); + p = (char *)home_replace_save(buf, (char_u *)p); } else { - p = vim_strsave(p); + p = xstrdup(p); } if (matches != NULL) { matches[count].buf = buf; matches[count].match = p; count++; } else { - (*file)[count++] = p; + (*file)[count++] = (char_u *)p; } } } @@ -2325,7 +2322,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) } } - if (patc != pat) { + if ((char_u *)patc != pat) { xfree(patc); } @@ -2337,12 +2334,12 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) // if the current buffer is first in the list, place it at the end if (matches[0].buf == curbuf) { for (int i = 1; i < count; i++) { - (*file)[i - 1] = matches[i].match; + (*file)[i - 1] = (char_u *)matches[i].match; } - (*file)[count - 1] = matches[0].match; + (*file)[count - 1] = (char_u *)matches[0].match; } else { for (int i = 0; i < count; i++) { - (*file)[i] = matches[i].match; + (*file)[i] = (char_u *)matches[i].match; } } xfree(matches); @@ -2355,12 +2352,12 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) /// Check for a match on the file name for buffer "buf" with regprog "prog". /// /// @param ignore_case When true, ignore case. Use 'fic' otherwise. -static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) +static char *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) { // First try the short file name, then the long file name. - char_u *match = fname_match(rmp, buf->b_sfname, ignore_case); + char *match = fname_match(rmp, (char *)buf->b_sfname, ignore_case); if (match == NULL && rmp->regprog != NULL) { - match = fname_match(rmp, buf->b_ffname, ignore_case); + match = fname_match(rmp, (char *)buf->b_ffname, ignore_case); } return match; } @@ -2370,20 +2367,20 @@ static char_u *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) /// @param ignore_case When true, ignore case. Use 'fileignorecase' otherwise. /// /// @return "name" when there is a match, NULL when not. -static char_u *fname_match(regmatch_T *rmp, char_u *name, bool ignore_case) +static char *fname_match(regmatch_T *rmp, char *name, bool ignore_case) { - char_u *match = NULL; - char_u *p; + char *match = NULL; + char *p; if (name != NULL) { // Ignore case when 'fileignorecase' or the argument is set. rmp->rm_ic = p_fic || ignore_case; - if (vim_regexec(rmp, name, (colnr_T)0)) { + if (vim_regexec(rmp, (char_u *)name, (colnr_T)0)) { match = name; } else if (rmp->regprog != NULL) { // Replace $(HOME) with '~' and try matching again. - p = home_replace_save(NULL, name); - if (vim_regexec(rmp, p, (colnr_T)0)) { + p = (char *)home_replace_save(NULL, (char_u *)name); + if (vim_regexec(rmp, (char_u *)p, (colnr_T)0)) { match = name; } xfree(p); @@ -2658,7 +2655,7 @@ void buflist_list(exarg_T *eap) if (buf_spname(buf) != NULL) { STRLCPY(NameBuff, buf_spname(buf), MAXPATHL); } else { - home_replace(buf, (char_u *)buf->b_fname, NameBuff, MAXPATHL, true); + home_replace(buf, buf->b_fname, (char *)NameBuff, MAXPATHL, true); } if (message_filtered(NameBuff)) { @@ -2688,7 +2685,7 @@ void buflist_list(exarg_T *eap) } // put "line 999" in column 40 or after the file name - i = 40 - vim_strsize(IObuff); + i = 40 - vim_strsize((char *)IObuff); do { IObuff[len++] = ' '; } while (--i > 0 && len < IOSIZE - 18); @@ -2699,7 +2696,7 @@ void buflist_list(exarg_T *eap) buf == curbuf ? (int64_t)curwin->w_cursor.lnum : (int64_t)buflist_findlnum(buf)); } - msg_outtrans(IObuff); + msg_outtrans((char *)IObuff); line_breakcheck(); } @@ -2735,10 +2732,10 @@ int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum) /// @param message give message when buffer already exists /// /// @return FAIL for failure (file name already in use by other buffer) OK otherwise. -int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) +int setfname(buf_T *buf, char *ffname_arg, char *sfname_arg, bool message) { - char_u *ffname = ffname_arg; - char_u *sfname = sfname_arg; + char *ffname = ffname_arg; + char *sfname = sfname_arg; buf_T *obuf = NULL; FileID file_id; bool file_id_valid = false; @@ -2760,7 +2757,7 @@ int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) // If the file name is already used in another buffer: // - if the buffer is loaded, fail // - if the buffer is not loaded, delete it from the list - file_id_valid = os_fileid((char *)ffname, &file_id); + file_id_valid = os_fileid(ffname, &file_id); if (!(buf->b_flags & BF_DUMMY)) { obuf = buflist_findname_file_id(ffname, &file_id, file_id_valid); } @@ -2775,16 +2772,16 @@ int setfname(buf_T *buf, char_u *ffname_arg, char_u *sfname_arg, bool message) // delete from the list close_buffer(NULL, obuf, DOBUF_WIPE, false, false); } - sfname = vim_strsave(sfname); + sfname = xstrdup(sfname); #ifdef USE_FNAME_CASE - path_fix_case(sfname); // set correct case for short file name + path_fix_case((char_u *)sfname); // set correct case for short file name #endif if (buf->b_sfname != buf->b_ffname) { xfree(buf->b_sfname); } xfree(buf->b_ffname); - buf->b_ffname = ffname; - buf->b_sfname = sfname; + buf->b_ffname = (char_u *)ffname; + buf->b_sfname = (char_u *)sfname; } buf->b_fname = (char *)buf->b_sfname; if (!file_id_valid) { @@ -2814,7 +2811,7 @@ void buf_set_name(int fnum, char_u *name) buf->b_sfname = NULL; // Allocate ffname and expand into full path. Also resolves .lnk // files on Win32. - fname_expand(buf, &buf->b_ffname, &buf->b_sfname); + fname_expand(buf, (char **)&buf->b_ffname, (char **)&buf->b_sfname); buf->b_fname = (char *)buf->b_sfname; } } @@ -2859,16 +2856,16 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum) /// @param errmsg give error message char_u *getaltfname(bool errmsg) { - char_u *fname; + char *fname; linenr_T dummy; - if (buflist_name_nr(0, &fname, &dummy) == FAIL) { + if (buflist_name_nr(0, (char_u **)&fname, &dummy) == FAIL) { if (errmsg) { emsg(_(e_noalt)); } return NULL; } - return fname; + return (char_u *)fname; } /// Add a file name to the buflist and return its number. @@ -2916,7 +2913,7 @@ void buflist_altfpos(win_T *win) bool otherfile(char_u *ffname) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return otherfile_buf(curbuf, ffname, NULL, false); + return otherfile_buf(curbuf, (char *)ffname, NULL, false); } /// Check that "ffname" is not the same file as the file loaded in "buf". @@ -2926,7 +2923,7 @@ bool otherfile(char_u *ffname) /// @param ffname full path name to check /// @param file_id_p information about the file at "ffname". /// @param file_id_valid whether a valid "file_id_p" was passed in. -static bool otherfile_buf(buf_T *buf, char_u *ffname, FileID *file_id_p, bool file_id_valid) +static bool otherfile_buf(buf_T *buf, char *ffname, FileID *file_id_p, bool file_id_valid) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { // no name is different @@ -2941,7 +2938,7 @@ static bool otherfile_buf(buf_T *buf, char_u *ffname, FileID *file_id_p, bool fi // If no struct stat given, get it now if (file_id_p == NULL) { file_id_p = &file_id; - file_id_valid = os_fileid((char *)ffname, file_id_p); + file_id_valid = os_fileid(ffname, file_id_p); } if (!file_id_valid) { // file_id not valid, assume files are different. @@ -2995,7 +2992,7 @@ static bool buf_same_file_id(buf_T *buf, FileID *file_id) /// @param fullname when non-zero print full path void fileinfo(int fullname, int shorthelp, int dont_truncate) { - char_u *name; + char *name; int n; char *p; char *buffer; @@ -3015,11 +3012,11 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate) STRLCPY(p, buf_spname(curbuf), IOSIZE - (p - buffer)); } else { if (!fullname && curbuf->b_fname != NULL) { - name = (char_u *)curbuf->b_fname; + name = curbuf->b_fname; } else { - name = curbuf->b_ffname; + name = (char *)curbuf->b_ffname; } - home_replace(shorthelp ? curbuf : NULL, name, (char_u *)p, + home_replace(shorthelp ? curbuf : NULL, name, p, (size_t)(IOSIZE - (p - buffer)), true); } @@ -3069,7 +3066,7 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate) (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1); } - (void)append_arg_number(curwin, (char_u *)buffer, IOSIZE, !shortmess(SHM_FILE)); + (void)append_arg_number(curwin, buffer, IOSIZE, !shortmess(SHM_FILE)); if (dont_truncate) { // Temporarily set msg_scroll to avoid the message being truncated. @@ -3103,14 +3100,14 @@ void col_print(char_u *buf, size_t buflen, int col, int vcol) } } -static char_u *lasttitle = NULL; -static char_u *lasticon = NULL; +static char *lasttitle = NULL; +static char *lasticon = NULL; /// Put the title name in the title bar and icon of the window. void maketitle(void) { - char_u *title_str = NULL; - char_u *icon_str = NULL; + char *title_str = NULL; + char *icon_str = NULL; int maxlen = 0; int len; int mustset; @@ -3145,14 +3142,13 @@ void maketitle(void) build_stl_str_hl(curwin, buf, sizeof(buf), (char *)p_titlestring, use_sandbox, 0, maxlen, NULL, NULL); - title_str = (char_u *)buf; + title_str = buf; if (called_emsg) { - set_string_option_direct("titlestring", -1, (char_u *)"", - OPT_FREE, SID_ERROR); + set_string_option_direct("titlestring", -1, "", OPT_FREE, SID_ERROR); } called_emsg |= save_called_emsg; } else { - title_str = p_titlestring; + title_str = (char *)p_titlestring; } } else { // Format: "fname + (path) (1 of 2) - VIM". @@ -3195,7 +3191,7 @@ void maketitle(void) // Get path of file, replace home dir with ~. *buf_p++ = ' '; *buf_p++ = '('; - home_replace(curbuf, curbuf->b_ffname, (char_u *)buf_p, + home_replace(curbuf, (char *)curbuf->b_ffname, buf_p, (SPACE_FOR_DIR - (size_t)(buf_p - buf)), true); #ifdef BACKSLASH_IN_FILENAME // Avoid "c:/name" to be reduced to "c". @@ -3232,18 +3228,17 @@ void maketitle(void) *buf_p = NUL; } - append_arg_number(curwin, (char_u *)buf_p, - (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf)), false); + append_arg_number(curwin, buf_p, (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf)), false); xstrlcat(buf_p, " - NVIM", (sizeof(buf) - (size_t)(buf_p - buf))); if (maxlen > 0) { // Make it shorter by removing a bit in the middle. - if (vim_strsize((char_u *)buf) > maxlen) { + if (vim_strsize(buf) > maxlen) { trunc_string((char_u *)buf, (char_u *)buf, maxlen, sizeof(buf)); } } - title_str = (char_u *)buf; + title_str = buf; #undef SPACE_FOR_FNAME #undef SPACE_FOR_DIR #undef SPACE_FOR_ARGNR @@ -3252,7 +3247,7 @@ void maketitle(void) mustset = value_change(title_str, &lasttitle); if (p_icon) { - icon_str = (char_u *)buf; + icon_str = buf; if (*p_iconstring != NUL) { if (stl_syntax & STL_IN_ICON) { int use_sandbox = false; @@ -3260,34 +3255,33 @@ void maketitle(void) use_sandbox = was_set_insecurely(curwin, "iconstring", 0); called_emsg = false; - build_stl_str_hl(curwin, (char *)icon_str, sizeof(buf), + build_stl_str_hl(curwin, icon_str, sizeof(buf), (char *)p_iconstring, use_sandbox, 0, 0, NULL, NULL); if (called_emsg) { - set_string_option_direct("iconstring", -1, - (char_u *)"", OPT_FREE, SID_ERROR); + set_string_option_direct("iconstring", -1, "", OPT_FREE, SID_ERROR); } called_emsg |= save_called_emsg; } else { - icon_str = p_iconstring; + icon_str = (char *)p_iconstring; } } else { - char_u *buf_p; + char *buf_p; if (buf_spname(curbuf) != NULL) { buf_p = buf_spname(curbuf); } else { // use file name only in icon - buf_p = (char_u *)path_tail((char *)curbuf->b_ffname); + buf_p = path_tail((char *)curbuf->b_ffname); } *icon_str = NUL; // Truncate name at 100 bytes. len = (int)STRLEN(buf_p); if (len > 100) { len -= 100; - len += mb_tail_off(buf_p, buf_p + len) + 1; + len += mb_tail_off((char_u *)buf_p, (char_u *)buf_p + len) + 1; buf_p += len; } STRCPY(icon_str, buf_p); - trans_characters(icon_str, IOSIZE); + trans_characters((char_u *)icon_str, IOSIZE); } } @@ -3306,7 +3300,7 @@ void maketitle(void) /// @param[in,out] last current title string /// /// @return true if resettitle() is to be called. -static bool value_change(char_u *str, char_u **last) +static bool value_change(char *str, char **last) FUNC_ATTR_WARN_UNUSED_RESULT { if ((str == NULL) != (*last == NULL) @@ -3316,7 +3310,7 @@ static bool value_change(char_u *str, char_u **last) *last = NULL; resettitle(); } else { - *last = vim_strsave(str); + *last = xstrdup(str); return true; } } @@ -3326,8 +3320,8 @@ static bool value_change(char_u *str, char_u **last) /// Set current window title void resettitle(void) { - ui_call_set_icon(cstr_as_string((char *)lasticon)); - ui_call_set_title(cstr_as_string((char *)lasttitle)); + ui_call_set_icon(cstr_as_string(lasticon)); + ui_call_set_title(cstr_as_string(lasttitle)); ui_flush(); } @@ -3431,7 +3425,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } // Get line & check if empty (cursorpos will show "0-1"). - const char_u *line_ptr = ml_get_buf(wp->w_buffer, lnum, false); + const char *line_ptr = (char *)ml_get_buf(wp->w_buffer, lnum, false); bool empty_line = (*line_ptr == NUL); // Get the byte value now, in case we need it below. This is more @@ -3445,7 +3439,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san wp->w_cursor.coladd = 0; byteval = 0; } else { - byteval = utf_ptr2char((char *)line_ptr + wp->w_cursor.col); + byteval = utf_ptr2char(line_ptr + wp->w_cursor.col); } int groupdepth = 0; @@ -3522,7 +3516,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san continue; } stl_items[curitem].type = Separate; - stl_items[curitem++].start = (char_u *)out_p; + stl_items[curitem++].start = out_p; continue; } @@ -3530,7 +3524,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (*fmt_p == STL_TRUNCMARK) { fmt_p++; stl_items[curitem].type = Trunc; - stl_items[curitem++].start = (char_u *)out_p; + stl_items[curitem++].start = out_p; continue; } @@ -3546,7 +3540,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Determine how long the group is. // Note: We set the current output position to null // so `vim_strsize` will work. - char_u *t = stl_items[stl_groupitems[groupdepth]].start; + char *t = stl_items[stl_groupitems[groupdepth]].start; *out_p = NUL; long group_len = vim_strsize(t); @@ -3579,7 +3573,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } if (n == curitem && group_start_userhl == group_end_userhl) { // empty group - out_p = (char *)t; + out_p = t; group_len = 0; for (n = stl_groupitems[groupdepth] + 1; n < curitem; n++) { // do not use the highlighting from the removed group @@ -3589,7 +3583,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // adjust the start position of TabPage to the next // item position if (stl_items[n].type == TabPage) { - stl_items[n].start = (char_u *)out_p; + stl_items[n].start = out_p; } } } @@ -3604,7 +3598,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san long n = 0; while (group_len >= stl_items[stl_groupitems[groupdepth]].maxwid) { group_len -= ptr2cells(t + n); - n += utfc_ptr2len((char *)t + n); + n += utfc_ptr2len(t + n); } // } @@ -3612,7 +3606,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san *t = '<'; // { Move the truncated output - memmove(t + 1, t + n, (size_t)((char_u *)out_p - (t + n))); + memmove(t + 1, t + n, (size_t)(out_p - (t + n))); out_p = out_p - n + 1; // Fill up space left over by half a double-wide char. while (++group_len < stl_items[stl_groupitems[groupdepth]].minwid) { @@ -3646,7 +3640,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } else { // { Move the group to the right group_len = (min_group_width - group_len) * utf_char2len(fillchar); - memmove(t + group_len, t, (size_t)((char_u *)out_p - t)); + memmove(t + group_len, t, (size_t)(out_p - t)); if (out_p + group_len >= (out_end_p + 1)) { group_len = (long)(out_end_p - out_p); } @@ -3692,7 +3686,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // to denote the styling to use. if (*fmt_p == STL_USER_HL) { stl_items[curitem].type = Highlight; - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].minwid = minwid > 9 ? 1 : minwid; fmt_p++; curitem++; @@ -3738,7 +3732,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } } stl_items[curitem].type = TabPage; - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].minwid = minwid; fmt_p++; curitem++; @@ -3755,7 +3749,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san break; } stl_items[curitem].type = ClickFunc; - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].cmd = xmemdupz(t, (size_t)(fmt_p - t)); stl_items[curitem].minwid = minwid; fmt_p++; @@ -3780,7 +3774,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (*fmt_p == '(') { stl_groupitems[groupdepth++] = curitem; stl_items[curitem].type = Group; - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].minwid = minwid; stl_items[curitem].maxwid = maxwid; fmt_p++; @@ -3821,9 +3815,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (buf_spname(wp->w_buffer) != NULL) { STRLCPY(NameBuff, buf_spname(wp->w_buffer), MAXPATHL); } else { - char_u *t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname - : (char_u *)wp->w_buffer->b_fname; - home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, true); + char *t = (opt == STL_FULLPATH) ? (char *)wp->w_buffer->b_ffname + : wp->w_buffer->b_fname; + home_replace(wp->w_buffer, t, (char *)NameBuff, MAXPATHL, true); } trans_characters(NameBuff, MAXPATHL); if (opt != STL_FILENAME) { @@ -3912,18 +3906,14 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san size_t parsed_usefmt = (size_t)(block_start - usefmt); size_t str_length = STRLEN(str); size_t fmt_length = STRLEN(fmt_p); - size_t new_fmt_len = parsed_usefmt - + str_length + fmt_length + 3; - char_u *new_fmt = (char_u *)xmalloc(new_fmt_len * sizeof(char_u)); - char_u *new_fmt_p = new_fmt; - - new_fmt_p = (char_u *)memcpy(new_fmt_p, usefmt, parsed_usefmt) - + parsed_usefmt; - new_fmt_p = (char_u *)memcpy(new_fmt_p, str, str_length) - + str_length; - new_fmt_p = (char_u *)memcpy(new_fmt_p, "%}", 2) + 2; - new_fmt_p = (char_u *)memcpy(new_fmt_p, fmt_p, fmt_length) - + fmt_length; + size_t new_fmt_len = parsed_usefmt + str_length + fmt_length + 3; + char *new_fmt = xmalloc(new_fmt_len * sizeof(char)); + char *new_fmt_p = new_fmt; + + new_fmt_p = (char *)memcpy(new_fmt_p, usefmt, parsed_usefmt) + parsed_usefmt; + new_fmt_p = (char *)memcpy(new_fmt_p, str, str_length) + str_length; + new_fmt_p = (char *)memcpy(new_fmt_p, "%}", 2) + 2; + new_fmt_p = (char *)memcpy(new_fmt_p, fmt_p, fmt_length) + fmt_length; *new_fmt_p = 0; new_fmt_p = NULL; @@ -3931,7 +3921,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san xfree(usefmt); } XFREE_CLEAR(str); - usefmt = (char *)new_fmt; + usefmt = new_fmt; fmt_p = usefmt + parsed_usefmt; evaldepth++; continue; @@ -3974,7 +3964,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Store the position percentage in our temporary buffer. // Note: We cannot store the value in `num` because // `get_rel_pos` can return a named position. Ex: "Top" - get_rel_pos(wp, (char_u *)buf_tmp, TMPLEN); + get_rel_pos(wp, buf_tmp, TMPLEN); str = buf_tmp; break; @@ -3989,14 +3979,14 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Note: The call will only return true if it actually // appended data to the `buf_tmp` buffer. - if (append_arg_number(wp, (char_u *)buf_tmp, (int)sizeof(buf_tmp), false)) { + if (append_arg_number(wp, buf_tmp, (int)sizeof(buf_tmp), false)) { str = buf_tmp; } break; case STL_KEYMAP: fillable = false; - if (get_keymap_str(wp, (char_u *)"<%s>", (char_u *)buf_tmp, TMPLEN)) { + if (get_keymap_str(wp, "<%s>", buf_tmp, TMPLEN)) { str = buf_tmp; } break; @@ -4066,11 +4056,10 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // (including the comma and null terminating character) if (*wp->w_buffer->b_p_ft != NUL && STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 2) { - vim_snprintf(buf_tmp, sizeof(buf_tmp), ",%s", - wp->w_buffer->b_p_ft); + vim_snprintf(buf_tmp, sizeof(buf_tmp), ",%s", wp->w_buffer->b_p_ft); // Uppercase the file extension - for (char_u *t = (char_u *)buf_tmp; *t != 0; t++) { - *t = (char_u)TOUPPER_LOC(*t); + for (char *t = buf_tmp; *t != 0; t++) { + *t = (char)TOUPPER_LOC(*t); } str = buf_tmp; } @@ -4121,8 +4110,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Create a highlight item based on the name if (*fmt_p == '#') { stl_items[curitem].type = Highlight; - stl_items[curitem].start = (char_u *)out_p; - stl_items[curitem].minwid = -syn_name2id_len((char_u *)t, (size_t)(fmt_p - t)); + stl_items[curitem].start = out_p; + stl_items[curitem].minwid = -syn_name2id_len(t, (size_t)(fmt_p - t)); curitem++; fmt_p++; } @@ -4133,7 +4122,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // If we made it this far, the item is normal and starts at // our current position in the output buffer. // Non-normal items would have `continued`. - stl_items[curitem].start = (char_u *)out_p; + stl_items[curitem].start = out_p; stl_items[curitem].type = Normal; // Copy the item string into the output buffer @@ -4151,7 +4140,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } // } - long l = vim_strsize((char_u *)t); + long l = vim_strsize(t); // If this item is non-empty, record that the last thing // we put in the output buffer was an item @@ -4162,7 +4151,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // If the item is too wide, truncate it from the beginning if (l > maxwid) { while (l >= maxwid) { - l -= ptr2cells((char_u *)t); + l -= ptr2cells(t); t += utfc_ptr2len(t); } @@ -4219,8 +4208,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san prevchar_isitem = true; // { Build the formatting string - char_u nstr[20]; - char_u *t = nstr; + char nstr[20]; + char *t = nstr; if (opt == STL_VIRTCOL_ALT) { *t++ = '-'; minwid--; @@ -4232,7 +4221,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Note: The `*` means we take the width as one of the arguments *t++ = '*'; - *t++ = (char_u)(base == kNumBaseHexadecimal ? 'X' : 'd'); + *t++ = base == kNumBaseHexadecimal ? 'X' : 'd'; *t = 0; // } @@ -4279,9 +4268,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san *++t = 0; // } - vim_snprintf(out_p, remaining_buf_len, (char *)nstr, 0, num, n); + vim_snprintf(out_p, remaining_buf_len, nstr, 0, num, n); } else { - vim_snprintf(out_p, remaining_buf_len, (char *)nstr, minwid, num); + vim_snprintf(out_p, remaining_buf_len, nstr, minwid, num); } // Advance the output buffer position to the end of the @@ -4318,15 +4307,15 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // We have now processed the entire statusline format string. // What follows is post-processing to handle alignment and highlighting. - int width = vim_strsize((char_u *)out); + int width = vim_strsize(out); if (maxwidth > 0 && width > maxwidth) { // Result is too long, must truncate somewhere. int item_idx = 0; - char_u *trunc_p; + char *trunc_p; // If there are no items, truncate from beginning if (itemcnt == 0) { - trunc_p = (char_u *)out; + trunc_p = out; // Otherwise, look for the truncation item } else { @@ -4349,7 +4338,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (width - vim_strsize(trunc_p) >= maxwidth) { // Walk from the beginning of the // string to find the last character that will fit. - trunc_p = (char_u *)out; + trunc_p = out; width = 0; for (;;) { width += ptr2cells(trunc_p); @@ -4359,7 +4348,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // Note: Only advance the pointer if the next // character will fit in the available output space - trunc_p += utfc_ptr2len((char *)trunc_p); + trunc_p += utfc_ptr2len(trunc_p); } // Ignore any items in the statusline that occur after @@ -4381,12 +4370,12 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san long trunc_len = 0; while (width >= maxwidth) { width -= ptr2cells(trunc_p + trunc_len); - trunc_len += utfc_ptr2len((char *)trunc_p + trunc_len); + trunc_len += utfc_ptr2len(trunc_p + trunc_len); } // } // { Truncate the string - char_u *trunc_end_p = trunc_p + trunc_len; + char *trunc_end_p = trunc_p + trunc_len; STRMOVE(trunc_p + 1, trunc_end_p); // Put a `<` to mark where we truncated at @@ -4452,10 +4441,10 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san for (int i = 0; i < num_separators; i++) { int dislocation = (i == (num_separators - 1)) ? final_spaces : standard_spaces; dislocation *= utf_char2len(fillchar); - char_u *start = stl_items[stl_separator_locations[i]].start; - char_u *seploc = start + dislocation; + char *start = stl_items[stl_separator_locations[i]].start; + char *seploc = start + dislocation; STRMOVE(seploc, start); - for (char_u *s = start; s < seploc;) { + for (char *s = start; s < seploc;) { MB_CHAR2BYTES(fillchar, s); } @@ -4491,7 +4480,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san StlClickRecord *cur_tab_rec = stl_tabtab; for (long l = 0; l < itemcnt; l++) { if (stl_items[l].type == TabPage) { - cur_tab_rec->start = (char *)stl_items[l].start; + cur_tab_rec->start = stl_items[l].start; if (stl_items[l].minwid == 0) { cur_tab_rec->def.type = kStlClickDisabled; cur_tab_rec->def.tabnr = 0; @@ -4508,7 +4497,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san cur_tab_rec->def.func = NULL; cur_tab_rec++; } else if (stl_items[l].type == ClickFunc) { - cur_tab_rec->start = (char *)stl_items[l].start; + cur_tab_rec->start = stl_items[l].start; cur_tab_rec->def.type = kStlClickFuncRun; cur_tab_rec->def.tabnr = stl_items[l].minwid; cur_tab_rec->def.func = stl_items[l].cmd; @@ -4533,7 +4522,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san /// Get relative cursor position in window into "buf[buflen]", in the form 99%, /// using "Top", "Bot" or "All" when appropriate. -void get_rel_pos(win_T *wp, char_u *buf, int buflen) +void get_rel_pos(win_T *wp, char *buf, int buflen) { // Need at least 3 chars for writing. if (buflen < 3) { @@ -4556,7 +4545,7 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen) } else if (above <= 0) { STRLCPY(buf, _("Top"), buflen); } else { - vim_snprintf((char *)buf, (size_t)buflen, "%2d%%", above > 1000000L + vim_snprintf(buf, (size_t)buflen, "%2d%%", above > 1000000L ? (int)(above / ((above + below) / 100L)) : (int)(above * 100L / (above + below))); } @@ -4570,7 +4559,7 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen) /// @param add_file if true, add "file" before the arg number /// /// @return true if it was appended. -static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) +static bool append_arg_number(win_T *wp, char *buf, int buflen, bool add_file) FUNC_ATTR_NONNULL_ALL { // Nothing to do @@ -4578,7 +4567,7 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) return false; } - char_u *p = buf + STRLEN(buf); // go to the end of the buffer + char *p = buf + STRLEN(buf); // go to the end of the buffer // Early out if the string is getting too long if (p - buf + 35 >= buflen) { @@ -4591,7 +4580,7 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) STRCPY(p, "file "); p += 5; } - vim_snprintf((char *)p, (size_t)(buflen - (p - buf)), + vim_snprintf(p, (size_t)(buflen - (p - buf)), wp->w_arg_idx_invalid ? "(%d) of %d)" : "%d of %d)", wp->w_arg_idx + 1, ARGCOUNT); @@ -4604,7 +4593,7 @@ static bool append_arg_number(win_T *wp, char_u *buf, int buflen, bool add_file) /// allocated memory. /// The "*ffname" and "*sfname" pointer values on call will not be freed. /// Note that the resulting "*ffname" pointer should be considered not allocated. -void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) +void fname_expand(buf_T *buf, char **ffname, char **sfname) { if (*ffname == NULL) { // no file name given, nothing to do return; @@ -4612,7 +4601,7 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) if (*sfname == NULL) { // no short file name given, use ffname *sfname = *ffname; } - *ffname = (char_u *)fix_fname((char *)(*ffname)); // expand to full path + *ffname = fix_fname((*ffname)); // expand to full path #ifdef WIN32 if (!buf->b_p_bin) { @@ -4620,24 +4609,24 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname) char *rfname = os_resolve_shortcut((const char *)(*ffname)); if (rfname != NULL) { xfree(*ffname); - *ffname = (char_u *)rfname; - *sfname = (char_u *)rfname; + *ffname = rfname; + *sfname = rfname; } } #endif } /// Get the file name for an argument list entry. -char_u *alist_name(aentry_T *aep) +char *alist_name(aentry_T *aep) { buf_T *bp; // Use the name from the associated buffer if it exists. bp = buflist_findnr(aep->ae_fnum); if (bp == NULL || bp->b_fname == NULL) { - return aep->ae_fname; + return (char *)aep->ae_fname; } - return (char_u *)bp->b_fname; + return bp->b_fname; } /// do_arg_all(): Open up to 'count' windows, one for each argument. @@ -4646,7 +4635,7 @@ char_u *alist_name(aentry_T *aep) /// @param keep_tabs keep current tabs, for ":tab drop file" void do_arg_all(int count, int forceit, int keep_tabs) { - char_u *opened; // Array of weight for which args are open: + uint8_t *opened; // Array of weight for which args are open: // 0: not opened // 1: opened in other tab // 2: opened in curtab @@ -4710,7 +4699,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) if (i < alist->al_ga.ga_len && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum || path_full_compare(alist_name(&AARGLIST(alist)[i]), - buf->b_ffname, + (char *)buf->b_ffname, true, true) & kEqualFiles)) { int weight = 1; @@ -4722,7 +4711,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) } if (weight > (int)opened[i]) { - opened[i] = (char_u)weight; + opened[i] = (uint8_t)weight; if (i == 0) { if (new_curwin != NULL) { new_curwin->w_arg_idx = opened_len; @@ -4854,7 +4843,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) new_curwin = curwin; new_curtab = curtab; } - (void)do_ecmd(0, (char *)alist_name(&AARGLIST(alist)[i]), NULL, NULL, ECMD_ONE, + (void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL, ECMD_ONE, ((buf_hide(curwin->w_buffer) || bufIsChanged(curwin->w_buffer)) ? ECMD_HIDE : 0) + ECMD_OLDBUF, @@ -5131,18 +5120,18 @@ void do_modelines(int flags) /// @param flags Same as for do_modelines(). static int chk_modeline(linenr_T lnum, int flags) { - char_u *s; - char_u *e; - char_u *linecopy; // local copy of any modeline found + char *s; + char *e; + char *linecopy; // local copy of any modeline found int prev; intmax_t vers; int end; int retval = OK; - char_u *save_sourcing_name; + char *save_sourcing_name; linenr_T save_sourcing_lnum; prev = -1; - for (s = ml_get(lnum); *s != NUL; s++) { + for (s = (char *)ml_get(lnum); *s != NUL; s++) { if (prev == -1 || ascii_isspace(prev)) { if ((prev != -1 && STRNCMP(s, "ex:", (size_t)3) == 0) || STRNCMP(s, "vi:", (size_t)3) == 0) { @@ -5171,7 +5160,7 @@ static int chk_modeline(linenr_T lnum, int flags) } } } - prev = *s; + prev = (uint8_t)(*s); } if (!*s) { @@ -5182,16 +5171,16 @@ static int chk_modeline(linenr_T lnum, int flags) s++; } while (s[-1] != ':'); - s = linecopy = vim_strsave(s); // copy the line, it will change + s = linecopy = xstrdup(s); // copy the line, it will change save_sourcing_lnum = sourcing_lnum; - save_sourcing_name = (char_u *)sourcing_name; + save_sourcing_name = sourcing_name; sourcing_lnum = lnum; // prepare for emsg() sourcing_name = "modelines"; end = false; while (end == false) { - s = (char_u *)skipwhite((char *)s); + s = skipwhite(s); if (*s == NUL) { break; } @@ -5218,7 +5207,7 @@ static int chk_modeline(linenr_T lnum, int flags) break; } end = true; - s = (char_u *)vim_strchr((char *)s, ' ') + 1; + s = vim_strchr(s, ' ') + 1; } *e = NUL; // truncate the set command @@ -5243,7 +5232,7 @@ static int chk_modeline(linenr_T lnum, int flags) } sourcing_lnum = save_sourcing_lnum; - sourcing_name = (char *)save_sourcing_name; + sourcing_name = save_sourcing_name; xfree(linecopy); @@ -5328,26 +5317,26 @@ bool buf_hide(const buf_T *const buf) /// @return special buffer name or /// NULL when the buffer has a normal file name. -char_u *buf_spname(buf_T *buf) +char *buf_spname(buf_T *buf) { if (bt_quickfix(buf)) { // Differentiate between the quickfix and location list buffers using // the buffer number stored in the global quickfix stack. if (buf->b_fnum == qf_stack_get_bufnr()) { - return (char_u *)_(msg_qflist); + return _(msg_qflist); } - return (char_u *)_(msg_loclist); + return _(msg_loclist); } // There is no _file_ when 'buftype' is "nofile", b_sfname // contains the name as specified by the user. if (bt_nofile(buf)) { if (buf->b_fname != NULL) { - return (char_u *)buf->b_fname; + return buf->b_fname; } if (bt_prompt(buf)) { - return (char_u *)_("[Prompt]"); + return _("[Prompt]"); } - return (char_u *)_("[Scratch]"); + return _("[Scratch]"); } if (buf->b_fname == NULL) { return buf_get_fname(buf); @@ -5530,13 +5519,13 @@ int buf_signcols(buf_T *buf, int maximum) } /// Get "buf->b_fname", use "[No Name]" if it is NULL. -char_u *buf_get_fname(const buf_T *buf) +char *buf_get_fname(const buf_T *buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { if (buf->b_fname == NULL) { - return (char_u *)_("[No Name]"); + return _("[No Name]"); } - return (char_u *)buf->b_fname; + return buf->b_fname; } /// Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed. @@ -5632,7 +5621,7 @@ void wipe_buffer(buf_T *buf, bool aucmd) void buf_open_scratch(handle_T bufnr, char *bufname) { (void)do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL); - (void)setfname(curbuf, (char_u *)bufname, NULL, true); + (void)setfname(curbuf, bufname, NULL, true); set_option_value("bh", 0L, "hide", OPT_LOCAL); set_option_value("bt", 0L, "nofile", OPT_LOCAL); set_option_value("swf", 0L, NULL, OPT_LOCAL); -- cgit From bab32bba7adc8ba9461629e51d8c7a7d2fa5976b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 29 Jun 2022 19:25:38 +0800 Subject: vim-patch:9.0.0002: map functionality outside of map.c (#19150) Problem: Map functionality outside of map.c. Solution: Move f_hasmapto() to map.c. Rename a function. (closes vim/vim#10611) https://github.com/vim/vim/commit/c207fd2535717030d78f9b92839e5f2ac004cc78 --- src/nvim/buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 46adb55746..baecda8e3c 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -815,8 +815,8 @@ static void free_buffer_stuff(buf_T *buf, int free_flags) uc_clear(&buf->b_ucmds); // clear local user commands buf_delete_signs(buf, (char_u *)"*"); // delete any signs extmark_free_all(buf); // delete any extmarks - map_clear_int(buf, MAP_ALL_MODES, true, false); // clear local mappings - map_clear_int(buf, MAP_ALL_MODES, true, true); // clear local abbrevs + map_clear_mode(buf, MAP_ALL_MODES, true, false); // clear local mappings + map_clear_mode(buf, MAP_ALL_MODES, true, true); // clear local abbrevs XFREE_CLEAR(buf->b_start_fenc); buf_updates_unload(buf, false); -- cgit From 565f72b9689e0c440ff72c712a090224aaf7631b Mon Sep 17 00:00:00 2001 From: Javier Lopez Date: Thu, 30 Jun 2022 07:59:52 -0500 Subject: feat(marks): restore viewport on jump #15831 ** Refactor Previously most functions used to "get" a mark returned a position, changed the line number and sometimes changed even the current buffer. Now functions return a {x}fmark_T making calling context aware whether the mark is in another buffer without arcane casting. A new function is provided for switching to the mark buffer and returning a flag style Enum to convey what happen in the movement. If the cursor changed, line, columns, if it changed buffer, etc. The function to get named mark was split into multiple functions. - mark_get() -> fmark_T - mark_get_global() -> xfmark_T - mark_get_local() -> fmark_T - mark_get_motion() -> fmark_T - mark_get_visual() -> fmark_T Functions that manage the changelist and jumplist were also modified to return mark types. - get_jumplist -> fmark_T - get_changelist -> fmark_T The refactor is also seen mainly on normal.c, where all the mark movement has been siphoned through one function nv_gomark, while the other functions handle getting the mark and setting their movement flags. To handle whether context marks should be left, etc. ** Mark View While doing the refactor the concept of a mark view was also implemented: The view of a mark currently implemented as the number of lines between the mark position on creation and the window topline. This allows for moving not only back to the position of a mark but having the window look similar to when the mark was defined. This is done by carrying and extra element in the fmark_T struct, which can be extended later to also restore horizontal shift. *** User space features 1. There's a new option, jumpoptions+=view enables the mark view restoring automatically when using the jumplist, changelist, alternate-file and mark motions. g; g, '[mark] `[mark] ** Limitations - The view information is not saved in shada. - Calls to get_mark should copy the value in the pointer since we are using pos_to_mark() to wrap and provide a homogeneous interfaces. This was also a limitation in the previous state of things. --- src/nvim/buffer.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index baecda8e3c..a2ecb69ac0 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -55,6 +55,7 @@ #include "nvim/main.h" #include "nvim/mapping.h" #include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/message.h" @@ -1789,7 +1790,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl buf_copy_options(buf, BCO_ALWAYS); } - buf->b_wininfo->wi_fpos.lnum = lnum; + buf->b_wininfo->wi_mark = (fmark_T)INIT_FMARK; + buf->b_wininfo->wi_mark.mark.lnum = lnum; buf->b_wininfo->wi_win = curwin; hash_init(&buf->b_s.b_keywtab); @@ -1937,7 +1939,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) { buf_T *buf; win_T *wp = NULL; - pos_T *fpos; + fmark_T *fm = NULL; colnr_T col; buf = buflist_findnr(n); @@ -1963,11 +1965,13 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) return FAIL; } + bool restore_view = false; // altfpos may be changed by getfile(), get it now if (lnum == 0) { - fpos = buflist_findfpos(buf); - lnum = fpos->lnum; - col = fpos->col; + fm = buflist_findfmark(buf); + lnum = fm->mark.lnum; + col = fm->mark.col; + restore_view = true; } else { col = 0; } @@ -2011,6 +2015,9 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) curwin->w_cursor.coladd = 0; curwin->w_set_curswant = true; } + if (jop_flags & JOP_VIEW && restore_view) { + mark_view_restore(fm); + } return OK; } RedrawingDisabled--; @@ -2022,7 +2029,7 @@ void buflist_getfpos(void) { pos_T *fpos; - fpos = buflist_findfpos(curbuf); + fpos = &buflist_findfmark(curbuf)->mark; curwin->w_cursor.lnum = fpos->lnum; check_cursor_lnum(); @@ -2462,8 +2469,11 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T } } if (lnum != 0) { - wip->wi_fpos.lnum = lnum; - wip->wi_fpos.col = col; + wip->wi_mark.mark.lnum = lnum; + wip->wi_mark.mark.col = col; + if (win != NULL) { + wip->wi_mark.view = mark_view_make(win->w_topline, wip->wi_mark.mark); + } } if (copy_options && win != NULL) { // Save the window-specific option values. @@ -2581,24 +2591,23 @@ void get_winopts(buf_T *buf) didset_window_options(curwin); } -/// Find the position (lnum and col) for the buffer 'buf' for the current -/// window. +/// Find the mark for the buffer 'buf' for the current window. /// /// @return a pointer to no_position if no position is found. -pos_T *buflist_findfpos(buf_T *buf) +fmark_T *buflist_findfmark(buf_T *buf) FUNC_ATTR_PURE { - static pos_T no_position = { 1, 0, 0 }; + static fmark_T no_position = { { 1, 0, 0 }, 0, 0, { 0 }, NULL }; wininfo_T *const wip = find_wininfo(buf, false, false); - return (wip == NULL) ? &no_position : &(wip->wi_fpos); + return (wip == NULL) ? &no_position : &(wip->wi_mark); } /// Find the lnum for the buffer 'buf' for the current window. linenr_T buflist_findlnum(buf_T *buf) FUNC_ATTR_PURE { - return buflist_findfpos(buf)->lnum; + return buflist_findfmark(buf)->mark.lnum; } /// List all known file names (for :files and :buffers command). -- cgit From 3b8804571c565a91c9ce729bb487c7ba21b659e0 Mon Sep 17 00:00:00 2001 From: Dundar Goc Date: Tue, 28 Jun 2022 13:03:09 +0200 Subject: refactor: replace char_u Work on https://github.com/neovim/neovim/issues/459 --- src/nvim/buffer.c | 167 +++++++++++++++++++++++++----------------------------- 1 file changed, 78 insertions(+), 89 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index a2ecb69ac0..7bdb905dfa 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -113,7 +113,7 @@ static int read_buffer(int read_stdin, exarg_T *eap, int flags) // the end. This makes it possible to retry when 'fileformat' or // 'fileencoding' was guessed wrong. line_count = curbuf->b_ml.ml_line_count; - retval = readfile(read_stdin ? NULL : (char *)curbuf->b_ffname, + retval = readfile(read_stdin ? NULL : curbuf->b_ffname, read_stdin ? NULL : curbuf->b_fname, line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap, flags | READ_BUFFER, silent); @@ -231,7 +231,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags) } #endif - retval = readfile((char *)curbuf->b_ffname, curbuf->b_fname, + retval = readfile(curbuf->b_ffname, curbuf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap, flags | READ_NEW | (read_fifo ? READ_FIFO : 0), silent); #ifdef UNIX @@ -803,8 +803,7 @@ static void free_buffer_stuff(buf_T *buf, int free_flags) // Avoid losing b:changedtick when deleting buffer: clearing variables // implies using clear_tv() on b:changedtick and that sets changedtick to // zero. - hashitem_T *const changedtick_hi = hash_find(&buf->b_vars->dv_hashtab, - (const char_u *)"changedtick"); + hashitem_T *const changedtick_hi = hash_find(&buf->b_vars->dv_hashtab, "changedtick"); assert(changedtick_hi != NULL); hash_remove(&buf->b_vars->dv_hashtab, changedtick_hi); } @@ -814,7 +813,7 @@ static void free_buffer_stuff(buf_T *buf, int free_flags) buf_init_changedtick(buf); } uc_clear(&buf->b_ucmds); // clear local user commands - buf_delete_signs(buf, (char_u *)"*"); // delete any signs + buf_delete_signs(buf, "*"); // delete any signs extmark_free_all(buf); // delete any extmarks map_clear_mode(buf, MAP_ALL_MODES, true, false); // clear local mappings map_clear_mode(buf, MAP_ALL_MODES, true, true); // clear local abbrevs @@ -943,7 +942,7 @@ void handle_swap_exists(bufref_T *old_curbuf) /// @param end_bnr buffer nr or last buffer nr in a range /// /// @return error message or NULL -char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit) +char *do_bufdel(int command, char *arg, int addr_count, int start_bnr, int end_bnr, int forceit) { int do_current = 0; // delete current buffer? int deleted = 0; // number of buffers deleted @@ -981,17 +980,17 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end break; } } else { // addr_count == 1 - arg = (char_u *)skipwhite((char *)arg); + arg = skipwhite(arg); if (*arg == NUL) { break; } if (!ascii_isdigit(*arg)) { - p = (char *)skiptowhite_esc(arg); - bnr = buflist_findpat(arg, (char_u *)p, command == DOBUF_WIPE, false, false); + p = skiptowhite_esc(arg); + bnr = buflist_findpat(arg, p, command == DOBUF_WIPE, false, false); if (bnr < 0) { // failed break; } - arg = (char_u *)p; + arg = p; } else { bnr = getdigits_int(&arg, false, 0); } @@ -1677,10 +1676,10 @@ static inline void buf_init_changedtick(buf_T *const buf) /// @param bufnr /// /// @return pointer to the buffer -buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int flags) +buf_T *buflist_new(char *ffname_arg, char *sfname_arg, linenr_T lnum, int flags) { - char *ffname = (char *)ffname_arg; - char *sfname = (char *)sfname_arg; + char *ffname = ffname_arg; + char *sfname = sfname_arg; buf_T *buf; fname_expand(curbuf, &ffname, &sfname); // will allocate ffname @@ -1747,8 +1746,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl } if (ffname != NULL) { - buf->b_ffname = (char_u *)ffname; - buf->b_sfname = vim_strsave((char_u *)sfname); + buf->b_ffname = ffname; + buf->b_sfname = xstrdup(sfname); } clear_wininfo(buf); @@ -1797,7 +1796,7 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl hash_init(&buf->b_s.b_keywtab); hash_init(&buf->b_s.b_keywtab_ic); - buf->b_fname = (char *)buf->b_sfname; + buf->b_fname = buf->b_sfname; if (!file_id_valid) { buf->file_id_valid = false; } else { @@ -2047,13 +2046,13 @@ void buflist_getfpos(void) /// Find file in buffer list by name (it has to be for the current window). /// /// @return buffer or NULL if not found -buf_T *buflist_findname_exp(char_u *fname) +buf_T *buflist_findname_exp(char *fname) { char *ffname; buf_T *buf = NULL; // First make the name into a full path name - ffname = FullName_save((char *)fname, + ffname = FullName_save(fname, #ifdef UNIX // force expansion, get rid of symbolic links true @@ -2062,7 +2061,7 @@ buf_T *buflist_findname_exp(char_u *fname) #endif ); // NOLINT(whitespace/parens) if (ffname != NULL) { - buf = buflist_findname((char_u *)ffname); + buf = buflist_findname(ffname); xfree(ffname); } return buf; @@ -2073,11 +2072,11 @@ buf_T *buflist_findname_exp(char_u *fname) /// Skips dummy buffers. /// /// @return buffer or NULL if not found -buf_T *buflist_findname(char_u *ffname) +buf_T *buflist_findname(char *ffname) { FileID file_id; - bool file_id_valid = os_fileid((char *)ffname, &file_id); - return buflist_findname_file_id((char *)ffname, &file_id, file_id_valid); + bool file_id_valid = os_fileid(ffname, &file_id); + return buflist_findname_file_id(ffname, &file_id, file_id_valid); } /// Same as buflist_findname(), but pass the FileID structure to avoid @@ -2105,7 +2104,7 @@ static buf_T *buflist_findname_file_id(char *ffname, FileID *file_id, bool file_ /// @param curtab_only find buffers in current tab only /// /// @return fnum of the found buffer or < 0 for error. -int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlisted, bool diffmode, +int buflist_findpat(const char *pattern, const char *pattern_end, bool unlisted, bool diffmode, bool curtab_only) FUNC_ATTR_NONNULL_ARG(1) { @@ -2236,7 +2235,7 @@ static int buf_time_compare(const void *s1, const void *s2) /// For command line expansion of ":buf" and ":sbuf". /// /// @return OK if matches found, FAIL otherwise. -int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) +int ExpandBufnames(char *pat, int *num_file, char ***file, int options) { int count = 0; int round; @@ -2258,20 +2257,20 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) STRCPY(patc, "\\(^\\|[\\/]\\)"); STRCPY(patc + 11, pat + 1); } else { - patc = (char *)pat; + patc = pat; } // attempt == 0: try match with '\<', match at start of word // attempt == 1: try match without '\<', match anywhere for (attempt = 0; attempt <= 1; attempt++) { - if (attempt > 0 && (char_u *)patc == pat) { + if (attempt > 0 && patc == pat) { break; // there was no anchor, no need to try again } regmatch_T regmatch; regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC); if (regmatch.regprog == NULL) { - if ((char_u *)patc != pat) { + if (patc != pat) { xfree(patc); } return FAIL; @@ -2298,7 +2297,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) count++; } else { if (options & WILD_HOME_REPLACE) { - p = (char *)home_replace_save(buf, (char_u *)p); + p = home_replace_save(buf, p); } else { p = xstrdup(p); } @@ -2307,7 +2306,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) matches[count].match = p; count++; } else { - (*file)[count++] = (char_u *)p; + (*file)[count++] = p; } } } @@ -2329,7 +2328,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) } } - if ((char_u *)patc != pat) { + if (patc != pat) { xfree(patc); } @@ -2341,12 +2340,12 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) // if the current buffer is first in the list, place it at the end if (matches[0].buf == curbuf) { for (int i = 1; i < count; i++) { - (*file)[i - 1] = (char_u *)matches[i].match; + (*file)[i - 1] = matches[i].match; } - (*file)[count - 1] = (char_u *)matches[0].match; + (*file)[count - 1] = matches[0].match; } else { for (int i = 0; i < count; i++) { - (*file)[i] = (char_u *)matches[i].match; + (*file)[i] = matches[i].match; } } xfree(matches); @@ -2362,9 +2361,9 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) static char *buflist_match(regmatch_T *rmp, buf_T *buf, bool ignore_case) { // First try the short file name, then the long file name. - char *match = fname_match(rmp, (char *)buf->b_sfname, ignore_case); + char *match = fname_match(rmp, buf->b_sfname, ignore_case); if (match == NULL && rmp->regprog != NULL) { - match = fname_match(rmp, (char *)buf->b_ffname, ignore_case); + match = fname_match(rmp, buf->b_ffname, ignore_case); } return match; } @@ -2382,12 +2381,12 @@ static char *fname_match(regmatch_T *rmp, char *name, bool ignore_case) if (name != NULL) { // Ignore case when 'fileignorecase' or the argument is set. rmp->rm_ic = p_fic || ignore_case; - if (vim_regexec(rmp, (char_u *)name, (colnr_T)0)) { + if (vim_regexec(rmp, name, (colnr_T)0)) { match = name; } else if (rmp->regprog != NULL) { // Replace $(HOME) with '~' and try matching again. - p = (char *)home_replace_save(NULL, (char_u *)name); - if (vim_regexec(rmp, (char_u *)p, (colnr_T)0)) { + p = home_replace_save(NULL, name); + if (vim_regexec(rmp, p, (colnr_T)0)) { match = name; } xfree(p); @@ -2414,16 +2413,14 @@ buf_T *buflist_findnr(int nr) /// @param helptail for help buffers return tail only /// /// @return a pointer to allocated memory, of NULL when failed. -char_u *buflist_nr2name(int n, int fullname, int helptail) +char *buflist_nr2name(int n, int fullname, int helptail) { - buf_T *buf; - - buf = buflist_findnr(n); + buf_T *buf = buflist_findnr(n); if (buf == NULL) { return NULL; } return home_replace_save(helptail ? buf : NULL, - fullname ? buf->b_ffname : (char_u *)buf->b_fname); + fullname ? buf->b_ffname : buf->b_fname); } /// Set the line and column numbers for the given buffer and window @@ -2719,16 +2716,14 @@ void buflist_list(exarg_T *eap) /// Used by insert_reg() and cmdline_paste() for '#' register. /// /// @return FAIL if not found, OK for success. -int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum) +int buflist_name_nr(int fnum, char **fname, linenr_T *lnum) { - buf_T *buf; - - buf = buflist_findnr(fnum); + buf_T *buf = buflist_findnr(fnum); if (buf == NULL || buf->b_fname == NULL) { return FAIL; } - *fname = (char_u *)buf->b_fname; + *fname = buf->b_fname; *lnum = buflist_findlnum(buf); return OK; @@ -2783,16 +2778,16 @@ int setfname(buf_T *buf, char *ffname_arg, char *sfname_arg, bool message) } sfname = xstrdup(sfname); #ifdef USE_FNAME_CASE - path_fix_case((char_u *)sfname); // set correct case for short file name + path_fix_case(sfname); // set correct case for short file name #endif if (buf->b_sfname != buf->b_ffname) { xfree(buf->b_sfname); } xfree(buf->b_ffname); - buf->b_ffname = (char_u *)ffname; - buf->b_sfname = (char_u *)sfname; + buf->b_ffname = ffname; + buf->b_sfname = sfname; } - buf->b_fname = (char *)buf->b_sfname; + buf->b_fname = buf->b_sfname; if (!file_id_valid) { buf->file_id_valid = false; } else { @@ -2806,22 +2801,20 @@ int setfname(buf_T *buf, char *ffname_arg, char *sfname_arg, bool message) /// Crude way of changing the name of a buffer. Use with care! /// The name should be relative to the current directory. -void buf_set_name(int fnum, char_u *name) +void buf_set_name(int fnum, char *name) { - buf_T *buf; - - buf = buflist_findnr(fnum); + buf_T *buf = buflist_findnr(fnum); if (buf != NULL) { if (buf->b_sfname != buf->b_ffname) { xfree(buf->b_sfname); } xfree(buf->b_ffname); - buf->b_ffname = vim_strsave(name); + buf->b_ffname = xstrdup(name); buf->b_sfname = NULL; // Allocate ffname and expand into full path. Also resolves .lnk // files on Win32. - fname_expand(buf, (char **)&buf->b_ffname, (char **)&buf->b_sfname); - buf->b_fname = (char *)buf->b_sfname; + fname_expand(buf, &buf->b_ffname, &buf->b_sfname); + buf->b_fname = buf->b_sfname; } } @@ -2847,12 +2840,10 @@ void buf_name_changed(buf_T *buf) /// Used by do_one_cmd(), do_write() and do_ecmd(). /// /// @return the buffer. -buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum) +buf_T *setaltfname(char *ffname, char *sfname, linenr_T lnum) { - buf_T *buf; - // Create a buffer. 'buflisted' is not set if it's a new buffer - buf = buflist_new(ffname, sfname, lnum, 0); + buf_T *buf = buflist_new(ffname, sfname, lnum, 0); if (buf != NULL && (cmdmod.cmod_flags & CMOD_KEEPALT) == 0) { curwin->w_alt_fnum = buf->b_fnum; } @@ -2863,29 +2854,27 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum) /// Return NULL if there isn't any, and give error message if requested. /// /// @param errmsg give error message -char_u *getaltfname(bool errmsg) +char *getaltfname(bool errmsg) { char *fname; linenr_T dummy; - if (buflist_name_nr(0, (char_u **)&fname, &dummy) == FAIL) { + if (buflist_name_nr(0, &fname, &dummy) == FAIL) { if (errmsg) { emsg(_(e_noalt)); } return NULL; } - return (char_u *)fname; + return fname; } /// Add a file name to the buflist and return its number. /// Uses same flags as buflist_new(), except BLN_DUMMY. /// /// Used by qf_init(), main() and doarglist() -int buflist_add(char_u *fname, int flags) +int buflist_add(char *fname, int flags) { - buf_T *buf; - - buf = buflist_new(fname, NULL, (linenr_T)0, flags); + buf_T *buf = buflist_new(fname, NULL, (linenr_T)0, flags); if (buf != NULL) { return buf->b_fnum; } @@ -2919,10 +2908,10 @@ void buflist_altfpos(win_T *win) /// Fname must have a full path (expanded by path_to_absolute()). /// /// @param ffname full path name to check -bool otherfile(char_u *ffname) +bool otherfile(char *ffname) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { - return otherfile_buf(curbuf, (char *)ffname, NULL, false); + return otherfile_buf(curbuf, ffname, NULL, false); } /// Check that "ffname" is not the same file as the file loaded in "buf". @@ -3023,7 +3012,7 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate) if (!fullname && curbuf->b_fname != NULL) { name = curbuf->b_fname; } else { - name = (char *)curbuf->b_ffname; + name = curbuf->b_ffname; } home_replace(shorthelp ? curbuf : NULL, name, p, (size_t)(IOSIZE - (p - buffer)), true); @@ -3071,7 +3060,7 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate) n); validate_virtcol(); len = STRLEN(buffer); - col_print((char_u *)buffer + len, IOSIZE - len, + col_print(buffer + len, IOSIZE - len, (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1); } @@ -3100,12 +3089,12 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate) xfree(buffer); } -void col_print(char_u *buf, size_t buflen, int col, int vcol) +void col_print(char *buf, size_t buflen, int col, int vcol) { if (col == vcol) { - vim_snprintf((char *)buf, buflen, "%d", col); + vim_snprintf(buf, buflen, "%d", col); } else { - vim_snprintf((char *)buf, buflen, "%d-%d", col, vcol); + vim_snprintf(buf, buflen, "%d-%d", col, vcol); } } @@ -3200,7 +3189,7 @@ void maketitle(void) // Get path of file, replace home dir with ~. *buf_p++ = ' '; *buf_p++ = '('; - home_replace(curbuf, (char *)curbuf->b_ffname, buf_p, + home_replace(curbuf, curbuf->b_ffname, buf_p, (SPACE_FOR_DIR - (size_t)(buf_p - buf)), true); #ifdef BACKSLASH_IN_FILENAME // Avoid "c:/name" to be reduced to "c". @@ -3209,7 +3198,7 @@ void maketitle(void) } #endif // Remove the file name. - char *p = (char *)path_tail_with_sep((char_u *)buf_p); + char *p = path_tail_with_sep(buf_p); if (p == buf_p) { // Must be a help buffer. xstrlcpy(buf_p, _("help"), SPACE_FOR_DIR - (size_t)(buf_p - buf)); @@ -3244,7 +3233,7 @@ void maketitle(void) if (maxlen > 0) { // Make it shorter by removing a bit in the middle. if (vim_strsize(buf) > maxlen) { - trunc_string((char_u *)buf, (char_u *)buf, maxlen, sizeof(buf)); + trunc_string(buf, buf, maxlen, sizeof(buf)); } } title_str = buf; @@ -3279,18 +3268,18 @@ void maketitle(void) if (buf_spname(curbuf) != NULL) { buf_p = buf_spname(curbuf); } else { // use file name only in icon - buf_p = path_tail((char *)curbuf->b_ffname); + buf_p = path_tail(curbuf->b_ffname); } *icon_str = NUL; // Truncate name at 100 bytes. len = (int)STRLEN(buf_p); if (len > 100) { len -= 100; - len += mb_tail_off((char_u *)buf_p, (char_u *)buf_p + len) + 1; + len += mb_tail_off(buf_p, buf_p + len) + 1; buf_p += len; } STRCPY(icon_str, buf_p); - trans_characters((char_u *)icon_str, IOSIZE); + trans_characters(icon_str, IOSIZE); } } @@ -3688,7 +3677,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // The first digit group is the item's min width if (ascii_isdigit(*fmt_p)) { - minwid = getdigits_int((char_u **)&fmt_p, false, 0); + minwid = getdigits_int(&fmt_p, false, 0); } // User highlight groups override the min width field @@ -3771,7 +3760,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (*fmt_p == '.') { fmt_p++; if (ascii_isdigit(*fmt_p)) { - maxwid = getdigits_int((char_u **)&fmt_p, false, 50); + maxwid = getdigits_int(&fmt_p, false, 50); } } @@ -3824,11 +3813,11 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san if (buf_spname(wp->w_buffer) != NULL) { STRLCPY(NameBuff, buf_spname(wp->w_buffer), MAXPATHL); } else { - char *t = (opt == STL_FULLPATH) ? (char *)wp->w_buffer->b_ffname + char *t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname : wp->w_buffer->b_fname; home_replace(wp->w_buffer, t, (char *)NameBuff, MAXPATHL, true); } - trans_characters(NameBuff, MAXPATHL); + trans_characters((char *)NameBuff, MAXPATHL); if (opt != STL_FILENAME) { str = (char *)NameBuff; } else { @@ -4708,7 +4697,7 @@ void do_arg_all(int count, int forceit, int keep_tabs) if (i < alist->al_ga.ga_len && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum || path_full_compare(alist_name(&AARGLIST(alist)[i]), - (char *)buf->b_ffname, + buf->b_ffname, true, true) & kEqualFiles)) { int weight = 1; @@ -5576,7 +5565,7 @@ bool buf_contents_changed(buf_T *buf) aucmd_prepbuf(&aco, newbuf); if (ml_open(curbuf) == OK - && readfile((char *)buf->b_ffname, buf->b_fname, + && readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, &ea, READ_NEW | READ_DUMMY, false) == OK) { // compare the two files line by line -- cgit From d0835617facc98daf79318e26d41669bb2ce1a6b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 5 Jul 2022 11:31:49 +0200 Subject: fix(terminal): crash if TermClose deletes own buffer #19222 - Partially fixes #10386 except for the case where the alternate buffer is the default, empty, first buffer created on startup. #vimlife - TODO: port patches related to `can_unload_buffer`, maybe that fully fixes #10386? vim-patch:8.0.1732: crash when terminal API call deletes the buffer --- src/nvim/buffer.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7bdb905dfa..411705cfa3 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -89,6 +89,7 @@ static char *msg_loclist = N_("[Location List]"); static char *msg_qflist = N_("[Quickfix List]"); static char *e_auabort = N_("E855: Autocommands caused command to abort"); +static char *e_buflocked = N_("E937: Attempt to delete a buffer that is in use"); // Number of times free_buffer() was called. static int buf_free_count = 0; @@ -438,7 +439,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i // Disallow deleting the buffer when it is locked (already being closed or // halfway a command that relies on it). Unloading is allowed. if (buf->b_locked > 0 && (del_buf || wipe_buf)) { - emsg(_("E937: Attempt to delete a buffer that is in use")); + emsg(_(e_buflocked)); return false; } @@ -529,7 +530,9 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i } if (buf->terminal) { + buf->b_locked++; terminal_close(&buf->terminal, -1); + buf->b_locked--; } // Always remove the buffer when there is no file name. @@ -1182,6 +1185,10 @@ int do_buffer(int action, int start, int dir, int count, int forceit) if (unload) { int forward; bufref_T bufref; + if (buf->b_locked) { + emsg(_(e_buflocked)); + return FAIL; + } set_bufref(&bufref, buf); // When unloading or deleting a buffer that's already unloaded and -- cgit From 0612101c92f7043e47a1b4e80120582ff538c4f8 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Jul 2022 05:37:30 +0800 Subject: vim-patch:8.2.5043: can open a cmdline window from a substitute expression Problem: Can open a cmdline window from a substitute expression. Solution: Disallow opening a command line window when text or buffer is locked. https://github.com/vim/vim/commit/71223e2db87c2bf3b09aecb46266b56cda26191d --- src/nvim/buffer.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 411705cfa3..7e1eae9632 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1963,11 +1963,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) return OK; } - if (text_locked()) { - text_locked_msg(); - return FAIL; - } - if (curbuf_locked()) { + if (text_or_buf_locked()) { return FAIL; } -- cgit From 39d51c833aed7e2ab946cd51bfff8d981269a8ef Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 13 Jul 2022 04:08:49 +0800 Subject: vim-patch:8.2.0035: saving and restoring called_emsg is clumsy (#19335) Problem: Saving and restoring called_emsg is clumsy. Solution: Count the number of error messages. https://github.com/vim/vim/commit/53989554a44caca0964376d60297f08ec257c53c --- src/nvim/buffer.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7e1eae9632..69aaee4f9b 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3136,18 +3136,16 @@ void maketitle(void) if (*p_titlestring != NUL) { if (stl_syntax & STL_IN_TITLE) { int use_sandbox = false; - int save_called_emsg = called_emsg; + const int called_emsg_before = called_emsg; use_sandbox = was_set_insecurely(curwin, "titlestring", 0); - called_emsg = false; build_stl_str_hl(curwin, buf, sizeof(buf), (char *)p_titlestring, use_sandbox, 0, maxlen, NULL, NULL); title_str = buf; - if (called_emsg) { + if (called_emsg > called_emsg_before) { set_string_option_direct("titlestring", -1, "", OPT_FREE, SID_ERROR); } - called_emsg |= save_called_emsg; } else { title_str = (char *)p_titlestring; } @@ -3252,17 +3250,15 @@ void maketitle(void) if (*p_iconstring != NUL) { if (stl_syntax & STL_IN_ICON) { int use_sandbox = false; - int save_called_emsg = called_emsg; + const int called_emsg_before = called_emsg; use_sandbox = was_set_insecurely(curwin, "iconstring", 0); - called_emsg = false; build_stl_str_hl(curwin, icon_str, sizeof(buf), (char *)p_iconstring, use_sandbox, 0, 0, NULL, NULL); - if (called_emsg) { + if (called_emsg > called_emsg_before) { set_string_option_direct("iconstring", -1, "", OPT_FREE, SID_ERROR); } - called_emsg |= save_called_emsg; } else { icon_str = (char *)p_iconstring; } -- cgit From 7b5b7b3cc6306e9313dcf677f212cb132bd38aa0 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 15 Jul 2022 14:50:10 +0800 Subject: vim-patch:8.0.1118: FEAT_WINDOWS adds a lot of #ifdefs Problem: FEAT_WINDOWS adds a lot of #ifdefs while it is nearly always enabled and only adds 7% to the binary size of the tiny build. Solution: Graduate FEAT_WINDOWS. https://github.com/vim/vim/commit/4033c55eca575777718c0701e26635a0cc47d907 --- src/nvim/buffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 69aaee4f9b..ee3a8c26b8 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -443,6 +443,7 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last, bool i return false; } + // check no autocommands closed the window if (win != NULL // Avoid bogus clang warning. && win_valid_any_tab(win)) { // Set b_last_cursor when closing the last window for the buffer. -- cgit From a649af4dbaba5ef13dcbf610fe584dbc67cf2435 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 15 Jul 2022 11:43:42 +0800 Subject: vim-patch:8.2.0426: some errors were not tested for Problem: Some errors were not tested for. Solution: Add tests. (Dominique Pelle, closes vim/vim#5824) https://github.com/vim/vim/commit/9b9be007e7d674f49fc2b650f840d08532b180ad Cherry-pick get_highest_fnum() from patch 8.1.1908 to make tests pass. --- src/nvim/buffer.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ee3a8c26b8..09f5ebe217 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -94,11 +94,19 @@ static char *e_buflocked = N_("E937: Attempt to delete a buffer that is in use") // Number of times free_buffer() was called. static int buf_free_count = 0; +static int top_file_num = 1; ///< highest file number + typedef enum { kBffClearWinInfo = 1, kBffInitChangedtick = 2, } BufFreeFlags; +/// @return the highest possible buffer number +int get_highest_fnum(void) +{ + return top_file_num - 1; +} + /// Read data from buffer for retrying. /// /// @param read_stdin read file from stdin, otherwise fifo @@ -1644,8 +1652,6 @@ void no_write_message_nobang(const buf_T *const buf) // functions for dealing with the buffer list // -static int top_file_num = 1; ///< highest file number - /// Initialize b:changedtick and changedtick_val attribute /// /// @param[out] buf Buffer to initialize for. -- cgit From 4a64cdafd64198d3607fabaed8fc54e473614269 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 15 Jul 2022 17:53:00 +0800 Subject: vim-patch:8.1.1547: functionality of bt_nofile() is confusing Problem: Functionality of bt_nofile() is confusing. Solution: Split into bt_nofile() and bt_nofilename(). https://github.com/vim/vim/commit/26910de8b0da6abab87bd5a397330f9cbe483309 --- src/nvim/buffer.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 09f5ebe217..f937450107 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5271,9 +5271,9 @@ bool bt_terminal(const buf_T *const buf) return buf != NULL && buf->b_p_bt[0] == 't'; } -/// @return true if "buf" is a "nofile", "acwrite", "terminal" or "prompt" / +/// @return true if "buf" is a "nofile", "acwrite", "terminal" or "prompt" /// buffer. This means the buffer name is not a file name. -bool bt_nofile(const buf_T *const buf) +bool bt_nofilename(const buf_T *const buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return buf != NULL && ((buf->b_p_bt[0] == 'n' && buf->b_p_bt[2] == 'f') @@ -5282,6 +5282,13 @@ bool bt_nofile(const buf_T *const buf) || buf->b_p_bt[0] == 'p'); } +/// @return true if "buf" has 'buftype' set to "nofile". +bool bt_nofile(const buf_T *const buf) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + return buf != NULL && buf->b_p_bt[0] == 'n' && buf->b_p_bt[2] == 'f'; +} + /// @return true if "buf" is a "nowrite", "nofile", "terminal" or "prompt" /// buffer. bool bt_dontwrite(const buf_T *const buf) @@ -5333,7 +5340,7 @@ char *buf_spname(buf_T *buf) } // There is no _file_ when 'buftype' is "nofile", b_sfname // contains the name as specified by the user. - if (bt_nofile(buf)) { + if (bt_nofilename(buf)) { if (buf->b_fname != NULL) { return buf->b_fname; } -- cgit