mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 11:58:17 +00:00
'inccommand': rework
- Eliminate/isolate static/global variables - Remove special-case parameter from buflist_new() - Remove special-case ECMD_RESERVED_BUFNR - To determine when u_undo_and_forget() should be done, check b_changedtick instead of a heuristic. - use mb_string2cells() instead of strlen() to measure the :sub patterns - call ml_close() before buf_clear_file(). Avoids leaks caught by ASan. Original patch by: Robin Elrharbi-Fleury (Robinhola) Audrey Rayé (Adrey06) Philémon Hullot (DesbyP) Aymeric Collange (aym7) Clément Guyomard (Clement0)
This commit is contained in:
@@ -268,6 +268,9 @@ open_buffer (
|
||||
bool buf_valid(buf_T *buf)
|
||||
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (buf == NULL) {
|
||||
return false;
|
||||
}
|
||||
FOR_ALL_BUFFERS(bp) {
|
||||
if (bp == buf) {
|
||||
return true;
|
||||
@@ -479,6 +482,18 @@ void buf_clear_file(buf_T *buf)
|
||||
buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */
|
||||
}
|
||||
|
||||
/// Clears the current buffer contents.
|
||||
void buf_clear(void)
|
||||
{
|
||||
linenr_T line_count = curbuf->b_ml.ml_line_count;
|
||||
while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) {
|
||||
ml_delete((linenr_T)1, false);
|
||||
}
|
||||
deleted_lines_mark(1, line_count); // prepare for display
|
||||
ml_close(curbuf, true); // free memline_T
|
||||
buf_clear_file(curbuf);
|
||||
}
|
||||
|
||||
/// buf_freeall() - free all things allocated for a buffer that are related to
|
||||
/// the file. Careful: get here with "curwin" NULL when exiting.
|
||||
///
|
||||
@@ -678,7 +693,7 @@ void handle_swap_exists(buf_T *old_curbuf)
|
||||
swap_exists_did_quit = true;
|
||||
close_buffer(curwin, curbuf, DOBUF_UNLOAD, false);
|
||||
if (!buf_valid(old_curbuf) || old_curbuf == curbuf) {
|
||||
old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED, 0);
|
||||
old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
|
||||
}
|
||||
if (old_curbuf != NULL) {
|
||||
enter_buffer(old_curbuf);
|
||||
@@ -1320,29 +1335,29 @@ void do_autochdir(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* functions for dealing with the buffer list
|
||||
*/
|
||||
//
|
||||
// functions for dealing with the buffer list
|
||||
//
|
||||
|
||||
/*
|
||||
* Add a file name to the buffer list. Return a pointer to the buffer.
|
||||
* If the same file name already exists return a pointer to that buffer.
|
||||
* If it does not exist, or if fname == NULL, a new entry is created.
|
||||
* If (flags & BLN_CURBUF) is TRUE, may use current buffer.
|
||||
* If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
|
||||
* If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
|
||||
* This is the ONLY way to create a new buffer.
|
||||
*/
|
||||
static int top_file_num = 1; /* highest file number */
|
||||
|
||||
buf_T *
|
||||
buflist_new(
|
||||
char_u *ffname, // full path of fname or relative
|
||||
char_u *sfname, // short fname or NULL
|
||||
linenr_T lnum, // preferred cursor line
|
||||
int flags, // BLN_ defines
|
||||
handle_T bufnr
|
||||
)
|
||||
/// Add a file name to the buffer list.
|
||||
/// If the same file name already exists return a pointer to that buffer.
|
||||
/// If it does not exist, or if fname == NULL, a new entry is created.
|
||||
/// If (flags & BLN_CURBUF) is TRUE, may use current buffer.
|
||||
/// If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
|
||||
/// If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
|
||||
/// If (flags & BLN_NEW) is TRUE, don't use an existing buffer.
|
||||
/// This is the ONLY way to create a new buffer.
|
||||
///
|
||||
/// @param ffname full path of fname or relative
|
||||
/// @param sfname short fname or NULL
|
||||
/// @param lnum preferred cursor line
|
||||
/// @param flags BLN_ defines
|
||||
/// @param bufnr
|
||||
///
|
||||
/// @return pointer to the buffer
|
||||
buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
|
||||
{
|
||||
buf_T *buf;
|
||||
|
||||
@@ -1460,9 +1475,7 @@ buflist_new(
|
||||
}
|
||||
lastbuf = buf;
|
||||
|
||||
// If bufnr is nonzero it is assumed to be a previously
|
||||
// reserved buffer number (handle)
|
||||
buf->handle = bufnr != 0 ? bufnr : top_file_num++;
|
||||
buf->b_fnum = top_file_num++;
|
||||
handle_register_buffer(buf);
|
||||
if (top_file_num < 0) { // wrap around (may cause duplicates)
|
||||
EMSG(_("W14: Warning: List of file names overflow"));
|
||||
@@ -2379,7 +2392,7 @@ buf_T *setaltfname(char_u *ffname, char_u *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, 0);
|
||||
buf = buflist_new(ffname, sfname, lnum, 0);
|
||||
if (buf != NULL && !cmdmod.keepalt) {
|
||||
curwin->w_alt_fnum = buf->b_fnum;
|
||||
}
|
||||
@@ -2416,7 +2429,7 @@ int buflist_add(char_u *fname, int flags)
|
||||
{
|
||||
buf_T *buf;
|
||||
|
||||
buf = buflist_new(fname, NULL, (linenr_T)0, flags, 0);
|
||||
buf = buflist_new(fname, NULL, (linenr_T)0, flags);
|
||||
if (buf != NULL) {
|
||||
return buf->b_fnum;
|
||||
}
|
||||
@@ -5199,7 +5212,7 @@ bool buf_contents_changed(buf_T *buf)
|
||||
bool differ = true;
|
||||
|
||||
// Allocate a buffer without putting it in the buffer list.
|
||||
buf_T *newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY, 0);
|
||||
buf_T *newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
|
||||
if (newbuf == NULL) {
|
||||
return true;
|
||||
}
|
||||
@@ -5259,3 +5272,15 @@ wipe_buffer (
|
||||
unblock_autocmds();
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates or switches to a special-purpose buffer.
|
||||
///
|
||||
/// @param bufnr Buffer to switch to, or 0 to create a new buffer.
|
||||
void buf_open_special(handle_T bufnr, char *bufname, char *buftype)
|
||||
{
|
||||
(void)do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
|
||||
(void)setfname(curbuf, (char_u *)bufname, NULL, true);
|
||||
set_option_value((char_u *)"bt", 0L, (char_u *)buftype, OPT_LOCAL);
|
||||
set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
|
||||
RESET_BINDING(curwin);
|
||||
}
|
||||
|
Reference in New Issue
Block a user