aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.clang-format8
-rw-r--r--src/nvim/CMakeLists.txt9
-rw-r--r--src/nvim/api/buffer.c150
-rw-r--r--src/nvim/auevents.lua1
-rw-r--r--src/nvim/buffer.c250
-rw-r--r--src/nvim/buffer_defs.h4
-rw-r--r--src/nvim/charset.c100
-rw-r--r--src/nvim/diff.c4
-rw-r--r--src/nvim/edit.c803
-rw-r--r--src/nvim/eval.c197
-rw-r--r--src/nvim/eval.h3
-rw-r--r--src/nvim/ex_cmds.c21
-rw-r--r--src/nvim/ex_cmds2.c164
-rw-r--r--src/nvim/ex_docmd.c6
-rw-r--r--src/nvim/ex_eval.c2
-rw-r--r--src/nvim/ex_getln.c27
-rw-r--r--src/nvim/fold.c4
-rw-r--r--src/nvim/globals.h8
-rw-r--r--src/nvim/main.c8
-rw-r--r--src/nvim/memfile.c144
-rw-r--r--src/nvim/memline.c6
-rw-r--r--src/nvim/normal.c12
-rw-r--r--src/nvim/ops.c144
-rw-r--r--src/nvim/option.c14
-rw-r--r--src/nvim/option_defs.h56
-rw-r--r--src/nvim/os/fs.c2
-rw-r--r--src/nvim/os/stdpaths.c15
-rw-r--r--src/nvim/path.c237
-rw-r--r--src/nvim/pos.h6
-rw-r--r--src/nvim/quickfix.c306
-rw-r--r--src/nvim/screen.c39
-rw-r--r--src/nvim/syntax.c28
-rw-r--r--src/nvim/tempfile.c3
-rw-r--r--src/nvim/terminal.c4
-rw-r--r--src/nvim/testdir/Makefile1
-rw-r--r--src/nvim/testdir/test88.in99
-rw-r--r--src/nvim/testdir/test88.ok29
-rw-r--r--src/nvim/undo.c8
-rw-r--r--src/nvim/version.c46
-rw-r--r--src/nvim/window.c41
40 files changed, 1620 insertions, 1389 deletions
diff --git a/src/.clang-format b/src/.clang-format
index 35e545ac4b..5a910ff34b 100644
--- a/src/.clang-format
+++ b/src/.clang-format
@@ -1,4 +1,4 @@
-BasedOnStyle: llvm
+BasedOnStyle: Google
Language: Cpp
ColumnLimit: 80
IndentWidth: 2
@@ -10,3 +10,9 @@ AlignEscapedNewlinesLeft: false
AllowShortFunctionsOnASingleLine: false
SpacesBeforeTrailingComments: 2
PenaltyReturnTypeOnItsOwnLine: 200
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+BinPackParameters: false
+BreakBeforeBinaryOperators: true
+ContinuationIndentWidth: 4
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index ea5125e4e7..487b554d6d 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -60,6 +60,11 @@ file(GLOB NEOVIM_SOURCES *.c os/*.c api/*.c api/private/*.c msgpack_rpc/*.c
file(GLOB_RECURSE NEOVIM_HEADERS *.h)
file(GLOB UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c)
+# Sort file lists to ensure generated files are created in the same order from
+# build to build.
+list(SORT NEOVIM_SOURCES)
+list(SORT NEOVIM_HEADERS)
+
foreach(sfile ${NEOVIM_SOURCES})
get_filename_component(f ${sfile} NAME)
if(${f} MATCHES "^(regexp_nfa.c)$")
@@ -72,11 +77,9 @@ list(REMOVE_ITEM NEOVIM_SOURCES ${to_remove})
# Handle legacy files that don't yet pass -Wconversion.
set(CONV_SOURCES
buffer.c
- charset.c
diff.c
edit.c
eval.c
- ex_cmds2.c
ex_cmds.c
ex_docmd.c
ex_getln.c
@@ -87,8 +90,6 @@ set(CONV_SOURCES
message.c
misc1.c
ops.c
- path.c
- quickfix.c
regexp.c
screen.c
search.c
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index fa4b8e5f7d..c25a9789c5 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -45,14 +45,22 @@ Integer buffer_line_count(Buffer buffer, Error *err)
/// Gets a buffer line
///
+/// @deprecated use buffer_get_lines instead.
+/// for positive indices (including 0) use
+/// "buffer_get_lines(buffer, index, index+1, true)"
+/// for negative indices use
+/// "buffer_get_lines(buffer, index-1, index, true)"
+///
/// @param buffer The buffer handle
/// @param index The line index
/// @param[out] err Details of an error that may have occurred
/// @return The line string
String buffer_get_line(Buffer buffer, Integer index, Error *err)
{
- String rv = {.size = 0};
- Array slice = buffer_get_line_slice(buffer, index, index, true, true, err);
+ String rv = { .size = 0 };
+
+ index = convert_index(index);
+ Array slice = buffer_get_lines(buffer, index, index+1, true, err);
if (!err->set && slice.size) {
rv = slice.items[0].data.string;
@@ -65,6 +73,12 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err)
/// Sets a buffer line
///
+/// @deprecated use buffer_set_lines instead.
+/// for positive indices use
+/// "buffer_set_lines(buffer, index, index+1, true, [line])"
+/// for negative indices use
+/// "buffer_set_lines(buffer, index-1, index, true, [line])"
+///
/// @param buffer The buffer handle
/// @param index The line index
/// @param line The new line.
@@ -72,23 +86,34 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err)
void buffer_set_line(Buffer buffer, Integer index, String line, Error *err)
{
Object l = STRING_OBJ(line);
- Array array = {.items = &l, .size = 1};
- buffer_set_line_slice(buffer, index, index, true, true, array, err);
+ Array array = { .items = &l, .size = 1 };
+ index = convert_index(index);
+ buffer_set_lines(buffer, index, index+1, true, array, err);
}
/// Deletes a buffer line
///
+/// @deprecated use buffer_set_lines instead.
+/// for positive indices use
+/// "buffer_set_lines(buffer, index, index+1, true, [])"
+/// for negative indices use
+/// "buffer_set_lines(buffer, index-1, index, true, [])"
/// @param buffer The buffer handle
/// @param index The line index
/// @param[out] err Details of an error that may have occurred
void buffer_del_line(Buffer buffer, Integer index, Error *err)
{
Array array = ARRAY_DICT_INIT;
- buffer_set_line_slice(buffer, index, index, true, true, array, err);
+ index = convert_index(index);
+ buffer_set_lines(buffer, index, index+1, true, array, err);
}
/// Retrieves a line range from the buffer
///
+/// @deprecated use buffer_get_lines(buffer, newstart, newend, false)
+/// where newstart = start + int(not include_start) - int(start < 0)
+/// newend = end + int(include_end) - int(end < 0)
+/// int(bool) = 1 if bool is true else 0
/// @param buffer The buffer handle
/// @param start The first line index
/// @param end The last line index
@@ -103,16 +128,48 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
Boolean include_end,
Error *err)
{
+ start = convert_index(start) + !include_start;
+ end = convert_index(end) + include_end;
+ return buffer_get_lines(buffer, start , end, false, err);
+}
+
+
+/// Retrieves a line range from the buffer
+///
+/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
+/// as length+1+index, i e -1 refers to the index past the end. So to get the
+/// last element set start=-2 and end=-1.
+///
+/// Out-of-bounds indices are clamped to the nearest valid value, unless
+/// `strict_indexing` is set.
+///
+/// @param buffer The buffer handle
+/// @param start The first line index
+/// @param end The last line index (exclusive)
+/// @param strict_indexing whether out-of-bounds should be an error.
+/// @param[out] err Details of an error that may have occurred
+/// @return An array of lines
+ArrayOf(String) buffer_get_lines(Buffer buffer,
+ Integer start,
+ Integer end,
+ Boolean strict_indexing,
+ Error *err)
+{
Array rv = ARRAY_DICT_INIT;
buf_T *buf = find_buffer_by_handle(buffer, err);
- if (!buf || !inbounds(buf, start)) {
+ if (!buf) {
return rv;
}
- start = normalize_index(buf, start) + (include_start ? 0 : 1);
- include_end = include_end || (end >= buf->b_ml.ml_line_count);
- end = normalize_index(buf, end) + (include_end ? 1 : 0);
+ bool oob = false;
+ start = normalize_index(buf, start, &oob);
+ end = normalize_index(buf, end, &oob);
+
+ if (strict_indexing && oob) {
+ api_set_error(err, Validation, _("Index out of bounds"));
+ return rv;
+ }
if (start >= end) {
// Return 0-length array
@@ -152,8 +209,14 @@ end:
return rv;
}
+
/// Replaces a line range on the buffer
///
+/// @deprecated use buffer_set_lines(buffer, newstart, newend, false, lines)
+/// where newstart = start + int(not include_start) + int(start < 0)
+/// newend = end + int(include_end) + int(end < 0)
+/// int(bool) = 1 if bool is true else 0
+///
/// @param buffer The buffer handle
/// @param start The first line index
/// @param end The last line index
@@ -170,20 +233,52 @@ void buffer_set_line_slice(Buffer buffer,
ArrayOf(String) replacement,
Error *err)
{
+ start = convert_index(start) + !include_start;
+ end = convert_index(end) + include_end;
+ buffer_set_lines(buffer, start, end, false, replacement, err);
+}
+
+
+/// Replaces line range on the buffer
+///
+/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
+/// as length+1+index, i e -1 refers to the index past the end. So to change
+/// or delete the last element set start=-2 and end=-1.
+///
+/// To insert lines at a given index, set both start and end to the same index.
+/// To delete a range of lines, set replacement to an empty array.
+///
+/// Out-of-bounds indices are clamped to the nearest valid value, unless
+/// `strict_indexing` is set.
+///
+/// @param buffer The buffer handle
+/// @param start The first line index
+/// @param end The last line index (exclusive)
+/// @param strict_indexing whether out-of-bounds should be an error.
+/// @param replacement An array of lines to use as replacement
+/// @param[out] err Details of an error that may have occurred
+void buffer_set_lines(Buffer buffer,
+ Integer start,
+ Integer end,
+ Boolean strict_indexing,
+ ArrayOf(String) replacement,
+ Error *err)
+{
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
return;
}
- if (!inbounds(buf, start)) {
+ bool oob = false;
+ start = normalize_index(buf, start, &oob);
+ end = normalize_index(buf, end, &oob);
+
+ if (strict_indexing && oob) {
api_set_error(err, Validation, _("Index out of bounds"));
return;
}
- start = normalize_index(buf, start) + (include_start ? 0 : 1);
- include_end = include_end || (end >= buf->b_ml.ml_line_count);
- end = normalize_index(buf, end) + (include_end ? 1 : 0);
if (start > end) {
api_set_error(err,
@@ -457,6 +552,8 @@ Boolean buffer_is_valid(Buffer buffer)
/// Inserts a sequence of lines to a buffer at a certain index
///
+/// @deprecated use buffer_set_lines(buffer, lnum, lnum, true, lines)
+///
/// @param buffer The buffer handle
/// @param lnum Insert the lines after `lnum`. If negative, it will append
/// to the end of the buffer.
@@ -467,8 +564,9 @@ void buffer_insert(Buffer buffer,
ArrayOf(String) lines,
Error *err)
{
- bool end_start = lnum < 0;
- buffer_set_line_slice(buffer, lnum, lnum, !end_start, end_start, lines, err);
+ // "lnum" will be the index of the line after inserting,
+ // no matter if it is negative or not
+ buffer_set_lines(buffer, lnum, lnum, true, lines, err);
}
/// Return a tuple (row,col) representing the position of the named mark
@@ -632,20 +730,26 @@ static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
}
// Normalizes 0-based indexes to buffer line numbers
-static int64_t normalize_index(buf_T *buf, int64_t index)
+static int64_t normalize_index(buf_T *buf, int64_t index, bool *oob)
{
+ int64_t line_count = buf->b_ml.ml_line_count;
// Fix if < 0
- index = index < 0 ? buf->b_ml.ml_line_count + index : index;
+ index = index < 0 ? line_count + index +1 : index;
+
+ // Check for oob
+ if (index > line_count) {
+ *oob = true;
+ index = line_count;
+ } else if (index < 0) {
+ *oob = true;
+ index = 0;
+ }
// Convert the index to a vim line number
index++;
- // Fix if > line_count
- index = index > buf->b_ml.ml_line_count ? buf->b_ml.ml_line_count : index;
return index;
}
-// Returns true if the 0-indexed `index` is within the 1-indexed buffer bounds.
-static bool inbounds(buf_T *buf, int64_t index)
+static int64_t convert_index(int64_t index)
{
- linenr_T nlines = buf->b_ml.ml_line_count;
- return index >= -nlines && index < nlines;
+ return index < 0 ? index - 1 : index;
}
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index aa4a8d8332..8d891effae 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -83,6 +83,7 @@ return {
'TermResponse', -- after setting "v:termresponse"
'TextChanged', -- text was modified
'TextChangedI', -- text was modified in Insert mode
+ 'TextYankPost', -- after a yank or delete was done (y, d, c)
'User', -- user defined autocommand
'VimEnter', -- after starting Vim
'VimLeave', -- before exiting Vim
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 62ab7495da..c514c4378e 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -141,14 +141,21 @@ open_buffer (
/* mark cursor position as being invalid */
curwin->w_valid = 0;
- if (curbuf->b_ffname != NULL
- ) {
+ if (curbuf->b_ffname != NULL) {
+ int old_msg_silent = msg_silent;
+ 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);
- /* Help buffer is filtered. */
- if (curbuf->b_help)
+ (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+ flags | READ_NEW);
+ msg_silent = old_msg_silent;
+
+ // Help buffer is filtered.
+ if (curbuf->b_help) {
fix_help_buffer();
+ }
} else if (read_stdin) {
int save_bin = curbuf->b_p_bin;
linenr_T line_count;
@@ -257,17 +264,16 @@ open_buffer (
return retval;
}
-/*
- * Return TRUE if "buf" points to a valid buffer (in the buffer list).
- */
-int buf_valid(buf_T *buf)
+/// Check that "buf" points to a valid buffer (in the buffer list).
+bool buf_valid(buf_T *buf)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
FOR_ALL_BUFFERS(bp) {
if (bp == buf) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
/*
@@ -2055,16 +2061,15 @@ void buflist_setfpos(buf_T *const buf, win_T *const win,
}
-/*
- * Return true when "wip" has 'diff' set and the diff is only for another tab
- * page. That's because a diff is local to a tab page.
- */
+/// 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)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
if (wip->wi_opt.wo_diff) {
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- /* return false when it's a window in the current tab page, thus
- * the buffer was in diff mode here */
+ // return false when it's a window in the current tab page, thus
+ // the buffer was in diff mode here
if (wip->wi_win == wp) {
return false;
}
@@ -2421,52 +2426,62 @@ void buflist_altfpos(win_T *win)
buflist_setfpos(curbuf, win, win->w_cursor.lnum, win->w_cursor.col, TRUE);
}
-/*
- * Return TRUE if 'ffname' is not the same file as current file.
- * Fname must have a full path (expanded by path_get_absolute_path()).
- */
-int otherfile(char_u *ffname)
+/// Check that "ffname" is not the same file as current file.
+/// Fname must have a full path (expanded by path_get_absolute_path()).
+///
+/// @param ffname full path name to check
+bool otherfile(char_u *ffname)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
return otherfile_buf(curbuf, ffname, NULL, false);
}
-static int otherfile_buf(buf_T *buf, char_u *ffname,
- FileID *file_id_p, bool file_id_valid)
+/// Check that "ffname" is not the same file as the file loaded in "buf".
+/// Fname must have a full path (expanded by path_get_absolute_path()).
+///
+/// @param buf buffer to check
+/// @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)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- /* no name is different */
+ // no name is different
if (ffname == NULL || *ffname == NUL || buf->b_ffname == NULL) {
- return TRUE;
+ return true;
}
if (fnamecmp(ffname, buf->b_ffname) == 0) {
- return FALSE;
+ return false;
}
{
FileID file_id;
- /* If no struct stat given, get it now */
+ // 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);
}
if (!file_id_valid) {
// file_id not valid, assume files are different.
- return TRUE;
+ return true;
}
- /* Use dev/ino to check if the files are the same, even when the names
- * are different (possible with links). Still need to compare the
- * name above, for when the file doesn't exist yet.
- * Problem: The dev/ino changes when a file is deleted (and created
- * again) and remains the same when renamed/moved. We don't want to
- * stat() each buffer each time, that would be too slow. Get the
- * dev/ino again when they appear to match, but not when they appear
- * to be different: Could skip a buffer when it's actually the same
- * file. */
+ // Use dev/ino to check if the files are the same, even when the names
+ // are different (possible with links). Still need to compare the
+ // name above, for when the file doesn't exist yet.
+ // Problem: The dev/ino changes when a file is deleted (and created
+ // again) and remains the same when renamed/moved. We don't want to
+ // stat() each buffer each time, that would be too slow. Get the
+ // dev/ino again when they appear to match, but not when they appear
+ // to be different: Could skip a buffer when it's actually the same
+ // file.
if (buf_same_file_id(buf, file_id_p)) {
buf_set_file_id(buf);
- if (buf_same_file_id(buf, file_id_p))
- return FALSE;
+ if (buf_same_file_id(buf, file_id_p)) {
+ return false;
+ }
}
}
- return TRUE;
+ return true;
}
// Set file_id for a buffer.
@@ -2483,11 +2498,14 @@ void buf_set_file_id(buf_T *buf)
}
}
-// return TRUE if file_id in buffer "buf" matches with "file_id".
+/// Check that file_id in buffer "buf" matches with "file_id".
+///
+/// @param buf buffer
+/// @param file_id file id
static bool buf_same_file_id(buf_T *buf, FileID *file_id)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- return buf->file_id_valid
- && os_fileid_equal(&(buf->file_id), file_id);
+ return buf->file_id_valid && os_fileid_equal(&(buf->file_id), file_id);
}
/*
@@ -2770,23 +2788,28 @@ void maketitle(void)
resettitle();
}
-/*
- * Used for title and icon: Check if "str" differs from "*last". Set "*last"
- * from "str" if it does.
- * Return TRUE when "*last" changed.
- */
-static int ti_change(char_u *str, char_u **last)
+/// Used for title and icon: Check if "str" differs from "*last". Set "*last"
+/// from "str" if it does by freeing the old value of "*last" and duplicating
+/// "str".
+///
+/// @param str desired title string
+/// @param[in,out] last current title string
+//
+/// @return true when "*last" changed.
+static bool ti_change(char_u *str, char_u **last)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
if ((str == NULL) != (*last == NULL)
|| (str != NULL && *last != NULL && STRCMP(str, *last) != 0)) {
xfree(*last);
- if (str == NULL)
+ if (str == NULL) {
*last = NULL;
- else
+ } else {
*last = vim_strsave(str);
- return TRUE;
+ }
+ return true;
}
- return FALSE;
+ return false;
}
/*
@@ -3014,7 +3037,7 @@ int build_stl_str_hl(
&& item[groupitem[groupdepth]].minwid == 0) {
bool has_normal_items = false;
for (long n = groupitem[groupdepth] + 1; n < curitem; n++) {
- if (item[n].type == Normal) {
+ if (item[n].type == Normal || item[n].type == Highlight) {
has_normal_items = true;
break;
}
@@ -3922,26 +3945,29 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen)
: (int)(above * 100L / (above + below)));
}
-/*
- * Append (file 2 of 8) to "buf[buflen]", if editing more than one file.
- * Return TRUE if it was appended.
- */
-static int
-append_arg_number (
- win_T *wp,
- char_u *buf,
- int buflen,
- int add_file /* Add "file" before the arg number */
-)
+/// Append (file 2 of 8) to "buf[buflen]", if editing more than one file.
+///
+/// @param wp window whose buffers to check
+/// @param[in,out] buf string buffer to add the text to
+/// @param buflen length of the string buffer
+/// @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)
+ FUNC_ATTR_NONNULL_ALL
{
- char_u *p;
+ // Nothing to do
+ if (ARGCOUNT <= 1) {
+ return false;
+ }
+
+ char_u *p = buf + STRLEN(buf); // go to the end of the buffer
- if (ARGCOUNT <= 1) /* nothing to do */
- return FALSE;
+ // Early out if the string is getting too long
+ if (p - buf + 35 >= buflen) {
+ return false;
+ }
- p = buf + STRLEN(buf); /* go to the end of the buffer */
- if (p - buf + 35 >= buflen) /* getting too long */
- return FALSE;
*p++ = ' ';
*p++ = '(';
if (add_file) {
@@ -3949,9 +3975,10 @@ append_arg_number (
p += 5;
}
vim_snprintf((char *)p, (size_t)(buflen - (p - buf)),
- wp->w_arg_idx_invalid ? "(%d) of %d)"
- : "%d of %d)", wp->w_arg_idx + 1, ARGCOUNT);
- return TRUE;
+ wp->w_arg_idx_invalid
+ ? "(%d) of %d)"
+ : "%d of %d)", wp->w_arg_idx + 1, ARGCOUNT);
+ return true;
}
/*
@@ -4585,11 +4612,16 @@ char_u *buf_spname(buf_T *buf)
return NULL;
}
-/*
- * Find a window for buffer "buf".
- * If found true is returned and "wp" and "tp" are set to the window and tabpage.
- * If not found false is returned.
- */
+/// Find a window for buffer "buf".
+/// If found true is returned and "wp" and "tp" are set to
+/// the window and tabpage.
+/// If not found, false is returned.
+///
+/// @param buf buffer to find a window for
+/// @param[out] wp stores the found window
+/// @param[out] tp stores the found tabpage
+///
+/// @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;
@@ -5103,50 +5135,54 @@ void set_buflisted(int on)
}
}
-/*
- * Read the file for "buf" again and check if the contents changed.
- * Return TRUE if it changed or this could not be checked.
- */
-int buf_contents_changed(buf_T *buf)
+/// Read the file for "buf" again and check if the contents changed.
+/// Return true if it changed or this could not be checked.
+///
+/// @param buf buffer to check
+///
+/// @return true if the buffer's contents have changed
+bool buf_contents_changed(buf_T *buf)
+ FUNC_ATTR_NONNULL_ALL
{
- buf_T *newbuf;
- int differ = TRUE;
- linenr_T lnum;
- aco_save_T aco;
- exarg_T ea;
+ bool differ = true;
- /* Allocate a buffer without putting it in the buffer list. */
- newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
- if (newbuf == NULL)
- return TRUE;
+ // Allocate a buffer without putting it in the buffer list.
+ buf_T *newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+ if (newbuf == NULL) {
+ return true;
+ }
- /* Force the 'fileencoding' and 'fileformat' to be equal. */
+ // Force the 'fileencoding' and 'fileformat' to be equal.
+ exarg_T ea;
prep_exarg(&ea, buf);
- /* set curwin/curbuf to buf and save a few things */
+ // set curwin/curbuf to buf and save a few things
+ aco_save_T aco;
aucmd_prepbuf(&aco, newbuf);
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) {
- /* compare the two files line by line */
+ (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
+ &ea, READ_NEW | READ_DUMMY) == OK) {
+ // compare the two files line by line
if (buf->b_ml.ml_line_count == curbuf->b_ml.ml_line_count) {
- differ = FALSE;
- for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
- if (STRCMP(ml_get_buf(buf, lnum, FALSE), ml_get(lnum)) != 0) {
- differ = TRUE;
+ differ = false;
+ for (linenr_T lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
+ if (STRCMP(ml_get_buf(buf, lnum, false), ml_get(lnum)) != 0) {
+ differ = true;
break;
}
+ }
}
}
xfree(ea.cmd);
- /* restore curwin/curbuf and a few other things */
+ // restore curwin/curbuf and a few other things
aucmd_restbuf(&aco);
- if (curbuf != newbuf) /* safety check */
- wipe_buffer(newbuf, FALSE);
+ if (curbuf != newbuf) { // safety check
+ wipe_buffer(newbuf, false);
+ }
return differ;
}
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 936a14b903..86e63eb52c 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -533,9 +533,9 @@ struct file_buffer {
/*
* Character table, only used in charset.c for 'iskeyword'
- * 32 bytes of 8 bits: 1 bit per character 0-255.
+ * bitset with 4*64=256 bits: 1 bit per character 0-255.
*/
- char_u b_chartab[32];
+ uint64_t b_chartab[4];
/* Table used for mappings local to a buffer. */
mapblock_T *(b_maphash[256]);
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 4e329b5cd8..83e2aaa6e6 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -32,16 +32,16 @@
#endif
-static int chartab_initialized = FALSE;
+static bool chartab_initialized = false;
-// b_chartab[] is an array of 32 bytes, each bit representing one of the
+// b_chartab[] is an array with 256 bits, each bit representing one of the
// characters 0-255.
#define SET_CHARTAB(buf, c) \
- (buf)->b_chartab[(unsigned)(c) >> 3] |= (1 << ((c) & 0x7))
+ (buf)->b_chartab[(unsigned)(c) >> 6] |= (1ull << ((c) & 0x3f))
#define RESET_CHARTAB(buf, c) \
- (buf)->b_chartab[(unsigned)(c) >> 3] &= ~(1 << ((c) & 0x7))
+ (buf)->b_chartab[(unsigned)(c) >> 6] &= ~(1ull << ((c) & 0x3f))
#define GET_CHARTAB(buf, c) \
- ((buf)->b_chartab[(unsigned)(c) >> 3] & (1 << ((c) & 0x7)))
+ ((buf)->b_chartab[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
/// Fill chartab[]. Also fills curbuf->b_chartab[] with flags for keyword
/// characters for current buffer.
@@ -69,12 +69,12 @@ static int chartab_initialized = FALSE;
/// an error, OK otherwise.
int init_chartab(void)
{
- return buf_init_chartab(curbuf, TRUE);
+ return buf_init_chartab(curbuf, true);
}
/// Helper for init_chartab
///
-/// @param global FALSE: only set buf->b_chartab[]
+/// @param global false: only set buf->b_chartab[]
///
/// @return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has
/// an error, OK otherwise.
@@ -84,13 +84,13 @@ int buf_init_chartab(buf_T *buf, int global)
int c2;
char_u *p;
int i;
- int tilde;
- int do_isalpha;
+ bool tilde;
+ bool do_isalpha;
if (global) {
// Set the default size for printable characters:
// From <Space> to '~' is 1 (printable), others are 2 (not printable).
- // This also inits all 'isident' and 'isfname' flags to FALSE.
+ // This also inits all 'isident' and 'isfname' flags to false.
c = 0;
while (c < ' ') {
@@ -133,7 +133,7 @@ int buf_init_chartab(buf_T *buf, int global)
}
}
- // Init word char flags all to FALSE
+ // Init word char flags all to false
memset(buf->b_chartab, 0, (size_t)32);
if (enc_dbcs != 0) {
@@ -169,11 +169,11 @@ int buf_init_chartab(buf_T *buf, int global)
}
while (*p) {
- tilde = FALSE;
- do_isalpha = FALSE;
+ tilde = false;
+ do_isalpha = false;
if ((*p == '^') && (p[1] != NUL)) {
- tilde = TRUE;
+ tilde = true;
++p;
}
@@ -212,7 +212,7 @@ int buf_init_chartab(buf_T *buf, int global)
// standard function isalpha(). This takes care of locale for
// single-byte characters).
if (c == '@') {
- do_isalpha = TRUE;
+ do_isalpha = true;
c = 1;
c2 = 255;
} else {
@@ -231,7 +231,7 @@ int buf_init_chartab(buf_T *buf, int global)
if (i == 0) {
// (re)set ID flag
if (tilde) {
- chartab[c] &= ~CT_ID_CHAR;
+ chartab[c] &= (uint8_t)~CT_ID_CHAR;
} else {
chartab[c] |= CT_ID_CHAR;
}
@@ -244,18 +244,18 @@ int buf_init_chartab(buf_T *buf, int global)
|| (p_altkeymap && (F_isalpha(c) || F_isdigit(c))))
&& !(enc_dbcs && (MB_BYTE2LEN(c) == 2))) {
if (tilde) {
- chartab[c] = (chartab[c] & ~CT_CELL_MASK)
- + ((dy_flags & DY_UHEX) ? 4 : 2);
- chartab[c] &= ~CT_PRINT_CHAR;
+ chartab[c] = (uint8_t)((chartab[c] & ~CT_CELL_MASK)
+ + ((dy_flags & DY_UHEX) ? 4 : 2));
+ chartab[c] &= (uint8_t)~CT_PRINT_CHAR;
} else {
- chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1;
+ chartab[c] = (uint8_t)((chartab[c] & ~CT_CELL_MASK) + 1);
chartab[c] |= CT_PRINT_CHAR;
}
}
} else if (i == 2) {
// (re)set fname flag
if (tilde) {
- chartab[c] &= ~CT_FNAME_CHAR;
+ chartab[c] &= (uint8_t)~CT_FNAME_CHAR;
} else {
chartab[c] |= CT_FNAME_CHAR;
}
@@ -280,7 +280,7 @@ int buf_init_chartab(buf_T *buf, int global)
}
}
}
- chartab_initialized = TRUE;
+ chartab_initialized = true;
return OK;
}
@@ -333,7 +333,8 @@ char_u *transstr(char_u *s) FUNC_ATTR_NONNULL_RET
{
char_u *res;
char_u *p;
- int l, c;
+ int c;
+ size_t l;
char_u hexbuf[11];
if (has_mbyte) {
@@ -343,7 +344,7 @@ char_u *transstr(char_u *s) FUNC_ATTR_NONNULL_RET
p = s;
while (*p != NUL) {
- if ((l = (*mb_ptr2len)(p)) > 1) {
+ if ((l = (size_t)(*mb_ptr2len)(p)) > 1) {
c = (*mb_ptr2char)(p);
p += l;
@@ -354,7 +355,7 @@ char_u *transstr(char_u *s) FUNC_ATTR_NONNULL_RET
len += STRLEN(hexbuf);
}
} else {
- l = byte2cells(*p++);
+ l = (size_t)byte2cells(*p++);
if (l > 0) {
len += l;
@@ -366,14 +367,14 @@ char_u *transstr(char_u *s) FUNC_ATTR_NONNULL_RET
}
res = xmallocz(len);
} else {
- res = xmallocz(vim_strsize(s));
+ res = xmallocz((size_t)vim_strsize(s));
}
*res = NUL;
p = s;
while (*p != NUL) {
- if (has_mbyte && ((l = (*mb_ptr2len)(p)) > 1)) {
+ if (has_mbyte && ((l = (size_t)(*mb_ptr2len)(p)) > 1)) {
c = (*mb_ptr2char)(p);
if (vim_isprintc(c)) {
@@ -477,9 +478,9 @@ char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
i += (*mb_ptr2len)(STR_PTR(i));
} else {
if (buf == NULL) {
- GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i));
+ GA_CHAR(i) = (char_u)TOLOWER_LOC(GA_CHAR(i));
} else {
- buf[i] = TOLOWER_LOC(buf[i]);
+ buf[i] = (char_u)TOLOWER_LOC(buf[i]);
}
++i;
}
@@ -493,7 +494,7 @@ char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
// Catch 22: chartab[] can't be initialized before the options are
// initialized, and initializing options may cause transchar() to be called!
-// When chartab_initialized == FALSE don't use chartab[].
+// When chartab_initialized == false don't use chartab[].
// Does NOT work for multi-byte characters, c must be <= 255.
// Also doesn't work for the first byte of a multi-byte, "c" must be a
// character!
@@ -518,7 +519,7 @@ char_u* transchar(int c)
if ((!chartab_initialized && (((c >= ' ') && (c <= '~')) || F_ischar(c)))
|| ((c < 256) && vim_isprintc_strict(c))) {
// printable character
- transchar_buf[i] = c;
+ transchar_buf[i] = (char_u)c;
transchar_buf[i + 1] = NUL;
} else {
transchar_nonprint(transchar_buf + i, c);
@@ -564,7 +565,7 @@ void transchar_nonprint(char_u *buf, int c)
// 0x00 - 0x1f and 0x7f
buf[0] = '^';
// DEL displayed as ^?
- buf[1] = c ^ 0x40;
+ buf[1] = (char_u)(c ^ 0x40);
buf[2] = NUL;
} else if (enc_utf8 && (c >= 0x80)) {
@@ -572,12 +573,12 @@ void transchar_nonprint(char_u *buf, int c)
} else if ((c >= ' ' + 0x80) && (c <= '~' + 0x80)) {
// 0xa0 - 0xfe
buf[0] = '|';
- buf[1] = c - 0x80;
+ buf[1] = (char_u)(c - 0x80);
buf[2] = NUL;
} else {
// 0x80 - 0x9f and 0xff
buf[0] = '~';
- buf[1] = (c - 0x80) ^ 0x40;
+ buf[1] = (char_u)((c - 0x80) ^ 0x40);
buf[2] = NUL;
}
}
@@ -592,11 +593,11 @@ void transchar_hex(char_u *buf, int c)
buf[0] = '<';
if (c > 255) {
- buf[++i] = nr2hex((unsigned)c >> 12);
- buf[++i] = nr2hex((unsigned)c >> 8);
+ buf[++i] = (char_u)nr2hex((unsigned)c >> 12);
+ buf[++i] = (char_u)nr2hex((unsigned)c >> 8);
}
- buf[++i] = nr2hex((unsigned)c >> 4);
- buf[++i] = nr2hex((unsigned)c);
+ buf[++i] = (char_u)(nr2hex((unsigned)c >> 4));
+ buf[++i] = (char_u)(nr2hex((unsigned)c));
buf[++i] = '>';
buf[++i] = NUL;
}
@@ -734,9 +735,8 @@ int vim_strnsize(char_u *s, int len)
/// @return Number of characters.
#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) { \
- int ts; \
- ts = (buf)->b_p_ts; \
- return (int)(ts - (col % ts)); \
+ const int ts = (int) (buf)->b_p_ts; \
+ return (ts - (int)(col % ts)); \
} else { \
return ptr2cells(p); \
}
@@ -1137,7 +1137,7 @@ static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
int n;
if ((*s == TAB) && (!wp->w_p_list || lcs_tab1)) {
- n = wp->w_buffer->b_p_ts;
+ n = (int)wp->w_buffer->b_p_ts;
return n - (col % n);
}
n = ptr2cells(s);
@@ -1205,11 +1205,11 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
char_u *line; // start of the line
int incr;
int head;
- int ts = wp->w_buffer->b_p_ts;
+ int ts = (int)wp->w_buffer->b_p_ts;
int c;
vcol = 0;
- line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
+ line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, false);
if (pos->col == MAXCOL) {
// continue until the NUL
@@ -1329,7 +1329,7 @@ colnr_T getvcol_nolist(pos_T *posp)
int list_save = curwin->w_p_list;
colnr_T vcol;
- curwin->w_p_list = FALSE;
+ curwin->w_p_list = false;
getvcol(curwin, posp, NULL, &vcol, NULL);
curwin->w_p_list = list_save;
return vcol;
@@ -1358,7 +1358,7 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
endadd = 0;
// Cannot put the cursor on part of a wide character.
- ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
+ ptr = ml_get_buf(wp->w_buffer, pos->lnum, false);
if (pos->col < (colnr_T)STRLEN(ptr)) {
int c = (*mb_ptr2char)(ptr + pos->col);
@@ -1595,7 +1595,7 @@ bool vim_islower(int c)
if (c >= 0x100) {
if (has_mbyte) {
- return iswlower(c);
+ return iswlower((wint_t)c);
}
// islower() can't handle these chars and may crash
@@ -1626,7 +1626,7 @@ bool vim_isupper(int c)
if (c >= 0x100) {
if (has_mbyte) {
- return iswupper(c);
+ return iswupper((wint_t)c);
}
// isupper() can't handle these chars and may crash
@@ -1653,7 +1653,7 @@ int vim_toupper(int c)
if (c >= 0x100) {
if (has_mbyte) {
- return towupper(c);
+ return (int)towupper((wint_t)c);
}
// toupper() can't handle these chars and may crash
@@ -1680,7 +1680,7 @@ int vim_tolower(int c)
if (c >= 0x100) {
if (has_mbyte) {
- return towlower(c);
+ return (int)towlower((wint_t)c);
}
// tolower() can't handle these chars and may crash
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 0be8b3c514..1149ca1e62 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -819,8 +819,8 @@ static void diff_file(char_u *tmp_orig, char_u *tmp_new, char_u *tmp_diff)
(diff_flags & DIFF_IWHITE) ? "-b " : "",
(diff_flags & DIFF_ICASE) ? "-i " : "",
tmp_orig, tmp_new);
- append_redir(cmd, (int)len, p_srr, tmp_diff);
- block_autocmds(); /* Avoid ShellCmdPost stuff */
+ append_redir(cmd, len, p_srr, tmp_diff);
+ block_autocmds(); // Avoid ShellCmdPost stuff
(void)call_shell(
cmd,
kShellOptFilter | kShellOptSilent | kShellOptDoOut,
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 6313ea2e81..614a5d43be 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -165,10 +165,6 @@ static int compl_restarting = FALSE; /* don't insert match */
* FALSE the word to be completed must be located. */
static int compl_started = FALSE;
-/* Set when doing something for completion that may call edit() recursively,
- * which is not allowed. */
-static int compl_busy = FALSE;
-
static int compl_matches = 0;
static char_u *compl_pattern = NULL;
static int compl_direction = FORWARD;
@@ -887,7 +883,7 @@ static int insert_handle_key(InsertState *s)
case Ctrl_T: // Make indent one shiftwidth greater.
if (s->c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS) {
- if (has_compl_option(false)) {
+ if (check_compl_option(false)) {
insert_do_complete(s);
}
break;
@@ -1102,7 +1098,7 @@ static int insert_handle_key(InsertState *s)
case Ctrl_K: // digraph or keyword completion
if (ctrl_x_mode == CTRL_X_DICTIONARY) {
- if (has_compl_option(true)) {
+ if (check_compl_option(true)) {
insert_do_complete(s);
}
break;
@@ -1264,30 +1260,28 @@ static void insert_do_cindent(InsertState *s)
}
}
-/*
- * edit(): Start inserting text.
- *
- * "cmdchar" can be:
- * 'i' normal insert command
- * 'a' normal append command
- * 'R' replace command
- * 'r' "r<CR>" command: insert one <CR>. Note: count can be > 1, for redo,
- * but still only one <CR> is inserted. The <Esc> is not used for redo.
- * 'g' "gI" command.
- * 'V' "gR" command for Virtual Replace mode.
- * 'v' "gr" command for single character Virtual Replace mode.
- *
- * This function is not called recursively. For CTRL-O commands, it returns
- * and lets the caller handle the Normal-mode command.
- *
- * Return TRUE if a CTRL-O command caused the return (insert mode pending).
- */
-int
-edit (
- int cmdchar,
- int startln, /* if set, insert at start of line */
- long count
-)
+/// edit(): Start inserting text.
+///
+/// "cmdchar" can be:
+/// 'i' normal insert command
+/// 'a' normal append command
+/// 'R' replace command
+/// 'r' "r<CR>" command: insert one <CR>.
+/// Note: count can be > 1, for redo, but still only one <CR> is inserted.
+/// <Esc> is not used for redo.
+/// 'g' "gI" command.
+/// 'V' "gR" command for Virtual Replace mode.
+/// 'v' "gr" command for single character Virtual Replace mode.
+///
+/// This function is not called recursively. For CTRL-O commands, it returns
+/// and lets the caller handle the Normal-mode command.
+///
+/// @param cmdchar command that started the insert
+/// @param startln if true, insert at start of line
+/// @param count repeat count for the command
+///
+/// @return true if a CTRL-O command caused the return (insert mode pending).
+bool edit(int cmdchar, bool startln, long count)
{
if (curbuf->terminal) {
if (ex_normal_busy) {
@@ -1795,33 +1789,37 @@ void backspace_until_column(int col)
}
}
-/*
- * Like del_char(), but make sure not to go before column "limit_col".
- * Only matters when there are composing characters.
- * Return TRUE when something was deleted.
- */
-static int del_char_after_col(int limit_col)
+/// Like del_char(), but make sure not to go before column "limit_col".
+/// Only matters when there are composing characters.
+///
+/// @param limit_col only delete the character if it is after this column
+//
+/// @return true when something was deleted.
+static bool del_char_after_col(int limit_col)
{
if (enc_utf8 && limit_col >= 0) {
colnr_T ecol = curwin->w_cursor.col + 1;
- /* Make sure the cursor is at the start of a character, but
- * skip forward again when going too far back because of a
- * composing character. */
+ // Make sure the cursor is at the start of a character, but
+ // skip forward again when going too far back because of a
+ // composing character.
mb_adjust_cursor();
while (curwin->w_cursor.col < (colnr_T)limit_col) {
int l = utf_ptr2len(get_cursor_pos_ptr());
- if (l == 0) /* end of line */
+ if (l == 0) { // end of line
break;
+ }
curwin->w_cursor.col += l;
}
- if (*get_cursor_pos_ptr() == NUL || curwin->w_cursor.col == ecol)
- return FALSE;
- del_bytes((long)((int)ecol - curwin->w_cursor.col), FALSE, TRUE);
- } else
- (void)del_char(FALSE);
- return TRUE;
+ if (*get_cursor_pos_ptr() == NUL || curwin->w_cursor.col == ecol) {
+ return false;
+ }
+ del_bytes((long)(ecol - curwin->w_cursor.col), false, true);
+ } else {
+ del_char(false);
+ }
+ return true;
}
/*
@@ -1846,47 +1844,48 @@ static void ins_ctrl_x(void)
}
}
-/*
- * Return TRUE if the 'dict' or 'tsr' option can be used.
- */
-static int has_compl_option(int dict_opt)
+/// Check that the "dict" or "tsr" option can be used.
+///
+/// @param dict_opt check "dict" when true, "tsr" when false.
+static bool check_compl_option(bool dict_opt)
{
- if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL
- && !curwin->w_p_spell
- )
+ if (dict_opt
+ ? (*curbuf->b_p_dict == NUL && *p_dict == NUL && !curwin->w_p_spell)
: (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) {
ctrl_x_mode = 0;
edit_submode = NULL;
msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty")
- : (char_u *)_("'thesaurus' option is empty"),
- hl_attr(HLF_E));
+ : (char_u *)_("'thesaurus' option is empty"), hl_attr(HLF_E));
if (emsg_silent == 0) {
vim_beep(BO_COMPL);
setcursor();
ui_flush();
os_delay(2000L, false);
}
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
-/*
- * Is the character 'c' a valid key to go to or keep us in CTRL-X mode?
- * This depends on the current mode.
- */
-int vim_is_ctrl_x_key(int c)
+/// Check that the character "c" a valid key to go to or keep us in CTRL-X mode?
+/// This depends on the current mode.
+///
+/// @param c character to check
+bool vim_is_ctrl_x_key(int c)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
- /* Always allow ^R - let it's results then be checked */
- if (c == Ctrl_R)
- return TRUE;
+ // Always allow ^R - let its results then be checked
+ if (c == Ctrl_R) {
+ return true;
+ }
- /* Accept <PageUp> and <PageDown> if the popup menu is visible. */
- if (ins_compl_pum_key(c))
- return TRUE;
+ // Accept <PageUp> and <PageDown> if the popup menu is visible.
+ if (ins_compl_pum_key(c)) {
+ return true;
+ }
switch (ctrl_x_mode) {
- case 0: /* Not in any CTRL-X mode */
+ case 0: // Not in any CTRL-X mode
return c == Ctrl_N || c == Ctrl_P || c == Ctrl_X;
case CTRL_X_NOT_DEFINED_YET:
return c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E
@@ -1924,35 +1923,37 @@ int vim_is_ctrl_x_key(int c)
return (c == Ctrl_P || c == Ctrl_N);
}
EMSG(_(e_internal));
- return FALSE;
+ return false;
}
-/*
- * Return TRUE when character "c" is part of the item currently being
- * completed. Used to decide whether to abandon complete mode when the menu
- * is visible.
- */
-static int ins_compl_accept_char(int c)
+/// Check that character "c" is part of the item currently being
+/// completed. Used to decide whether to abandon complete mode when the menu
+/// is visible.
+///
+/// @param c character to check
+static bool ins_compl_accept_char(int c)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (ctrl_x_mode & CTRL_X_WANT_IDENT)
- /* When expanding an identifier only accept identifier chars. */
+ if (ctrl_x_mode & CTRL_X_WANT_IDENT) {
+ // When expanding an identifier only accept identifier chars.
return vim_isIDc(c);
+ }
switch (ctrl_x_mode) {
case CTRL_X_FILES:
- /* When expanding file name only accept file name chars. But not
- * path separators, so that "proto/<Tab>" expands files in
- * "proto", not "proto/" as a whole */
+ // When expanding file name only accept file name chars. But not
+ // path separators, so that "proto/<Tab>" expands files in
+ // "proto", not "proto/" as a whole
return vim_isfilec(c) && !vim_ispathsep(c);
case CTRL_X_CMDLINE:
case CTRL_X_OMNI:
- /* Command line and Omni completion can work with just about any
- * printable character, but do stop at white space. */
+ // Command line and Omni completion can work with just about any
+ // printable character, but do stop at white space.
return vim_isprintc(c) && !ascii_iswhite(c);
case CTRL_X_WHOLE_LINE:
- /* For while line completion a space can be part of the line. */
+ // For while line completion a space can be part of the line.
return vim_isprintc(c);
}
return vim_iswordc(c);
@@ -2197,15 +2198,19 @@ ins_compl_add (
return OK;
}
-/*
- * Return TRUE if "str[len]" matches with match->cp_str, considering
- * match->cp_icase.
- */
-static int ins_compl_equal(compl_T *match, char_u *str, int len)
+/// Check that "str[len]" matches with "match->cp_str", considering
+/// "match->cp_icase".
+///
+/// @param match completion match
+/// @param str character string to check
+/// @param len lenth of "str"
+static bool ins_compl_equal(compl_T *match, char_u *str, size_t len)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- if (match->cp_icase)
- return STRNICMP(match->cp_str, str, (size_t)len) == 0;
- return STRNCMP(match->cp_str, str, (size_t)len) == 0;
+ if (match->cp_icase) {
+ return STRNICMP(match->cp_str, str, len) == 0;
+ }
+ return STRNCMP(match->cp_str, str, len) == 0;
}
/*
@@ -2353,13 +2358,13 @@ void set_completion(colnr_T startcol, list_T *list)
int save_w_wrow = curwin->w_wrow;
compl_curr_match = compl_first_match;
- if (compl_no_insert) {
+ if (compl_no_insert || compl_no_select) {
ins_complete(K_DOWN, false);
- } else {
- ins_complete(Ctrl_N, false);
if (compl_no_select) {
- ins_complete(Ctrl_P, false);
+ ins_complete(K_UP, false);
}
+ } else {
+ ins_complete(Ctrl_N, false);
}
// Lazily show the popup menu, unless we got interrupted.
@@ -2403,44 +2408,33 @@ static void ins_compl_del_pum(void)
}
}
-/*
- * Return TRUE if the popup menu should be displayed.
- */
-static int pum_wanted(void)
+/// Check if the popup menu should be displayed.
+static bool pum_wanted(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- /* 'completeopt' must contain "menu" or "menuone" */
- if (vim_strchr(p_cot, 'm') == NULL)
- return FALSE;
-
- /* The display looks bad on a B&W display. */
- if (t_colors < 8
- )
- return FALSE;
- return TRUE;
+ // "completeopt" must contain "menu" or "menuone"
+ return vim_strchr(p_cot, 'm') != NULL;
}
-/*
- * Return TRUE if there are two or more matches to be shown in the popup menu.
- * One if 'completopt' contains "menuone".
- */
-static int pum_enough_matches(void)
+/// Check that there are two or more matches to be shown in the popup menu.
+/// One if "completopt" contains "menuone".
+static bool pum_enough_matches(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- compl_T *compl;
- int i;
-
- /* Don't display the popup menu if there are no matches or there is only
- * one (ignoring the original text). */
- compl = compl_first_match;
- i = 0;
+ // Don't display the popup menu if there are no matches or there is only
+ // one (ignoring the original text).
+ compl_T *comp = compl_first_match;
+ int i = 0;
do {
- if (compl == NULL
- || ((compl->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2))
+ if (comp == NULL || ((comp->cp_flags & ORIGINAL_TEXT) == 0 && ++i == 2)) {
break;
- compl = compl->cp_next;
- } while (compl != compl_first_match);
+ }
+ comp = comp->cp_next;
+ } while (comp != compl_first_match);
- if (strstr((char *)p_cot, "menuone") != NULL)
+ if (strstr((char *)p_cot, "menuone") != NULL) {
return i >= 1;
+ }
return i >= 2;
}
@@ -2871,10 +2865,9 @@ static void ins_compl_clear(void)
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
}
-/*
- * Return TRUE when Insert completion is active.
- */
-int ins_compl_active(void)
+/// Check that Insert completion is active.
+bool ins_compl_active(void)
+ FUNC_ATTR_PURE
{
return compl_started;
}
@@ -2918,14 +2911,13 @@ static int ins_compl_bs(void)
return NUL;
}
-/*
- * Return TRUE when we need to find matches again, ins_compl_restart() is to
- * be called.
- */
-static int ins_compl_need_restart(void)
+/// Check that we need to find matches again, ins_compl_restart() is to
+/// be called.
+static bool ins_compl_need_restart(void)
+ FUNC_ATTR_PURE
{
- /* Return TRUE if we didn't complete finding matches or when the
- * 'completefunc' returned "always" in the "refresh" dictionary item. */
+ // Return true if we didn't complete finding matches or when the
+ // "completefunc" returned "always" in the "refresh" dictionary item.
return compl_was_interrupted
|| ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI)
&& compl_opt_refresh_always);
@@ -3073,16 +3065,16 @@ static void ins_compl_addfrommatch(void)
ins_compl_addleader(c);
}
-/*
- * Prepare for Insert mode completion, or stop it.
- * Called just after typing a character in Insert mode.
- * Returns TRUE when the character is not to be inserted;
- */
-static int ins_compl_prep(int c)
+/// Prepare for Insert mode completion, or stop it.
+/// Called just after typing a character in Insert mode.
+///
+/// @param c character that was typed
+///
+/// @return true when the character is not to be inserted;
+static bool ins_compl_prep(int c)
{
- char_u *ptr;
- int want_cindent;
- int retval = FALSE;
+ char_u *ptr;
+ bool retval = false;
/* Forget any previous 'special' messages if this is actually
* a ^X mode key - bar ^R, in which case we wait to see what it gives us.
@@ -3092,8 +3084,10 @@ static int ins_compl_prep(int c)
/* Ignore end of Select mode mapping and mouse scroll buttons. */
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
- || c == K_MOUSELEFT || c == K_MOUSERIGHT)
+ || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT
+ || c == K_FOCUSGAINED || c == K_FOCUSLOST) {
return retval;
+ }
/* Set "compl_get_longest" when finding the first matches. */
if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
@@ -3247,11 +3241,9 @@ static int ins_compl_prep(int c)
ins_compl_fixRedoBufForLeader(ptr);
}
- want_cindent = (can_cindent && cindent_on());
- /*
- * When completing whole lines: fix indent for 'cindent'.
- * Otherwise, break line if it's too long.
- */
+ bool want_cindent = (can_cindent && cindent_on());
+ // When completing whole lines: fix indent for 'cindent'.
+ // Otherwise, break line if it's too long.
if (compl_cont_mode == CTRL_X_WHOLE_LINE) {
/* re-indent the current line */
if (want_cindent) {
@@ -3271,22 +3263,24 @@ static int ins_compl_prep(int c)
inc_cursor();
}
- /* If the popup menu is displayed pressing CTRL-Y means accepting
- * the selection without inserting anything. When
- * compl_enter_selects is set the Enter key does the same. */
+ // If the popup menu is displayed pressing CTRL-Y means accepting
+ // the selection without inserting anything. When
+ // compl_enter_selects is set the Enter key does the same.
if ((c == Ctrl_Y || (compl_enter_selects
&& (c == CAR || c == K_KENTER || c == NL)))
- && pum_visible())
- retval = TRUE;
+ && pum_visible()) {
+ retval = true;
+ }
/* CTRL-E means completion is Ended, go back to the typed text. */
if (c == Ctrl_E) {
ins_compl_delete();
- if (compl_leader != NULL)
+ if (compl_leader != NULL) {
ins_bytes(compl_leader + ins_compl_len());
- else if (compl_first_match != NULL)
+ } else if (compl_first_match != NULL) {
ins_bytes(compl_orig_text + ins_compl_len());
- retval = TRUE;
+ }
+ retval = true;
}
auto_format(FALSE, TRUE);
@@ -4245,22 +4239,22 @@ void ins_compl_check_keys(int frequency)
static int ins_compl_key2dir(int c)
{
if (c == Ctrl_P || c == Ctrl_L
- || (pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP
- || c == K_S_UP || c == K_UP)))
+ || c == K_PAGEUP || c == K_KPAGEUP
+ || c == K_S_UP || c == K_UP) {
return BACKWARD;
+ }
return FORWARD;
}
-/*
- * Return TRUE for keys that are used for completion only when the popup menu
- * is visible.
- */
-static int ins_compl_pum_key(int c)
+/// Check that "c" is a valid completion key only while the popup menu is shown
+///
+/// @param c character to check
+static bool ins_compl_pum_key(int c)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
- || c == K_PAGEDOWN || c == K_KPAGEDOWN || c ==
- K_S_DOWN
- || c == K_UP || c == K_DOWN);
+ || c == K_PAGEDOWN || c == K_KPAGEDOWN
+ || c == K_S_DOWN || c == K_UP || c == K_DOWN);
}
/*
@@ -4280,11 +4274,12 @@ static int ins_compl_key2count(int c)
return 1;
}
-/*
- * Return TRUE if completion with "c" should insert the match, FALSE if only
- * to change the currently selected completion.
- */
-static int ins_compl_use_match(int c)
+/// Check that completion with "c" should insert the match, false if only
+/// to change the currently selected completion.
+///
+/// @param c character to check
+static bool ins_compl_use_match(int c)
+ FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (c) {
case K_UP:
@@ -4295,9 +4290,9 @@ static int ins_compl_use_match(int c)
case K_PAGEUP:
case K_KPAGEUP:
case K_S_UP:
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/*
@@ -6313,18 +6308,22 @@ char_u *get_last_insert_save(void)
return s;
}
-/*
- * Check the word in front of the cursor for an abbreviation.
- * Called when the non-id character "c" has been entered.
- * When an abbreviation is recognized it is removed from the text and
- * the replacement string is inserted in typebuf.tb_buf[], followed by "c".
- */
-static int echeck_abbr(int c)
+/// Check the word in front of the cursor for an abbreviation.
+/// Called when the non-id character "c" has been entered.
+/// When an abbreviation is recognized it is removed from the text and
+/// the replacement string is inserted in typebuf.tb_buf[], followed by "c".
+///
+/// @param c character
+///
+/// @return true if the word is a known abbreviation.
+static bool echeck_abbr(int c)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- /* Don't check for abbreviation in paste mode, when disabled and just
- * after moving around with cursor keys. */
- if (p_paste || no_abbr || arrow_used)
- return FALSE;
+ // Don't check for abbreviation in paste mode, when disabled and just
+ // after moving around with cursor keys.
+ if (p_paste || no_abbr || arrow_used) {
+ return false;
+ }
return check_abbr(c, get_cursor_line_ptr(), curwin->w_cursor.col,
curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
@@ -6560,13 +6559,11 @@ static void replace_do_bs(int limit_col)
(void)del_char_after_col(limit_col);
}
-/*
- * Return TRUE if C-indenting is on.
- */
-static int cindent_on(void) {
- return !p_paste && (curbuf->b_p_cin
- || *curbuf->b_p_inde != NUL
- );
+/// Check that C-indenting is on.
+static bool cindent_on(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return !p_paste && (curbuf->b_p_cin || *curbuf->b_p_inde != NUL);
}
/*
@@ -6596,32 +6593,33 @@ void fix_indent(void) {
do_c_expr_indent();
}
-/*
- * return TRUE if 'cinkeys' contains the key "keytyped",
- * when == '*': Only if key is preceded with '*' (indent before insert)
- * when == '!': Only if key is preceded with '!' (don't insert)
- * when == ' ': Only if key is not preceded with '*'(indent afterwards)
- *
- * "keytyped" can have a few special values:
- * KEY_OPEN_FORW
- * KEY_OPEN_BACK
- * KEY_COMPLETE just finished completion.
- *
- * If line_is_empty is TRUE accept keys with '0' before them.
- */
-int in_cinkeys(int keytyped, int when, int line_is_empty)
+/// Check that "cinkeys" contains the key "keytyped",
+/// when == '*': Only if key is preceded with '*' (indent before insert)
+/// when == '!': Only if key is preceded with '!' (don't insert)
+/// when == ' ': Only if key is not preceded with '*' (indent afterwards)
+///
+/// "keytyped" can have a few special values:
+/// KEY_OPEN_FORW :
+/// KEY_OPEN_BACK :
+/// KEY_COMPLETE : Just finished completion.
+///
+/// @param keytyped key that was typed
+/// @param when condition on when to perform the check
+/// @param line_is_empty when true, accept keys with '0' before them.
+bool in_cinkeys(int keytyped, int when, bool line_is_empty)
{
- char_u *look;
+ char_u *look;
int try_match;
int try_match_word;
- char_u *p;
- char_u *line;
+ char_u *p;
+ char_u *line;
int icase;
int i;
- if (keytyped == NUL)
- /* Can happen with CTRL-Y and CTRL-E on a short line. */
- return FALSE;
+ if (keytyped == NUL) {
+ // Can happen with CTRL-Y and CTRL-E on a short line.
+ return false;
+ }
if (*curbuf->b_p_inde != NUL)
look = curbuf->b_p_indk; /* 'indentexpr' set: use 'indentkeys' */
@@ -6637,68 +6635,64 @@ int in_cinkeys(int keytyped, int when, int line_is_empty)
case '!': try_match = (*look == '!'); break;
default: try_match = (*look != '*'); break;
}
- if (*look == '*' || *look == '!')
- ++look;
+ if (*look == '*' || *look == '!') {
+ look++;
+ }
- /*
- * If there is a '0', only accept a match if the line is empty.
- * But may still match when typing last char of a word.
- */
+ // If there is a '0', only accept a match if the line is empty.
+ // But may still match when typing last char of a word.
if (*look == '0') {
try_match_word = try_match;
- if (!line_is_empty)
- try_match = FALSE;
- ++look;
- } else
- try_match_word = FALSE;
+ if (!line_is_empty) {
+ try_match = false;
+ }
+ look++;
+ } else {
+ try_match_word = false;
+ }
- /*
- * does it look like a control character?
- */
- if (*look == '^'
- && look[1] >= '?' && look[1] <= '_'
- ) {
- if (try_match && keytyped == Ctrl_chr(look[1]))
- return TRUE;
+ // Does it look like a control character?
+ if (*look == '^' && look[1] >= '?' && look[1] <= '_') {
+ if (try_match && keytyped == Ctrl_chr(look[1])) {
+ return true;
+ }
look += 2;
- }
- /*
- * 'o' means "o" command, open forward.
- * 'O' means "O" command, open backward.
- */
- else if (*look == 'o') {
- if (try_match && keytyped == KEY_OPEN_FORW)
- return TRUE;
- ++look;
+
+ // 'o' means "o" command, open forward.
+ // 'O' means "O" command, open backward.
+ } else if (*look == 'o') {
+ if (try_match && keytyped == KEY_OPEN_FORW) {
+ return true;
+ }
+ look++;
} else if (*look == 'O') {
- if (try_match && keytyped == KEY_OPEN_BACK)
- return TRUE;
- ++look;
- }
- /*
- * 'e' means to check for "else" at start of line and just before the
- * cursor.
- */
- else if (*look == 'e') {
+ if (try_match && keytyped == KEY_OPEN_BACK) {
+ return true;
+ }
+ look++;
+
+ // 'e' means to check for "else" at start of line and just before the
+ // cursor.
+ } else if (*look == 'e') {
if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4) {
p = get_cursor_line_ptr();
if (skipwhite(p) == p + curwin->w_cursor.col - 4 &&
- STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0)
- return TRUE;
+ STRNCMP(p + curwin->w_cursor.col - 4, "else", 4) == 0) {
+ return true;
+ }
}
- ++look;
- }
- /*
- * ':' only causes an indent if it is at the end of a label or case
- * statement, or when it was before typing the ':' (to fix
- * class::method for C++).
- */
- else if (*look == ':') {
+ look++;
+
+ // ':' only causes an indent if it is at the end of a label or case
+ // statement, or when it was before typing the ':' (to fix
+ // class::method for C++).
+ } else if (*look == ':') {
if (try_match && keytyped == ':') {
p = get_cursor_line_ptr();
- if (cin_iscase(p, FALSE) || cin_isscopedecl(p) || cin_islabel())
- return TRUE;
- /* Need to get the line again after cin_islabel(). */
+ if (cin_iscase(p, false) || cin_isscopedecl(p) || cin_islabel()) {
+ return true;
+ }
+ // Need to get the line again after cin_islabel().
p = get_cursor_line_ptr();
if (curwin->w_cursor.col > 2
&& p[curwin->w_cursor.col - 1] == ':'
@@ -6708,28 +6702,27 @@ int in_cinkeys(int keytyped, int when, int line_is_empty)
|| cin_islabel());
p = get_cursor_line_ptr();
p[curwin->w_cursor.col - 1] = ':';
- if (i)
- return TRUE;
+ if (i) {
+ return true;
+ }
}
}
- ++look;
- }
- /*
- * Is it a key in <>, maybe?
- */
- else if (*look == '<') {
+ look++;
+
+ // Is it a key in <>, maybe?
+ } else if (*look == '<') {
if (try_match) {
- /*
- * make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
- * <:> and <!> so that people can re-indent on o, O, e, 0, <,
- * >, *, : and ! keys if they really really want to.
- */
+ // make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>,
+ // <:> and <!> so that people can re-indent on o, O, e, 0, <,
+ // >, *, : and ! keys if they really really want to.
if (vim_strchr((char_u *)"<>!*oOe0:", look[1]) != NULL
- && keytyped == look[1])
- return TRUE;
+ && keytyped == look[1]) {
+ return true;
+ }
- if (keytyped == get_special_key_code(look + 1))
- return TRUE;
+ if (keytyped == get_special_key_code(look + 1)) {
+ return true;
+ }
}
while (*look && *look != '>')
look++;
@@ -6800,18 +6793,18 @@ int in_cinkeys(int keytyped, int when, int line_is_empty)
(int)(curwin->w_cursor.col - (p - look)))
match = FALSE;
}
- if (match)
- return TRUE;
+ if (match) {
+ return true;
+ }
}
look = p;
- }
- /*
- * ok, it's a boring generic character.
- */
- else {
- if (try_match && *look == keytyped)
- return TRUE;
- ++look;
+
+ // Ok, it's a boring generic character.
+ } else {
+ if (try_match && *look == keytyped) {
+ return true;
+ }
+ look++;
}
/*
@@ -6819,7 +6812,7 @@ int in_cinkeys(int keytyped, int when, int line_is_empty)
*/
look = skip_to_option_part(look);
}
- return FALSE;
+ return false;
}
/*
@@ -7046,27 +7039,24 @@ static void ins_ctrl_hat(void)
status_redraw_curbuf();
}
-/*
- * Handle ESC in insert mode.
- * Returns TRUE when leaving insert mode, FALSE when going to repeat the
- * insert.
- */
-static int
-ins_esc (
- long *count,
- int cmdchar,
- int nomove /* don't move cursor */
-)
+/// Handle ESC in insert mode.
+///
+/// @param[in,out] count repeat count of the insert command
+/// @param cmdchar command that started the insert
+/// @param nomove when true, don't move the cursor
+///
+/// @return true when leaving insert mode, false when repeating the insert.
+static bool ins_esc(long *count, int cmdchar, bool nomove)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- int temp;
- static int disabled_redraw = FALSE;
+ static bool disabled_redraw = false;
check_spell_redraw();
- temp = curwin->w_cursor.col;
+ int temp = curwin->w_cursor.col;
if (disabled_redraw) {
- --RedrawingDisabled;
- disabled_redraw = FALSE;
+ RedrawingDisabled--;
+ disabled_redraw = false;
}
if (!arrow_used) {
/*
@@ -7096,9 +7086,10 @@ ins_esc (
if (cmdchar == 'r' || cmdchar == 'v') {
stuffRedoReadbuff(ESC_STR); // No ESC in redo buffer
}
- ++RedrawingDisabled;
- disabled_redraw = TRUE;
- return FALSE; /* repeat the insert */
+ RedrawingDisabled++;
+ disabled_redraw = true;
+ // Repeat the insert
+ return false;
}
stop_insert(&curwin->w_cursor, TRUE, nomove);
undisplay_dollar();
@@ -7148,16 +7139,15 @@ ins_esc (
setmouse();
ui_cursor_shape(); /* may show different cursor shape */
- /*
- * When recording or for CTRL-O, need to display the new mode.
- * Otherwise remove the mode message.
- */
- if (Recording || restart_edit != NUL)
+ // When recording or for CTRL-O, need to display the new mode.
+ // Otherwise remove the mode message.
+ if (Recording || restart_edit != NUL) {
showmode();
- else if (p_smd)
+ } else if (p_smd) {
MSG("");
-
- return TRUE; /* exit Insert mode */
+ }
+ // Exit Insert mode
+ return true;
}
/*
@@ -7195,14 +7185,16 @@ static void ins_ctrl_(void)
showmode();
}
-/*
- * If 'keymodel' contains "startsel", may start selection.
- * Returns TRUE when a CTRL-O and other keys stuffed.
- */
-static int ins_start_select(int c)
+/// If 'keymodel' contains "startsel", may start selection.
+///
+/// @param c character to check
+//
+/// @return true when a CTRL-O and other keys stuffed.
+static bool ins_start_select(int c)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
if (!km_startsel) {
- return FALSE;
+ return false;
}
switch (c) {
case K_KHOME:
@@ -7213,32 +7205,27 @@ static int ins_start_select(int c)
case K_KPAGEDOWN:
if (!(mod_mask & MOD_MASK_SHIFT))
break;
- /* FALLTHROUGH */
+ // FALLTHROUGH
case K_S_LEFT:
case K_S_RIGHT:
case K_S_UP:
case K_S_DOWN:
case K_S_END:
case K_S_HOME:
- /* Start selection right away, the cursor can move with
- * CTRL-O when beyond the end of the line. */
+ // Start selection right away, the cursor can move with
+ // CTRL-O when beyond the end of the line.
start_selection();
- /* Execute the key in (insert) Select mode. */
+ // Execute the key in (insert) Select mode.
stuffcharReadbuff(Ctrl_O);
if (mod_mask) {
- char_u buf[4];
-
- buf[0] = K_SPECIAL;
- buf[1] = KS_MODIFIER;
- buf[2] = mod_mask;
- buf[3] = NUL;
+ char_u buf[4] = { K_SPECIAL, KS_MODIFIER, mod_mask, NUL };
stuffReadbuff(buf);
}
stuffcharReadbuff(c);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/*
@@ -7362,18 +7349,23 @@ static void ins_bs_one(colnr_T *vcolp)
(void)del_char(FALSE);
}
-/*
- * Handle Backspace, delete-word and delete-line in Insert mode.
- * Return TRUE when backspace was actually used.
- */
-static int ins_bs(int c, int mode, int *inserted_space_p)
+/// Handle Backspace, delete-word and delete-line in Insert mode.
+///
+/// @param c charcter that was typed
+/// @param mode backspace mode to use
+/// @param[in,out] inserted_space_p whether a space was the last
+// character inserted
+///
+/// @return true when backspace was actually used.
+static bool ins_bs(int c, int mode, int *inserted_space_p)
+ FUNC_ATTR_NONNULL_ARG(3)
{
linenr_T lnum;
int cc;
int temp = 0; /* init for GCC */
colnr_T save_col;
colnr_T mincol;
- int did_backspace = FALSE;
+ bool did_backspace = false;
int in_indent;
int oldState;
int cpc[MAX_MCO]; /* composing characters */
@@ -7399,28 +7391,29 @@ static int ins_bs(int c, int mode, int *inserted_space_p)
return false;
}
- if (stop_arrow() == FAIL)
- return FALSE;
+ if (stop_arrow() == FAIL) {
+ return false;
+ }
in_indent = inindent(0);
- if (in_indent)
- can_cindent = FALSE;
- end_comment_pending = NUL; /* After BS, don't auto-end comment */
- if (revins_on) /* put cursor after last inserted char */
+ if (in_indent) {
+ can_cindent = false;
+ }
+ end_comment_pending = NUL; // After BS, don't auto-end comment
+ if (revins_on) { // put cursor after last inserted char
inc_cursor();
-
- /* Virtualedit:
- * BACKSPACE_CHAR eats a virtual space
- * BACKSPACE_WORD eats all coladd
- * BACKSPACE_LINE eats all coladd and keeps going
- */
+ }
+ // Virtualedit:
+ // BACKSPACE_CHAR eats a virtual space
+ // BACKSPACE_WORD eats all coladd
+ // BACKSPACE_LINE eats all coladd and keeps going
if (curwin->w_cursor.coladd > 0) {
if (mode == BACKSPACE_CHAR) {
- --curwin->w_cursor.coladd;
- return TRUE;
+ curwin->w_cursor.coladd--;
+ return true;
}
if (mode == BACKSPACE_WORD) {
curwin->w_cursor.coladd = 0;
- return TRUE;
+ return true;
}
curwin->w_cursor.coladd = 0;
}
@@ -7432,10 +7425,10 @@ static int ins_bs(int c, int mode, int *inserted_space_p)
lnum = Insstart.lnum;
if (curwin->w_cursor.lnum == lnum || revins_on) {
if (u_save((linenr_T)(curwin->w_cursor.lnum - 2),
- (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) {
- return FALSE;
+ (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) {
+ return false;
}
- --Insstart.lnum;
+ Insstart.lnum--;
Insstart.col = MAXCOL;
}
/*
@@ -7677,12 +7670,12 @@ static int ins_bs(int c, int mode, int *inserted_space_p)
if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1)
dollar_vcol = curwin->w_virtcol;
- /* When deleting a char the cursor line must never be in a closed fold.
- * E.g., when 'foldmethod' is indent and deleting the first non-white
- * char before a Tab. */
- if (did_backspace)
+ // When deleting a char the cursor line must never be in a closed fold.
+ // E.g., when 'foldmethod' is indent and deleting the first non-white
+ // char before a Tab.
+ if (did_backspace) {
foldOpenCursor();
-
+ }
return did_backspace;
}
@@ -8001,35 +7994,37 @@ static void ins_pagedown(void)
}
}
-/*
- * Handle TAB in Insert or Replace mode.
- * Return TRUE when the TAB needs to be inserted like a normal character.
- */
-static int ins_tab(void)
+/// Handle TAB in Insert or Replace mode.
+///
+/// @return true when the TAB needs to be inserted like a normal character.
+static bool ins_tab(void)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
- int ind;
int i;
int temp;
- if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum)
+ if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum) {
Insstart_blank_vcol = get_nolist_virtcol();
- if (echeck_abbr(TAB + ABBR_OFF))
- return FALSE;
+ }
+ if (echeck_abbr(TAB + ABBR_OFF)) {
+ return false;
+ }
- ind = inindent(0);
- if (ind)
- can_cindent = FALSE;
+ int ind = inindent(0);
+ if (ind) {
+ can_cindent = false;
+ }
- /*
- * When nothing special, insert TAB like a normal character
- */
+ // When nothing special, insert TAB like a normal character
if (!curbuf->b_p_et
&& !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf))
- && get_sts_value() == 0)
- return TRUE;
+ && get_sts_value() == 0) {
+ return true;
+ }
- if (stop_arrow() == FAIL)
- return TRUE;
+ if (stop_arrow() == FAIL) {
+ return true;
+ }
did_ai = FALSE;
did_si = FALSE;
@@ -8037,12 +8032,13 @@ static int ins_tab(void)
can_si_back = FALSE;
AppendToRedobuff((char_u *)"\t");
- if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */
+ if (p_sta && ind) { // insert tab in indent, use "shiftwidth"
temp = get_sw_value(curbuf);
- else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */
+ } else if (curbuf->b_p_sts != 0) { // use "softtabstop" when set
temp = get_sts_value();
- else /* otherwise use 'tabstop' */
+ } else { // otherwise use "tabstop"
temp = (int)curbuf->b_p_ts;
+ }
temp -= get_nolist_virtcol() % temp;
/*
@@ -8182,21 +8178,20 @@ static int ins_tab(void)
curwin->w_p_list = save_list;
}
- return FALSE;
+ return false;
}
-/*
- * Handle CR or NL in insert mode.
- * Return TRUE when it can't undo.
- */
-static int ins_eol(int c)
+/// Handle CR or NL in insert mode.
+///
+/// @return true when it can't undo.
+static bool ins_eol(int c)
{
- int i;
-
- if (echeck_abbr(c + ABBR_OFF))
- return FALSE;
- if (stop_arrow() == FAIL)
- return TRUE;
+ if (echeck_abbr(c + ABBR_OFF)) {
+ return false;
+ }
+ if (stop_arrow() == FAIL) {
+ return true;
+ }
undisplay_dollar();
/*
@@ -8229,9 +8224,9 @@ static int ins_eol(int c)
curwin->w_cursor.col += (colnr_T)STRLEN(get_cursor_pos_ptr());
AppendToRedobuff(NL_STR);
- i = open_line(FORWARD,
- has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM :
- 0, old_indent);
+ bool i = open_line(FORWARD,
+ has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0,
+ old_indent);
old_indent = 0;
can_cindent = TRUE;
/* When inserting a line the cursor line must never be in a closed fold. */
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 72f2b984b0..5477e79cad 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -160,6 +160,7 @@ static char *e_listdictarg = N_(
static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary");
static char *e_listreq = N_("E714: List required");
static char *e_dictreq = N_("E715: Dictionary required");
+static char *e_strreq = N_("E114: String required");
static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
static char *e_funcexts = N_(
@@ -379,6 +380,7 @@ static struct vimvar {
{ VV_NAME("option_type", VAR_STRING), VV_RO },
{ VV_NAME("errors", VAR_LIST), 0 },
{ VV_NAME("msgpack_types", VAR_DICT), VV_RO },
+ { VV_NAME("event", VAR_DICT), VV_RO },
};
/* shorthand */
@@ -546,6 +548,10 @@ void eval_init(void)
set_vim_var_dict(VV_MSGPACK_TYPES, msgpack_types_dict);
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+
+ dict_T *v_event = dict_alloc();
+ v_event->dv_lock = VAR_FIXED;
+ set_vim_var_dict(VV_EVENT, v_event);
set_vim_var_list(VV_ERRORS, list_alloc());
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
set_vim_var_nr(VV_HLSEARCH, 1L);
@@ -4011,12 +4017,22 @@ eval6 (
* When either side is a float the result is a float.
*/
if (use_float) {
- if (op == '*')
+ if (op == '*') {
f1 = f1 * f2;
- else if (op == '/') {
- /* We rely on the floating point library to handle divide
- * by zero to result in "inf" and not a crash. */
- f1 = f2 != 0 ? f1 / f2 : INFINITY;
+ } else if (op == '/') {
+ // Division by zero triggers error from AddressSanitizer
+ f1 = (f2 == 0
+ ? (
+#ifdef NAN
+ f1 == 0
+ ? NAN
+ :
+#endif
+ (f1 > 0
+ ? INFINITY
+ : -INFINITY)
+ )
+ : f1 / f2);
} else {
EMSG(_("E804: Cannot use '%' with Float"));
return FAIL;
@@ -6008,6 +6024,27 @@ static void rettv_dict_alloc(typval_T *rettv)
++d->dv_refcount;
}
+/// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary.
+///
+/// @param d The Dictionary to clear
+void dict_clear(dict_T *d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ hash_lock(&d->dv_hashtab);
+ assert(d->dv_hashtab.ht_locked > 0);
+
+ size_t todo = d->dv_hashtab.ht_used;
+ for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) {
+ if (!HASHITEM_EMPTY(hi)) {
+ dictitem_free(HI2DI(hi));
+ hash_remove(&d->dv_hashtab, hi);
+ todo--;
+ }
+ }
+
+ hash_unlock(&d->dv_hashtab);
+}
+
/*
* Unreference a Dictionary: decrement the reference count and free it when it
@@ -6249,6 +6286,24 @@ int dict_add_list(dict_T *d, char *key, list_T *list)
return OK;
}
+/// Set all existing keys in "dict" as read-only.
+///
+/// This does not protect against adding new keys to the Dictionary.
+///
+/// @param dict The dict whose keys should be frozen
+void dict_set_keys_readonly(dict_T *dict)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t todo = dict->dv_hashtab.ht_used;
+ for (hashitem_T *hi = dict->dv_hashtab.ht_array; todo > 0 ; hi++) {
+ if (HASHITEM_EMPTY(hi)) {
+ continue;
+ }
+ todo--;
+ HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
+ }
+}
+
/*
* Get the number of items in a Dictionary.
*/
@@ -6849,9 +6904,25 @@ vim_to_msgpack_error_ret: \
#define CONV_FLOAT(flt) \
do { \
- char numbuf[NUMBUFLEN]; \
- vim_snprintf(numbuf, NUMBUFLEN - 1, "%g", (flt)); \
- ga_concat(gap, (char_u *) numbuf); \
+ const float_T flt_ = (flt); \
+ switch (fpclassify(flt_)) { \
+ case FP_NAN: { \
+ ga_concat(gap, (char_u *) "str2float('nan')"); \
+ break; \
+ } \
+ case FP_INFINITE: { \
+ if (flt_ < 0) { \
+ ga_append(gap, '-'); \
+ } \
+ ga_concat(gap, (char_u *) "str2float('inf')"); \
+ break; \
+ } \
+ default: { \
+ char numbuf[NUMBUFLEN]; \
+ vim_snprintf(numbuf, NUMBUFLEN - 1, "%g", flt_); \
+ ga_concat(gap, (char_u *) numbuf); \
+ } \
+ } \
} while (0)
#define CONV_FUNC(fun) \
@@ -7291,7 +7362,7 @@ static struct fst {
{ "pathshorten", 1, 1, f_pathshorten },
{ "pow", 2, 2, f_pow },
{ "prevnonblank", 1, 1, f_prevnonblank },
- { "printf", 2, 19, f_printf },
+ { "printf", 2, MAX_FUNC_ARGS, f_printf },
{ "pumvisible", 0, 0, f_pumvisible },
{ "py3eval", 1, 1, f_py3eval },
{ "pyeval", 1, 1, f_pyeval },
@@ -7305,8 +7376,8 @@ static struct fst {
{ "resolve", 1, 1, f_resolve },
{ "reverse", 1, 1, f_reverse },
{ "round", 1, 1, f_round },
- { "rpcnotify", 2, 64, f_rpcnotify },
- { "rpcrequest", 2, 64, f_rpcrequest },
+ { "rpcnotify", 2, MAX_FUNC_ARGS, f_rpcnotify },
+ { "rpcrequest", 2, MAX_FUNC_ARGS, f_rpcrequest },
{ "rpcstart", 1, 2, f_rpcstart },
{ "rpcstop", 1, 1, f_rpcstop },
{ "screenattr", 2, 2, f_screenattr },
@@ -10554,8 +10625,6 @@ static void f_getregtype(typval_T *argvars, typval_T *rettv)
{
char_u *strregname;
int regname;
- char_u buf[NUMBUFLEN + 2];
- long reglen = 0;
if (argvars[0].v_type != VAR_UNKNOWN) {
strregname = get_tv_string_chk(&argvars[0]);
@@ -10572,18 +10641,13 @@ static void f_getregtype(typval_T *argvars, typval_T *rettv)
if (regname == 0)
regname = '"';
- buf[0] = NUL;
- buf[1] = NUL;
- switch (get_reg_type(regname, &reglen)) {
- case MLINE: buf[0] = 'V'; break;
- case MCHAR: buf[0] = 'v'; break;
- case MBLOCK:
- buf[0] = Ctrl_V;
- sprintf((char *)buf + 1, "%" PRId64, (int64_t)(reglen + 1));
- break;
- }
+ colnr_T reglen = 0;
+ char buf[NUMBUFLEN + 2];
+ char_u reg_type = get_reg_type(regname, &reglen);
+ format_reg_type(reg_type, reglen, buf, ARRAY_SIZE(buf));
+
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave(buf);
+ rettv->vval.v_string = (char_u *)xstrdup(buf);
}
/*
@@ -15229,43 +15293,51 @@ static void f_setline(typval_T *argvars, typval_T *rettv)
/// replace its content or create a new one.
/// @param[in] title_arg New list title. Defaults to caller function name.
/// @param[out] rettv Return value: 0 in case of success, -1 otherwise.
-static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg,
- typval_T *title_arg, typval_T *rettv)
- FUNC_ATTR_NONNULL_ARG(2, 3, 4, 5)
+static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
+ FUNC_ATTR_NONNULL_ARG(2, 3)
{
- char_u *act;
- int action = ' ';
char_u *title = NULL;
-
+ int action = ' ';
rettv->vval.v_number = -1;
- if (list_arg->v_type != VAR_LIST)
+ typval_T *list_arg = &args[0];
+ if (list_arg->v_type != VAR_LIST) {
EMSG(_(e_listreq));
- else {
- list_T *l = list_arg->vval.v_list;
+ return;
+ }
- if (action_arg->v_type != VAR_UNKNOWN) {
- act = get_tv_string_chk(action_arg);
- if (act == NULL)
- return; /* type error; errmsg already given */
- if (*act == 'a' || *act == 'r')
- action = *act;
- }
+ typval_T *action_arg = &args[1];
+ if (action_arg->v_type == VAR_UNKNOWN) {
+ // Option argument was not given.
+ goto skip_args;
+ } else if (action_arg->v_type != VAR_STRING) {
+ EMSG(_(e_strreq));
+ return;
+ }
+ char_u *act = get_tv_string_chk(action_arg);
+ if (*act == 'a' || *act == 'r') {
+ action = *act;
+ }
- if (title_arg->v_type == VAR_STRING) {
- title = get_tv_string_chk(title_arg);
- if (!title) {
- return; // type error; errmsg already given
- }
- }
+ typval_T *title_arg = &args[2];
+ if (title_arg->v_type == VAR_UNKNOWN) {
+ // Option argument was not given.
+ goto skip_args;
+ }
+ title = get_tv_string_chk(title_arg);
+ if (!title) {
+ // Type error. Error already printed by get_tv_string_chk().
+ return;
+ }
- if (!title) {
- title = (char_u*)(wp ? "setloclist()" : "setqflist()");
- }
+skip_args:
+ if (!title) {
+ title = (char_u*)(wp ? "setloclist()" : "setqflist()");
+ }
- if (l && set_errorlist(wp, l, action, title) == OK) {
- rettv->vval.v_number = 0;
- }
+ list_T *l = list_arg->vval.v_list;
+ if (l && set_errorlist(wp, l, action, title) == OK) {
+ rettv->vval.v_number = 0;
}
}
@@ -15280,7 +15352,7 @@ static void f_setloclist(typval_T *argvars, typval_T *rettv)
win = find_win_by_nr(&argvars[0], NULL);
if (win != NULL) {
- set_qf_ll_list(win, &argvars[1], &argvars[2], &argvars[3], rettv);
+ set_qf_ll_list(win, &argvars[1], rettv);
}
}
@@ -15417,7 +15489,7 @@ static void f_setpos(typval_T *argvars, typval_T *rettv)
*/
static void f_setqflist(typval_T *argvars, typval_T *rettv)
{
- set_qf_ll_list(NULL, &argvars[0], &argvars[1], &argvars[2], rettv);
+ set_qf_ll_list(NULL, argvars, rettv);
}
/*
@@ -18159,14 +18231,7 @@ void set_vim_var_dict(int idx, dict_T *val)
if (val != NULL) {
++val->dv_refcount;
// Set readonly
- size_t todo = val->dv_hashtab.ht_used;
- for (hashitem_T *hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi) {
- if (HASHITEM_EMPTY(hi)) {
- continue;
- }
- --todo;
- HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
- }
+ dict_set_keys_readonly(val);
}
}
@@ -21951,7 +22016,15 @@ repeat:
}
if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S') {
+ // vim_strsave_shellescape() needs a NUL terminated string.
+ c = (*fnamep)[*fnamelen];
+ if (c != NUL) {
+ (*fnamep)[*fnamelen] = NUL;
+ }
p = vim_strsave_shellescape(*fnamep, false, false);
+ if (c != NUL) {
+ (*fnamep)[*fnamelen] = c;
+ }
xfree(*bufp);
*bufp = *fnamep = p;
*fnamelen = STRLEN(p);
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 79a1341d98..f51b0f4921 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -113,7 +113,8 @@ enum {
VV_OPTION_TYPE,
VV_ERRORS,
VV_MSGPACK_TYPES,
- VV_LEN, /* number of v: vars */
+ VV_EVENT,
+ VV_LEN, // number of v: vars
};
/// Maximum number of function arguments
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index ad21e71c51..5ea5beb478 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1377,9 +1377,9 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp)
}
}
#endif
- if (otmp != NULL)
- append_redir(buf, (int)len, p_srr, otmp);
-
+ if (otmp != NULL) {
+ append_redir(buf, len, p_srr, otmp);
+ }
return buf;
}
@@ -1390,7 +1390,7 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp)
* The caller should make sure that there is enough room:
* STRLEN(opt) + STRLEN(fname) + 3
*/
-void append_redir(char_u *buf, int buflen, char_u *opt, char_u *fname)
+void append_redir(char_u *buf, size_t buflen, char_u *opt, char_u *fname)
{
char_u *p;
char_u *end;
@@ -1506,8 +1506,11 @@ void ex_file(exarg_T *eap)
if (rename_buffer(eap->arg) == FAIL)
return;
}
- /* print full file name if :cd used */
- fileinfo(FALSE, FALSE, eap->forceit);
+
+ if (!shortmess(SHM_FILEINFO)) {
+ // print full file name if :cd used
+ fileinfo(false, false, eap->forceit);
+ }
}
/*
@@ -2483,7 +2486,9 @@ do_ecmd (
msg_scroll = msg_scroll_save;
msg_scrolled_ign = TRUE;
- fileinfo(FALSE, TRUE, FALSE);
+ if (!shortmess(SHM_FILEINFO)) {
+ fileinfo(false, true, false);
+ }
msg_scrolled_ign = FALSE;
}
@@ -3017,7 +3022,7 @@ void do_sub(exarg_T *eap)
// The number of lines joined is the number of lines in the range
linenr_T joined_lines_count = eap->line2 - eap->line1 + 1
// plus one extra line if not at the end of file.
- + eap->line2 < curbuf->b_ml.ml_line_count ? 1 : 0;
+ + (eap->line2 < curbuf->b_ml.ml_line_count ? 1 : 0);
if (joined_lines_count > 1) {
do_join(joined_lines_count, FALSE, TRUE, FALSE, true);
sub_nsubs = joined_lines_count - 1;
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 47774f5a99..71ea170e1c 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -57,23 +57,23 @@ typedef struct scriptitem_S {
char_u *sn_name;
bool file_id_valid;
FileID file_id;
- int sn_prof_on; /* TRUE when script is/was profiled */
- int sn_pr_force; /* forceit: profile functions in this script */
- proftime_T sn_pr_child; /* time set when going into first child */
- int sn_pr_nest; /* nesting for sn_pr_child */
- /* profiling the script as a whole */
- int sn_pr_count; /* nr of times sourced */
- proftime_T sn_pr_total; /* time spent in script + children */
- proftime_T sn_pr_self; /* time spent in script itself */
- proftime_T sn_pr_start; /* time at script start */
- proftime_T sn_pr_children; /* time in children after script start */
- /* profiling the script per line */
- garray_T sn_prl_ga; /* things stored for every line */
- proftime_T sn_prl_start; /* start time for current line */
- proftime_T sn_prl_children; /* time spent in children for this line */
- proftime_T sn_prl_wait; /* wait start time for current line */
- int sn_prl_idx; /* index of line being timed; -1 if none */
- int sn_prl_execed; /* line being timed was executed */
+ bool sn_prof_on; ///< true when script is/was profiled
+ int sn_pr_force; ///< forceit: profile functions in this script
+ proftime_T sn_pr_child; ///< time set when going into first child
+ int sn_pr_nest; ///< nesting for sn_pr_child
+ // profiling the script as a whole
+ int sn_pr_count; ///< nr of times sourced
+ proftime_T sn_pr_total; ///< time spent in script + children
+ proftime_T sn_pr_self; ///< time spent in script itself
+ proftime_T sn_pr_start; ///< time at script start
+ proftime_T sn_pr_children; ///< time in children after script start
+ // profiling the script per line
+ garray_T sn_prl_ga; ///< things stored for every line
+ proftime_T sn_prl_start; ///< start time for current line
+ proftime_T sn_prl_children; ///< time spent in children for this line
+ proftime_T sn_prl_wait; ///< wait start time for current line
+ linenr_T sn_prl_idx; ///< index of line being timed; -1 if none
+ int sn_prl_execed; ///< line being timed was executed
} scriptitem_T;
static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL};
@@ -81,9 +81,9 @@ static garray_T script_items = {0, 0, sizeof(scriptitem_T), 4, NULL};
/* Struct used in sn_prl_ga for every line of a script. */
typedef struct sn_prl_S {
- int snp_count; /* nr of times line was executed */
- proftime_T sn_prl_total; /* time spent in a line + children */
- proftime_T sn_prl_self; /* time spent in a line itself */
+ int snp_count; ///< nr of times line was executed
+ proftime_T sn_prl_total; ///< time spent in a line + children
+ proftime_T sn_prl_self; ///< time spent in a line itself
} sn_prl_T;
/*
@@ -93,18 +93,18 @@ typedef struct sn_prl_S {
* sourcing can be done recursively.
*/
struct source_cookie {
- FILE *fp; /* opened file for sourcing */
- char_u *nextline; /* if not NULL: line that was read ahead */
- int finished; /* ":finish" used */
+ FILE *fp; ///< opened file for sourcing
+ char_u *nextline; ///< if not NULL: line that was read ahead
+ int finished; ///< ":finish" used
#if defined(USE_CRNL)
- int fileformat; /* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
- int error; /* TRUE if LF found after CR-LF */
+ int fileformat; ///< EOL_UNKNOWN, EOL_UNIX or EOL_DOS
+ int error; ///< TRUE if LF found after CR-LF
#endif
- linenr_T breakpoint; /* next line with breakpoint or zero */
- char_u *fname; /* name of sourced file */
- int dbg_tick; /* debug_tick when breakpoint was set */
- int level; /* top nesting level of sourced file */
- vimconv_T conv; /* type of conversion */
+ linenr_T breakpoint; ///< next line with breakpoint or zero
+ char_u *fname; ///< name of sourced file
+ int dbg_tick; ///< debug_tick when breakpoint was set
+ int level; ///< top nesting level of sourced file
+ vimconv_T conv; ///< type of conversion
};
# define PRL_ITEM(si, idx) (((sn_prl_T *)(si)->sn_prl_ga.ga_data)[(idx)])
@@ -272,7 +272,7 @@ void do_debug(char_u *cmd)
xfree(cmdline);
}
- lines_left = Rows - 1;
+ lines_left = (int)(Rows - 1);
}
xfree(cmdline);
@@ -281,7 +281,7 @@ void do_debug(char_u *cmd)
redraw_all_later(NOT_VALID);
need_wait_return = FALSE;
msg_scroll = save_msg_scroll;
- lines_left = Rows - 1;
+ lines_left = (int)(Rows - 1);
State = save_State;
did_emsg = save_did_emsg;
cmd_silent = save_cmd_silent;
@@ -392,12 +392,12 @@ int dbg_check_skipped(exarg_T *eap)
* This is a grow-array of structs.
*/
struct debuggy {
- int dbg_nr; /* breakpoint number */
- int dbg_type; /* DBG_FUNC or DBG_FILE */
- char_u *dbg_name; /* function or file name */
- regprog_T *dbg_prog; /* regexp program */
- linenr_T dbg_lnum; /* line number in function or file */
- int dbg_forceit; /* ! used */
+ int dbg_nr; ///< breakpoint number
+ int dbg_type; ///< DBG_FUNC or DBG_FILE
+ char_u *dbg_name; ///< function or file name
+ regprog_T *dbg_prog; ///< regexp program
+ linenr_T dbg_lnum; ///< line number in function or file
+ int dbg_forceit; ///< ! used
};
static garray_T dbg_breakp = {0, 0, sizeof(struct debuggy), 4, NULL};
@@ -563,13 +563,14 @@ void ex_breakdel(exarg_T *eap)
}
if (ascii_isdigit(*eap->arg)) {
- /* ":breakdel {nr}" */
- nr = atol((char *)eap->arg);
- for (int i = 0; i < gap->ga_len; ++i)
+ // ":breakdel {nr}"
+ nr = atoi((char *)eap->arg);
+ for (int i = 0; i < gap->ga_len; ++i) {
if (DEBUGGY(gap, i).dbg_nr == nr) {
todel = i;
break;
}
+ }
} else if (*eap->arg == '*') {
todel = 0;
del_all = TRUE;
@@ -602,11 +603,13 @@ void ex_breakdel(exarg_T *eap)
--gap->ga_len;
if (todel < gap->ga_len)
memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1),
- (gap->ga_len - todel) * sizeof(struct debuggy));
- if (eap->cmdidx == CMD_breakdel)
+ (size_t)(gap->ga_len - todel) * sizeof(struct debuggy));
+ if (eap->cmdidx == CMD_breakdel) {
++debug_tick;
- if (!del_all)
+ }
+ if (!del_all) {
break;
+ }
}
/* If all breakpoints were removed clear the array. */
@@ -810,8 +813,8 @@ void ex_pydo3(exarg_T *eap)
/* Command line expansion for :profile. */
static enum {
- PEXP_SUBCMD, /* expand :profile sub-commands */
- PEXP_FUNC /* expand :profile func {funcname} */
+ PEXP_SUBCMD, ///< expand :profile sub-commands
+ PEXP_FUNC ///< expand :profile func {funcname}
} pexpand_what;
static char *pexpand_cmds[] = {
@@ -892,7 +895,7 @@ static void profile_reset(void)
for (int id = 1; id <= script_items.ga_len; id++) {
scriptitem_T *si = &SCRIPT_ITEM(id);
if (si->sn_prof_on) {
- si->sn_prof_on = 0;
+ si->sn_prof_on = false;
si->sn_pr_force = 0;
si->sn_pr_child = profile_zero();
si->sn_pr_nest = 0;
@@ -949,7 +952,7 @@ static void profile_init(scriptitem_T *si)
ga_init(&si->sn_prl_ga, sizeof(sn_prl_T), 100);
si->sn_prl_idx = -1;
- si->sn_prof_on = TRUE;
+ si->sn_prof_on = true;
si->sn_pr_nest = 0;
}
@@ -1255,7 +1258,7 @@ check_changed_any (
int save;
int i;
int bufnum = 0;
- int bufcount = 0;
+ size_t bufcount = 0;
int *bufnrs;
FOR_ALL_BUFFERS(buf) {
@@ -1520,7 +1523,7 @@ do_arglist (
didone = TRUE;
xfree(ARGLIST[match].ae_fname);
memmove(ARGLIST + match, ARGLIST + match + 1,
- (ARGCOUNT - match - 1) * sizeof(aentry_T));
+ (size_t)(ARGCOUNT - match - 1) * sizeof(aentry_T));
--ALIST(curwin)->al_ga.ga_len;
if (curwin->w_arg_idx > match)
--curwin->w_arg_idx;
@@ -1537,9 +1540,7 @@ do_arglist (
int i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
&exp_count, &exp_files, EW_DIR|EW_FILE|EW_ADDSLASH|EW_NOTFOUND);
ga_clear(&new_ga);
- if (i == FAIL)
- return FAIL;
- if (exp_count == 0) {
+ if (i == FAIL || exp_count == 0) {
EMSG(_(e_nomatch));
return FAIL;
}
@@ -1702,10 +1703,11 @@ void ex_argument(exarg_T *eap)
{
int i;
- if (eap->addr_count > 0)
- i = eap->line2 - 1;
- else
+ if (eap->addr_count > 0) {
+ i = (int)eap->line2 - 1;
+ } else {
i = curwin->w_arg_idx;
+ }
do_argfile(eap, i);
}
@@ -1844,22 +1846,25 @@ void ex_argadd(exarg_T *eap)
void ex_argdelete(exarg_T *eap)
{
if (eap->addr_count > 0) {
- /* ":1,4argdel": Delete all arguments in the range. */
- if (eap->line2 > ARGCOUNT)
+ // ":1,4argdel": Delete all arguments in the range.
+ if (eap->line2 > ARGCOUNT) {
eap->line2 = ARGCOUNT;
- int n = eap->line2 - eap->line1 + 1;
- if (*eap->arg != NUL || n <= 0)
+ }
+ linenr_T n = eap->line2 - eap->line1 + 1;
+ if (*eap->arg != NUL || n <= 0) {
EMSG(_(e_invarg));
- else {
- for (int i = eap->line1; i <= eap->line2; ++i)
+ } else {
+ for (linenr_T i = eap->line1; i <= eap->line2; ++i) {
xfree(ARGLIST[i - 1].ae_fname);
+ }
memmove(ARGLIST + eap->line1 - 1, ARGLIST + eap->line2,
- (size_t)((ARGCOUNT - eap->line2) * sizeof(aentry_T)));
- ALIST(curwin)->al_ga.ga_len -= n;
- if (curwin->w_arg_idx >= eap->line2)
- curwin->w_arg_idx -= n;
- else if (curwin->w_arg_idx > eap->line1)
- curwin->w_arg_idx = eap->line1;
+ (size_t)(ARGCOUNT - eap->line2) * sizeof(aentry_T));
+ ALIST(curwin)->al_ga.ga_len -= (int)n;
+ if (curwin->w_arg_idx >= eap->line2) {
+ curwin->w_arg_idx -= (int)n;
+ } else if (curwin->w_arg_idx > eap->line1) {
+ curwin->w_arg_idx = (int)eap->line1;
+ }
}
} else if (*eap->arg == NUL)
EMSG(_(e_argreq));
@@ -1909,7 +1914,7 @@ void ex_listdo(exarg_T *eap)
}
break;
case CMD_argdo:
- i = eap->line1 - 1;
+ i = (int)eap->line1 - 1;
break;
default:
break;
@@ -1942,10 +1947,11 @@ void ex_listdo(exarg_T *eap)
ex_cc(eap);
buf = curbuf;
- i = eap->line1 - 1;
+ i = (int)eap->line1 - 1;
if (eap->addr_count <= 0) {
// Default to all quickfix/location list entries.
- eap->line2 = qf_size;
+ assert(qf_size < MAXLNUM);
+ eap->line2 = (linenr_T)qf_size;
}
}
} else {
@@ -2098,7 +2104,7 @@ alist_add_list (
after = ARGCOUNT;
if (after < ARGCOUNT)
memmove(&(ARGLIST[after + count]), &(ARGLIST[after]),
- (ARGCOUNT - after) * sizeof(aentry_T));
+ (size_t)(ARGCOUNT - after) * sizeof(aentry_T));
for (int i = 0; i < count; ++i) {
ARGLIST[after + i].ae_fname = files[i];
ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
@@ -2571,7 +2577,7 @@ do_source (
while (script_items.ga_len < current_SID) {
++script_items.ga_len;
SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
- SCRIPT_ITEM(script_items.ga_len).sn_prof_on = FALSE;
+ SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false;
}
si = &SCRIPT_ITEM(current_SID);
si->sn_name = fname_exp;
@@ -3386,8 +3392,8 @@ static void script_host_execute(char *name, exarg_T *eap)
// script
list_append_string(args, script ? script : eap->arg, -1);
// current range
- list_append_number(args, eap->line1);
- list_append_number(args, eap->line2);
+ list_append_number(args, (int)eap->line1);
+ list_append_number(args, (int)eap->line2);
(void)eval_call_provider(name, "execute", args);
}
@@ -3403,16 +3409,16 @@ static void script_host_execute_file(char *name, exarg_T *eap)
// filename
list_append_string(args, buffer, -1);
// current range
- list_append_number(args, eap->line1);
- list_append_number(args, eap->line2);
+ list_append_number(args, (int)eap->line1);
+ list_append_number(args, (int)eap->line2);
(void)eval_call_provider(name, "execute_file", args);
}
static void script_host_do_range(char *name, exarg_T *eap)
{
list_T *args = list_alloc();
- list_append_number(args, eap->line1);
- list_append_number(args, eap->line2);
+ list_append_number(args, (int)eap->line1);
+ list_append_number(args, (int)eap->line2);
list_append_string(args, eap->arg, -1);
(void)eval_call_provider(name, "do_range", args);
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 3a24f194c1..a7e98e7f04 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -6290,10 +6290,8 @@ void ex_splitview(exarg_T *eap)
if (eap->cmdidx == CMD_tabedit
|| eap->cmdidx == CMD_tabfind
|| eap->cmdidx == CMD_tabnew) {
- if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab
- : eap->addr_count == 0 ? 0
- : (int)eap->line2 + 1) != FAIL) {
- apply_autocmds(EVENT_TABNEW, eap->arg, eap->arg, FALSE, curbuf);
+ if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab : eap->addr_count == 0
+ ? 0 : (int)eap->line2 + 1, eap->arg) != FAIL) {
do_exedit(eap, old_curwin);
apply_autocmds(EVENT_TABNEWENTERED, NULL, NULL, FALSE, curbuf);
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index bf67047ae8..a1e54e74a6 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -378,7 +378,7 @@ char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should
char_u *p, *val;
if (type == ET_ERROR) {
- *should_free = FALSE;
+ *should_free = true;
mesg = ((struct msglist *)value)->throw_msg;
if (cmdname != NULL && *cmdname != NUL) {
size_t cmdlen = STRLEN(cmdname);
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 39bff9b2ad..cffda1ca55 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1130,7 +1130,7 @@ static int command_line_handle_key(CommandLineState *s)
if (!mouse_has(MOUSE_COMMAND)) {
return command_line_not_changed(s); // Ignore mouse
}
- cmdline_paste(0, true, true);
+ cmdline_paste(eval_has_provider("clipboard") ? '*' : 0, true, true);
redrawcmd();
return command_line_changed(s);
@@ -2424,20 +2424,17 @@ void restore_cmdline_alloc(char_u *p)
xfree(p);
}
-/*
- * paste a yank register into the command line.
- * used by CTRL-R command in command-line mode
- * insert_reg() can't be used here, because special characters from the
- * register contents will be interpreted as commands.
- *
- * return FAIL for failure, OK otherwise
- */
-static int
-cmdline_paste (
- int regname,
- int literally, /* Insert text literally instead of "as typed" */
- int remcr /* remove trailing CR */
-)
+/// Paste a yank register into the command line.
+/// Used by CTRL-R command in command-line mode.
+/// insert_reg() can't be used here, because special characters from the
+/// register contents will be interpreted as commands.
+///
+/// @param regname Register name.
+/// @param literally Insert text literally instead of "as typed".
+/// @param remcr When true, remove trailing CR.
+///
+/// @returns FAIL for failure, OK otherwise
+static bool cmdline_paste(int regname, bool literally, bool remcr)
{
long i;
char_u *arg;
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 6c135ef47b..70ab4ced75 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -762,6 +762,10 @@ void clearFolding(win_T *win)
*/
void foldUpdate(win_T *wp, linenr_T top, linenr_T bot)
{
+ if (compl_busy) {
+ return;
+ }
+
fold_T *fp;
if (wp->w_buffer->terminal) {
return;
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 69e65c3208..40b5718071 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -214,6 +214,10 @@ EXTERN int compl_length INIT(= 0);
* stop looking for matches. */
EXTERN int compl_interrupted INIT(= FALSE);
+// Set when doing something for completion that may call edit() recursively,
+// which is not allowed. Also used to disable folding during completion
+EXTERN int compl_busy INIT(= false);
+
/* List of flags for method of completion. */
EXTERN int compl_cont_status INIT(= 0);
# define CONT_ADDING 1 /* "normal" or "adding" expansion */
@@ -918,8 +922,8 @@ EXTERN int KeyTyped; // TRUE if user typed current char
EXTERN int KeyStuffed; // TRUE if current char from stuffbuf
EXTERN int maptick INIT(= 0); // tick for each non-mapped char
-EXTERN char_u chartab[256]; /* table used in charset.c; See
- init_chartab() for explanation */
+EXTERN uint8_t chartab[256]; // table used in charset.c; See
+ // init_chartab() for explanation
EXTERN int must_redraw INIT(= 0); /* type of redraw necessary */
EXTERN int skip_redraw INIT(= FALSE); /* skip redraw once */
diff --git a/src/nvim/main.c b/src/nvim/main.c
index a2aca65001..5b5c8a22aa 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -317,14 +317,16 @@ int main(int argc, char **argv)
}
// open terminals when opening files that start with term://
- do_cmdline_cmd("autocmd BufReadCmd term://* "
+#define PROTO "term://"
+ do_cmdline_cmd("autocmd BufReadCmd " PROTO "* nested "
":call termopen( "
// Capture the command string
"matchstr(expand(\"<amatch>\"), "
- "'\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), "
+ "'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), "
// capture the working directory
"{'cwd': get(matchlist(expand(\"<amatch>\"), "
- "'\\c\\mterm://\\(.\\{-}\\)//'), 1, '')})");
+ "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})");
+#undef PROTO
/* Execute --cmd arguments. */
exe_pre_commands(&params);
diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c
index 8cf5642a80..6599db787f 100644
--- a/src/nvim/memfile.c
+++ b/src/nvim/memfile.c
@@ -79,8 +79,6 @@ static size_t total_mem_used = 0; /// total memory used for memfiles
/// - NULL, on failure.
memfile_T *mf_open(char_u *fname, int flags)
{
- off_t size;
-
memfile_T *mfp = xmalloc(sizeof(memfile_T));
if (fname == NULL) { // no file, use memory only
@@ -88,11 +86,9 @@ memfile_T *mf_open(char_u *fname, int flags)
mfp->mf_ffname = NULL;
mfp->mf_fd = -1;
} else { // try to open the file
- mf_do_open(mfp, fname, flags);
-
- if (mfp->mf_fd < 0) { // fail if file could not be opened
+ if (!mf_do_open(mfp, fname, flags)) {
xfree(mfp);
- return NULL;
+ return NULL; // fail if file could not be opened
}
}
@@ -115,6 +111,8 @@ memfile_T *mf_open(char_u *fname, int flags)
}
}
+ off_t size;
+
// When recovering, the actual block size will be retrieved from block 0
// in ml_recover(). The size used here may be wrong, therefore mf_blocknr_max
// must be rounded up.
@@ -171,13 +169,12 @@ memfile_T *mf_open(char_u *fname, int flags)
/// FAIL If file could not be opened.
int mf_open_file(memfile_T *mfp, char_u *fname)
{
- mf_do_open(mfp, fname, O_RDWR|O_CREAT|O_EXCL); // try to open the file
-
- if (mfp->mf_fd < 0)
- return FAIL;
+ if (mf_do_open(mfp, fname, O_RDWR | O_CREAT | O_EXCL)) {
+ mfp->mf_dirty = true;
+ return OK;
+ }
- mfp->mf_dirty = true;
- return OK;
+ return FAIL;
}
/// Close a memory file and optionally delete the associated file.
@@ -185,28 +182,28 @@ int mf_open_file(memfile_T *mfp, char_u *fname)
/// @param del_file Whether to delete associated file.
void mf_close(memfile_T *mfp, bool del_file)
{
- bhdr_T *hp, *nextp;
-
if (mfp == NULL) { // safety check
return;
}
if (mfp->mf_fd >= 0 && close(mfp->mf_fd) < 0) {
EMSG(_(e_swapclose));
}
- if (del_file && mfp->mf_fname != NULL)
+ if (del_file && mfp->mf_fname != NULL) {
os_remove((char *)mfp->mf_fname);
+ }
+
// free entries in used list
- for (hp = mfp->mf_used_first; hp != NULL; hp = nextp) {
+ for (bhdr_T *hp = mfp->mf_used_first, *nextp; hp != NULL; hp = nextp) {
total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
nextp = hp->bh_next;
mf_free_bhdr(hp);
}
- while (mfp->mf_free_first != NULL) // free entries in free list
+ while (mfp->mf_free_first != NULL) { // free entries in free list
xfree(mf_rem_free(mfp));
+ }
mf_hash_free(&mfp->mf_hash);
mf_hash_free_all(&mfp->mf_trans); // free hashtable and its items
- xfree(mfp->mf_fname);
- xfree(mfp->mf_ffname);
+ mf_free_fnames(mfp);
xfree(mfp);
}
@@ -216,28 +213,28 @@ void mf_close(memfile_T *mfp, bool del_file)
void mf_close_file(buf_T *buf, bool getlines)
{
memfile_T *mfp = buf->b_ml.ml_mfp;
- if (mfp == NULL || mfp->mf_fd < 0) // nothing to close
+ if (mfp == NULL || mfp->mf_fd < 0) { // nothing to close
return;
+ }
if (getlines) {
// get all blocks in memory by accessing all lines (clumsy!)
mf_dont_release = true;
- for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
+ for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum) {
(void)ml_get_buf(buf, lnum, false);
+ }
mf_dont_release = false;
// TODO(elmart): should check if all blocks are really in core
}
- if (close(mfp->mf_fd) < 0) // close the file
+ if (close(mfp->mf_fd) < 0) { // close the file
EMSG(_(e_swapclose));
+ }
mfp->mf_fd = -1;
if (mfp->mf_fname != NULL) {
os_remove((char *)mfp->mf_fname); // delete the swap file
- xfree(mfp->mf_fname);
- xfree(mfp->mf_ffname);
- mfp->mf_fname = NULL;
- mfp->mf_ffname = NULL;
+ mf_free_fnames(mfp);
}
}
@@ -390,11 +387,11 @@ void mf_put(memfile_T *mfp, bhdr_T *hp, bool dirty, bool infile)
/// Signal block as no longer used (may put it in the free list).
void mf_free(memfile_T *mfp, bhdr_T *hp)
{
- xfree(hp->bh_data); // free data
+ xfree(hp->bh_data); // free data
mf_rem_hash(mfp, hp); // get *hp out of the hash list
mf_rem_used(mfp, hp); // get *hp out of the used list
if (hp->bh_bnum < 0) {
- xfree(hp); // don't want negative numbers in free list
+ xfree(hp); // don't want negative numbers in free list
mfp->mf_neg_count--;
} else {
mf_ins_free(mfp, hp); // put *hp in the free list
@@ -475,10 +472,11 @@ int mf_sync(memfile_T *mfp, int flags)
/// These are blocks that need to be written to a newly created swapfile.
void mf_set_dirty(memfile_T *mfp)
{
- bhdr_T *hp;
- for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
- if (hp->bh_bnum > 0)
+ for (bhdr_T *hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev) {
+ if (hp->bh_bnum > 0) {
hp->bh_flags |= BH_DIRTY;
+ }
+ }
mfp->mf_dirty = true;
}
@@ -506,10 +504,11 @@ static void mf_ins_used(memfile_T *mfp, bhdr_T *hp)
hp->bh_next = mfp->mf_used_first;
mfp->mf_used_first = hp;
hp->bh_prev = NULL;
- if (hp->bh_next == NULL) // list was empty, adjust last pointer
+ if (hp->bh_next == NULL) { // list was empty, adjust last pointer
mfp->mf_used_last = hp;
- else
+ } else {
hp->bh_next->bh_prev = hp;
+ }
mfp->mf_used_count += hp->bh_page_count;
total_mem_used += hp->bh_page_count * mfp->mf_page_size;
}
@@ -615,9 +614,10 @@ bool mf_release_all(void)
FOR_ALL_BUFFERS(buf) {
memfile_T *mfp = buf->b_ml.ml_mfp;
if (mfp != NULL) {
- // If no swap file yet, may open one.
- if (mfp->mf_fd < 0 && buf->b_may_swap)
+ // If no swap file yet, try to open one.
+ if (mfp->mf_fd < 0 && buf->b_may_swap) {
ml_open_file(buf);
+ }
// Flush as many blocks as possible, only if there is a swapfile.
if (mfp->mf_fd >= 0) {
@@ -752,7 +752,8 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
else
page_count = hp2->bh_page_count;
size = page_size * page_count;
- if (mf_write_block(mfp, hp2 == NULL ? hp : hp2, offset, size) == FAIL) {
+ void *data = (hp2 == NULL) ? hp->bh_data : hp2->bh_data;
+ if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size) {
/// Avoid repeating the error message, this mostly happens when the
/// disk is full. We give the message again only after a successful
/// write or when hitting a key. We keep on trying, in case some
@@ -773,20 +774,6 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
return OK;
}
-/// Write block to memfile's file.
-///
-/// @return OK On success.
-/// FAIL On failure.
-static int mf_write_block(memfile_T *mfp, bhdr_T *hp,
- off_t offset, unsigned size)
-{
- void *data = hp->bh_data;
- int result = OK;
- if ((unsigned)write_eintr(mfp->mf_fd, data, size) != size)
- result = FAIL;
- return result;
-}
-
/// Make block number positive and add it to the translation list.
///
/// @return OK On success.
@@ -856,13 +843,23 @@ blocknr_T mf_trans_del(memfile_T *mfp, blocknr_T old_nr)
return new_bnum;
}
-/// Set full file name of memfile's swapfile, out of simple file name and some
-/// other considerations.
+/// Frees mf_fname and mf_ffname.
+void mf_free_fnames(memfile_T *mfp)
+{
+ xfree(mfp->mf_fname);
+ xfree(mfp->mf_ffname);
+ mfp->mf_fname = NULL;
+ mfp->mf_ffname = NULL;
+}
+
+/// Set the simple file name and the full file name of memfile's swapfile, out
+/// of simple file name and some other considerations.
///
/// Only called when creating or renaming the swapfile. Either way it's a new
/// name so we must work out the full path name.
-void mf_set_ffname(memfile_T *mfp)
+void mf_set_fnames(memfile_T *mfp, char_u *fname)
{
+ mfp->mf_fname = fname;
mfp->mf_ffname = (char_u *)FullName_save((char *)mfp->mf_fname, false);
}
@@ -878,7 +875,7 @@ void mf_fullname(memfile_T *mfp)
}
}
-/// Return TRUE if there are any translations pending for memfile.
+/// Return true if there are any translations pending for memfile.
bool mf_need_trans(memfile_T *mfp)
{
return mfp->mf_fname != NULL && mfp->mf_neg_count > 0;
@@ -889,11 +886,11 @@ bool mf_need_trans(memfile_T *mfp)
/// "fname" must be in allocated memory, and is consumed (also when error).
///
/// @param flags Flags for open().
-static void mf_do_open(memfile_T *mfp, char_u *fname, int flags)
+/// @return A bool indicating success of the `open` call.
+static bool mf_do_open(memfile_T *mfp, char_u *fname, int flags)
{
// fname cannot be NameBuff, because it must have been allocated.
- mfp->mf_fname = fname;
- mf_set_ffname(mfp);
+ mf_set_fnames(mfp, fname);
/// Extra security check: When creating a swap file it really shouldn't
/// exist yet. If there is a symbolic link, this is most likely an attack.
@@ -904,26 +901,26 @@ static void mf_do_open(memfile_T *mfp, char_u *fname, int flags)
EMSG(_("E300: Swap file already exists (symlink attack?)"));
} else {
// try to open the file
- flags |= O_NOFOLLOW;
- mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags);
+ mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags | O_NOFOLLOW);
}
// If the file cannot be opened, use memory only
if (mfp->mf_fd < 0) {
- xfree(mfp->mf_fname);
- xfree(mfp->mf_ffname);
- mfp->mf_fname = NULL;
- mfp->mf_ffname = NULL;
- } else {
+ mf_free_fnames(mfp);
+ return false;
+ }
+
#ifdef HAVE_FD_CLOEXEC
- int fdflags = fcntl(mfp->mf_fd, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
- fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
+ int fdflags = fcntl(mfp->mf_fd, F_GETFD);
+ if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
+ fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
+ }
#endif
#ifdef HAVE_SELINUX
- mch_copy_sec(fname, mfp->mf_fname);
+ mch_copy_sec(fname, mfp->mf_fname);
#endif
- }
+
+ return true;
}
//
@@ -948,20 +945,21 @@ static void mf_hash_init(mf_hashtab_T *mht)
/// The hash table must not be used again without another mf_hash_init() call.
static void mf_hash_free(mf_hashtab_T *mht)
{
- if (mht->mht_buckets != mht->mht_small_buckets)
+ if (mht->mht_buckets != mht->mht_small_buckets) {
xfree(mht->mht_buckets);
+ }
}
/// Free the array of a hash table and all the items it contains.
static void mf_hash_free_all(mf_hashtab_T *mht)
{
- mf_hashitem_T *next;
-
- for (size_t idx = 0; idx <= mht->mht_mask; idx++)
+ for (size_t idx = 0; idx <= mht->mht_mask; idx++) {
+ mf_hashitem_T *next;
for (mf_hashitem_T *mhi = mht->mht_buckets[idx]; mhi != NULL; mhi = next) {
next = mhi->mhi_next;
xfree(mhi);
}
+ }
mf_hash_free(mht);
}
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index f58b2ac38f..b568279d7d 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -426,10 +426,8 @@ void ml_setname(buf_T *buf)
/* try to rename the swap file */
if (vim_rename(mfp->mf_fname, fname) == 0) {
success = TRUE;
- xfree(mfp->mf_fname);
- mfp->mf_fname = fname;
- xfree(mfp->mf_ffname);
- mf_set_ffname(mfp);
+ mf_free_fnames(mfp);
+ mf_set_fnames(mfp, fname);
ml_upd_block0(buf, UB_SAME_DIR);
break;
}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index e064d34e09..2895816b8f 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2344,9 +2344,12 @@ do_mouse (
if (mouse_row == 0 && firstwin->w_winrow > 0) {
if (is_drag) {
if (in_tab_line) {
- tabpage_move(tab_page_click_defs[mouse_col].type == kStlClickTabClose
- ? 9999
- : tab_page_click_defs[mouse_col].tabnr - 1);
+ if (tab_page_click_defs[mouse_col].type == kStlClickTabClose) {
+ tabpage_move(9999);
+ } else {
+ int tabnr = tab_page_click_defs[mouse_col].tabnr;
+ tabpage_move(tabnr < tabpage_index(curtab) ? tabnr - 1 : tabnr);
+ }
}
return false;
}
@@ -4096,6 +4099,7 @@ dozet:
case 't': scroll_cursor_top(0, true);
redraw_later(VALID);
+ set_fraction(curwin);
break;
/* "z." and "zz": put cursor in middle of screen */
@@ -4104,6 +4108,7 @@ dozet:
case 'z': scroll_cursor_halfway(true);
redraw_later(VALID);
+ set_fraction(curwin);
break;
/* "z^", "z-" and "zb": put cursor at bottom of screen */
@@ -4124,6 +4129,7 @@ dozet:
case 'b': scroll_cursor_bot(0, true);
redraw_later(VALID);
+ set_fraction(curwin);
break;
/* "zH" - scroll screen right half-page */
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index b1adc85e1d..5f48fdbf3d 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -19,6 +19,7 @@
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_getln.h"
+#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
#include "nvim/indent.h"
@@ -835,12 +836,13 @@ int do_record(int c)
yankreg_T *old_y_previous;
int retval;
- if (Recording == FALSE) { /* start recording */
- /* registers 0-9, a-z and " are allowed */
- if (c < 0 || (!ASCII_ISALNUM(c) && c != '"'))
+ if (Recording == false) {
+ // start recording
+ // registers 0-9, a-z and " are allowed
+ if (c < 0 || (!ASCII_ISALNUM(c) && c != '"')) {
retval = FAIL;
- else {
- Recording = TRUE;
+ } else {
+ Recording = c;
showmode();
regname = c;
retval = OK;
@@ -1259,21 +1261,18 @@ get_spec_reg (
return FALSE;
}
-/*
- * Paste a yank register into the command line.
- * Only for non-special registers.
- * Used by CTRL-R command in command-line mode
- * insert_reg() can't be used here, because special characters from the
- * register contents will be interpreted as commands.
- *
- * return FAIL for failure, OK otherwise
- */
-int
-cmdline_paste_reg (
- int regname,
- int literally, /* Insert text literally instead of "as typed" */
- int remcr /* don't add trailing CR */
-)
+/// Paste a yank register into the command line.
+/// Only for non-special registers.
+/// Used by CTRL-R command in command-line mode
+/// insert_reg() can't be used here, because special characters from the
+/// register contents will be interpreted as commands.
+///
+/// @param regname Register name.
+/// @param literally Insert text literally instead of "as typed".
+/// @param remcr When true, don't add CR characters.
+///
+/// @returns FAIL for failure, OK otherwise
+bool cmdline_paste_reg(int regname, bool literally, bool remcr)
{
long i;
@@ -1284,13 +1283,9 @@ cmdline_paste_reg (
for (i = 0; i < reg->y_size; i++) {
cmdline_paste_str(reg->y_array[i], literally);
- /* Insert ^M between lines and after last line if type is MLINE.
- * Don't do this when "remcr" is TRUE and the next line is empty. */
- if (reg->y_type == MLINE
- || (i < reg->y_size - 1
- && !(remcr
- && i == reg->y_size - 2
- && *reg->y_array[i + 1] == NUL))) {
+ // Insert ^M between lines and after last line if type is MLINE.
+ // Don't do this when "remcr" is true.
+ if ((reg->y_type == MLINE || i < reg->y_size - 1) && !remcr) {
cmdline_paste_str((char_u *)"\r", literally);
}
@@ -1409,8 +1404,9 @@ int op_delete(oparg_T *oap)
op_yank_reg(oap, false, reg, false);
}
- if(oap->regname == 0) {
+ if (oap->regname == 0) {
set_clipboard(0, reg);
+ yank_do_autocmd(oap, reg);
}
}
@@ -2309,6 +2305,8 @@ bool op_yank(oparg_T *oap, bool message)
yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK);
op_yank_reg(oap, message, reg, is_append_register(oap->regname));
set_clipboard(oap->regname, reg);
+ yank_do_autocmd(oap, reg);
+
return true;
}
@@ -2524,6 +2522,58 @@ static void yank_copy_line(yankreg_T *reg, struct block_def *bd, long y_idx)
*pnew = NUL;
}
+/// Execute autocommands for TextYankPost.
+///
+/// @param oap Operator arguments.
+/// @param reg The yank register used.
+static void yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
+ FUNC_ATTR_NONNULL_ALL
+{
+ static bool recursive = false;
+
+ if (recursive || !has_event(EVENT_TEXTYANKPOST)) {
+ // No autocommand was defined
+ // or we yanked from this autocommand.
+ return;
+ }
+
+ recursive = true;
+
+ // set v:event to a dictionary with information about the yank
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+
+ // the yanked text
+ list_T *list = list_alloc();
+ for (linenr_T i = 0; i < reg->y_size; i++) {
+ list_append_string(list, reg->y_array[i], -1);
+ }
+ list->lv_lock = VAR_FIXED;
+ dict_add_list(dict, "regcontents", list);
+
+ // the register type
+ char buf[NUMBUFLEN+2];
+ format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf));
+ dict_add_nr_str(dict, "regtype", 0, (char_u *)buf);
+
+ // name of requested register or the empty string for an unnamed operation.
+ buf[0] = (char)oap->regname;
+ buf[1] = NUL;
+ dict_add_nr_str(dict, "regname", 0, (char_u *)buf);
+
+ // kind of operation (yank/delete/change)
+ buf[0] = get_op_char(oap->op_type);
+ buf[1] = NUL;
+ dict_add_nr_str(dict, "operator", 0, (char_u *)buf);
+
+ dict_set_keys_readonly(dict);
+ textlock++;
+ apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, false, curbuf);
+ textlock--;
+ dict_clear(dict);
+
+ recursive = false;
+}
+
/*
* Put contents of register "regname" into the text.
@@ -4631,7 +4681,7 @@ theend:
* Used for getregtype()
* Returns MAUTO for error.
*/
-char_u get_reg_type(int regname, long *reglen)
+char_u get_reg_type(int regname, colnr_T *reg_width)
{
switch (regname) {
case '%': /* file name */
@@ -4654,13 +4704,45 @@ char_u get_reg_type(int regname, long *reglen)
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
if (reg->y_array != NULL) {
- if (reglen != NULL && reg->y_type == MBLOCK)
- *reglen = reg->y_width;
+ if (reg_width != NULL && reg->y_type == MBLOCK) {
+ *reg_width = reg->y_width;
+ }
return reg->y_type;
}
return MAUTO;
}
+/// Format the register type as a string.
+///
+/// @param reg_type The register type.
+/// @param reg_width The width, only used if "reg_type" is MBLOCK.
+/// @param[out] buf Buffer to store formatted string. The allocated size should
+/// be at least NUMBUFLEN+2 to always fit the value.
+/// @param buf_len The allocated size of the buffer.
+void format_reg_type(char_u reg_type, colnr_T reg_width,
+ char* buf, size_t buf_len)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(buf_len > 1);
+ switch (reg_type) {
+ case MLINE:
+ buf[0] = 'V';
+ buf[1] = NUL;
+ break;
+ case MCHAR:
+ buf[0] = 'v';
+ buf[1] = NUL;
+ break;
+ case MBLOCK:
+ snprintf(buf, buf_len, CTRL_V_STR "%" PRIdCOLNR, reg_width + 1);
+ break;
+ case MAUTO:
+ buf[0] = NUL;
+ break;
+ }
+}
+
+
/// When `flags` has `kGRegList` return a list with text `s`.
/// Otherwise just return `s`.
///
diff --git a/src/nvim/option.c b/src/nvim/option.c
index af7b272467..5efd71444a 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -6167,16 +6167,14 @@ int has_format_option(int x)
return vim_strchr(curbuf->b_p_fo, x) != NULL;
}
-/*
- * Return TRUE if "x" is present in 'shortmess' option, or
- * 'shortmess' contains 'a' and "x" is present in SHM_A.
- */
-int shortmess(int x)
+/// @returns true if "x" is present in 'shortmess' option, or
+/// 'shortmess' contains 'a' and "x" is present in SHM_ALL_ABBREVIATIONS.
+bool shortmess(int x)
{
return p_shm != NULL &&
- ( vim_strchr(p_shm, x) != NULL
- || (vim_strchr(p_shm, 'a') != NULL
- && vim_strchr((char_u *)SHM_A, x) != NULL));
+ (vim_strchr(p_shm, x) != NULL
+ || (vim_strchr(p_shm, 'a') != NULL
+ && vim_strchr((char_u *)SHM_ALL_ABBREVIATIONS, x) != NULL));
}
/*
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 10706a0753..8e74e5036e 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -151,26 +151,42 @@
#define COCU_ALL "nvic" /* flags for 'concealcursor' */
-/* characters for p_shm option: */
-#define SHM_RO 'r' /* readonly */
-#define SHM_MOD 'm' /* modified */
-#define SHM_FILE 'f' /* (file 1 of 2) */
-#define SHM_LAST 'i' /* last line incomplete */
-#define SHM_TEXT 'x' /* tx instead of textmode */
-#define SHM_LINES 'l' /* "L" instead of "lines" */
-#define SHM_NEW 'n' /* "[New]" instead of "[New file]" */
-#define SHM_WRI 'w' /* "[w]" instead of "written" */
-#define SHM_A "rmfixlnw" /* represented by 'a' flag */
-#define SHM_WRITE 'W' /* don't use "written" at all */
-#define SHM_TRUNC 't' /* trunctate file messages */
-#define SHM_TRUNCALL 'T' /* trunctate all messages */
-#define SHM_OVER 'o' /* overwrite file messages */
-#define SHM_OVERALL 'O' /* overwrite more messages */
-#define SHM_SEARCH 's' /* no search hit bottom messages */
-#define SHM_ATTENTION 'A' /* no ATTENTION messages */
-#define SHM_INTRO 'I' /* intro messages */
-#define SHM_COMPLETIONMENU 'c' // completion menu messages
-#define SHM_ALL "rmfixlnwaWtToOsAIc" /* all possible flags for 'shm' */
+/// characters for p_shm option:
+enum {
+ SHM_RO = 'r', ///< Readonly.
+ SHM_MOD = 'm', ///< Modified.
+ SHM_FILE = 'f', ///< (file 1 of 2)
+ SHM_LAST = 'i', ///< Last line incomplete.
+ SHM_TEXT = 'x', ///< Tx instead of textmode.
+ SHM_LINES = 'l', ///< "L" instead of "lines".
+ SHM_NEW = 'n', ///< "[New]" instead of "[New file]".
+ SHM_WRI = 'w', ///< "[w]" instead of "written".
+ SHM_ABBREVIATIONS = 'a', ///< Use abbreviations from #SHM_ALL_ABBREVIATIONS.
+ SHM_WRITE = 'W', ///< Don't use "written" at all.
+ SHM_TRUNC = 't', ///< Trunctate file messages.
+ SHM_TRUNCALL = 'T', ///< Trunctate all messages.
+ SHM_OVER = 'o', ///< Overwrite file messages.
+ SHM_OVERALL = 'O', ///< Overwrite more messages.
+ SHM_SEARCH = 's', ///< No search hit bottom messages.
+ SHM_ATTENTION = 'A', ///< No ATTENTION messages.
+ SHM_INTRO = 'I', ///< Intro messages.
+ SHM_COMPLETIONMENU = 'c', ///< Completion menu messages.
+ SHM_RECORDING = 'q', ///< Short recording message.
+ SHM_FILEINFO = 'F', ///< No file info messages.
+};
+/// Represented by 'a' flag.
+#define SHM_ALL_ABBREVIATIONS ((char_u[]) { \
+ SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI, \
+ 0, \
+})
+/// All possible flags for 'shm'.
+#define SHM_ALL ((char_u[]) { \
+ SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW, SHM_WRI, \
+ SHM_ABBREVIATIONS, SHM_WRITE, SHM_TRUNC, SHM_TRUNCALL, SHM_OVER, \
+ SHM_OVERALL, SHM_SEARCH, SHM_ATTENTION, SHM_INTRO, SHM_COMPLETIONMENU, \
+ SHM_RECORDING, SHM_FILEINFO, \
+ 0, \
+})
/* characters for p_go: */
#define GO_ASEL 'a' /* autoselect */
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 2e671653ed..34d8fde4f1 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -166,7 +166,7 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
// Glue together the given directory from $PATH with name and save into
// buf.
STRLCPY(buf, path, e - path + 1);
- append_path((char *) buf, (const char *) name, (int)buf_len);
+ append_path((char *) buf, (const char *) name, buf_len);
if (is_executable(buf)) {
// Check if the caller asked for a copy of the path.
diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c
index c9631a434c..81ceb919c4 100644
--- a/src/nvim/os/stdpaths.c
+++ b/src/nvim/os/stdpaths.c
@@ -22,9 +22,9 @@ static const char *xdg_env_vars[] = {
static const char *const xdg_defaults[] = {
#ifdef WIN32
// Windows
- [kXDGConfigHome] = "$LOCALAPPDATA\\nvim\\config",
- [kXDGDataHome] = "$LOCALAPPDATA\\nvim\\data",
- [kXDGCacheHome] = "$LOCALAPPDATA\\nvim\\cache",
+ [kXDGConfigHome] = "$LOCALAPPDATA",
+ [kXDGDataHome] = "$LOCALAPPDATA",
+ [kXDGCacheHome] = "$TEMP",
[kXDGRuntimeDir] = NULL,
[kXDGConfigDirs] = NULL,
[kXDGDataDirs] = NULL,
@@ -66,12 +66,21 @@ char *stdpaths_get_xdg_var(const XDGVarType idx)
/// @param[in] idx XDG directory to use.
///
/// @return [allocated] `{xdg_directory}/nvim`
+///
+/// In WIN32 get_xdg_home(kXDGDataHome) returns `{xdg_directory}/nvim-data` to
+/// avoid storing configuration and data files in the same path.
static char *get_xdg_home(const XDGVarType idx)
FUNC_ATTR_WARN_UNUSED_RESULT
{
char *dir = stdpaths_get_xdg_var(idx);
if (dir) {
+#if defined(WIN32)
+ dir = concat_fnames_realloc(dir,
+ (idx == kXDGDataHome ? "nvim-data" : "nvim"),
+ true);
+#else
dir = concat_fnames_realloc(dir, "nvim", true);
+#endif
}
return dir;
}
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 5cd93ab811..22a3f96cfa 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -268,16 +268,13 @@ char_u *shorten_dir(char_u *str)
*/
bool dir_of_file_exists(char_u *fname)
{
- char_u *p;
- int c;
- bool retval;
-
- p = path_tail_with_sep(fname);
- if (p == fname)
+ char_u *p = path_tail_with_sep(fname);
+ if (p == fname) {
return true;
- c = *p;
+ }
+ char_u c = *p;
*p = NUL;
- retval = os_isdir(fname);
+ bool retval = os_isdir(fname);
*p = c;
return retval;
}
@@ -539,15 +536,10 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
size_t wildoff, int flags, bool didstar)
FUNC_ATTR_NONNULL_ALL
{
- char_u *buf;
- char_u *p, *s, *e;
int start_len = gap->ga_len;
- char_u *pat;
- int starts_with_dot;
- int matches;
- int len;
+ size_t len;
bool starstar = false;
- static int stardepth = 0; /* depth for "**" expansion */
+ static int stardepth = 0; // depth for "**" expansion
/* Expanding "**" may take a long time, check for CTRL-C. */
if (stardepth > 0) {
@@ -558,16 +550,14 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
// Make room for file name. When doing encoding conversion the actual
// length may be quite a bit longer, thus use the maximum possible length.
- buf = xmalloc(MAXPATHL);
-
- /*
- * Find the first part in the path name that contains a wildcard.
- * When EW_ICASE is set every letter is considered to be a wildcard.
- * Copy it into "buf", including the preceding characters.
- */
- p = buf;
- s = buf;
- e = NULL;
+ char_u *buf = xmalloc(MAXPATHL);
+
+ // Find the first part in the path name that contains a wildcard.
+ // When EW_ICASE is set every letter is considered to be a wildcard.
+ // Copy it into "buf", including the preceding characters.
+ char_u *p = buf;
+ char_u *s = buf;
+ char_u *e = NULL;
const char_u *path_end = path;
while (*path_end != NUL) {
/* May ignore a wildcard that has a backslash before it; it will
@@ -588,7 +578,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
e = p;
}
if (has_mbyte) {
- len = (*mb_ptr2len)(path_end);
+ len = (size_t)(*mb_ptr2len)(path_end);
STRNCPY(p, path_end, len);
p += len;
path_end += len;
@@ -613,9 +603,9 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
if (p[0] == '*' && p[1] == '*')
starstar = true;
- /* convert the file pattern to a regexp pattern */
- starts_with_dot = (*s == '.');
- pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
+ // convert the file pattern to a regexp pattern
+ int starts_with_dot = (*s == '.');
+ char_u *pat = file_pat_to_reg_pat(s, e, NULL, false);
if (pat == NULL) {
xfree(buf);
return 0;
@@ -646,9 +636,9 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
if (!didstar && stardepth < 100 && starstar && e - s == 2
&& *path_end == '/') {
STRCPY(s, path_end + 1);
- ++stardepth;
- (void)do_path_expand(gap, buf, (int)(s - buf), flags, true);
- --stardepth;
+ stardepth++;
+ (void)do_path_expand(gap, buf, (size_t)(s - buf), flags, true);
+ stardepth--;
}
*s = NUL;
@@ -703,10 +693,11 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
xfree(buf);
vim_regfree(regmatch.regprog);
- matches = gap->ga_len - start_len;
- if (matches > 0)
+ size_t matches = (size_t)(gap->ga_len - start_len);
+ if (matches > 0) {
qsort(((char_u **)gap->ga_data) + start_len, matches,
- sizeof(char_u *), pstrcmp);
+ sizeof(char_u *), pstrcmp);
+ }
return matches;
}
@@ -736,27 +727,24 @@ static int find_previous_pathsep(char_u *path, char_u **psep)
*/
static bool is_unique(char_u *maybe_unique, garray_T *gap, int i)
{
- int candidate_len;
- int other_path_len;
- char_u **other_paths = (char_u **)gap->ga_data;
- char_u *rival;
+ char_u **other_paths = (char_u **)gap->ga_data;
for (int j = 0; j < gap->ga_len; j++) {
- if (j == i)
- continue; /* don't compare it with itself */
-
- candidate_len = (int)STRLEN(maybe_unique);
- other_path_len = (int)STRLEN(other_paths[j]);
- if (other_path_len < candidate_len)
- continue; /* it's different when it's shorter */
-
- rival = other_paths[j] + other_path_len - candidate_len;
+ if (j == i) {
+ continue; // don't compare it with itself
+ }
+ size_t candidate_len = STRLEN(maybe_unique);
+ size_t other_path_len = STRLEN(other_paths[j]);
+ if (other_path_len < candidate_len) {
+ continue; // it's different when it's shorter
+ }
+ char_u *rival = other_paths[j] + other_path_len - candidate_len;
if (fnamecmp(maybe_unique, rival) == 0
- && (rival == other_paths[j] || vim_ispathsep(*(rival - 1))))
- return false; /* match */
+ && (rival == other_paths[j] || vim_ispathsep(*(rival - 1)))) {
+ return false; // match
+ }
}
-
- return true; /* no match found */
+ return true; // no match found
}
/*
@@ -770,12 +758,8 @@ static bool is_unique(char_u *maybe_unique, garray_T *gap, int i)
*/
static void expand_path_option(char_u *curdir, garray_T *gap)
{
- char_u *path_option = *curbuf->b_p_path == NUL
- ? p_path : curbuf->b_p_path;
- char_u *buf;
- int len;
-
- buf = xmalloc(MAXPATHL);
+ char_u *path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
+ char_u *buf = xmalloc(MAXPATHL);
while (*path_option != NUL) {
copy_option_part(&path_option, buf, MAXPATHL, " ,");
@@ -787,26 +771,27 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
if (curbuf->b_ffname == NULL)
continue;
char_u *p = path_tail(curbuf->b_ffname);
- len = (int)(p - curbuf->b_ffname);
- if (len + (int)STRLEN(buf) >= MAXPATHL)
+ size_t len = (size_t)(p - curbuf->b_ffname);
+ if (len + STRLEN(buf) >= MAXPATHL) {
continue;
- if (buf[1] == NUL)
+ }
+ if (buf[1] == NUL) {
buf[len] = NUL;
- else
+ } else {
STRMOVE(buf + len, buf + 2);
+ }
memmove(buf, curbuf->b_ffname, len);
simplify_filename(buf);
- } else if (buf[0] == NUL)
- /* relative to current directory */
- STRCPY(buf, curdir);
- else if (path_with_url((char *)buf))
- /* URL can't be used here */
- continue;
- else if (!path_is_absolute_path(buf)) {
- /* Expand relative path to their full path equivalent */
- len = (int)STRLEN(curdir);
- if (len + (int)STRLEN(buf) + 3 > MAXPATHL)
+ } else if (buf[0] == NUL) {
+ STRCPY(buf, curdir); // relative to current directory
+ } else if (path_with_url((char *)buf)) {
+ continue; // URL can't be used here
+ } else if (!path_is_absolute_path(buf)) {
+ // Expand relative path to their full path equivalent
+ size_t len = STRLEN(curdir);
+ if (len + STRLEN(buf) + 3 > MAXPATHL) {
continue;
+ }
STRMOVE(buf + len + 1, buf);
STRCPY(buf, curdir);
buf[len] = PATHSEP;
@@ -860,31 +845,25 @@ static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
*/
static void uniquefy_paths(garray_T *gap, char_u *pattern)
{
- int len;
- char_u **fnames = (char_u **)gap->ga_data;
+ char_u **fnames = (char_u **)gap->ga_data;
bool sort_again = false;
- char_u *pat;
- char_u *file_pattern;
- char_u *curdir;
regmatch_T regmatch;
garray_T path_ga;
- char_u **in_curdir = NULL;
- char_u *short_name;
+ char_u **in_curdir = NULL;
+ char_u *short_name;
ga_remove_duplicate_strings(gap);
ga_init(&path_ga, (int)sizeof(char_u *), 1);
- /*
- * We need to prepend a '*' at the beginning of file_pattern so that the
- * regex matches anywhere in the path. FIXME: is this valid for all
- * possible patterns?
- */
- len = (int)STRLEN(pattern);
- file_pattern = xmalloc(len + 2);
+ // We need to prepend a '*' at the beginning of file_pattern so that the
+ // regex matches anywhere in the path. FIXME: is this valid for all
+ // possible patterns?
+ size_t len = STRLEN(pattern);
+ char_u *file_pattern = xmalloc(len + 2);
file_pattern[0] = '*';
file_pattern[1] = NUL;
STRCAT(file_pattern, pattern);
- pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, TRUE);
+ char_u *pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, true);
xfree(file_pattern);
if (pat == NULL)
return;
@@ -895,11 +874,11 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
if (regmatch.regprog == NULL)
return;
- curdir = xmalloc(MAXPATHL);
+ char_u *curdir = xmalloc(MAXPATHL);
os_dirname(curdir, MAXPATHL);
expand_path_option(curdir, &path_ga);
- in_curdir = xcalloc(gap->ga_len, sizeof(char_u *));
+ in_curdir = xcalloc((size_t)gap->ga_len, sizeof(char_u *));
for (int i = 0; i < gap->ga_len && !got_int; i++) {
char_u *path = fnames[i];
@@ -908,7 +887,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
char_u *pathsep_p;
char_u *path_cutoff;
- len = (int)STRLEN(path);
+ len = STRLEN(path);
is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0
&& curdir[dir_end - path] == NUL;
if (is_in_curdir)
@@ -1113,9 +1092,8 @@ static bool has_special_wildchar(char_u *p)
int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
char_u ***file, int flags)
{
- int i;
garray_T ga;
- char_u *p;
+ char_u *p;
static bool recursive = false;
int add_pat;
bool did_expand_in_path = false;
@@ -1140,11 +1118,11 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
* avoids starting the shell for each argument separately.
* For `=expr` do use the internal function.
*/
- for (i = 0; i < num_pat; i++) {
+ for (int i = 0; i < num_pat; i++) {
if (has_special_wildchar(pat[i])
- && !(vim_backtick(pat[i]) && pat[i][1] == '=')
- )
+ && !(vim_backtick(pat[i]) && pat[i][1] == '=')) {
return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
+ }
}
#endif
@@ -1155,7 +1133,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
*/
ga_init(&ga, (int)sizeof(char_u *), 30);
- for (i = 0; i < num_pat; ++i) {
+ for (int i = 0; i < num_pat; ++i) {
add_pat = -1;
p = pat[i];
@@ -1212,7 +1190,9 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
recursive = true;
did_expand_in_path = true;
} else {
- add_pat = path_expand(&ga, p, flags);
+ size_t tmp_add_pat = path_expand(&ga, p, flags);
+ assert(tmp_add_pat <= INT_MAX);
+ add_pat = (int)tmp_add_pat;
}
}
}
@@ -1261,14 +1241,12 @@ static int expand_backtick(
int flags /* EW_* flags */
)
{
- char_u *p;
- char_u *cmd;
- char_u *buffer;
+ char_u *p;
+ char_u *buffer;
int cnt = 0;
- int i;
- /* Create the command: lop off the backticks. */
- cmd = vim_strnsave(pat + 1, (int)STRLEN(pat) - 2);
+ // Create the command: lop off the backticks.
+ char_u *cmd = vim_strnsave(pat + 1, STRLEN(pat) - 2);
if (*cmd == '=') /* `={expr}`: Expand expression */
buffer = eval_to_string(cmd + 1, &p, TRUE);
@@ -1288,7 +1266,7 @@ static int expand_backtick(
++p;
/* add an entry if it is not empty */
if (p > cmd) {
- i = *p;
+ char_u i = *p;
*p = NUL;
addfile(gap, cmd, flags);
*p = i;
@@ -1541,9 +1519,8 @@ find_file_name_in_path (
char_u *rel_fname /* file we are searching relative to */
)
{
- char_u *file_name;
- int c;
- char_u *tofree = NULL;
+ char_u *file_name;
+ char_u *tofree = NULL;
if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
tofree = eval_includeexpr(ptr, len);
@@ -1554,8 +1531,8 @@ find_file_name_in_path (
}
if (options & FNAME_EXP) {
- file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS,
- TRUE, rel_fname);
+ file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, true,
+ rel_fname);
/*
* If the file could not be found in a normal way, try applying
@@ -1572,7 +1549,7 @@ find_file_name_in_path (
}
}
if (file_name == NULL && (options & FNAME_MESS)) {
- c = ptr[len];
+ char_u c = ptr[len];
ptr[len] = NUL;
EMSG2(_("E447: Can't find file \"%s\" in path"), ptr);
ptr[len] = c;
@@ -1631,7 +1608,7 @@ bool vim_isAbsName(char_u *name)
/// @param force is a flag to force expanding even if the path is absolute
///
/// @return FAIL for failure, OK otherwise
-int vim_FullName(const char *fname, char *buf, int len, bool force)
+int vim_FullName(const char *fname, char *buf, size_t len, bool force)
FUNC_ATTR_NONNULL_ARG(2)
{
int retval = OK;
@@ -2017,14 +1994,12 @@ int expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file,
*/
int match_suffix(char_u *fname)
{
- int fnamelen, setsuflen;
- char_u *setsuf;
-#define MAXSUFLEN 30 /* maximum length of a file suffix */
+#define MAXSUFLEN 30 // maximum length of a file suffix
char_u suf_buf[MAXSUFLEN];
- fnamelen = (int)STRLEN(fname);
- setsuflen = 0;
- for (setsuf = p_su; *setsuf; ) {
+ size_t fnamelen = STRLEN(fname);
+ size_t setsuflen = 0;
+ for (char_u *setsuf = p_su; *setsuf; ) {
setsuflen = copy_option_part(&setsuf, suf_buf, MAXSUFLEN, ".,");
if (setsuflen == 0) {
char_u *tail = path_tail(fname);
@@ -2035,10 +2010,10 @@ int match_suffix(char_u *fname)
break;
}
} else {
- if (fnamelen >= setsuflen
- && fnamencmp(suf_buf, fname + fnamelen - setsuflen,
- (size_t)setsuflen) == 0)
+ if (fnamelen >= setsuflen &&
+ fnamencmp(suf_buf, fname + fnamelen - setsuflen, setsuflen) == 0) {
break;
+ }
setsuflen = 0;
}
}
@@ -2049,7 +2024,7 @@ int match_suffix(char_u *fname)
///
/// @param directory Directory name, relative to current directory.
/// @return `FAIL` for failure, `OK` for success.
-int path_full_dir_name(char *directory, char *buffer, int len)
+int path_full_dir_name(char *directory, char *buffer, size_t len)
{
int SUCCESS = 0;
int retval = OK;
@@ -2091,10 +2066,10 @@ int path_full_dir_name(char *directory, char *buffer, int len)
// Append to_append to path with a slash in between.
// Append to_append to path with a slash in between.
-int append_path(char *path, const char *to_append, int max_len)
+int append_path(char *path, const char *to_append, size_t max_len)
{
- int current_length = STRLEN(path);
- int to_append_length = STRLEN(to_append);
+ size_t current_length = strlen(path);
+ size_t to_append_length = strlen(to_append);
// Do not append empty strings.
if (to_append_length == 0) {
@@ -2129,12 +2104,14 @@ int append_path(char *path, const char *to_append, int max_len)
/// Expand a given file to its absolute path.
///
-/// @param fname The filename which should be expanded.
-/// @param buf Buffer to store the absolute path of `fname`.
-/// @param len Length of `buf`.
-/// @param force Also expand when `fname` is already absolute.
-/// @return `FAIL` for failure, `OK` for success.
-static int path_get_absolute_path(const char_u *fname, char_u *buf, int len, int force)
+/// @param fname filename which should be expanded.
+/// @param buf buffer to store the absolute path of "fname".
+/// @param len length of "buf".
+/// @param force also expand when "fname" is already absolute.
+///
+/// @return FAIL for failure, OK for success.
+static int path_get_absolute_path(const char_u *fname, char_u *buf,
+ size_t len, int force)
{
char_u *p;
*buf = NUL;
diff --git a/src/nvim/pos.h b/src/nvim/pos.h
index 7071df51e8..864f3fe866 100644
--- a/src/nvim/pos.h
+++ b/src/nvim/pos.h
@@ -2,7 +2,11 @@
#define NVIM_POS_H
typedef long linenr_T; // line number type
-typedef int colnr_T; // column number type
+
+/// Column number type
+typedef int colnr_T;
+/// Format used to print values which have colnr_T type
+#define PRIdCOLNR "d"
#define MAXLNUM 0x7fffffff // maximum (invalid) line number
#define MAXCOL 0x7fffffff // maximum column number, 31 bits
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index f3abf864fb..3bc6d46dd9 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -200,9 +200,8 @@ qf_init_ext (
char_u *pattern;
char_u *fmtstr = NULL;
int col = 0;
- char_u use_viscol = FALSE;
- int type = 0;
- int valid;
+ bool use_viscol = false;
+ char_u type = 0;
linenr_T buflnum = lnumfirst;
long lnum = 0L;
int enr = 0;
@@ -220,16 +219,16 @@ qf_init_ext (
int i;
int round;
int idx = 0;
- int multiline = FALSE;
- int multiignore = FALSE;
- int multiscan = FALSE;
- int retval = -1; /* default: return error flag */
- char_u *directory = NULL;
- char_u *currfile = NULL;
- char_u *tail = NULL;
- char_u *p_str = NULL;
- listitem_T *p_li = NULL;
- struct dir_stack_T *file_stack = NULL;
+ bool multiline = false;
+ bool multiignore = false;
+ bool multiscan = false;
+ int retval = -1; // default: return error flag
+ char_u *directory = NULL;
+ char_u *currfile = NULL;
+ char_u *tail = NULL;
+ char_u *p_str = NULL;
+ listitem_T *p_li = NULL;
+ struct dir_stack_T *file_stack = NULL;
regmatch_T regmatch;
static struct fmtpattern {
char_u convchar;
@@ -278,15 +277,16 @@ qf_init_ext (
/*
* Get some space to modify the format string into.
*/
- i = 3 * FMT_PATTERNS + 4 * (int)STRLEN(efm);
- for (round = FMT_PATTERNS; round > 0; )
- i += (int)STRLEN(fmt_pat[--round].pattern);
+ size_t fmtstr_size = 3 * FMT_PATTERNS + 4 * STRLEN(efm);
+ for (round = FMT_PATTERNS; round > 0; ) {
+ fmtstr_size += STRLEN(fmt_pat[--round].pattern);
+ }
#ifdef COLON_IN_FILENAME
- i += 12; /* "%f" can become twelve chars longer */
+ fmtstr_size += 12; // "%f" can become twelve chars longer
#else
- i += 2; /* "%f" can become two chars longer */
+ fmtstr_size += 2; // "%f" can become two chars longer
#endif
- fmtstr = xmalloc(i);
+ fmtstr = xmalloc(fmtstr_size);
while (efm[0] != NUL) {
/*
@@ -530,11 +530,9 @@ qf_init_ext (
fmt_start = NULL;
}
- /*
- * Try to match each part of 'errorformat' until we find a complete
- * match or no match.
- */
- valid = TRUE;
+ // Try to match each part of 'errorformat' until we find a complete
+ // match or no match.
+ bool valid = true;
restofline:
for (; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) {
idx = fmt_ptr->prefix;
@@ -546,7 +544,7 @@ restofline:
errmsg[0] = NUL;
lnum = 0;
col = 0;
- use_viscol = FALSE;
+ use_viscol = false;
enr = -1;
type = 0;
tail = NULL;
@@ -555,25 +553,23 @@ restofline:
int r = vim_regexec(&regmatch, IObuff, (colnr_T)0);
fmt_ptr->prog = regmatch.regprog;
if (r) {
- if ((idx == 'C' || idx == 'Z') && !multiline)
+ if ((idx == 'C' || idx == 'Z') && !multiline) {
continue;
- if (vim_strchr((char_u *)"EWI", idx) != NULL)
- type = idx;
- else
+ }
+ if (vim_strchr((char_u *)"EWI", idx) != NULL) {
+ type = (char_u)idx;
+ } else {
type = 0;
- /*
- * Extract error message data from matched line.
- * We check for an actual submatch, because "\[" and "\]" in
- * the 'errorformat' may cause the wrong submatch to be used.
- */
- if ((i = (int)fmt_ptr->addr[0]) > 0) { /* %f */
- int c;
-
- if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+ }
+ // Extract error message data from matched line.
+ // We check for an actual submatch, because "\[" and "\]" in
+ // the 'errorformat' may cause the wrong submatch to be used.
+ if ((i = (int)fmt_ptr->addr[0]) > 0) { // %f
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
continue;
-
- /* Expand ~/file and $HOME/file to full path. */
- c = *regmatch.endp[i];
+ }
+ // Expand ~/file and $HOME/file to full path.
+ char_u c = *regmatch.endp[i];
*regmatch.endp[i] = NUL;
expand_env(regmatch.startp[i], namebuf, CMDBUFFSIZE);
*regmatch.endp[i] = c;
@@ -629,14 +625,14 @@ restofline:
col -= col % 8;
}
}
- ++col;
- use_viscol = TRUE;
+ col++;
+ use_viscol = true;
}
if ((i = (int)fmt_ptr->addr[8]) > 0) { /* %v */
if (regmatch.startp[i] == NULL)
continue;
col = (int)atol((char *)regmatch.startp[i]);
- use_viscol = TRUE;
+ use_viscol = true;
}
if ((i = (int)fmt_ptr->addr[9]) > 0) { /* %s */
if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
@@ -653,7 +649,7 @@ restofline:
break;
}
}
- multiscan = FALSE;
+ multiscan = false;
if (fmt_ptr == NULL || idx == 'D' || idx == 'X') {
if (fmt_ptr != NULL) {
@@ -667,20 +663,21 @@ restofline:
} else if (idx == 'X') /* leave directory */
directory = qf_pop_dir(&dir_stack);
}
- namebuf[0] = NUL; /* no match found, remove file name */
- lnum = 0; /* don't jump to this line */
- valid = FALSE;
- STRCPY(errmsg, IObuff); /* copy whole line to error message */
- if (fmt_ptr == NULL)
- multiline = multiignore = FALSE;
+ namebuf[0] = NUL; // no match found, remove file name
+ lnum = 0; // don't jump to this line
+ valid = false;
+ STRCPY(errmsg, IObuff); // copy whole line to error message
+ if (fmt_ptr == NULL) {
+ multiline = multiignore = false;
+ }
} else if (fmt_ptr != NULL) {
/* honor %> item */
if (fmt_ptr->conthere)
fmt_start = fmt_ptr;
if (vim_strchr((char_u *)"AEWI", idx) != NULL) {
- multiline = TRUE; /* start of a multi-line message */
- multiignore = FALSE; /* reset continuation */
+ multiline = true; // start of a multi-line message
+ multiignore = false; // reset continuation
} else if (vim_strchr((char_u *)"CZ", idx)
!= NULL) { /* continuation of multi-line msg */
if (qfprev == NULL)
@@ -702,15 +699,17 @@ restofline:
qfprev->qf_viscol = use_viscol;
if (!qfprev->qf_fnum)
qfprev->qf_fnum = qf_get_fnum(directory,
- *namebuf || directory ? namebuf
- : currfile && valid ? currfile : 0);
- if (idx == 'Z')
- multiline = multiignore = FALSE;
+ *namebuf
+ || directory ? namebuf : currfile
+ && valid ? currfile : 0);
+ if (idx == 'Z') {
+ multiline = multiignore = false;
+ }
line_breakcheck();
continue;
} else if (vim_strchr((char_u *)"OPQ", idx) != NULL) {
- /* global file names */
- valid = FALSE;
+ // global file names
+ valid = false;
if (*namebuf == NUL || os_file_exists(namebuf)) {
if (*namebuf && idx == 'P')
currfile = qf_push_dir(namebuf, &file_stack);
@@ -719,14 +718,15 @@ restofline:
*namebuf = NUL;
if (tail && *tail) {
STRMOVE(IObuff, skipwhite(tail));
- multiscan = TRUE;
+ multiscan = true;
goto restofline;
}
}
}
- if (fmt_ptr->flags == '-') { /* generally exclude this line */
- if (multiline)
- multiignore = TRUE; /* also exclude continuation lines */
+ if (fmt_ptr->flags == '-') { // generally exclude this line
+ if (multiline) {
+ multiignore = true; // also exclude continuation lines
+ }
continue;
}
}
@@ -867,26 +867,27 @@ void qf_free_all(win_T *wp)
qf_free(qi, i);
}
-/*
- * Add an entry to the end of the list of errors.
- * Returns OK or FAIL.
- */
-static int
-qf_add_entry (
- qf_info_T *qi, /* quickfix list */
- qfline_T **prevp, /* nonnull pointer (to previously added entry or NULL) */
- char_u *dir, /* optional directory name */
- char_u *fname, /* file name or NULL */
- int bufnum, /* buffer number or zero */
- char_u *mesg, /* message */
- long lnum, /* line number */
- int col, /* column */
- int vis_col, /* using visual column */
- char_u *pattern, /* search pattern */
- int nr, /* error number */
- int type, /* type character */
- int valid /* valid entry */
-)
+/// Add an entry to the end of the list of errors.
+///
+/// @param qi quickfix list
+/// @param prevp nonnull pointer (to previously added entry or NULL)
+/// @param dir optional directory name
+/// @param fname file name or NULL
+/// @param bufnum buffer number or zero
+/// @param mesg message
+/// @param lnum line number
+/// @param col column
+/// @param vis_col using visual column
+/// @param pattern search pattern
+/// @param nr error number
+/// @param type type character
+/// @param valid valid entry
+///
+/// @returns OK or FAIL.
+static int qf_add_entry(qf_info_T *qi, qfline_T **prevp, char_u *dir,
+ char_u *fname, int bufnum, char_u *mesg, long lnum,
+ int col, char_u vis_col, char_u *pattern, int nr,
+ char_u type, char_u valid)
{
qfline_T *qfp = xmalloc(sizeof(qfline_T));
@@ -1657,12 +1658,13 @@ win_found:
* flag is present in 'shortmess'; But when not jumping, print the
* whole message. */
i = msg_scroll;
- if (curbuf == old_curbuf && curwin->w_cursor.lnum == old_lnum)
- msg_scroll = TRUE;
- else if (!msg_scrolled && shortmess(SHM_OVERALL))
- msg_scroll = FALSE;
- msg_attr_keep(IObuff, 0, TRUE);
- msg_scroll = i;
+ if (curbuf == old_curbuf && curwin->w_cursor.lnum == old_lnum) {
+ msg_scroll = true;
+ } else if (!msg_scrolled && shortmess(SHM_OVERALL)) {
+ msg_scroll = false;
+ }
+ msg_attr_keep(IObuff, 0, true);
+ msg_scroll = (int)i;
}
} else {
if (opened_window)
@@ -1827,10 +1829,12 @@ void qf_age(exarg_T *eap)
}
}
- if (eap->addr_count != 0)
- count = eap->line2;
- else
+ if (eap->addr_count != 0) {
+ assert(eap->line2 <= INT_MAX);
+ count = (int)eap->line2;
+ } else {
count = 1;
+ }
while (count--) {
if (eap->cmdidx == CMD_colder || eap->cmdidx == CMD_lolder) {
if (qi->qf_curlist == 0) {
@@ -1882,6 +1886,8 @@ static void qf_free(qf_info_T *qi, int idx)
--qi->qf_lists[idx].qf_count;
}
xfree(qi->qf_lists[idx].qf_title);
+ qi->qf_lists[idx].qf_start = NULL;
+ qi->qf_lists[idx].qf_ptr = NULL;
qi->qf_lists[idx].qf_title = NULL;
qi->qf_lists[idx].qf_index = 0;
}
@@ -1948,7 +1954,7 @@ static char_u *qf_types(int c, int nr)
p = (char_u *)"";
else {
cc[0] = ' ';
- cc[1] = c;
+ cc[1] = (char_u)c;
cc[2] = NUL;
p = cc;
}
@@ -2036,12 +2042,13 @@ void ex_copen(exarg_T *eap)
}
}
- if (eap->addr_count != 0)
- height = eap->line2;
- else
+ if (eap->addr_count != 0) {
+ assert(eap->line2 <= INT_MAX);
+ height = (int)eap->line2;
+ } else {
height = QF_WINHEIGHT;
-
- reset_VIsual_and_resel(); /* stop Visual mode */
+ }
+ reset_VIsual_and_resel(); // stop Visual mode
/*
* Find existing quickfix window, or open a new one.
@@ -2299,13 +2306,15 @@ static void qf_fill_buffer(qf_info_T *qi)
if (qfp->qf_fnum != 0
&& (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL
&& errbuf->b_fname != NULL) {
- if (qfp->qf_type == 1) /* :helpgrep */
- STRCPY(IObuff, path_tail(errbuf->b_fname));
- else
- STRCPY(IObuff, errbuf->b_fname);
+ if (qfp->qf_type == 1) { // :helpgrep
+ STRLCPY(IObuff, path_tail(errbuf->b_fname), sizeof(IObuff));
+ } else {
+ STRLCPY(IObuff, errbuf->b_fname, sizeof(IObuff));
+ }
len = (int)STRLEN(IObuff);
- } else
+ } else {
len = 0;
+ }
IObuff[len++] = '|';
if (qfp->qf_lnum > 0) {
@@ -2432,7 +2441,7 @@ void ex_make(exarg_T *eap)
{
char_u *fname;
char_u *cmd;
- unsigned len;
+ size_t len;
win_T *wp = NULL;
qf_info_T *qi = &ql_info;
int res;
@@ -2473,9 +2482,10 @@ void ex_make(exarg_T *eap)
/*
* If 'shellpipe' empty: don't redirect to 'errorfile'.
*/
- len = (unsigned)STRLEN(p_shq) * 2 + (unsigned)STRLEN(eap->arg) + 1;
- if (*p_sp != NUL)
- len += (unsigned)STRLEN(p_sp) + (unsigned)STRLEN(fname) + 3;
+ len = STRLEN(p_shq) * 2 + STRLEN(eap->arg) + 1;
+ if (*p_sp != NUL) {
+ len += STRLEN(p_sp) + STRLEN(fname) + 3;
+ }
cmd = xmalloc(len);
sprintf((char *)cmd, "%s%s%s", (char *)p_shq, (char *)eap->arg,
(char *)p_shq);
@@ -2546,11 +2556,11 @@ static char_u *get_mef_name(void)
/* Keep trying until the name doesn't exist yet. */
for (;; ) {
- if (start == -1)
- start = os_get_pid();
- else
+ if (start == -1) {
+ start = (int)os_get_pid();
+ } else {
off += 19;
-
+ }
name = xmalloc(STRLEN(p_mef) + 30);
STRCPY(name, p_mef);
sprintf((char *)name + (p - p_mef), "%d%d", start, off);
@@ -2897,7 +2907,7 @@ void ex_vimgrep(exarg_T *eap)
int found_match;
buf_T *first_match_buf = NULL;
time_t seconds = 0;
- int save_mls;
+ long save_mls;
char_u *save_ei = NULL;
aco_save_T aco;
int flags = 0;
@@ -3454,18 +3464,12 @@ int get_errorlist(win_T *wp, list_T *list)
*/
int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
{
- listitem_T *li;
- dict_T *d;
- char_u *filename, *pattern, *text, *type;
- int bufnum;
- long lnum;
- int col, nr;
- int vcol;
- qfline_T *prevp = NULL;
- int valid, status;
+ listitem_T *li;
+ dict_T *d;
+ qfline_T *prevp = NULL;
int retval = OK;
- qf_info_T *qi = &ql_info;
- int did_bufnr_emsg = FALSE;
+ qf_info_T *qi = &ql_info;
+ bool did_bufnr_emsg = false;
if (wp != NULL) {
qi = ll_get_or_alloc_list(wp);
@@ -3492,21 +3496,22 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
if (d == NULL)
continue;
- filename = get_dict_string(d, (char_u *)"filename", TRUE);
- bufnum = get_dict_number(d, (char_u *)"bufnr");
- lnum = get_dict_number(d, (char_u *)"lnum");
- col = get_dict_number(d, (char_u *)"col");
- vcol = get_dict_number(d, (char_u *)"vcol");
- nr = get_dict_number(d, (char_u *)"nr");
- type = get_dict_string(d, (char_u *)"type", TRUE);
- pattern = get_dict_string(d, (char_u *)"pattern", TRUE);
- text = get_dict_string(d, (char_u *)"text", TRUE);
- if (text == NULL)
+ char_u *filename = get_dict_string(d, (char_u *)"filename", true);
+ int bufnum = (int)get_dict_number(d, (char_u *)"bufnr");
+ long lnum = get_dict_number(d, (char_u *)"lnum");
+ int col = (int)get_dict_number(d, (char_u *)"col");
+ char_u vcol = (char_u)get_dict_number(d, (char_u *)"vcol");
+ int nr = (int)get_dict_number(d, (char_u *)"nr");
+ char_u *type = get_dict_string(d, (char_u *)"type", true);
+ char_u *pattern = get_dict_string(d, (char_u *)"pattern", true);
+ char_u *text = get_dict_string(d, (char_u *)"text", true);
+ if (text == NULL) {
text = vim_strsave((char_u *)"");
-
- valid = TRUE;
- if ((filename == NULL && bufnum == 0) || (lnum == 0 && pattern == NULL))
- valid = FALSE;
+ }
+ bool valid = true;
+ if ((filename == NULL && bufnum == 0) || (lnum == 0 && pattern == NULL)) {
+ valid = false;
+ }
/* Mark entries with non-existing buffer number as not valid. Give the
* error message only once. */
@@ -3515,22 +3520,23 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
did_bufnr_emsg = TRUE;
EMSGN(_("E92: Buffer %" PRId64 " not found"), bufnum);
}
- valid = FALSE;
+ valid = false;
bufnum = 0;
}
- status = qf_add_entry(qi, &prevp,
- NULL, /* dir */
- filename,
- bufnum,
- text,
- lnum,
- col,
- vcol, /* vis_col */
- pattern, /* search pattern */
- nr,
- type == NULL ? NUL : *type,
- valid);
+ int status = qf_add_entry(qi,
+ &prevp,
+ NULL, // dir
+ filename,
+ bufnum,
+ text,
+ lnum,
+ col,
+ vcol, // vis_col
+ pattern, // search pattern
+ nr,
+ (char_u)(type == NULL ? NUL : *type),
+ valid);
xfree(filename);
xfree(pattern);
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index cd440fe8dc..1cc270023c 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -6780,8 +6780,8 @@ int showmode(void)
if (Recording
&& edit_submode == NULL /* otherwise it gets too long */
) {
- MSG_PUTS_ATTR(_("recording"), attr);
- need_clear = TRUE;
+ recording_mode(attr);
+ need_clear = true;
}
mode_displayed = TRUE;
@@ -6820,26 +6820,33 @@ static void msg_pos_mode(void)
msg_row = Rows - 1;
}
-/*
- * Delete mode message. Used when ESC is typed which is expected to end
- * Insert mode (but Insert mode didn't end yet!).
- * Caller should check "mode_displayed".
- */
-void unshowmode(int force)
+/// Delete mode message. Used when ESC is typed which is expected to end
+/// Insert mode (but Insert mode didn't end yet!).
+/// Caller should check "mode_displayed".
+void unshowmode(bool force)
{
- /*
- * Don't delete it right now, when not redrawing or inside a mapping.
- */
- if (!redrawing() || (!force && char_avail() && !KeyTyped))
- redraw_cmdline = TRUE; /* delete mode later */
- else {
+ // Don't delete it right now, when not redrawing or inside a mapping.
+ if (!redrawing() || (!force && char_avail() && !KeyTyped)) {
+ redraw_cmdline = true; // delete mode later
+ } else {
msg_pos_mode();
- if (Recording)
- MSG_PUTS_ATTR(_("recording"), hl_attr(HLF_CM));
+ if (Recording) {
+ recording_mode(hl_attr(HLF_CM));
+ }
msg_clr_eos();
}
}
+static void recording_mode(int attr)
+{
+ MSG_PUTS_ATTR(_("recording"), attr);
+ if (!shortmess(SHM_RECORDING)) {
+ char_u s[4];
+ vim_snprintf((char *)s, ARRAY_SIZE(s), " @%c", Recording);
+ MSG_PUTS_ATTR(s, attr);
+ }
+}
+
/*
* Draw the tab pages line at the top of the Vim window.
*/
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 478fa973a1..26f0a6c94b 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -5533,25 +5533,29 @@ char_u *get_syntax_name(expand_T *xp, int idx)
}
-/*
- * Function called for expression evaluation: get syntax ID at file position.
- */
-int
-syn_get_id (
+// Function called for expression evaluation: get syntax ID at file position.
+int syn_get_id(
win_T *wp,
long lnum,
colnr_T col,
- int trans, /* remove transparency */
- bool *spellp, /* return: can do spell checking */
- int keep_state /* keep state of char at "col" */
+ int trans, // remove transparency
+ bool *spellp, // return: can do spell checking
+ int keep_state // keep state of char at "col"
)
{
- /* When the position is not after the current position and in the same
- * line of the same buffer, need to restart parsing. */
+ // When the position is not after the current position and in the same
+ // line of the same buffer, need to restart parsing.
if (wp->w_buffer != syn_buf
|| lnum != current_lnum
- || col < current_col)
+ || col < current_col) {
syntax_start(wp, lnum);
+ } else if (wp->w_buffer == syn_buf
+ && lnum == current_lnum
+ && col > current_col) {
+ // next_match may not be correct when moving around, e.g. with the
+ // "skip" expression in searchpair()
+ next_match_idx = -1;
+ }
(void)get_syntax_attr(col, spellp, keep_state);
@@ -6391,7 +6395,7 @@ do_highlight (
HL_TABLE()[idx].sg_cterm_bg = color + 1;
if (is_normal_group) {
cterm_normal_bg_color = color + 1;
- {
+ if (!ui_rgb_attached()) {
must_redraw = CLEAR;
if (color >= 0) {
if (t_colors < 16)
diff --git a/src/nvim/tempfile.c b/src/nvim/tempfile.c
index a218c03fdb..afe926b2ef 100644
--- a/src/nvim/tempfile.c
+++ b/src/nvim/tempfile.c
@@ -32,8 +32,9 @@ static void vim_maketempdir(void)
char_u path[TEMP_FILE_PATH_MAXLEN];
for (size_t i = 0; i < ARRAY_SIZE(temp_dirs); ++i) {
// Expand environment variables, leave room for "/nvimXXXXXX/999999999"
+ // Skip the directory check if the expansion fails.
expand_env((char_u *)temp_dirs[i], template, TEMP_FILE_PATH_MAXLEN - 22);
- if (!os_isdir(template)) { // directory doesn't exist
+ if (template[0] == '$' || !os_isdir(template)) {
continue;
}
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 42fd81f643..63a7e20880 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -411,6 +411,10 @@ static int terminal_execute(VimState *state, int key)
apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
break;
+ // Temporary fix until paste events gets implemented
+ case K_PASTE:
+ break;
+
case K_LEFTMOUSE:
case K_LEFTDRAG:
case K_LEFTRELEASE:
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 63ca4cf6c4..ec236e72b4 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -32,7 +32,6 @@ SCRIPTS := \
test69.out \
test73.out \
test79.out \
- test88.out \
test_listlbr.out \
test_breakindent.out \
test_close_count.out \
diff --git a/src/nvim/testdir/test88.in b/src/nvim/testdir/test88.in
deleted file mode 100644
index 9e43f703e9..0000000000
--- a/src/nvim/testdir/test88.in
+++ /dev/null
@@ -1,99 +0,0 @@
-vim: set ft=vim
-
-Tests for correct display (cursor column position) with +conceal and
-tabulators.
-
-STARTTEST
-:so small.vim
-:if !has('conceal')
- e! test.ok
- wq! test.out
-:endif
-:" Conceal settings.
-:set conceallevel=2
-:set concealcursor=nc
-:syntax match test /|/ conceal
-:" Save current cursor position. Only works in <expr> mode, can't be used
-:" with :normal because it moves the cursor to the command line. Thanks to ZyX
-:" <zyx.vim@gmail.com> for the idea to use an <expr> mapping.
-:let positions = []
-:nnoremap <expr> GG ":let positions += ['".screenrow().":".screencol()."']\n"
-:" Start test.
-/^start:
-:normal ztj
-GGk
-:" We should end up in the same column when running these commands on the two
-:" lines.
-:normal ft
-GGk
-:normal $
-GGk
-:normal 0j
-GGk
-:normal ft
-GGk
-:normal $
-GGk
-:normal 0j0j
-GGk
-:" Same for next test block.
-:normal ft
-GGk
-:normal $
-GGk
-:normal 0j
-GGk
-:normal ft
-GGk
-:normal $
-GGk
-:normal 0j0j
-GGk
-:" And check W with multiple tabs and conceals in a line.
-:normal W
-GGk
-:normal W
-GGk
-:normal W
-GGk
-:normal $
-GGk
-:normal 0j
-GGk
-:normal W
-GGk
-:normal W
-GGk
-:normal W
-GGk
-:normal $
-GGk
-:set lbr
-:normal $
-GGk
-:set list listchars=tab:>-
-:normal 0
-GGk
-:normal W
-GGk
-:normal W
-GGk
-:normal W
-GGk
-:normal $
-GGk
-:" Display result.
-:call append('$', 'end:')
-:call append('$', positions)
-:/^end/,$wq! test.out
-ENDTEST
-
-start:
-.concealed. text
-|concealed| text
-
- .concealed. text
- |concealed| text
-
-.a. .b. .c. .d.
-|a| |b| |c| |d|
diff --git a/src/nvim/testdir/test88.ok b/src/nvim/testdir/test88.ok
deleted file mode 100644
index 12949f274a..0000000000
--- a/src/nvim/testdir/test88.ok
+++ /dev/null
@@ -1,29 +0,0 @@
-end:
-2:1
-2:17
-2:20
-3:1
-3:17
-3:20
-5:8
-5:25
-5:28
-6:8
-6:25
-6:28
-8:1
-8:9
-8:17
-8:25
-8:27
-9:1
-9:9
-9:17
-9:25
-9:26
-9:26
-9:1
-9:9
-9:17
-9:25
-9:26
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 4a8a24d79d..7d9b2c7c3b 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -1782,7 +1782,13 @@ void undo_time(long step, int sec, int file, int absolute)
/* "target" is the node below which we want to be.
* Init "closest" to a value we can't reach. */
if (absolute) {
- target = step;
+ if (step == 0) {
+ // target 0 does not exist, got to 1 and above it.
+ target = 1;
+ above = true;
+ } else {
+ target = step;
+ }
closest = -1;
} else {
/* When doing computations with time_t subtract starttime, because
diff --git a/src/nvim/version.c b/src/nvim/version.c
index efd3c230a7..ebf21d162f 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -69,6 +69,14 @@ static char *features[] = {
// clang-format off
static int included_patches[] = {
+ 1654,
+ 1652,
+ 1643,
+ 1641,
+ 1574,
+ 1570,
+ 1511,
+ 1425,
1366,
// 1219 NA
@@ -149,7 +157,7 @@ static int included_patches[] = {
// 1144 NA
// 1143,
// 1142,
- // 1141,
+ 1141,
// 1140,
// 1139 NA
// 1138 NA
@@ -178,7 +186,7 @@ static int included_patches[] = {
// 1115 NA
// 1114,
// 1113,
- // 1112,
+ 1112,
// 1111,
// 1110,
// 1109 NA
@@ -297,7 +305,7 @@ static int included_patches[] = {
// 996 NA
// 995 NA
// 994 NA
- // 993,
+ // 993 NA
// 992 NA
991,
// 990 NA
@@ -316,12 +324,12 @@ static int included_patches[] = {
977,
// 976 NA
975,
- // 974,
- // 973,
+ 974,
+ 973,
972,
// 971 NA
// 970 NA
- // 969,
+ // 969 NA
// 968 NA
// 967 NA
// 966 NA
@@ -329,25 +337,25 @@ static int included_patches[] = {
// 964 NA
963,
// 962 NA
- // 961,
+ 961,
// 960 NA
// 959 NA
- // 958,
+ 958,
// 957,
- // 956,
+ // 956 NA
955,
// 954 NA
953,
- // 952,
+ 952,
// 951,
950,
949,
// 948 NA
- // 947,
+ // 947 NA
946,
945,
944,
- // 943,
+ // 943 NA
// 942,
// 941,
// 940 NA
@@ -365,7 +373,7 @@ static int included_patches[] = {
// 928 NA
// 927 NA
926,
- // 925,
+ 925,
// 924 NA
// 923 NA
922,
@@ -376,17 +384,17 @@ static int included_patches[] = {
// 917 NA
916,
915,
- // 914,
+ // 914 NA
// 913 NA
912,
// 911 NA
// 910 NA
- // 909,
+ // 909 NA
// 908 NA
// 907 NA
// 906 NA
- // 905,
- // 904,
+ // 905 NA
+ // 904 NA
903,
// 902 NA
901,
@@ -398,7 +406,7 @@ static int included_patches[] = {
895,
// 894 NA
893,
- // 892,
+ // 892 NA
891,
// 890 NA
// 889,
@@ -433,7 +441,7 @@ static int included_patches[] = {
// 860 NA
859,
858,
- // 857,
+ 857,
856,
// 855 NA
// 854 NA
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 39106a7b8d..1b8c953596 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -248,7 +248,7 @@ newwindow:
/* First create a new tab with the window, then go back to
* the old tab and close the window there. */
wp = curwin;
- if (win_new_tabpage((int)Prenum) == OK
+ if (win_new_tabpage((int)Prenum, NULL) == OK
&& valid_tabpage(oldtab)) {
newtab = curtab;
goto_tabpage_tp(oldtab, TRUE, TRUE);
@@ -2952,14 +2952,15 @@ void free_tabpage(tabpage_T *tp)
xfree(tp);
}
-/*
- * Create a new Tab page with one window.
- * It will edit the current buffer, like after ":split".
- * When "after" is 0 put it just after the current Tab page.
- * Otherwise put it just before tab page "after".
- * Return FAIL or OK.
- */
-int win_new_tabpage(int after)
+/// Create a new tabpage with one window.
+///
+/// It will edit the current buffer, like after :split.
+///
+/// @param after Put new tabpage after tabpage "after", or after the current
+/// tabpage in case of 0.
+/// @param filename Will be passed to apply_autocmds().
+/// @return Was the new tabpage created successfully? FAIL or OK.
+int win_new_tabpage(int after, char_u *filename)
{
tabpage_T *tp = curtab;
tabpage_T *newtp;
@@ -2999,10 +3000,12 @@ int win_new_tabpage(int after)
newtp->tp_topframe = topframe;
last_status(FALSE);
-
redraw_all_later(CLEAR);
- apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
- apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+
+ apply_autocmds(EVENT_TABNEW, filename, filename, false, curbuf);
+ apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf);
+ apply_autocmds(EVENT_TABENTER, NULL, NULL, false, curbuf);
+
return OK;
}
@@ -3023,7 +3026,7 @@ int may_open_tabpage(void)
if (n != 0) {
cmdmod.tab = 0; /* reset it to avoid doing it twice */
postponed_split_tab = 0;
- return win_new_tabpage(n);
+ return win_new_tabpage(n, NULL);
}
return FAIL;
}
@@ -3047,9 +3050,11 @@ int make_tabpages(int maxcount)
*/
block_autocmds();
- for (todo = count - 1; todo > 0; --todo)
- if (win_new_tabpage(0) == FAIL)
+ for (todo = count - 1; todo > 0; --todo) {
+ if (win_new_tabpage(0, NULL) == FAIL) {
break;
+ }
+ }
unblock_autocmds();
@@ -4619,10 +4624,8 @@ void win_drag_vsep_line(win_T *dragwin, int offset)
#define FRACTION_MULT 16384L
-/*
- * Set wp->w_fraction for the current w_wrow and w_height.
- */
-static void set_fraction(win_T *wp)
+// Set wp->w_fraction for the current w_wrow and w_height.
+void set_fraction(win_T *wp)
{
wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height / 2)
/ (long)wp->w_height;