aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2016-10-31 03:50:19 +0100
committerJustin M. Keyes <justinkz@gmail.com>2016-11-08 21:20:08 +0100
commitc04ffe866d276d6a6bd9e9c6a8b0dbb71504db7c (patch)
tree0fca258fbfb83cb871a493916d9dd6e0ef1195c3 /src
parente8c0f909626094350be7ee7b524697804da38dc1 (diff)
downloadrneovim-c04ffe866d276d6a6bd9e9c6a8b0dbb71504db7c.tar.gz
rneovim-c04ffe866d276d6a6bd9e9c6a8b0dbb71504db7c.tar.bz2
rneovim-c04ffe866d276d6a6bd9e9c6a8b0dbb71504db7c.zip
'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)
Diffstat (limited to 'src')
-rw-r--r--src/nvim/buffer.c79
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/ex_cmds.c513
-rw-r--r--src/nvim/ex_cmds.h21
-rw-r--r--src/nvim/ex_cmds.lua6
-rw-r--r--src/nvim/ex_docmd.c25
-rw-r--r--src/nvim/ex_docmd.h3
-rw-r--r--src/nvim/ex_getln.c23
-rw-r--r--src/nvim/fileio.c5
-rw-r--r--src/nvim/globals.h1
-rw-r--r--src/nvim/mark.c2
-rw-r--r--src/nvim/memline.c15
-rw-r--r--src/nvim/quickfix.c2
-rw-r--r--src/nvim/shada.c2
-rw-r--r--src/nvim/syntax.c13
-rw-r--r--src/nvim/undo.c30
-rw-r--r--src/nvim/window.c2
17 files changed, 335 insertions, 409 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 65a42f063a..190c281c76 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -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);
+}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 508bdac46d..512555eac1 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -7703,7 +7703,7 @@ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
&& !error
&& (name = get_tv_string_chk(&argvars[0])) != NULL
&& !error)
- buf = buflist_new(name, NULL, (linenr_T)1, 0, 0);
+ buf = buflist_new(name, NULL, (linenr_T)1, 0);
if (buf != NULL)
rettv->vval.v_number = buf->b_fnum;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 97aac76860..9f781c0f8e 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -10,6 +10,9 @@
#include <inttypes.h>
#include <math.h>
+#include "nvim/api/private/defs.h"
+#include "nvim/api/buffer.h"
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/ex_cmds.h"
@@ -65,12 +68,6 @@
*/
typedef struct sign sign_T;
-// boolean to know if inc_sub needs to undo
-static bool inc_sub_did_changes = false;
-
-// reuse the same bufnr for inc_sub
-static handle_T inc_sub_bufnr = 0;
-
/// Case matching style to use for :substitute
typedef enum {
kSubHonorOptions = 0, ///< Honor the user's 'ignorecase'/'smartcase' options
@@ -90,6 +87,15 @@ typedef struct {
SubIgnoreType do_ic; ///< ignore case flag
} subflags_T;
+/// Lines matched during 'incsubstitute'.
+typedef struct {
+ linenr_T lnum;
+ long nmatch;
+ char_u *line;
+ kvec_t(colnr_T) cols; //< columns of in-line matches
+} MatchedLine;
+typedef kvec_t(MatchedLine) MatchedLineVec;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds.c.generated.h"
#endif
@@ -1530,7 +1536,7 @@ int rename_buffer(char_u *new_fname)
}
curbuf->b_flags |= BF_NOTEDITED;
if (xfname != NULL && *xfname != NUL) {
- buf = buflist_new(fname, xfname, curwin->w_cursor.lnum, 0, 0);
+ buf = buflist_new(fname, xfname, curwin->w_cursor.lnum, 0);
if (buf != NULL && !cmdmod.keepalt) {
curwin->w_alt_fnum = buf->b_fnum;
}
@@ -2027,37 +2033,34 @@ theend:
return retval;
}
-/*
- * start editing a new file
- *
- * fnum: file number; if zero use ffname/sfname
- * ffname: the file name
- * - full path if sfname used,
- * - any file name if sfname is NULL
- * - empty string to re-edit with the same file name (but may be
- * in a different directory)
- * - NULL to start an empty buffer
- * sfname: the short file name (or NULL)
- * eap: contains the command to be executed after loading the file and
- * forced 'ff' and 'fenc'
- * newlnum: if > 0: put cursor on this line number (if possible)
- * if ECMD_LASTL: use last position in loaded file
- * if ECMD_LAST: use last position in all files
- * if ECMD_ONE: use first line
- * flags:
- * ECMD_HIDE: if TRUE don't free the current buffer
- * ECMD_SET_HELP: set b_help flag of (new) buffer before opening file
- * ECMD_OLDBUF: use existing buffer if it exists
- * ECMD_FORCEIT: ! used for Ex command
- * ECMD_ADDBUF: don't edit, just add to buffer list
- * oldwin: Should be "curwin" when editing a new buffer in the current
- * window, NULL when splitting the window first. When not NULL info
- * of the previous buffer for "oldwin" is stored.
- *
- * return FAIL for failure, OK otherwise
- */
-int
-do_ecmd (
+/// start editing a new file
+///
+/// @param fnum file number; if zero use ffname/sfname
+/// @param ffname the file name
+/// - full path if sfname used,
+/// - any file name if sfname is NULL
+/// - empty string to re-edit with the same file name (but may
+/// be in a different directory)
+/// - NULL to start an empty buffer
+/// @param sfname the short file name (or NULL)
+/// @param eap contains the command to be executed after loading the file
+/// and forced 'ff' and 'fenc'
+/// @param newlnum if > 0: put cursor on this line number (if possible)
+/// ECMD_LASTL: use last position in loaded file
+/// ECMD_LAST: use last position in all files
+/// ECMD_ONE: use first line
+/// @param flags ECMD_HIDE: if TRUE don't free the current buffer
+/// ECMD_SET_HELP: set b_help flag of (new) buffer before
+/// opening file
+/// ECMD_OLDBUF: use existing buffer if it exists
+/// ECMD_FORCEIT: ! used for Ex command
+/// ECMD_ADDBUF: don't edit, just add to buffer list
+/// @param oldwin Should be "curwin" when editing a new buffer in the current
+/// window, NULL when splitting the window first. When not NULL
+/// info of the previous buffer for "oldwin" is stored.
+///
+/// @return FAIL for failure, OK otherwise
+int do_ecmd (
int fnum,
char_u *ffname,
char_u *sfname,
@@ -2182,9 +2185,10 @@ do_ecmd (
buflist_altfpos(oldwin);
}
- if (fnum && !(flags & ECMD_RESERVED_BUFNR)) {
+ if (fnum) {
buf = buflist_findnr(fnum);
} else {
+ ILOG("here");
if (flags & ECMD_ADDBUF) {
linenr_T tlnum = 1L;
@@ -2193,12 +2197,11 @@ do_ecmd (
if (tlnum <= 0)
tlnum = 1L;
}
- (void)buflist_new(ffname, sfname, tlnum, BLN_LISTED, fnum);
+ (void)buflist_new(ffname, sfname, tlnum, BLN_LISTED);
goto theend;
}
buf = buflist_new(ffname, sfname, 0L,
- BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED),
- fnum);
+ BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED));
// Autocmds may change curwin and curbuf.
if (oldwin != NULL) {
oldwin = curwin;
@@ -3098,16 +3101,17 @@ static char_u *sub_parse_flags(char_u *cmd, subflags_T *subflags,
return cmd;
}
-/* do_sub()
- *
- * Perform a substitution from line eap->line1 to line eap->line2 using the
- * command pointed to by eap->arg which should be of the form:
- *
- * /pattern/substitution/{flags}
- *
- * The usual escapes are supported as described in the regexp docs.
- */
-void do_sub(exarg_T *eap)
+/// do_sub()
+///
+/// Perform a substitution from line eap->line1 to line eap->line2 using the
+/// command pointed to by eap->arg which should be of the form:
+///
+/// /pattern/substitution/{flags}
+///
+/// The usual escapes are supported as described in the regexp docs.
+///
+/// @return buffer used for 'incsubstitute'
+buf_T *do_sub(exarg_T *eap)
{
long i = 0;
regmmatch_T regmatch;
@@ -3123,24 +3127,22 @@ void do_sub(exarg_T *eap)
};
char_u *pat = NULL, *sub = NULL; // init for GCC
int delimiter;
+ bool has_second_delim = false;
int sublen;
int got_quit = false;
int got_match = false;
int which_pat;
char_u *cmd = eap->arg;
linenr_T first_line = 0; // first changed line
- linenr_T last_line= 0; // below last changed line AFTER the
- // change
+ linenr_T last_line= 0; // below last changed line AFTER the change
linenr_T old_line_count = curbuf->b_ml.ml_line_count;
- char_u *sub_firstline; // allocated copy of first sub line
- bool endcolumn = false; // cursor in last column when done
+ char_u *sub_firstline; // allocated copy of first sub line
+ bool endcolumn = false; // cursor in last column when done
+ MatchedLineVec matched_lines = KV_INITIAL_VALUE;
pos_T old_cursor = curwin->w_cursor;
int start_nsubs;
int save_ma = 0;
- inc_sub_did_changes = false;
- bool has_second_delim = false;
-
if (!global_busy) {
sub_nsubs = 0;
sub_nlines = 0;
@@ -3158,7 +3160,7 @@ void do_sub(exarg_T *eap)
/* don't accept alphanumeric for separator */
if (isalpha(*cmd)) {
EMSG(_("E146: Regular expressions can't be delimited by letters"));
- return;
+ return NULL;
}
/*
* undocumented vi feature:
@@ -3169,7 +3171,7 @@ void do_sub(exarg_T *eap)
++cmd;
if (vim_strchr((char_u *)"/?&", *cmd) == NULL) {
EMSG(_(e_backslash));
- return;
+ return NULL;
}
if (*cmd != '&') {
which_pat = RE_SEARCH; // use last '/' pattern
@@ -3217,7 +3219,7 @@ void do_sub(exarg_T *eap)
} else if (!eap->skip) { /* use previous pattern and substitution */
if (old_sub.sub == NULL) { /* there is no previous command */
EMSG(_(e_nopresub));
- return;
+ return NULL;
}
pat = NULL; /* search_regcomp() will use previous pattern */
sub = (char_u *) old_sub.sub;
@@ -3228,7 +3230,7 @@ void do_sub(exarg_T *eap)
}
if (sub_joining_lines(eap, pat, sub, cmd)) {
- return;
+ return NULL;
}
cmd = sub_parse_flags(cmd, &subflags, &which_pat);
@@ -3242,7 +3244,7 @@ void do_sub(exarg_T *eap)
i = getdigits_long(&cmd);
if (i <= 0 && !eap->skip && subflags.do_error) {
EMSG(_(e_zerocount));
- return;
+ return NULL;
}
eap->line1 = eap->line2;
eap->line2 += i - 1;
@@ -3258,17 +3260,17 @@ void do_sub(exarg_T *eap)
eap->nextcmd = check_nextcmd(cmd);
if (eap->nextcmd == NULL) {
EMSG(_(e_trailing));
- return;
+ return NULL;
}
}
if (eap->skip) /* not executing commands, only parsing */
- return;
+ return NULL;
if (!subflags.do_count && !MODIFIABLE(curbuf)) {
// Substitution is not allowed in non-'modifiable' buffer
EMSG(_(e_modifiable));
- return;
+ return NULL;
}
int search_options = eap->is_live ? 0 : SEARCH_HIS;
@@ -3277,7 +3279,7 @@ void do_sub(exarg_T *eap)
if (subflags.do_error) {
EMSG(_(e_invcmd));
}
- return;
+ return NULL;
}
// the 'i' or 'I' flag overrules 'ignorecase' and 'smartcase'
@@ -3297,9 +3299,6 @@ void do_sub(exarg_T *eap)
if (!(sub[0] == '\\' && sub[1] == '='))
sub = regtilde(sub, p_magic);
- // list to save matched lines
- MatchedLineVec lmatch = KV_INITIAL_VALUE;
-
// Check for a match on each line.
linenr_T line2 = eap->line2;
for (linenr_T lnum = eap->line1;
@@ -3368,7 +3367,7 @@ void do_sub(exarg_T *eap)
copycol = 0;
matchcol = 0;
// the current match
- MatchedLine cmatch = { 0, 0, NULL, KV_INITIAL_VALUE };
+ MatchedLine matched_line = { 0, 0, NULL, KV_INITIAL_VALUE };
/* At first match, remember current cursor position. */
if (!got_match) {
@@ -3405,9 +3404,9 @@ void do_sub(exarg_T *eap)
curwin->w_cursor.lnum = lnum;
do_again = FALSE;
- // increment number of match on the line and store the column
- cmatch.nmatch++;
- kv_push(cmatch.start_col, regmatch.startpos[0].col);
+ // Increment the in-line match count and store the column.
+ matched_line.nmatch++;
+ kv_push(matched_line.cols, regmatch.startpos[0].col);
/*
* 1. Match empty string does not count, except for first
@@ -3627,8 +3626,8 @@ void do_sub(exarg_T *eap)
* use "\=col("."). */
curwin->w_cursor.col = regmatch.startpos[0].col;
- // 3. Substitute the string. Don't do this while incsubstitution and
- // there's no word to replace by eg : ":%s/pattern"
+ // 3. Substitute the string. During 'incsubstitute' only do this if
+ // there is a replace pattern.
if (!eap->is_live || has_second_delim) {
if (subflags.do_count) {
// prevent accidentally changing the buffer by a function
@@ -3873,11 +3872,9 @@ skip:
xfree(sub_firstline); /* free the copy of the original line */
sub_firstline = NULL;
- // saving info about the matched line
- cmatch.lnum = lnum;
- cmatch.line = vim_strsave(ml_get(lnum));
-
- kv_push(lmatch, cmatch);
+ matched_line.lnum = lnum;
+ matched_line.line = vim_strsave(ml_get(lnum));
+ kv_push(matched_lines, matched_line);
}
line_breakcheck();
@@ -3946,78 +3943,65 @@ skip:
subflags.do_all = save_do_all;
subflags.do_ask = save_do_ask;
- // inc_sub if sub on the whole file and there are results to display
- if (lmatch.size != 0) {
- // we did incsubstitute only if we had no word to replace by
- // by and no ending slash
- if (!subflags.do_count && (!eap->is_live || has_second_delim)) {
- inc_sub_did_changes = true;
- }
- if (pat != NULL && *p_ics != NUL && eap->is_live) {
- bool split = true;
-
- // p_ics is "", "nosplit" or "split"
- if (*p_ics == 'n' || eap[0].cmdlinep[0][0] == 's') {
- split = false;
- }
-
- // Place cursor on the first match after the cursor
- // If all matches are before the cursor, then do_sub did
- // already place the cursor on the last match
-
- linenr_T cur_lnum = 0;
- colnr_T cur_col = -1;
- MatchedLine current;
-
- for (size_t j = 0; j < lmatch.size; j++) {
- current = lmatch.items[j];
- cur_lnum = current.lnum;
-
- // 1. Match on line of the cursor, need to iterate over the
- // matches on this line to see if there is one on a later
- // column
- if (cur_lnum == old_cursor.lnum) {
- for (size_t i = 0; i < current.start_col.size; i++) {
- if (current.start_col.items[i] >= old_cursor.col) {
- cur_col = current.start_col.items[i];
- break;
- }
- }
- // match on cursor's line, after the cursor
- if (cur_col != -1) {
- curwin->w_cursor.lnum = cur_lnum;
- curwin->w_cursor.col = cur_col;
+ // Show 'incsubstitute' preview if there are matched lines.
+ buf_T *incsub_buf = NULL;
+ if (matched_lines.size != 0 && pat != NULL && *p_ics != NUL && eap->is_live) {
+ // Place cursor on the first match after the cursor.
+ // If all matches are before the cursor, then do_sub already placed the
+ // cursor on the last match.
+
+ linenr_T cur_lnum = 0;
+ colnr_T cur_col = -1;
+ MatchedLine current;
+
+ for (size_t j = 0; j < matched_lines.size; j++) {
+ current = matched_lines.items[j];
+ cur_lnum = current.lnum;
+
+ // 1. Match on line of the cursor, need to iterate over the
+ // matches on this line to see if there is one on a later
+ // column
+ if (cur_lnum == old_cursor.lnum) {
+ for (size_t i = 0; i < current.cols.size; i++) {
+ if (current.cols.items[i] >= old_cursor.col) {
+ cur_col = current.cols.items[i];
break;
}
- // 2. Match on line after cursor, just put cursor on column
- // of first match there
- } else if (cur_lnum > old_cursor.lnum) {
- cur_col = current.start_col.items[0];
- curwin->w_cursor.lnum = cur_lnum;
- curwin->w_cursor.col = cur_col;
- break;
}
+ // match on cursor's line, after the cursor
+ if (cur_col != -1) {
+ curwin->w_cursor.lnum = cur_lnum;
+ curwin->w_cursor.col = cur_col;
+ break;
+ }
+ // 2. Match on line after cursor, just put cursor on column
+ // of first match there
+ } else if (cur_lnum > old_cursor.lnum) {
+ cur_col = current.cols.items[0];
+ curwin->w_cursor.lnum = cur_lnum;
+ curwin->w_cursor.col = cur_col;
+ break;
}
-
- inc_sub_display(pat, sub, &lmatch, split);
- } else if (*p_ics != NUL && eap->is_live) {
- curwin->w_cursor = old_cursor;
}
- } else {
- curwin->w_cursor = old_cursor;
- }
-
- MatchedLine current;
- for (size_t j = 0; j < lmatch.size; j++) {
- current = lmatch.items[j];
- if (current.line) { xfree(current.line); }
+ incsub_buf = incsub_display(pat, sub, eap->line1, eap->line2,
+ &matched_lines);
- kv_destroy(current.start_col);
+ } else if (*p_ics != NUL && eap->is_live) {
+ curwin->w_cursor = old_cursor; // don't move the cursor
}
+ MatchedLine current;
+ for (size_t j = 0; j < matched_lines.size; j++) {
+ current = matched_lines.items[j];
+ if (current.line) {
+ xfree(current.line);
+ }
+ kv_destroy(current.cols);
+ }
- kv_destroy(lmatch);
+ kv_destroy(matched_lines);
+ return incsub_buf;
} // NOLINT(readability/fn_size)
/*
@@ -6058,192 +6042,143 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
}
}
-/// Open a window for displaying of the inc_sub mode.
-///
-/// Does not allow editing in the window. Closes the window and restores
-/// the window layout before returning.
-///
-/// @param pat The pattern word
-/// @param sub The replacement word
-/// @param lmatch The list containing our data
-static void inc_sub_display(char_u *pat,
- char_u *sub,
- MatchedLineVec *lmatch,
- bool split)
- FUNC_ATTR_NONNULL_ARG(1, 2, 3)
+/// Shows a preview of :substitute (for 'incsubstitute').
+/// With incsubstitute=split, shows a special buffer in a window, draws the
+/// screen, then restores the layout.
+static buf_T *incsub_display(char_u *pat, char_u *sub,
+ linenr_T line1, linenr_T line2,
+ MatchedLineVec *matched_lines)
+ FUNC_ATTR_NONNULL_ALL
{
- garray_T winsizes;
- int save_restart_edit = restart_edit;
- int save_State = State;
- int save_exmode = exmode_active;
- int save_cmdmsg_rl = cmdmsg_rl;
-
- // Can't do this recursively. Can't do it when typing a password.
- if (cmdline_star > 0) {
- beep_flush();
- return;
- }
-
- // Save current window sizes.
- win_size_save(&winsizes);
-
- // Save the current window to restore it later
- win_T *oldwin = curwin;
-
- if (split) {
- // don't use a new tab page
- cmdmod.tab = 0;
-
- // Create a window for the command-line buffer.
- if (win_split((int)p_cwh, WSP_BOT) == FAIL) {
- beep_flush();
- return;
- }
- cmdwin_type = get_cmdline_type();
-
- // Create the command-line buffer empty.
- (void)do_ecmd(inc_sub_bufnr, NULL, NULL, NULL, ECMD_ONE,
- ECMD_HIDE | ECMD_RESERVED_BUFNR, NULL);
- inc_sub_bufnr = curbuf->handle;
- (void)setfname(curbuf, (char_u *) "[inc_sub]", NULL, true);
- set_option_value((char_u *) "bt", 0L, (char_u *) "incsub", OPT_LOCAL);
- set_option_value((char_u *) "swf", 0L, NULL, OPT_LOCAL);
- curbuf->b_p_ma = false; // Not Modifiable
+ static handle_T bufnr = 0; // special buffer, re-used on each visit
+
+ garray_T save_winsizes;
+ win_T *save_curwin = curwin;
+ cmdmod_T save_cmdmod = cmdmod;
+ char_u *save_shm_p = vim_strsave(p_shm);
+ size_t sub_size = mb_string2cells(sub);
+ size_t pat_size = mb_string2cells(pat);
+
+ // We keep a special-purpose buffer around, but don't assume it exists.
+ buf_T *incsub_buf = bufnr ? buflist_findnr(bufnr) : 0;
+ win_size_save(&save_winsizes); // Save current window sizes.
+ cmdmod.tab = 0; // disable :tab modifier
+ cmdmod.noswapfile = true; // disable swap for 'incsubstitute' buffer
+ // disable file info message
+ set_option_value((char_u *)"shm", 0L, (char_u *)"F", 0);
+
+ bool outside_curline = (line1 != curwin->w_cursor.lnum
+ || line2 != curwin->w_cursor.lnum);
+ bool split = outside_curline && (*p_ics != 'n') && (sub_size || pat_size);
+ if (incsub_buf == curbuf) { // Preview buffer cannot preview itself!
+ split = false;
+ incsub_buf = NULL;
+ }
+
+ if (split && win_split((int)p_cwh, WSP_BOT) != FAIL) {
+ buf_open_special(incsub_buf ? bufnr : 0, "[inc_sub]", "incsub");
+ buf_clear();
+ incsub_buf = curbuf;
+ set_option_value((char_u *)"bl", 0L, NULL, OPT_LOCAL);
+ set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
+ bufnr = incsub_buf->handle;
+ curbuf->b_p_ma = true;
+ curbuf->b_p_ul = -1;
curwin->w_p_fen = false;
- curwin->w_p_rl = cmdmsg_rl;
- cmdmsg_rl = false;
- RESET_BINDING(curwin);
+ curbuf->b_p_tw = 0; // Reset 'textwidth' (was set by ftplugin)
- // Showing the prompt may have set need_wait_return, reset it.
- need_wait_return = false;
-
- // Reset 'textwidth' after setting 'filetype'
- // (the Vim filetype plugin sets 'textwidth' to 78).
- curbuf->b_p_tw = 0;
-
- // Save the buffer used in the split
- livebuf = curbuf;
-
- // Initialize line and highlight variables
- int line = 0;
- int src_id_highlight = 0;
- long sub_size = STRLEN(sub);
- long pat_size = STRLEN(pat);
-
- // Get the width of the column which display the number of the line
- linenr_T highest_num_line = kv_last(*lmatch).lnum;
-
- // computing the length of the column that will display line number
+ // Width of the "| lnum|..." column which displays the line numbers.
+ linenr_T highest_num_line = kv_last(*matched_lines).lnum;
int col_width = log10(highest_num_line) + 1 + 3;
- // will be allocated in the loop
char *str = NULL;
-
size_t old_line_size = 0;
size_t line_size;
+ int src_id_highlight = 0;
+ int hl_id = syn_check_group((char_u *)"IncSubstitute", 13);
- // Append the lines to our buffer
- for (size_t i = 0; i < (*lmatch).size; i++) {
- MatchedLine mat = (*lmatch).items[i];
- line_size = STRLEN(mat.line) + col_width + 1;
+ // Dump the lines into the incsub buffer.
+ for (size_t line = 0; line < matched_lines->size; line++) {
+ MatchedLine mat = matched_lines->items[line];
+ line_size = mb_string2cells(mat.line) + col_width + 1;
- // Reallocation if str not long enough
+ // Reallocate if str not long enough
if (line_size > old_line_size) {
str = xrealloc(str, line_size * sizeof(char));
old_line_size = line_size;
}
- // put ' [ lnum]line' into str and append it to the incsubstitute buffer
+ // put " | lnum|line" into str and append it to the incsubstitute buffer
snprintf(str, line_size, " [%*ld]%s", col_width - 3, mat.lnum, mat.line);
- ml_append(line++, (char_u *)str, (colnr_T)line_size, false);
+ ml_append(line, (char_u *)str, (colnr_T)line_size, false);
// highlight the replaced part
if (sub_size > 0) {
- int hlgroup_ls = syn_check_group((char_u *)"IncSubstitute", 13);
-
- for (size_t j = 0; j < mat.start_col.size; j++) {
- src_id_highlight =
- bufhl_add_hl(curbuf,
- src_id_highlight,
- hlgroup_ls, // id of our highlight
- line,
- mat.start_col.items[j] + col_width
- + j * (sub_size - pat_size) + 1,
- mat.start_col.items[j] + col_width
- + j * (sub_size - pat_size) + sub_size);
+ for (size_t i = 0; i < mat.cols.size; i++) {
+ colnr_T col_start = mat.cols.items[i] + col_width
+ + i * (sub_size - pat_size) + 1;
+ colnr_T col_end = col_start - 1 + sub_size;
+ src_id_highlight = bufhl_add_hl(curbuf, src_id_highlight, hl_id,
+ line + 1, col_start, col_end);
}
}
}
xfree(str);
- redraw_later(SOME_VALID);
}
- // Restore the old window
- win_enter(oldwin, false);
- win_size_restore(&winsizes);
- ga_clear(&winsizes);
- exmode_active = save_exmode;
- restart_edit = save_restart_edit;
- cmdmsg_rl = save_cmdmsg_rl;
- State = save_State;
+ redraw_later(SOME_VALID);
+
+ win_enter(save_curwin, false); // Return to original window
+ win_size_restore(&save_winsizes);
+ ga_clear(&save_winsizes);
+
+ set_option_value((char_u *)"shm", 0L, save_shm_p, 0);
+ xfree(save_shm_p);
- cmdwin_type = 0;
+ // Update screen now. Must do this _before_ close_windows().
int save_rd = RedrawingDisabled;
RedrawingDisabled = 0;
- update_screen(0);
+ update_screen(NOT_VALID);
RedrawingDisabled = save_rd;
- setmouse();
-}
+ cmdmod = save_cmdmod;
+ return incsub_buf;
+}
-/// :substitute command implementation
+/// :substitute command
///
-/// Uses do_sub() to do the actual substitution. Undoes the substitution and
-/// removes it from the undo history unless finishing the command. If
-/// ics is set to "", it just calls do_sub().
-void do_inc_sub(exarg_T *eap)
+/// If 'incsubstitute' is empty, this just calls do_sub().
+/// If 'incsubstitute' is set, substitutes as-you-type ("live").
+/// If the command is cancelled the changes are removed from undo history.
+void ex_substitute(exarg_T *eap)
{
- // if incsubstitute disabled, do it the classical way
- if (*p_ics == NUL || !eap->is_live) {
- do_sub(eap);
+ if (*p_ics == NUL || !eap->is_live) { // 'incsubstitute' is disabled
+ (void)do_sub(eap);
return;
}
- // Save the state of eap
- char_u *tmp = eap->arg;
-
+ char_u *save_eap = eap->arg;
save_search_patterns();
+ int save_changedtick = curbuf->b_changedtick;
+ long save_b_p_ul = curbuf->b_p_ul;
+ curbuf->b_p_ul = LONG_MAX; // make sure we can undo all changes
+ block_autocmds(); // disable events before incsub opening window/buffer
+ emsg_off++; // No error messages for live commands
- // save the value of undolevels to the maximum value to avoid losing
- // history when it is set to a low value
- long b_p_ul_save = curbuf->b_p_ul;
- curbuf->b_p_ul = LONG_MAX;
-
- // Incsub window/buffer is opened in do_sub, so to suppress autocmd
- // we need to start it before the call
- block_autocmds();
+ buf_T *incsub_buf = do_sub(eap);
- emsg_off++; // No error messages for live commands
- do_sub(eap);
- emsg_off--;
- if (inc_sub_did_changes) {
- if (!u_undo_and_forget(1)) {
- abort();
- }
- inc_sub_did_changes = false;
+ if (save_changedtick != curbuf->b_changedtick
+ && !u_undo_and_forget(1)) {
+ abort();
}
-
- // Put back eap in first state
- eap->arg = tmp;
- restore_search_patterns();
- curbuf->b_p_ul = b_p_ul_save;
-
- update_screen(0);
- if (livebuf != NULL && buf_valid(livebuf)) {
- close_windows(livebuf, false);
- wipe_buffer(livebuf, false);
+ if (buf_valid(incsub_buf)) {
+ // XXX: Must do this *after* u_undo_and_forget(), why?
+ close_windows(incsub_buf, false);
}
+ curbuf->b_p_ul = save_b_p_ul;
+ eap->arg = save_eap;
+ restore_search_patterns();
+ emsg_off--;
unblock_autocmds();
- redraw_later(SOME_VALID);
}
diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h
index 82848528ce..ccb2202edb 100644
--- a/src/nvim/ex_cmds.h
+++ b/src/nvim/ex_cmds.h
@@ -6,8 +6,6 @@
#include "nvim/os/time.h"
#include "nvim/eval_defs.h"
#include "nvim/pos.h"
-#include "nvim/lib/klist.h"
-#include "nvim/lib/kvec.h"
// flags for do_ecmd()
#define ECMD_HIDE 0x01 // don't free the current buffer
@@ -18,6 +16,7 @@
#define ECMD_ADDBUF 0x10 // don't edit, just add to buffer list
#define ECMD_RESERVED_BUFNR 0x20 // bufnr argument is reserved bufnr
+
/* for lnum argument in do_ecmd() */
#define ECMD_LASTL (linenr_T)0 /* use last position in loaded file */
#define ECMD_LAST (linenr_T)-1 /* use last position in all files */
@@ -30,24 +29,6 @@ typedef struct {
list_T *additional_elements; ///< Additional data left from ShaDa file.
} SubReplacementString;
-
-// Defs for inc_sub functionality
-
-/// Structure to backup and display matched lines in incsubstitution
-typedef struct {
- linenr_T lnum;
- long nmatch;
- char_u *line;
- // list of column numbers of matches on this line
- kvec_t(colnr_T) start_col;
-} MatchedLine;
-
-// List of matched lines
-typedef kvec_t(MatchedLine) MatchedLineVec;
-
-// End defs for inc_sub functionality
-
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds.h.generated.h"
#endif
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 04fc163222..95ede4bdc5 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -2194,7 +2194,7 @@ return {
command='substitute',
flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN),
addr_type=ADDR_LINES,
- func='do_inc_sub',
+ func='ex_substitute',
},
{
command='sNext',
@@ -3181,7 +3181,7 @@ return {
enum='CMD_and',
flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY),
addr_type=ADDR_LINES,
- func='do_sub',
+ func='ex_substitute',
},
{
command='<',
@@ -3222,6 +3222,6 @@ return {
enum='CMD_tilde',
flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY),
addr_type=ADDR_LINES,
- func='do_sub',
+ func='ex_substitute',
},
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index d8b92e9ec0..30347cbe85 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1248,7 +1248,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
memset(&ea, 0, sizeof(ea));
ea.line1 = 1;
ea.line2 = 1;
- ea.is_live = flags & DOCMD_LIVE_PREVIEW;
+ ea.is_live = flags & DOCMD_LIVE;
ex_nesting_level++;
/* When the last file has not been edited :q has to be typed twice. */
@@ -9652,25 +9652,22 @@ static void ex_terminal(exarg_T *eap)
/// Check whether commandline starts with a live command
///
-/// @param[in] cmd_live Commandline to check. May start with a range.
+/// @param[in] cmd Commandline to check. May start with a range.
///
/// @return True if first command is a live command
-/// Currently :s is the only one
-bool is_live(char_u *cmd_live)
+bool cmd_is_live(char_u *cmd)
{
- exarg_T ea;
- ea.cmd = cmd_live;
+ if (cmd == NULL) {
+ return false;
+ }
+ exarg_T ea;
// parse the command line
- if (ea.cmd != NULL) {
- ea.cmd = skip_range(ea.cmd, NULL);
- if (*ea.cmd == '*') {
- ea.cmd = skipwhite(ea.cmd + 1);
- }
- find_command(&ea, NULL);
- } else {
- return false;
+ ea.cmd = skip_range(cmd, NULL);
+ if (*ea.cmd == '*') {
+ ea.cmd = skipwhite(ea.cmd + 1);
}
+ find_command(&ea, NULL);
return (ea.cmdidx == CMD_substitute);
}
diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h
index e30ece3e1b..84f1a13a15 100644
--- a/src/nvim/ex_docmd.h
+++ b/src/nvim/ex_docmd.h
@@ -10,8 +10,7 @@
#define DOCMD_KEYTYPED 0x08 // don't reset KeyTyped
#define DOCMD_EXCRESET 0x10 // reset exception environment (for debugging
#define DOCMD_KEEPLINE 0x20 // keep typed line for repeating with "."
-#define DOCMD_LIVE_PREVIEW 0x40 // Command is a live preview like
- // incsubstitution
+#define DOCMD_LIVE 0x40 // show updates as-you-type ("live" command)
/* defines for eval_vars() */
#define VALID_PATH 1
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index d1a2ab8bcf..dba7a107e2 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1591,9 +1591,12 @@ static int command_line_changed(CommandLineState *s)
msg_starthere();
redrawcmdline();
s->did_incsearch = true;
- } else if (*p_ics != NUL && s->firstc == ':' && is_live(ccline.cmdbuff)) {
- // compute a live action
- do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_LIVE_PREVIEW);
+ } else if (s->firstc == ':'
+ && *p_ics != NUL // 'incsubstitute' is set
+ && cmdline_star == 0 // not typing a password
+ && cmd_is_live(ccline.cmdbuff)) {
+ // process a "live" command
+ do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_LIVE);
redrawcmdline();
}
@@ -5141,16 +5144,12 @@ static int ex_window(void)
}
cmdwin_type = get_cmdline_type();
- /* Create the command-line buffer empty. */
- (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
- (void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE);
- set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
- set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
- curbuf->b_p_ma = TRUE;
- curwin->w_p_fen = FALSE;
+ // Create empty command-line buffer.
+ buf_open_special(0, "[Command Line]", "nofile");
curwin->w_p_rl = cmdmsg_rl;
- cmdmsg_rl = FALSE;
- RESET_BINDING(curwin);
+ cmdmsg_rl = false;
+ curbuf->b_p_ma = true;
+ curwin->w_p_fen = false;
/* Do execute autocommands for setting the filetype (load syntax). */
unblock_autocmds();
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 7ce2c57420..e83e9f6b01 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -5067,7 +5067,7 @@ void buf_reload(buf_T *buf, int orig_mode)
savebuf = NULL;
} else {
// Allocate a buffer without putting it in the buffer list.
- savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY, 0);
+ savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
if (savebuf != NULL && buf == curbuf) {
/* Open the memline. */
curbuf = savebuf;
@@ -6409,8 +6409,9 @@ win_found:
&& curbuf != aco->new_curbuf
&& buf_valid(aco->new_curbuf)
&& aco->new_curbuf->b_ml.ml_mfp != NULL) {
- if (curwin->w_s == &curbuf->b_s)
+ if (curwin->w_s == &curbuf->b_s) {
curwin->w_s = &aco->new_curbuf->b_s;
+ }
--curbuf->b_nwindows;
curbuf = aco->new_curbuf;
curwin->w_buffer = curbuf;
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index a5188e98d7..690be70c4d 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -603,7 +603,6 @@ EXTERN int redraw_tabline INIT(= FALSE); /* need to redraw tabline */
EXTERN buf_T *firstbuf INIT(= NULL); // first buffer
EXTERN buf_T *lastbuf INIT(= NULL); // last buffer
EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
-EXTERN buf_T *livebuf INIT(= NULL); // buffer used for live actions
// Iterates over all buffers in the buffer list.
# define FOR_ALL_BUFFERS(buf) for (buf_T *buf = firstbuf; buf != NULL; buf = buf->b_next)
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 96983a6c3b..6453c41415 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -474,7 +474,7 @@ static void fname2fnum(xfmark_T *fm)
p = path_shorten_fname(NameBuff, IObuff);
// buflist_new() will call fmarks_check_names()
- (void)buflist_new(NameBuff, p, (linenr_T)1, 0, 0);
+ (void)buflist_new(NameBuff, p, (linenr_T)1, 0);
}
}
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 5505335769..a9a53ebca7 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -2340,14 +2340,13 @@ int ml_replace(linenr_T lnum, char_u *line, int copy)
return OK;
}
-/*
- * Delete line 'lnum' in the current buffer.
- *
- * Check: The caller of this function should probably also call
- * deleted_lines() after this.
- *
- * return FAIL for failure, OK otherwise
- */
+/// Delete line `lnum` in the current buffer.
+///
+/// @note The caller of this function should probably also call
+/// deleted_lines() after this.
+///
+/// @param message Show "--No lines in buffer--" message.
+/// @return FAIL for failure, OK otherwise
int ml_delete(linenr_T lnum, int message)
{
ml_flush_line(curbuf);
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 97172a15ff..f23037613b 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -3327,7 +3327,7 @@ load_dummy_buffer (
aco_save_T aco;
// Allocate a buffer without putting it in the buffer list.
- newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY, 0);
+ newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
if (newbuf == NULL) {
return NULL;
}
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 1cd8f44ea8..01c0807d82 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1405,7 +1405,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
cur_entry.data.buffer_list.buffers[i].fname);
buf_T *const buf = buflist_new(
cur_entry.data.buffer_list.buffers[i].fname, sfname, 0,
- BLN_LISTED, 0);
+ BLN_LISTED);
if (buf != NULL) {
RESET_FMARK(&buf->b_last_cursor,
cur_entry.data.buffer_list.buffers[i].pos, 0);
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index a1c6718b06..68d0e3da0f 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -7160,16 +7160,13 @@ int syn_namen2id(char_u *linep, int len)
*/
int syn_check_group(char_u *pp, int len)
{
- int id;
- char_u *name;
-
- name = vim_strnsave(pp, len);
-
- id = syn_name2id(name);
- if (id == 0) /* doesn't exist yet */
+ char_u *name = vim_strnsave(pp, len);
+ int id = syn_name2id(name);
+ if (id == 0) { // doesn't exist yet
id = syn_add_group(name);
- else
+ } else {
xfree(name);
+ }
return id;
}
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index a4af45d441..20adf40012 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -1685,7 +1685,7 @@ void u_redo(int count)
u_doit(count, false);
}
-/// undo and forget.
+/// undo, and remove the undo branch from the undo tree.
bool u_undo_and_forget(int count)
{
if (curbuf->b_u_synced == false) {
@@ -1726,9 +1726,7 @@ bool u_undo_and_forget(int count)
return true;
}
-/*
- * Undo or redo, depending on 'undo_undoes', 'count' times.
- */
+/// Undo or redo, depending on `undo_undoes`, `count` times.
static void u_doit(int startcount, bool quiet)
{
int count = startcount;
@@ -2342,17 +2340,13 @@ static void u_undoredo(int undo)
#endif
}
-/*
- * If we deleted or added lines, report the number of less/more lines.
- * Otherwise, report the number of changes (this may be incorrect
- * in some cases, but it's better than nothing).
- */
-static void
-u_undo_end(
- int did_undo, // just did an undo
- int absolute, // used ":undo N"
- bool quiet
-)
+/// If we deleted or added lines, report the number of less/more lines.
+/// Otherwise, report the number of changes (this may be incorrect
+/// in some cases, but it's better than nothing).
+static void u_undo_end(
+ int did_undo, //< just did an undo
+ int absolute, //< used ":undo N"
+ bool quiet)
{
char *msgstr;
u_header_T *uhp;
@@ -2361,9 +2355,9 @@ u_undo_end(
if ((fdo_flags & FDO_UNDO) && KeyTyped)
foldOpenCursor();
- if (global_busy // no messages now, wait until global is finished
- || !messaging() // 'lazyredraw' set, don't do messages now
- || quiet) { // livemode doesn't show messages
+ if (quiet
+ || global_busy // no messages until global is finished
+ || !messaging()) { // 'lazyredraw' set, don't do messages now
return;
}
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 45b52e9454..8512556c0a 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -2903,7 +2903,7 @@ static int win_alloc_firstwin(win_T *oldwin)
if (oldwin == NULL) {
/* Very first window, need to create an empty buffer for it and
* initialize from scratch. */
- curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED, 0);
+ curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
if (curbuf == NULL) {
return FAIL;
}