aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/clint.py4
-rw-r--r--src/nvim/CMakeLists.txt3
-rw-r--r--src/nvim/README.md10
-rw-r--r--src/nvim/api/buffer.c22
-rw-r--r--src/nvim/api/private/helpers.c8
-rw-r--r--src/nvim/api/private/helpers.h4
-rw-r--r--src/nvim/api/ui_events.in.h4
-rw-r--r--src/nvim/api/vim.c2
-rw-r--r--src/nvim/ascii.h26
-rw-r--r--src/nvim/buffer.c18
-rw-r--r--src/nvim/buffer_defs.h459
-rw-r--r--src/nvim/change.c4
-rw-r--r--src/nvim/channel.c1
-rw-r--r--src/nvim/channel.h2
-rw-r--r--src/nvim/charset.c1
-rw-r--r--src/nvim/cursor_shape.h8
-rw-r--r--src/nvim/diff.c21
-rw-r--r--src/nvim/edit.c1312
-rw-r--r--src/nvim/eval.c514
-rw-r--r--src/nvim/eval.lua3
-rw-r--r--src/nvim/eval/funcs.c335
-rw-r--r--src/nvim/eval/typval.h4
-rw-r--r--src/nvim/eval/userfunc.c129
-rw-r--r--src/nvim/eval/userfunc.h2
-rw-r--r--src/nvim/event/loop.c36
-rw-r--r--src/nvim/event/stream.c5
-rw-r--r--src/nvim/ex_cmds.c39
-rw-r--r--src/nvim/ex_cmds.lua39
-rw-r--r--src/nvim/ex_cmds_defs.h61
-rw-r--r--src/nvim/ex_docmd.c169
-rw-r--r--src/nvim/ex_eval.c2
-rw-r--r--src/nvim/ex_getln.c30
-rw-r--r--src/nvim/ex_getln.h2
-rw-r--r--src/nvim/ex_session.c2
-rw-r--r--src/nvim/extmark.c27
-rw-r--r--src/nvim/fileio.c39
-rw-r--r--src/nvim/fold.c347
-rw-r--r--src/nvim/getchar.c4
-rw-r--r--src/nvim/getchar.h4
-rw-r--r--src/nvim/globals.h539
-rw-r--r--src/nvim/hardcopy.c587
-rw-r--r--src/nvim/if_cscope.c372
-rw-r--r--src/nvim/if_cscope_defs.h31
-rw-r--r--src/nvim/indent.c30
-rw-r--r--src/nvim/indent_c.c9
-rw-r--r--src/nvim/keymap.h20
-rw-r--r--src/nvim/lua/executor.c152
-rw-r--r--src/nvim/lua/treesitter.c32
-rw-r--r--src/nvim/macros.h42
-rw-r--r--src/nvim/main.c1
-rw-r--r--src/nvim/marktree.c9
-rw-r--r--src/nvim/mbyte.c126
-rw-r--r--src/nvim/memline.c87
-rw-r--r--src/nvim/menu.c2
-rw-r--r--src/nvim/message.c6
-rw-r--r--src/nvim/misc1.c3
-rw-r--r--src/nvim/mouse.c19
-rw-r--r--src/nvim/move.c131
-rw-r--r--src/nvim/msgpack_rpc/channel.h2
-rw-r--r--src/nvim/msgpack_rpc/server.c2
-rw-r--r--src/nvim/normal.c60
-rw-r--r--src/nvim/ops.c60
-rw-r--r--src/nvim/option.c475
-rw-r--r--src/nvim/option_defs.h2
-rw-r--r--src/nvim/options.lua13
-rw-r--r--src/nvim/os/fs.c69
-rw-r--r--src/nvim/os/shell.c1
-rw-r--r--src/nvim/os/signal.c33
-rw-r--r--src/nvim/os/time.c55
-rw-r--r--src/nvim/popupmnu.c52
-rw-r--r--src/nvim/quickfix.c30
-rw-r--r--src/nvim/regexp.c35
-rw-r--r--src/nvim/regexp_defs.h20
-rw-r--r--src/nvim/screen.c143
-rw-r--r--src/nvim/search.c36
-rw-r--r--src/nvim/sign.c210
-rw-r--r--src/nvim/spell.c25
-rw-r--r--src/nvim/syntax.c2
-rw-r--r--src/nvim/tag.c18
-rw-r--r--src/nvim/terminal.c5
-rw-r--r--src/nvim/testdir/Makefile2
-rw-r--r--src/nvim/testdir/test49.vim4
-rw-r--r--src/nvim/testdir/test_autocmd.vim77
-rw-r--r--src/nvim/testdir/test_compiler.vim9
-rw-r--r--src/nvim/testdir/test_diffmode.vim10
-rw-r--r--src/nvim/testdir/test_digraph.vim12
-rw-r--r--src/nvim/testdir/test_expr.vim2
-rw-r--r--src/nvim/testdir/test_filetype.vim6
-rw-r--r--src/nvim/testdir/test_functions.vim36
-rw-r--r--src/nvim/testdir/test_hardcopy.vim169
-rw-r--r--src/nvim/testdir/test_listchars.vim20
-rw-r--r--src/nvim/testdir/test_maparg.vim7
-rw-r--r--src/nvim/testdir/test_mapping.vim74
-rw-r--r--src/nvim/testdir/test_messages.vim34
-rw-r--r--src/nvim/testdir/test_number.vim11
-rw-r--r--src/nvim/testdir/test_options.vim43
-rw-r--r--src/nvim/testdir/test_plus_arg_edit.vim28
-rw-r--r--src/nvim/testdir/test_profile.vim26
-rw-r--r--src/nvim/testdir/test_quickfix.vim15
-rw-r--r--src/nvim/testdir/test_quotestar.vim3
-rw-r--r--src/nvim/testdir/test_restricted.vim103
-rw-r--r--src/nvim/testdir/test_search.vim6
-rw-r--r--src/nvim/testdir/test_signs.vim413
-rw-r--r--src/nvim/testdir/test_spell.vim11
-rw-r--r--src/nvim/testdir/test_substitute.vim19
-rw-r--r--src/nvim/testdir/test_taglist.vim17
-rw-r--r--src/nvim/testdir/test_timers.vim4
-rw-r--r--src/nvim/testdir/test_user_func.vim4
-rw-r--r--src/nvim/testdir/test_utf8.vim43
-rw-r--r--src/nvim/testdir/test_writefile.vim7
-rw-r--r--src/nvim/tui/input.c26
-rw-r--r--src/nvim/tui/input.h2
-rw-r--r--src/nvim/tui/terminfo.c9
-rw-r--r--src/nvim/tui/tui.c184
-rw-r--r--src/nvim/ui.c2
-rw-r--r--src/nvim/version.c28
-rw-r--r--src/nvim/viml/parser/expressions.h4
-rw-r--r--src/nvim/window.c64
-rw-r--r--src/nvim/xdiff/xdiff.h24
-rw-r--r--src/nvim/xdiff/xdiffi.c44
-rw-r--r--src/nvim/xdiff/xdiffi.h2
-rw-r--r--src/nvim/xdiff/xemit.c12
-rw-r--r--src/nvim/xdiff/xemit.h2
-rw-r--r--src/nvim/xdiff/xhistogram.c12
-rw-r--r--src/nvim/xdiff/xinclude.h8
-rw-r--r--src/nvim/xdiff/xmacros.h2
-rw-r--r--src/nvim/xdiff/xpatience.c30
-rw-r--r--src/nvim/xdiff/xprepare.h2
-rw-r--r--src/nvim/xdiff/xtypes.h2
-rw-r--r--src/nvim/xdiff/xutils.c10
-rw-r--r--src/nvim/xdiff/xutils.h2
-rw-r--r--src/tree_sitter/api.h37
-rw-r--r--src/tree_sitter/array.h28
-rw-r--r--src/tree_sitter/atomic.h4
-rw-r--r--src/tree_sitter/bits.h2
-rw-r--r--src/tree_sitter/language.c6
-rw-r--r--src/tree_sitter/language.h14
-rw-r--r--src/tree_sitter/lexer.c13
-rw-r--r--src/tree_sitter/lexer.h2
-rw-r--r--src/tree_sitter/node.c4
-rw-r--r--src/tree_sitter/parser.c75
-rw-r--r--src/tree_sitter/query.c590
-rw-r--r--src/tree_sitter/stack.c2
-rw-r--r--src/tree_sitter/subtree.c13
-rw-r--r--src/tree_sitter/subtree.h4
-rw-r--r--src/tree_sitter/utf16.c33
-rw-r--r--src/tree_sitter/utf16.h21
147 files changed, 6003 insertions, 3779 deletions
diff --git a/src/clint.py b/src/clint.py
index 12bada6aac..8dc41fdb93 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -1773,7 +1773,7 @@ def CheckSpacingForFunctionCall(filename, line, linenum, error):
fncall = match.group(1)
break
- # Except in if/for/while/switch, there should never be space
+ # Except in if/for/while/switch/case, there should never be space
# immediately inside parens (eg "f( 3, 4 )"). We make an exception
# for nested parens ( (a+b) + c ). Likewise, there should never be
# a space before a ( when it's a function argument. I assume it's a
@@ -1787,7 +1787,7 @@ def CheckSpacingForFunctionCall(filename, line, linenum, error):
# Note that we assume the contents of [] to be short enough that
# they'll never need to wrap.
if ( # Ignore control structures.
- not Search(r'\b(if|for|while|switch|return|sizeof)\b', fncall) and
+ not Search(r'\b(if|for|while|switch|case|return|sizeof)\b', fncall) and
# Ignore pointers/references to functions.
not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
# Ignore pointers/references to arrays.
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 62290b0778..982fab173f 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -221,7 +221,7 @@ set(gen_cflags ${gen_cflags} ${C_FLAGS_${build_type}_ARRAY} ${C_FLAGS_ARRAY})
function(get_preproc_output varname iname)
if(MSVC)
- set(${varname} /P /Fi${iname} PARENT_SCOPE)
+ set(${varname} /P /Fi${iname} /nologo PARENT_SCOPE)
else()
set(${varname} -E -o ${iname} PARENT_SCOPE)
endif()
@@ -574,7 +574,6 @@ set_target_properties(
libnvim
PROPERTIES
POSITION_INDEPENDENT_CODE ON
- OUTPUT_NAME nvim
)
set_property(
TARGET libnvim
diff --git a/src/nvim/README.md b/src/nvim/README.md
index 3f7c05757a..d14ba85546 100644
--- a/src/nvim/README.md
+++ b/src/nvim/README.md
@@ -23,14 +23,18 @@ Logs
Low-level log messages sink to `$NVIM_LOG_FILE`.
-Use `LOG_CALLSTACK()` (Linux only) to log the current stacktrace. To log to an
-alternate file (e.g. stderr) use `LOG_CALLSTACK_TO_FILE(FILE*)`.
-
UI events are logged at DEBUG level (`DEBUG_LOG_LEVEL`).
rm -rf build/
make CMAKE_EXTRA_FLAGS="-DMIN_LOG_LEVEL=0"
+Use `LOG_CALLSTACK()` (Linux only) to log the current stacktrace. To log to an
+alternate file (e.g. stderr) use `LOG_CALLSTACK_TO_FILE(FILE*)`. Requires
+`-no-pie` ([ref](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=860394#15)):
+
+ rm -rf build/
+ make CMAKE_EXTRA_FLAGS="-DMIN_LOG_LEVEL=0 -DCMAKE_C_FLAGS=-no-pie"
+
Many log messages have a shared prefix, such as "UI" or "RPC". Use the shell to
filter the log, e.g. at DEBUG level you might want to exclude UI messages:
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index a666ed92da..b345dcaccd 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1123,7 +1123,7 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
}
if (!ns_initialized((uint64_t)ns_id)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
return rv;
}
@@ -1190,7 +1190,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start,
}
if (!ns_initialized((uint64_t)ns_id)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
return rv;
}
Integer limit = -1;
@@ -1280,7 +1280,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id,
}
if (!ns_initialized((uint64_t)ns_id)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
return 0;
}
@@ -1308,7 +1308,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id,
if (id >= 0) {
id_num = (uint64_t)id;
} else {
- api_set_error(err, kErrorTypeValidation, _("Invalid mark id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid mark id");
return 0;
}
@@ -1337,7 +1337,7 @@ Boolean nvim_buf_del_extmark(Buffer buffer,
return false;
}
if (!ns_initialized((uint64_t)ns_id)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
return false;
}
@@ -1402,7 +1402,7 @@ Integer nvim_buf_add_highlight(Buffer buffer,
uint64_t ns_id = src2ns(&src_id);
- if (!(0 <= line && line < buf->b_ml.ml_line_count)) {
+ if (!(line < buf->b_ml.ml_line_count)) {
// safety check, we can't add marks outside the range
return src_id;
}
@@ -1420,10 +1420,10 @@ Integer nvim_buf_add_highlight(Buffer buffer,
end_line++;
}
- ns_id = extmark_add_decoration(buf, ns_id, hlg_id,
- (int)line, (colnr_T)col_start,
- end_line, (colnr_T)col_end,
- VIRTTEXT_EMPTY);
+ extmark_add_decoration(buf, ns_id, hlg_id,
+ (int)line, (colnr_T)col_start,
+ end_line, (colnr_T)col_end,
+ VIRTTEXT_EMPTY);
return src_id;
}
@@ -1655,7 +1655,7 @@ Integer nvim__buf_add_decoration(Buffer buffer, Integer ns_id, String hl_group,
}
if (!ns_initialized((uint64_t)ns_id)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid ns_id");
return 0;
}
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index a1745ef777..a458762cc6 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1544,7 +1544,7 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
*col = MAXCOL;
return true;
} else if (id < 0) {
- api_set_error(err, kErrorTypeValidation, _("Mark id must be positive"));
+ api_set_error(err, kErrorTypeValidation, "Mark id must be positive");
return false;
}
@@ -1554,7 +1554,7 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
*col = extmark.col;
return true;
} else {
- api_set_error(err, kErrorTypeValidation, _("No mark with requested id"));
+ api_set_error(err, kErrorTypeValidation, "No mark with requested id");
return false;
}
@@ -1565,7 +1565,7 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
|| pos.items[0].type != kObjectTypeInteger
|| pos.items[1].type != kObjectTypeInteger) {
api_set_error(err, kErrorTypeValidation,
- _("Position must have 2 integer elements"));
+ "Position must have 2 integer elements");
return false;
}
Integer pos_row = pos.items[0].data.integer;
@@ -1575,7 +1575,7 @@ bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, int
return true;
} else {
api_set_error(err, kErrorTypeValidation,
- _("Position must be a mark id Integer or position Array"));
+ "Position must be a mark id Integer or position Array");
return false;
}
}
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index 048b937136..df3a263dcf 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -63,8 +63,8 @@
#define FIXED_TEMP_ARRAY(name, fixsize) \
Array name = ARRAY_DICT_INIT; \
Object name##__items[fixsize]; \
- args.size = fixsize; \
- args.items = name##__items; \
+ name.size = fixsize; \
+ name.items = name##__items; \
#define STATIC_CSTR_AS_STRING(s) ((String) {.data = s, .size = sizeof(s) - 1})
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
index 6677e248cf..ab31db39e9 100644
--- a/src/nvim/api/ui_events.in.h
+++ b/src/nvim/api/ui_events.in.h
@@ -115,6 +115,10 @@ void win_close(Integer grid)
void msg_set_pos(Integer grid, Integer row, Boolean scrolled, String sep_char)
FUNC_API_SINCE(6) FUNC_API_BRIDGE_IMPL FUNC_API_COMPOSITOR_IMPL;
+void win_viewport(Integer grid, Window win, Integer topline,
+ Integer botline, Integer curline, Integer curcol)
+ FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY;
+
void popupmenu_show(Array items, Integer selected,
Integer row, Integer col, Integer grid)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 9657a37831..087ab37296 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -254,7 +254,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
if (execute) {
int save_msg_scroll = msg_scroll;
- /* Avoid a 1 second delay when the keys start Insert mode. */
+ // Avoid a 1 second delay when the keys start Insert mode.
msg_scroll = false;
if (!dangerous) {
ex_normal_busy++;
diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h
index ff6840d690..31423e79af 100644
--- a/src/nvim/ascii.h
+++ b/src/nvim/ascii.h
@@ -23,26 +23,28 @@
#define NL '\012'
#define NL_STR "\012"
#define FF '\014'
-#define CAR '\015' /* CR is used by Mac OS X */
+#define CAR '\015' // CR is used by Mac OS X
#define ESC '\033'
#define ESC_STR "\033"
#define DEL 0x7f
#define DEL_STR "\177"
#define CSI 0x9b // Control Sequence Introducer
#define CSI_STR "\233"
-#define DCS 0x90 /* Device Control String */
-#define STERM 0x9c /* String Terminator */
+#define DCS 0x90 // Device Control String
+#define DCS_STR "\033P"
+#define STERM 0x9c // String Terminator
+#define STERM_STR "\033\\"
#define POUND 0xA3
-#define Ctrl_chr(x) (TOUPPER_ASC(x) ^ 0x40) /* '?' -> DEL, '@' -> ^@, etc. */
+#define Ctrl_chr(x) (TOUPPER_ASC(x) ^ 0x40) // '?' -> DEL, '@' -> ^@, etc.
#define Meta(x) ((x) | 0x80)
#define CTRL_F_STR "\006"
#define CTRL_H_STR "\010"
#define CTRL_V_STR "\026"
-#define Ctrl_AT 0 /* @ */
+#define Ctrl_AT 0 // @
#define Ctrl_A 1
#define Ctrl_B 2
#define Ctrl_C 3
@@ -69,16 +71,14 @@
#define Ctrl_X 24
#define Ctrl_Y 25
#define Ctrl_Z 26
-/* CTRL- [ Left Square Bracket == ESC*/
-#define Ctrl_BSL 28 /* \ BackSLash */
-#define Ctrl_RSB 29 /* ] Right Square Bracket */
-#define Ctrl_HAT 30 /* ^ */
+// CTRL- [ Left Square Bracket == ESC
+#define Ctrl_BSL 28 // \ BackSLash
+#define Ctrl_RSB 29 // ] Right Square Bracket
+#define Ctrl_HAT 30 // ^
#define Ctrl__ 31
-/*
- * Character that separates dir names in a path.
- */
+// Character that separates dir names in a path.
#ifdef BACKSLASH_IN_FILENAME
# define PATHSEP psepc
# define PATHSEPSTR pseps
@@ -168,4 +168,4 @@ static inline bool ascii_isspace(int c)
return (c >= 9 && c <= 13) || c == ' ';
}
-#endif /* NVIM_ASCII_H */
+#endif // NVIM_ASCII_H
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 790609ab94..24ba43676a 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1750,6 +1750,7 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, false, curbuf);
}
if (aborting()) { // autocmds may abort script processing
+ xfree(ffname);
return NULL;
}
if (buf == curbuf) {
@@ -3397,14 +3398,27 @@ int build_stl_str_hl(
fillchar = '-';
}
+ // The cursor in windows other than the current one isn't always
+ // up-to-date, esp. because of autocommands and timers.
+ linenr_T lnum = wp->w_cursor.lnum;
+ if (lnum > wp->w_buffer->b_ml.ml_line_count) {
+ lnum = wp->w_buffer->b_ml.ml_line_count;
+ wp->w_cursor.lnum = lnum;
+ }
+
// Get line & check if empty (cursorpos will show "0-1").
- char_u *line_ptr = ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, false);
+ const char_u *line_ptr = ml_get_buf(wp->w_buffer, lnum, false);
bool empty_line = (*line_ptr == NUL);
// Get the byte value now, in case we need it below. This is more
// efficient than making a copy of the line.
int byteval;
- if (wp->w_cursor.col > (colnr_T)STRLEN(line_ptr)) {
+ const size_t len = STRLEN(line_ptr);
+ if (wp->w_cursor.col > (colnr_T)len) {
+ // Line may have changed since checking the cursor column, or the lnum
+ // was adjusted above.
+ wp->w_cursor.col = (colnr_T)len;
+ wp->w_cursor.coladd = 0;
byteval = 0;
} else {
byteval = utf_ptr2char(line_ptr + wp->w_cursor.col);
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 9cdf36e4ed..2460159fc0 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -67,14 +67,14 @@ typedef struct {
* off off w_botline not valid
* on off not possible
*/
-#define VALID_WROW 0x01 /* w_wrow (window row) is valid */
-#define VALID_WCOL 0x02 /* w_wcol (window col) is valid */
-#define VALID_VIRTCOL 0x04 /* w_virtcol (file col) is valid */
-#define VALID_CHEIGHT 0x08 /* w_cline_height and w_cline_folded valid */
-#define VALID_CROW 0x10 /* w_cline_row is valid */
-#define VALID_BOTLINE 0x20 /* w_botine and w_empty_rows are valid */
-#define VALID_BOTLINE_AP 0x40 /* w_botine is approximated */
-#define VALID_TOPLINE 0x80 /* w_topline is valid (for cursor position) */
+#define VALID_WROW 0x01 // w_wrow (window row) is valid
+#define VALID_WCOL 0x02 // w_wcol (window col) is valid
+#define VALID_VIRTCOL 0x04 // w_virtcol (file col) is valid
+#define VALID_CHEIGHT 0x08 // w_cline_height and w_cline_folded valid
+#define VALID_CROW 0x10 // w_cline_row is valid
+#define VALID_BOTLINE 0x20 // w_botine and w_empty_rows are valid
+#define VALID_BOTLINE_AP 0x40 // w_botine is approximated
+#define VALID_TOPLINE 0x80 // w_topline is valid (for cursor position)
// flags for b_flags
#define BF_RECOVERED 0x01 // buffer has been recovered
@@ -92,7 +92,7 @@ typedef struct {
#define BF_DUMMY 0x80 // dummy buffer, only used internally
#define BF_PRESERVED 0x100 // ":preserve" was used
-/* Mask to check for flags that prevent normal writing */
+// Mask to check for flags that prevent normal writing
#define BF_WRITE_MASK (BF_NOTEDITED + BF_NEW + BF_READERR)
typedef struct window_S win_T;
@@ -160,90 +160,92 @@ typedef struct
*/
typedef struct {
int wo_arab;
-# define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */
+# define w_p_arab w_onebuf_opt.wo_arab // 'arabic'
int wo_bri;
# define w_p_bri w_onebuf_opt.wo_bri // 'breakindent'
char_u *wo_briopt;
-# define w_p_briopt w_onebuf_opt.wo_briopt /* 'breakindentopt' */
+# define w_p_briopt w_onebuf_opt.wo_briopt // 'breakindentopt'
int wo_diff;
-# define w_p_diff w_onebuf_opt.wo_diff /* 'diff' */
- long wo_fdc;
-# define w_p_fdc w_onebuf_opt.wo_fdc /* 'foldcolumn' */
- int wo_fdc_save;
-# define w_p_fdc_save w_onebuf_opt.wo_fdc_save /* 'foldenable' saved for diff mode */
+# define w_p_diff w_onebuf_opt.wo_diff // 'diff'
+ char_u *wo_fdc;
+# define w_p_fdc w_onebuf_opt.wo_fdc // 'foldcolumn'
+ char_u *wo_fdc_save;
+# define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode
int wo_fen;
-# define w_p_fen w_onebuf_opt.wo_fen /* 'foldenable' */
+# define w_p_fen w_onebuf_opt.wo_fen // 'foldenable'
int wo_fen_save;
-# define w_p_fen_save w_onebuf_opt.wo_fen_save /* 'foldenable' saved for diff mode */
+ // 'foldenable' saved for diff mode
+# define w_p_fen_save w_onebuf_opt.wo_fen_save
char_u *wo_fdi;
-# define w_p_fdi w_onebuf_opt.wo_fdi /* 'foldignore' */
+# define w_p_fdi w_onebuf_opt.wo_fdi // 'foldignore'
long wo_fdl;
-# define w_p_fdl w_onebuf_opt.wo_fdl /* 'foldlevel' */
+# define w_p_fdl w_onebuf_opt.wo_fdl // 'foldlevel'
int wo_fdl_save;
-# define w_p_fdl_save w_onebuf_opt.wo_fdl_save /* 'foldlevel' state saved for diff mode */
+ // 'foldlevel' state saved for diff mode
+# define w_p_fdl_save w_onebuf_opt.wo_fdl_save
char_u *wo_fdm;
-# define w_p_fdm w_onebuf_opt.wo_fdm /* 'foldmethod' */
+# define w_p_fdm w_onebuf_opt.wo_fdm // 'foldmethod'
char_u *wo_fdm_save;
-# define w_p_fdm_save w_onebuf_opt.wo_fdm_save /* 'fdm' saved for diff mode */
+# define w_p_fdm_save w_onebuf_opt.wo_fdm_save // 'fdm' saved for diff mode
long wo_fml;
-# define w_p_fml w_onebuf_opt.wo_fml /* 'foldminlines' */
+# define w_p_fml w_onebuf_opt.wo_fml // 'foldminlines'
long wo_fdn;
-# define w_p_fdn w_onebuf_opt.wo_fdn /* 'foldnestmax' */
+# define w_p_fdn w_onebuf_opt.wo_fdn // 'foldnestmax'
char_u *wo_fde;
-# define w_p_fde w_onebuf_opt.wo_fde /* 'foldexpr' */
+# define w_p_fde w_onebuf_opt.wo_fde // 'foldexpr'
char_u *wo_fdt;
-# define w_p_fdt w_onebuf_opt.wo_fdt /* 'foldtext' */
+# define w_p_fdt w_onebuf_opt.wo_fdt // 'foldtext'
char_u *wo_fmr;
-# define w_p_fmr w_onebuf_opt.wo_fmr /* 'foldmarker' */
+# define w_p_fmr w_onebuf_opt.wo_fmr // 'foldmarker'
int wo_lbr;
-# define w_p_lbr w_onebuf_opt.wo_lbr /* 'linebreak' */
+# define w_p_lbr w_onebuf_opt.wo_lbr // 'linebreak'
int wo_list;
-#define w_p_list w_onebuf_opt.wo_list /* 'list' */
+#define w_p_list w_onebuf_opt.wo_list // 'list'
int wo_nu;
-#define w_p_nu w_onebuf_opt.wo_nu /* 'number' */
+#define w_p_nu w_onebuf_opt.wo_nu // 'number'
int wo_rnu;
-#define w_p_rnu w_onebuf_opt.wo_rnu /* 'relativenumber' */
+#define w_p_rnu w_onebuf_opt.wo_rnu // 'relativenumber'
long wo_nuw;
-# define w_p_nuw w_onebuf_opt.wo_nuw /* 'numberwidth' */
+# define w_p_nuw w_onebuf_opt.wo_nuw // 'numberwidth'
int wo_wfh;
-# define w_p_wfh w_onebuf_opt.wo_wfh /* 'winfixheight' */
+# define w_p_wfh w_onebuf_opt.wo_wfh // 'winfixheight'
int wo_wfw;
-# define w_p_wfw w_onebuf_opt.wo_wfw /* 'winfixwidth' */
+# define w_p_wfw w_onebuf_opt.wo_wfw // 'winfixwidth'
int wo_pvw;
-# define w_p_pvw w_onebuf_opt.wo_pvw /* 'previewwindow' */
+# define w_p_pvw w_onebuf_opt.wo_pvw // 'previewwindow'
int wo_rl;
-# define w_p_rl w_onebuf_opt.wo_rl /* 'rightleft' */
+# define w_p_rl w_onebuf_opt.wo_rl // 'rightleft'
char_u *wo_rlc;
-# define w_p_rlc w_onebuf_opt.wo_rlc /* 'rightleftcmd' */
+# define w_p_rlc w_onebuf_opt.wo_rlc // 'rightleftcmd'
long wo_scr;
-#define w_p_scr w_onebuf_opt.wo_scr /* 'scroll' */
+#define w_p_scr w_onebuf_opt.wo_scr // 'scroll'
int wo_spell;
-# define w_p_spell w_onebuf_opt.wo_spell /* 'spell' */
+# define w_p_spell w_onebuf_opt.wo_spell // 'spell'
int wo_cuc;
-# define w_p_cuc w_onebuf_opt.wo_cuc /* 'cursorcolumn' */
+# define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn'
int wo_cul;
-# define w_p_cul w_onebuf_opt.wo_cul /* 'cursorline' */
+# define w_p_cul w_onebuf_opt.wo_cul // 'cursorline'
char_u *wo_cc;
-# define w_p_cc w_onebuf_opt.wo_cc /* 'colorcolumn' */
+# define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn'
char_u *wo_stl;
-#define w_p_stl w_onebuf_opt.wo_stl /* 'statusline' */
+#define w_p_stl w_onebuf_opt.wo_stl // 'statusline'
int wo_scb;
-# define w_p_scb w_onebuf_opt.wo_scb /* 'scrollbind' */
- int wo_diff_saved; /* options were saved for starting diff mode */
+# define w_p_scb w_onebuf_opt.wo_scb // 'scrollbind'
+ int wo_diff_saved; // options were saved for starting diff mode
# define w_p_diff_saved w_onebuf_opt.wo_diff_saved
- int wo_scb_save; /* 'scrollbind' saved for diff mode*/
+ int wo_scb_save; // 'scrollbind' saved for diff mode
# define w_p_scb_save w_onebuf_opt.wo_scb_save
int wo_wrap;
-#define w_p_wrap w_onebuf_opt.wo_wrap /* 'wrap' */
- int wo_wrap_save; /* 'wrap' state saved for diff mode*/
+#define w_p_wrap w_onebuf_opt.wo_wrap // 'wrap'
+ int wo_wrap_save; // 'wrap' state saved for diff mode
# define w_p_wrap_save w_onebuf_opt.wo_wrap_save
- char_u *wo_cocu; /* 'concealcursor' */
+ char_u *wo_cocu; // 'concealcursor'
# define w_p_cocu w_onebuf_opt.wo_cocu
- long wo_cole; /* 'conceallevel' */
+ long wo_cole; // 'conceallevel'
# define w_p_cole w_onebuf_opt.wo_cole
int wo_crb;
-# define w_p_crb w_onebuf_opt.wo_crb /* 'cursorbind' */
- int wo_crb_save; /* 'cursorbind' state saved for diff mode*/
+# define w_p_crb w_onebuf_opt.wo_crb // 'cursorbind'
+ int wo_crb_save; // 'cursorbind' state saved for diff mode
# define w_p_crb_save w_onebuf_opt.wo_crb_save
char_u *wo_scl;
# define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
@@ -271,14 +273,14 @@ typedef struct {
* most-recently-used order.
*/
struct wininfo_S {
- wininfo_T *wi_next; /* next entry or NULL for last entry */
- wininfo_T *wi_prev; /* previous entry or NULL for first entry */
- win_T *wi_win; /* pointer to window that did set wi_fpos */
- pos_T wi_fpos; /* last cursor position in the file */
- bool wi_optset; /* true when wi_opt has useful values */
- winopt_T wi_opt; /* local window options */
- bool wi_fold_manual; /* copy of w_fold_manual */
- garray_T wi_folds; /* clone of w_folds */
+ wininfo_T *wi_next; // next entry or NULL for last entry
+ wininfo_T *wi_prev; // previous entry or NULL for first entry
+ win_T *wi_win; // pointer to window that did set wi_fpos
+ pos_T wi_fpos; // last cursor position in the file
+ bool wi_optset; // true when wi_opt has useful values
+ winopt_T wi_opt; // local window options
+ bool wi_fold_manual; // copy of w_fold_manual
+ garray_T wi_folds; // clone of w_folds
};
/*
@@ -288,8 +290,8 @@ struct wininfo_S {
* TODO: move struct arglist to another header
*/
typedef struct arglist {
- garray_T al_ga; /* growarray with the array of file names */
- int al_refcount; /* number of windows using this arglist */
+ garray_T al_ga; // growarray with the array of file names
+ int al_refcount; // number of windows using this arglist
int id; ///< id of this arglist
} alist_T;
@@ -301,8 +303,8 @@ typedef struct arglist {
* TODO: move aentry_T to another header
*/
typedef struct argentry {
- char_u *ae_fname; /* file name as specified */
- int ae_fnum; /* buffer number with expanded file name */
+ char_u *ae_fname; // file name as specified
+ int ae_fnum; // buffer number with expanded file name
} aentry_T;
# define ALIST(win) (win)->w_alist
@@ -318,21 +320,21 @@ typedef struct argentry {
* Used for the typeahead buffer: typebuf.
*/
typedef struct {
- char_u *tb_buf; /* buffer for typed characters */
- char_u *tb_noremap; /* mapping flags for characters in tb_buf[] */
- int tb_buflen; /* size of tb_buf[] */
- int tb_off; /* current position in tb_buf[] */
- int tb_len; /* number of valid bytes in tb_buf[] */
- int tb_maplen; /* nr of mapped bytes in tb_buf[] */
- int tb_silent; /* nr of silently mapped bytes in tb_buf[] */
- int tb_no_abbr_cnt; /* nr of bytes without abbrev. in tb_buf[] */
- int tb_change_cnt; /* nr of time tb_buf was changed; never zero */
+ char_u *tb_buf; // buffer for typed characters
+ char_u *tb_noremap; // mapping flags for characters in tb_buf[]
+ int tb_buflen; // size of tb_buf[]
+ int tb_off; // current position in tb_buf[]
+ int tb_len; // number of valid bytes in tb_buf[]
+ int tb_maplen; // nr of mapped bytes in tb_buf[]
+ int tb_silent; // nr of silently mapped bytes in tb_buf[]
+ int tb_no_abbr_cnt; // nr of bytes without abbrev. in tb_buf[]
+ int tb_change_cnt; // nr of time tb_buf was changed; never zero
} typebuf_T;
-/* Struct to hold the saved typeahead for save_typeahead(). */
+// Struct to hold the saved typeahead for save_typeahead().
typedef struct {
typebuf_T save_typebuf;
- int typebuf_valid; /* TRUE when save_typebuf valid */
+ int typebuf_valid; // TRUE when save_typebuf valid
int old_char;
int old_mod_mask;
buffheader_T save_readbuf1;
@@ -363,15 +365,15 @@ struct mapblock {
*/
struct stl_hlrec {
char_u *start;
- int userhl; /* 0: no HL, 1-9: User HL, < 0 for syn ID */
+ int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID
};
-/* values for b_syn_spell: what to do with toplevel text */
-#define SYNSPL_DEFAULT 0 /* spell check if @Spell not defined */
-#define SYNSPL_TOP 1 /* spell check toplevel text */
-#define SYNSPL_NOTOP 2 /* don't spell check toplevel text */
+// values for b_syn_spell: what to do with toplevel text
+#define SYNSPL_DEFAULT 0 // spell check if @Spell not defined
+#define SYNSPL_TOP 1 // spell check toplevel text
+#define SYNSPL_NOTOP 2 // don't spell check toplevel text
-/* avoid #ifdefs for when b_spell is not available */
+// avoid #ifdefs for when b_spell is not available
# define B_SPELL(buf) ((buf)->b_spell)
typedef struct qf_info_S qf_info_T;
@@ -380,10 +382,10 @@ typedef struct qf_info_S qf_info_T;
* Used for :syntime: timing of executing a syntax pattern.
*/
typedef struct {
- proftime_T total; /* total time used */
- proftime_T slowest; /* time of slowest call */
- long count; /* nr of times used */
- long match; /* nr of times matched */
+ proftime_T total; // total time used
+ proftime_T slowest; // time of slowest call
+ long count; // nr of times used
+ long match; // nr of times matched
} syn_time_T;
/*
@@ -411,25 +413,23 @@ typedef struct {
char_u *b_syn_linecont_pat; // line continuation pattern
regprog_T *b_syn_linecont_prog; // line continuation program
syn_time_T b_syn_linecont_time;
- int b_syn_linecont_ic; /* ignore-case flag for above */
- int b_syn_topgrp; /* for ":syntax include" */
- int b_syn_conceal; /* auto-conceal for :syn cmds */
- int b_syn_folditems; /* number of patterns with the HL_FOLD
- flag set */
- /*
- * b_sst_array[] contains the state stack for a number of lines, for the
- * start of that line (col == 0). This avoids having to recompute the
- * syntax state too often.
- * b_sst_array[] is allocated to hold the state for all displayed lines,
- * and states for 1 out of about 20 other lines.
- * b_sst_array pointer to an array of synstate_T
- * b_sst_len number of entries in b_sst_array[]
- * b_sst_first pointer to first used entry in b_sst_array[] or NULL
- * b_sst_firstfree pointer to first free entry in b_sst_array[] or NULL
- * b_sst_freecount number of free entries in b_sst_array[]
- * b_sst_check_lnum entries after this lnum need to be checked for
- * validity (MAXLNUM means no check needed)
- */
+ int b_syn_linecont_ic; // ignore-case flag for above
+ int b_syn_topgrp; // for ":syntax include"
+ int b_syn_conceal; // auto-conceal for :syn cmds
+ int b_syn_folditems; // number of patterns with the HL_FOLD
+ // flag set
+ // b_sst_array[] contains the state stack for a number of lines, for the
+ // start of that line (col == 0). This avoids having to recompute the
+ // syntax state too often.
+ // b_sst_array[] is allocated to hold the state for all displayed lines,
+ // and states for 1 out of about 20 other lines.
+ // b_sst_array pointer to an array of synstate_T
+ // b_sst_len number of entries in b_sst_array[]
+ // b_sst_first pointer to first used entry in b_sst_array[] or NULL
+ // b_sst_firstfree pointer to first free entry in b_sst_array[] or NULL
+ // b_sst_freecount number of free entries in b_sst_array[]
+ // b_sst_check_lnum entries after this lnum need to be checked for
+ // validity (MAXLNUM means no check needed)
synstate_T *b_sst_array;
int b_sst_len;
synstate_T *b_sst_first;
@@ -488,10 +488,10 @@ struct file_buffer {
memline_T b_ml; // associated memline (also contains line count
- buf_T *b_next; /* links in list of buffers */
+ buf_T *b_next; // links in list of buffers
buf_T *b_prev;
- int b_nwindows; /* nr of windows open on this buffer */
+ int b_nwindows; // nr of windows open on this buffer
int b_flags; // various BF_ flags
int b_locked; // Buffer is being closed or referenced, don't
@@ -532,24 +532,23 @@ struct file_buffer {
*/
bool b_mod_set; /* true when there are changes since the last
time the display was updated */
- linenr_T b_mod_top; /* topmost lnum that was changed */
- linenr_T b_mod_bot; /* lnum below last changed line, AFTER the
- change */
- long b_mod_xlines; /* number of extra buffer lines inserted;
- negative when lines were deleted */
+ linenr_T b_mod_top; // topmost lnum that was changed
+ linenr_T b_mod_bot; // lnum below last changed line, AFTER the
+ // change
+ long b_mod_xlines; // number of extra buffer lines inserted;
+ // negative when lines were deleted
+ wininfo_T *b_wininfo; // list of last used info for each window
- wininfo_T *b_wininfo; /* list of last used info for each window */
+ long b_mtime; // last change time of original file
+ long b_mtime_read; // last change time when reading
+ uint64_t b_orig_size; // size of original file in bytes
+ int b_orig_mode; // mode of original file
- long b_mtime; /* last change time of original file */
- long b_mtime_read; /* last change time when reading */
- uint64_t b_orig_size; /* size of original file in bytes */
- int b_orig_mode; /* mode of original file */
+ fmark_T b_namedm[NMARKS]; // current named marks (mark.c)
- fmark_T b_namedm[NMARKS]; /* current named marks (mark.c) */
-
- /* These variables are set when VIsual_active becomes FALSE */
+ // These variables are set when VIsual_active becomes FALSE
visualinfo_T b_visual;
- int b_visual_mode_eval; /* b_visual.vi_mode for visualmode() */
+ int b_visual_mode_eval; // b_visual.vi_mode for visualmode()
fmark_T b_last_cursor; // cursor position when last unloading this
// buffer
@@ -560,8 +559,8 @@ struct file_buffer {
* the changelist contains old change positions
*/
fmark_T b_changelist[JUMPLISTSIZE];
- int b_changelistlen; /* number of active entries */
- bool b_new_change; /* set by u_savecommon() */
+ int b_changelistlen; // number of active entries
+ bool b_new_change; // set by u_savecommon()
/*
* Character table, only used in charset.c for 'iskeyword'
@@ -572,9 +571,9 @@ struct file_buffer {
// Table used for mappings local to a buffer.
mapblock_T *(b_maphash[MAX_MAPHASH]);
- /* First abbreviation local to a buffer. */
+ // First abbreviation local to a buffer.
mapblock_T *b_first_abbr;
- /* User commands local to the buffer. */
+ // User commands local to the buffer.
garray_T b_ucmds;
/*
* start and end of an operator, also used for '[ and ']
@@ -583,31 +582,31 @@ struct file_buffer {
pos_T b_op_start_orig; // used for Insstart_orig
pos_T b_op_end;
- bool b_marks_read; /* Have we read ShaDa marks yet? */
+ bool b_marks_read; // Have we read ShaDa marks yet?
/*
* The following only used in undo.c.
*/
- u_header_T *b_u_oldhead; /* pointer to oldest header */
- u_header_T *b_u_newhead; /* pointer to newest header; may not be valid
- if b_u_curhead is not NULL */
- u_header_T *b_u_curhead; /* pointer to current header */
- int b_u_numhead; /* current number of headers */
- bool b_u_synced; /* entry lists are synced */
- long b_u_seq_last; /* last used undo sequence number */
- long b_u_save_nr_last; /* counter for last file write */
- long b_u_seq_cur; /* hu_seq of header below which we are now */
- time_t b_u_time_cur; /* uh_time of header below which we are now */
- long b_u_save_nr_cur; /* file write nr after which we are now */
+ u_header_T *b_u_oldhead; // pointer to oldest header
+ u_header_T *b_u_newhead; // pointer to newest header; may not be valid
+ // if b_u_curhead is not NULL
+ u_header_T *b_u_curhead; // pointer to current header
+ int b_u_numhead; // current number of headers
+ bool b_u_synced; // entry lists are synced
+ long b_u_seq_last; // last used undo sequence number
+ long b_u_save_nr_last; // counter for last file write
+ long b_u_seq_cur; // hu_seq of header below which we are now
+ time_t b_u_time_cur; // uh_time of header below which we are now
+ long b_u_save_nr_cur; // file write nr after which we are now
/*
* variables for "U" command in undo.c
*/
- char_u *b_u_line_ptr; /* saved line for "U" command */
- linenr_T b_u_line_lnum; /* line number of line in u_line */
- colnr_T b_u_line_colnr; /* optional column number */
+ char_u *b_u_line_ptr; // saved line for "U" command
+ linenr_T b_u_line_lnum; // line number of line in u_line
+ colnr_T b_u_line_colnr; // optional column number
- bool b_scanned; /* ^N/^P have scanned this buffer */
+ bool b_scanned; // ^N/^P have scanned this buffer
// flags for use of ":lmap" and IM control
long b_p_iminsert; // input mode for insert
@@ -617,10 +616,10 @@ struct file_buffer {
#define B_IMODE_LMAP 1 // Input via langmap
# define B_IMODE_LAST 1
- short b_kmap_state; /* using "lmap" mappings */
-# define KEYMAP_INIT 1 /* 'keymap' was set, call keymap_init() */
-# define KEYMAP_LOADED 2 /* 'keymap' mappings have been loaded */
- garray_T b_kmap_ga; /* the keymap table */
+ int16_t b_kmap_state; // using "lmap" mappings
+# define KEYMAP_INIT 1 // 'keymap' was set, call keymap_init()
+# define KEYMAP_LOADED 2 // 'keymap' mappings have been loaded
+ garray_T b_kmap_ga; // the keymap table
/*
* Options local to a buffer.
@@ -720,9 +719,9 @@ struct file_buffer {
int b_p_udf; ///< 'undofile'
char_u *b_p_lw; ///< 'lispwords' local value
- /* end of buffer options */
+ // end of buffer options
- /* values set from b_p_cino */
+ // values set from b_p_cino
int b_ind_level;
int b_ind_open_imag;
int b_ind_no_brace;
@@ -763,11 +762,11 @@ struct file_buffer {
linenr_T b_no_eol_lnum; /* non-zero lnum when last line of next binary
* write should not have an end-of-line */
- int b_start_eol; /* last line had eol when it was read */
- int b_start_ffc; /* first char of 'ff' when edit started */
- char_u *b_start_fenc; /* 'fileencoding' when edit started or NULL */
- int b_bad_char; /* "++bad=" argument when edit started or 0 */
- int b_start_bomb; /* 'bomb' when it was read */
+ int b_start_eol; // last line had eol when it was read
+ int b_start_ffc; // first char of 'ff' when edit started
+ char_u *b_start_fenc; // 'fileencoding' when edit started or NULL
+ int b_bad_char; // "++bad=" argument when edit started or 0
+ int b_start_bomb; // 'bomb' when it was read
ScopeDictDictItem b_bufvar; ///< Variable for "b:" Dictionary.
dict_T *b_vars; ///< b: scope dictionary.
@@ -866,8 +865,8 @@ struct file_buffer {
typedef struct diffblock_S diff_T;
struct diffblock_S {
diff_T *df_next;
- linenr_T df_lnum[DB_COUNT]; /* line number in buffer */
- linenr_T df_count[DB_COUNT]; /* nr of inserted/changed lines */
+ linenr_T df_lnum[DB_COUNT]; // line number in buffer
+ linenr_T df_count[DB_COUNT]; // nr of inserted/changed lines
};
#define SNAP_HELP_IDX 0
@@ -915,11 +914,11 @@ struct tabpage_S {
* wl_lnum and wl_lastlnum are invalid too.
*/
typedef struct w_line {
- linenr_T wl_lnum; /* buffer line number for logical line */
- uint16_t wl_size; /* height in screen lines */
- char wl_valid; /* TRUE values are valid for text in buffer */
- char wl_folded; /* TRUE when this is a range of folded lines */
- linenr_T wl_lastlnum; /* last buffer line number for logical line */
+ linenr_T wl_lnum; // buffer line number for logical line
+ uint16_t wl_size; // height in screen lines
+ char wl_valid; // TRUE values are valid for text in buffer
+ char wl_folded; // TRUE when this is a range of folded lines
+ linenr_T wl_lastlnum; // last buffer line number for logical line
} wline_T;
/*
@@ -942,9 +941,9 @@ struct frame_S {
win_T *fr_win; // window that fills this frame
};
-#define FR_LEAF 0 /* frame is a leaf */
-#define FR_ROW 1 /* frame with a row of windows */
-#define FR_COL 2 /* frame with a column of windows */
+#define FR_LEAF 0 // frame is a leaf
+#define FR_ROW 1 // frame with a row of windows
+#define FR_COL 2 // frame with a column of windows
/*
* Struct used for highlighting 'hlsearch' matches, matches defined by
@@ -1145,16 +1144,16 @@ struct window_S {
top of the window */
char w_topline_was_set; /* flag set to TRUE when topline is set,
e.g. by winrestview() */
- int w_topfill; /* number of filler lines above w_topline */
- int w_old_topfill; /* w_topfill at last redraw */
- bool w_botfill; /* true when filler lines are actually
- below w_topline (at end of file) */
- bool w_old_botfill; /* w_botfill at last redraw */
- colnr_T w_leftcol; /* window column number of the left most
- character in the window; used when
- 'wrap' is off */
- colnr_T w_skipcol; /* starting column when a single line
- doesn't fit in the window */
+ int w_topfill; // number of filler lines above w_topline
+ int w_old_topfill; // w_topfill at last redraw
+ bool w_botfill; // true when filler lines are actually
+ // below w_topline (at end of file)
+ bool w_old_botfill; // w_botfill at last redraw
+ colnr_T w_leftcol; // window column number of the left most
+ // character in the window; used when
+ // 'wrap' is off
+ colnr_T w_skipcol; // starting column when a single line
+ // doesn't fit in the window
//
// Layout of the window in the screen.
@@ -1188,16 +1187,18 @@ struct window_S {
int w_valid;
pos_T w_valid_cursor; /* last known position of w_cursor, used
to adjust w_valid */
- colnr_T w_valid_leftcol; /* last known w_leftcol */
+ colnr_T w_valid_leftcol; // last known w_leftcol
+
+ bool w_viewport_invalid;
/*
* w_cline_height is the number of physical lines taken by the buffer line
* that the cursor is on. We use this to avoid extra calls to plines().
*/
- int w_cline_height; /* current size of cursor line */
- bool w_cline_folded; /* cursor line is folded */
+ int w_cline_height; // current size of cursor line
+ bool w_cline_folded; // cursor line is folded
- int w_cline_row; /* starting row of the cursor line */
+ int w_cline_row; // starting row of the cursor line
colnr_T w_virtcol; // column number of the cursor in the
// buffer line, as opposed to the column
@@ -1211,7 +1212,7 @@ struct window_S {
* This is related to positions in the window, not in the display or
* buffer, thus w_wrow is relative to w_winrow.
*/
- int w_wrow, w_wcol; /* cursor position in window */
+ int w_wrow, w_wcol; // cursor position in window
linenr_T w_botline; // number of the line below the bottom of
// the window
@@ -1229,42 +1230,42 @@ struct window_S {
* what is currently displayed. wl_valid is reset to indicated this.
* This is used for efficient redrawing.
*/
- int w_lines_valid; /* number of valid entries */
+ int w_lines_valid; // number of valid entries
wline_T *w_lines;
- garray_T w_folds; /* array of nested folds */
- bool w_fold_manual; /* when true: some folds are opened/closed
- manually */
- bool w_foldinvalid; /* when true: folding needs to be
- recomputed */
- int w_nrwidth; /* width of 'number' and 'relativenumber'
- column being used */
+ garray_T w_folds; // array of nested folds
+ bool w_fold_manual; // when true: some folds are opened/closed
+ // manually
+ bool w_foldinvalid; // when true: folding needs to be
+ // recomputed
+ int w_nrwidth; // width of 'number' and 'relativenumber'
+ // column being used
/*
* === end of cached values ===
*/
- int w_redr_type; /* type of redraw to be performed on win */
- int w_upd_rows; /* number of window lines to update when
- w_redr_type is REDRAW_TOP */
- linenr_T w_redraw_top; /* when != 0: first line needing redraw */
- linenr_T w_redraw_bot; /* when != 0: last line needing redraw */
- int w_redr_status; /* if TRUE status line must be redrawn */
+ int w_redr_type; // type of redraw to be performed on win
+ int w_upd_rows; // number of window lines to update when
+ // w_redr_type is REDRAW_TOP
+ linenr_T w_redraw_top; // when != 0: first line needing redraw
+ linenr_T w_redraw_bot; // when != 0: last line needing redraw
+ int w_redr_status; // if TRUE status line must be redrawn
- /* remember what is shown in the ruler for this window (if 'ruler' set) */
- pos_T w_ru_cursor; /* cursor position shown in ruler */
- colnr_T w_ru_virtcol; /* virtcol shown in ruler */
- linenr_T w_ru_topline; /* topline shown in ruler */
- linenr_T w_ru_line_count; /* line count used for ruler */
- int w_ru_topfill; /* topfill shown in ruler */
- char w_ru_empty; /* TRUE if ruler shows 0-1 (empty line) */
+ // remember what is shown in the ruler for this window (if 'ruler' set)
+ pos_T w_ru_cursor; // cursor position shown in ruler
+ colnr_T w_ru_virtcol; // virtcol shown in ruler
+ linenr_T w_ru_topline; // topline shown in ruler
+ linenr_T w_ru_line_count; // line count used for ruler
+ int w_ru_topfill; // topfill shown in ruler
+ char w_ru_empty; // TRUE if ruler shows 0-1 (empty line)
- int w_alt_fnum; /* alternate file (for # and CTRL-^) */
+ int w_alt_fnum; // alternate file (for # and CTRL-^)
- alist_T *w_alist; /* pointer to arglist for this window */
- int w_arg_idx; /* current index in argument list (can be
- out of range!) */
- int w_arg_idx_invalid; /* editing another file than w_arg_idx */
+ alist_T *w_alist; // pointer to arglist for this window
+ int w_arg_idx; // current index in argument list (can be
+ // out of range!)
+ int w_arg_idx_invalid; // editing another file than w_arg_idx
char_u *w_localdir; /* absolute path of local directory or
NULL */
@@ -1278,16 +1279,18 @@ struct window_S {
winopt_T w_onebuf_opt;
winopt_T w_allbuf_opt;
- /* A few options have local flags for P_INSECURE. */
- uint32_t w_p_stl_flags; /* flags for 'statusline' */
- uint32_t w_p_fde_flags; /* flags for 'foldexpr' */
- uint32_t w_p_fdt_flags; /* flags for 'foldtext' */
- int *w_p_cc_cols; /* array of columns to highlight or NULL */
- int w_p_brimin; /* minimum width for breakindent */
- int w_p_brishift; /* additional shift for breakindent */
- bool w_p_brisbr; /* sbr in 'briopt' */
-
- /* transform a pointer to a "onebuf" option into a "allbuf" option */
+ // A few options have local flags for P_INSECURE.
+ uint32_t w_p_stl_flags; // flags for 'statusline'
+ uint32_t w_p_fde_flags; // flags for 'foldexpr'
+ uint32_t w_p_fdt_flags; // flags for 'foldtext'
+ int *w_p_cc_cols; // array of columns to highlight or NULL
+ int w_p_brimin; // minimum width for breakindent
+ int w_p_brishift; // additional shift for breakindent
+ bool w_p_brisbr; // sbr in 'briopt'
+ long w_p_siso; // 'sidescrolloff' local value
+ long w_p_so; // 'scrolloff' local value
+
+ // transform a pointer to a "onebuf" option into a "allbuf" option
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
long w_scbind_pos;
@@ -1300,20 +1303,20 @@ struct window_S {
* a new line after setting the w_pcmark. If not, then we revert to
* using the previous w_pcmark.
*/
- pos_T w_pcmark; /* previous context mark */
- pos_T w_prev_pcmark; /* previous w_pcmark */
+ pos_T w_pcmark; // previous context mark
+ pos_T w_prev_pcmark; // previous w_pcmark
/*
* the jumplist contains old cursor positions
*/
xfmark_T w_jumplist[JUMPLISTSIZE];
- int w_jumplistlen; /* number of active entries */
- int w_jumplistidx; /* current position */
+ int w_jumplistlen; // number of active entries
+ int w_jumplistidx; // current position
- int w_changelistidx; /* current position in b_changelist */
+ int w_changelistidx; // current position in b_changelist
- matchitem_T *w_match_head; /* head of match list */
- int w_next_match_id; /* next match ID */
+ matchitem_T *w_match_head; // head of match list
+ int w_next_match_id; // next match ID
/*
* the tagstack grows from 0 upwards:
@@ -1321,9 +1324,9 @@ struct window_S {
* entry 1: newer
* entry 2: newest
*/
- taggy_T w_tagstack[TAGSTACKSIZE]; /* the tag stack */
- int w_tagstackidx; /* idx just below active entry */
- int w_tagstacklen; /* number of tags on stack */
+ taggy_T w_tagstack[TAGSTACKSIZE]; // the tag stack
+ int w_tagstackidx; // idx just below active entry
+ int w_tagstacklen; // number of tags on stack
ScreenGrid w_grid; // the grid specific to the window
bool w_pos_changed; // true if window position changed
@@ -1341,13 +1344,11 @@ struct window_S {
linenr_T w_nrwidth_line_count; /* line count when ml_nrwidth_width
* was computed. */
- int w_nrwidth_width; /* nr of chars to print line count. */
+ int w_nrwidth_width; // nr of chars to print line count.
- qf_info_T *w_llist; /* Location list for this window */
- /*
- * Location list reference used in the location list window.
- * In a non-location list window, w_llist_ref is NULL.
- */
+ qf_info_T *w_llist; // Location list for this window
+ // Location list reference used in the location list window.
+ // In a non-location list window, w_llist_ref is NULL.
qf_info_T *w_llist_ref;
};
diff --git a/src/nvim/change.c b/src/nvim/change.c
index a341b8fce1..51afb40b40 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -361,8 +361,8 @@ void changed_bytes(linenr_T lnum, colnr_T col)
/// insert/delete bytes at column
///
-/// Like changed_bytes() but also adjust extmark for "added" bytes.
-/// When "added" is negative text was deleted.
+/// Like changed_bytes() but also adjust extmark for "new" bytes.
+/// When "new" is negative text was deleted.
static void inserted_bytes(linenr_T lnum, colnr_T col, int old, int new)
{
if (curbuf_splice_pending == 0) {
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index c66a0682e3..5eb29a7290 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -19,7 +19,6 @@
#include "nvim/ascii.h"
static bool did_stdio = false;
-PMap(uint64_t) *channels = NULL;
/// next free id for a job or rpc channel
/// 1 is reserved for stdio channel
diff --git a/src/nvim/channel.h b/src/nvim/channel.h
index c733e276be..9d26852ce5 100644
--- a/src/nvim/channel.h
+++ b/src/nvim/channel.h
@@ -85,7 +85,7 @@ struct Channel {
bool callback_scheduled;
};
-EXTERN PMap(uint64_t) *channels;
+EXTERN PMap(uint64_t) *channels INIT(= NULL);
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "channel.h.generated.h"
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 0f9e2e23c0..f9d5adbc12 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1570,6 +1570,7 @@ char_u* skiptohex(char_u *q)
///
/// @return Pointer to the next whitespace or NUL character.
char_u *skiptowhite(const char_u *p)
+ FUNC_ATTR_NONNULL_ALL
{
while (*p != ' ' && *p != '\t' && *p != NUL) {
p++;
diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h
index 2c466603f0..a23fa6836d 100644
--- a/src/nvim/cursor_shape.h
+++ b/src/nvim/cursor_shape.h
@@ -33,11 +33,11 @@ SHAPE_HOR = 1, ///< horizontal bar cursor
SHAPE_VER = 2 ///< vertical bar cursor
} CursorShape;
-#define MSHAPE_NUMBERED 1000 /* offset for shapes identified by number */
-#define MSHAPE_HIDE 1 /* hide mouse pointer */
+#define MSHAPE_NUMBERED 1000 // offset for shapes identified by number
+#define MSHAPE_HIDE 1 // hide mouse pointer
-#define SHAPE_MOUSE 1 /* used for mouse pointer shape */
-#define SHAPE_CURSOR 2 /* used for text cursor shape */
+#define SHAPE_MOUSE 1 // used for mouse pointer shape
+#define SHAPE_CURSOR 2 // used for text cursor shape
typedef struct cursor_entry {
char *full_name; ///< mode description
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 04309444d9..3de5fc49bd 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -648,8 +648,8 @@ void diff_redraw(bool dofold)
foldUpdateAll(wp);
}
- /* A change may have made filler lines invalid, need to take care
- * of that for other windows. */
+ // A change may have made filler lines invalid, need to take care
+ // of that for other windows.
int n = diff_check(wp, wp->w_topline);
if (((wp != curwin) && (wp->w_topfill > 0)) || (n > 0)) {
@@ -1385,11 +1385,18 @@ void diff_win_options(win_T *wp, int addbuf)
curbuf = curwin->w_buffer;
if (!wp->w_p_diff) {
- wp->w_p_fdc_save = wp->w_p_fdc;
wp->w_p_fen_save = wp->w_p_fen;
wp->w_p_fdl_save = wp->w_p_fdl;
+
+ if (wp->w_p_diff_saved) {
+ free_string_option(wp->w_p_fdc_save);
+ }
+ wp->w_p_fdc_save = vim_strsave(wp->w_p_fdc);
}
- wp->w_p_fdc = diff_foldcolumn;
+ xfree(wp->w_p_fdc);
+ wp->w_p_fdc = (char_u *)xstrdup("2");
+ assert(diff_foldcolumn >= 0 && diff_foldcolumn <= 9);
+ snprintf((char *)wp->w_p_fdc, STRLEN(wp->w_p_fdc) + 1, "%d", diff_foldcolumn);
wp->w_p_fen = true;
wp->w_p_fdl = 0;
foldUpdateAll(wp);
@@ -1443,9 +1450,9 @@ void ex_diffoff(exarg_T *eap)
wp->w_p_fdm = vim_strsave(*wp->w_p_fdm_save
? wp->w_p_fdm_save
: (char_u *)"manual");
- if (wp->w_p_fdc == diff_foldcolumn) {
- wp->w_p_fdc = wp->w_p_fdc_save;
- }
+ free_string_option(wp->w_p_fdc);
+ wp->w_p_fdc = vim_strsave(wp->w_p_fdc_save);
+
if (wp->w_p_fdl == 0) {
wp->w_p_fdl = wp->w_p_fdl_save;
}
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index cebd08af28..a291ed0401 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -184,7 +184,7 @@ static bool compl_used_match; // Selected one of the matches.
static int compl_was_interrupted = FALSE; /* didn't finish finding
completions. */
-static int compl_restarting = FALSE; /* don't insert match */
+static bool compl_restarting = false; // don't insert match
// When the first completion is done "compl_started" is set. When it's
// false the word to be completed must be located.
@@ -197,7 +197,7 @@ static int compl_matches = 0;
static char_u *compl_pattern = NULL;
static int compl_direction = FORWARD;
static int compl_shows_dir = FORWARD;
-static int compl_pending = 0; /* > 1 for postponed CTRL-N */
+static int compl_pending = 0; // > 1 for postponed CTRL-N
static pos_T compl_startpos;
static colnr_T compl_col = 0; /* column where the text starts
* that is being completed */
@@ -249,30 +249,30 @@ typedef struct insert_state {
#define BACKSPACE_WORD_NOT_SPACE 3
#define BACKSPACE_LINE 4
-static size_t spell_bad_len = 0; /* length of located bad word */
+static size_t spell_bad_len = 0; // length of located bad word
-static colnr_T Insstart_textlen; /* length of line when insert started */
-static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */
-static bool update_Insstart_orig = true; /* set Insstart_orig to Insstart */
+static colnr_T Insstart_textlen; // length of line when insert started
+static colnr_T Insstart_blank_vcol; // vcol for first inserted blank
+static bool update_Insstart_orig = true; // set Insstart_orig to Insstart
-static char_u *last_insert = NULL; /* the text of the previous insert,
- K_SPECIAL and CSI are escaped */
-static int last_insert_skip; /* nr of chars in front of previous insert */
-static int new_insert_skip; /* nr of chars in front of current insert */
-static int did_restart_edit; /* "restart_edit" when calling edit() */
+static char_u *last_insert = NULL; // the text of the previous insert,
+ // K_SPECIAL and CSI are escaped
+static int last_insert_skip; // nr of chars in front of previous insert
+static int new_insert_skip; // nr of chars in front of current insert
+static int did_restart_edit; // "restart_edit" when calling edit()
static bool can_cindent; // may do cindenting on this line
-static int old_indent = 0; /* for ^^D command in insert mode */
+static int old_indent = 0; // for ^^D command in insert mode
-static int revins_on; /* reverse insert mode on */
-static int revins_chars; /* how much to skip after edit */
-static int revins_legal; /* was the last char 'legal'? */
-static int revins_scol; /* start column of revins session */
+static int revins_on; // reverse insert mode on
+static int revins_chars; // how much to skip after edit
+static int revins_legal; // was the last char 'legal'?
+static int revins_scol; // start column of revins session
-static int ins_need_undo; /* call u_save() before inserting a
- char. Set when edit() is called.
- after that arrow_used is used. */
+static bool ins_need_undo; // call u_save() before inserting a
+ // char. Set when edit() is called.
+ // after that arrow_used is used.
static bool did_add_space = false; // auto_format() added an extra space
// under the cursor
@@ -464,8 +464,8 @@ static void insert_enter(InsertState *s)
change_warning(s->i == 0 ? 0 : s->i + 1);
}
- ui_cursor_shape(); /* may show different cursor shape */
- do_digraph(-1); /* clear digraphs */
+ ui_cursor_shape(); // may show different cursor shape
+ do_digraph(-1); // clear digraphs
// Get the current length of the redo buffer, those characters have to be
// skipped if we want to get to the inserted characters.
@@ -574,10 +574,8 @@ static int insert_check(VimState *state)
foldCheckClose();
}
- int cmdchar_todo = s->cmdchar;
if (bt_prompt(curbuf)) {
- init_prompt(cmdchar_todo);
- cmdchar_todo = NUL;
+ init_prompt(s->cmdchar);
}
// If we inserted a character at the last position of the last line in the
@@ -595,7 +593,7 @@ static int insert_check(VimState *state)
if (curwin->w_wcol < s->mincol - curbuf->b_p_ts
&& curwin->w_wrow == curwin->w_winrow
- + curwin->w_height_inner - 1 - p_so
+ + curwin->w_height_inner - 1 - get_scrolloff_value()
&& (curwin->w_cursor.lnum != curwin->w_topline
|| curwin->w_topfill > 0)) {
if (curwin->w_topfill > 0) {
@@ -1422,9 +1420,8 @@ bool edit(int cmdchar, bool startln, long count)
* Only redraw when there are no characters available. This speeds up
* inserting sequences of characters (e.g., for CTRL-R).
*/
-static void
-ins_redraw (
- int ready /* not busy with something */
+static void ins_redraw(
+ bool ready // not busy with something
)
{
bool conceal_cursor_moved = false;
@@ -1505,7 +1502,7 @@ ins_redraw (
}
showruler(false);
setcursor();
- emsg_on_display = FALSE; /* may remove error message now */
+ emsg_on_display = false; // may remove error message now
}
/*
@@ -1514,24 +1511,25 @@ ins_redraw (
static void ins_ctrl_v(void)
{
int c;
- int did_putchar = FALSE;
+ bool did_putchar = false;
- /* may need to redraw when no more chars available now */
- ins_redraw(FALSE);
+ // may need to redraw when no more chars available now
+ ins_redraw(false);
if (redrawing() && !char_avail()) {
- edit_putchar('^', TRUE);
- did_putchar = TRUE;
+ edit_putchar('^', true);
+ did_putchar = true;
}
AppendToRedobuff(CTRL_V_STR);
add_to_showcmd_c(Ctrl_V);
c = get_literal();
- if (did_putchar)
- /* when the line fits in 'columns' the '^' is at the start of the next
- * line and will not removed by the redraw */
+ if (did_putchar) {
+ // when the line fits in 'columns' the '^' is at the start of the next
+ // line and will not removed by the redraw
edit_unputchar();
+ }
clear_showcmd();
insert_special(c, true, true);
revins_chars++;
@@ -1543,16 +1541,16 @@ static void ins_ctrl_v(void)
* Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
*/
static int pc_status;
-#define PC_STATUS_UNSET 0 /* pc_bytes was not set */
-#define PC_STATUS_RIGHT 1 /* right halve of double-wide char */
-#define PC_STATUS_LEFT 2 /* left halve of double-wide char */
-#define PC_STATUS_SET 3 /* pc_bytes was filled */
-static char_u pc_bytes[MB_MAXBYTES + 1]; /* saved bytes */
+#define PC_STATUS_UNSET 0 // pc_bytes was not set
+#define PC_STATUS_RIGHT 1 // right halve of double-wide char
+#define PC_STATUS_LEFT 2 // left halve of double-wide char
+#define PC_STATUS_SET 3 // pc_bytes was filled
+static char_u pc_bytes[MB_MAXBYTES + 1]; // saved bytes
static int pc_attr;
static int pc_row;
static int pc_col;
-void edit_putchar(int c, int highlight)
+void edit_putchar(int c, bool highlight)
{
int attr;
@@ -1585,7 +1583,7 @@ void edit_putchar(int c, int highlight)
}
}
- /* save the character to be able to put it back */
+ // save the character to be able to put it back
if (pc_status == PC_STATUS_UNSET) {
grid_getbytes(&curwin->w_grid, pc_row, pc_col, pc_bytes, &pc_attr);
pc_status = PC_STATUS_SET;
@@ -1708,29 +1706,29 @@ change_indent (
int type,
int amount,
int round,
- int replaced, /* replaced character, put on replace stack */
- int call_changed_bytes /* call changed_bytes() */
+ int replaced, // replaced character, put on replace stack
+ int call_changed_bytes // call changed_bytes()
)
{
int vcol;
int last_vcol;
- int insstart_less; /* reduction for Insstart.col */
+ int insstart_less; // reduction for Insstart.col
int new_cursor_col;
int i;
char_u *ptr;
int save_p_list;
int start_col;
colnr_T vc;
- colnr_T orig_col = 0; /* init for GCC */
- char_u *new_line, *orig_line = NULL; /* init for GCC */
+ colnr_T orig_col = 0; // init for GCC
+ char_u *new_line, *orig_line = NULL; // init for GCC
- /* VREPLACE mode needs to know what the line was like before changing */
+ // VREPLACE mode needs to know what the line was like before changing
if (State & VREPLACE_FLAG) {
- orig_line = vim_strsave(get_cursor_line_ptr()); /* Deal with NULL below */
+ orig_line = vim_strsave(get_cursor_line_ptr()); // Deal with NULL below
orig_col = curwin->w_cursor.col;
}
- /* for the following tricks we don't want list mode */
+ // for the following tricks we don't want list mode
save_p_list = curwin->w_p_list;
curwin->w_p_list = FALSE;
vc = getvcol_nolist(&curwin->w_cursor);
@@ -1743,7 +1741,7 @@ change_indent (
*/
start_col = curwin->w_cursor.col;
- /* determine offset from first non-blank */
+ // determine offset from first non-blank
new_cursor_col = curwin->w_cursor.col;
beginline(BL_WHITE);
new_cursor_col -= curwin->w_cursor.col;
@@ -1757,8 +1755,9 @@ change_indent (
if (new_cursor_col < 0)
vcol = get_indent() - vcol;
- if (new_cursor_col > 0) /* can't fix replace stack */
+ if (new_cursor_col > 0) { // can't fix replace stack
start_col = -1;
+ }
/*
* Set the new indent. The cursor will be put on the first non-blank.
@@ -1768,9 +1767,10 @@ change_indent (
else {
int save_State = State;
- /* Avoid being called recursively. */
- if (State & VREPLACE_FLAG)
+ // Avoid being called recursively.
+ if (State & VREPLACE_FLAG) {
State = INSERT;
+ }
shift_line(type == INDENT_DEC, round, 1, call_changed_bytes);
State = save_State;
}
@@ -1873,8 +1873,8 @@ change_indent (
*/
if (REPLACE_NORMAL(State) && start_col >= 0) {
while (start_col > (int)curwin->w_cursor.col) {
- replace_join(0); /* remove a NUL from the replace stack */
- --start_col;
+ replace_join(0); // remove a NUL from the replace stack
+ start_col--;
}
while (start_col < (int)curwin->w_cursor.col || replaced) {
replace_push(NUL);
@@ -1892,10 +1892,10 @@ change_indent (
* put it back again the way we wanted it.
*/
if (State & VREPLACE_FLAG) {
- /* Save new line */
+ // Save new line
new_line = vim_strsave(get_cursor_line_ptr());
- /* We only put back the new line up to the cursor */
+ // We only put back the new line up to the cursor
new_line[curwin->w_cursor.col] = NUL;
int new_col = curwin->w_cursor.col;
@@ -1905,10 +1905,10 @@ change_indent (
curbuf_splice_pending++;
- /* Backspace from cursor to start of line */
+ // Backspace from cursor to start of line
backspace_until_column(0);
- /* Insert new stuff into line again */
+ // Insert new stuff into line again
ins_bytes(new_line);
xfree(new_line);
@@ -1934,10 +1934,11 @@ void truncate_spaces(char_u *line)
{
int i;
- /* find start of trailing white space */
+ // find start of trailing white space
for (i = (int)STRLEN(line) - 1; i >= 0 && ascii_iswhite(line[i]); i--) {
- if (State & REPLACE_FLAG)
- replace_join(0); /* remove a NUL from the replace stack */
+ if (State & REPLACE_FLAG) {
+ replace_join(0); // remove a NUL from the replace stack
+ }
}
line[i + 1] = NUL;
}
@@ -2006,7 +2007,7 @@ static void ins_ctrl_x(void)
compl_cont_status |= CONT_INTRPT;
else
compl_cont_status = 0;
- /* We're not sure which CTRL-X mode it will be yet */
+ // We're not sure which CTRL-X mode it will be yet
ctrl_x_mode = CTRL_X_NOT_DEFINED_YET;
edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode));
edit_submode_pre = NULL;
@@ -2155,8 +2156,8 @@ int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname,
{
char_u *str = str_arg;
int i, c;
- int actual_len; /* Take multi-byte characters */
- int actual_compl_length; /* into account. */
+ int actual_len; // Take multi-byte characters
+ int actual_compl_length; // into account.
int min_len;
bool has_lower = false;
bool was_letter = false;
@@ -2176,16 +2177,15 @@ int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname,
} else
actual_len = len;
- /* Find actual length of original text. */
- if (has_mbyte) {
+ // Find actual length of original text.
+ {
const char_u *p = compl_orig_text;
actual_compl_length = 0;
while (*p != NUL) {
MB_PTR_ADV(p);
actual_compl_length++;
}
- } else
- actual_compl_length = compl_length;
+ }
/* "actual_len" may be smaller than "actual_compl_length" when using
* thesaurus, only use the minimum when comparing. */
@@ -2355,7 +2355,7 @@ static int ins_compl_add(char_u *const str, int len,
} while (match != NULL && match != compl_first_match);
}
- /* Remove any popup menu before changing the list of matches. */
+ // Remove any popup menu before changing the list of matches.
ins_compl_del_pum();
/*
@@ -2411,16 +2411,18 @@ static int ins_compl_add(char_u *const str, int len,
else if (dir == FORWARD) {
match->cp_next = compl_curr_match->cp_next;
match->cp_prev = compl_curr_match;
- } else { /* BACKWARD */
+ } else { // BACKWARD
match->cp_next = compl_curr_match;
match->cp_prev = compl_curr_match->cp_prev;
}
- if (match->cp_next)
+ if (match->cp_next) {
match->cp_next->cp_prev = match;
- if (match->cp_prev)
+ }
+ if (match->cp_prev) {
match->cp_prev->cp_next = match;
- else /* if there's nothing before, it is the first match */
+ } else { // if there's nothing before, it is the first match
compl_first_match = match;
+ }
compl_curr_match = match;
/*
@@ -2461,7 +2463,7 @@ static void ins_compl_longest_match(compl_T *match)
int had_match;
if (compl_leader == NULL) {
- /* First match, use it as a whole. */
+ // First match, use it as a whole.
compl_leader = vim_strsave(match->cp_str);
had_match = (curwin->w_cursor.col > compl_col);
ins_compl_delete();
@@ -2474,7 +2476,7 @@ static void ins_compl_longest_match(compl_T *match)
ins_compl_delete();
compl_used_match = false;
} else {
- /* Reduce the text if this match differs from compl_leader. */
+ // Reduce the text if this match differs from compl_leader.
p = compl_leader;
s = match->cp_str;
while (*p != NUL) {
@@ -2491,7 +2493,7 @@ static void ins_compl_longest_match(compl_T *match)
}
if (*p != NUL) {
- /* Leader was shortened, need to change the inserted text. */
+ // Leader was shortened, need to change the inserted text.
*p = NUL;
had_match = (curwin->w_cursor.col > compl_col);
ins_compl_delete();
@@ -2541,7 +2543,7 @@ static int ins_compl_make_cyclic(void)
* Find the end of the list.
*/
match = compl_first_match;
- /* there's always an entry for the compl_orig_text, it doesn't count. */
+ // there's always an entry for the compl_orig_text, it doesn't count.
while (match->cp_next != NULL && match->cp_next != compl_first_match) {
match = match->cp_next;
++count;
@@ -2588,7 +2590,7 @@ void set_completion(colnr_T startcol, list_T *list)
startcol = curwin->w_cursor.col;
compl_col = startcol;
compl_length = (int)curwin->w_cursor.col - (int)startcol;
- /* compl_pattern doesn't need to be set */
+ // compl_pattern doesn't need to be set
compl_orig_text = vim_strnsave(get_cursor_line_ptr() + compl_col,
compl_length);
if (p_ic) {
@@ -2721,10 +2723,10 @@ void ins_compl_show_pum(void)
if (!pum_wanted() || !pum_enough_matches())
return;
- /* Dirty hard-coded hack: remove any matchparen highlighting. */
+ // Dirty hard-coded hack: remove any matchparen highlighting.
do_cmdline_cmd("if exists('g:loaded_matchparen')|3match none|endif");
- /* Update the screen before drawing the popup menu over it. */
+ // Update the screen before drawing the popup menu over it.
update_screen(0);
if (compl_match_array == NULL) {
@@ -2815,17 +2817,19 @@ void ins_compl_show_pum(void)
compl = compl->cp_next;
} while (compl != NULL && compl != compl_first_match);
- if (!shown_match_ok) /* no displayed match at all */
+ if (!shown_match_ok) { // no displayed match at all
cur = -1;
+ }
} else {
- /* popup menu already exists, only need to find the current item.*/
- for (i = 0; i < compl_match_arraysize; ++i)
+ // popup menu already exists, only need to find the current item.
+ for (i = 0; i < compl_match_arraysize; i++) {
if (compl_match_array[i].pum_text == compl_shown_match->cp_str
|| compl_match_array[i].pum_text
== compl_shown_match->cp_text[CPT_ABBR]) {
cur = i;
break;
}
+ }
}
// In Replace mode when a $ is displayed at the end of the line only
@@ -2845,8 +2849,8 @@ void ins_compl_show_pum(void)
}
}
-#define DICT_FIRST (1) /* use just first element in "dict" */
-#define DICT_EXACT (2) /* "dict" is the exact name of a file */
+#define DICT_FIRST (1) // use just first element in "dict"
+#define DICT_EXACT (2) // "dict" is the exact name of a file
/*
* Add any identifiers that match the given pattern in the list of dictionary
@@ -2856,8 +2860,8 @@ static void
ins_compl_dictionaries (
char_u *dict_start,
char_u *pat,
- int flags, /* DICT_FIRST and/or DICT_EXACT */
- int thesaurus /* Thesaurus completion */
+ int flags, // DICT_FIRST and/or DICT_EXACT
+ int thesaurus // Thesaurus completion
)
{
char_u *dict = dict_start;
@@ -2879,9 +2883,9 @@ ins_compl_dictionaries (
}
buf = xmalloc(LSIZE);
- regmatch.regprog = NULL; /* so that we can goto theend */
+ regmatch.regprog = NULL; // so that we can goto theend
- /* If 'infercase' is set, don't use 'smartcase' here */
+ // If 'infercase' is set, don't use 'smartcase' here
save_p_scs = p_scs;
if (curbuf->b_p_inf)
p_scs = FALSE;
@@ -2904,10 +2908,10 @@ ins_compl_dictionaries (
goto theend;
}
- /* ignore case depends on 'ignorecase', 'smartcase' and "pat" */
+ // ignore case depends on 'ignorecase', 'smartcase' and "pat"
regmatch.rm_ic = ignorecase(pat);
while (*dict != NUL && !got_int && !compl_interrupted) {
- /* copy one dictionary file name into buf */
+ // copy one dictionary file name into buf
if (flags == DICT_EXACT) {
count = 1;
files = &dict;
@@ -2932,7 +2936,7 @@ ins_compl_dictionaries (
else
ptr = pat;
spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0);
- } else if (count > 0) { /* avoid warning for using "files" uninit */
+ } else if (count > 0) { // avoid warning for using "files" uninit
ins_compl_files(count, files, thesaurus, flags,
&regmatch, buf, &dir);
if (flags != DICT_EXACT)
@@ -2998,20 +3002,18 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags,
break;
wstart = ptr;
- /* Find end of the word. */
- if (has_mbyte)
- /* Japanese words may have characters in
- * different classes, only separate words
- * with single-byte non-word characters. */
- while (*ptr != NUL) {
- int l = (*mb_ptr2len)(ptr);
-
- if (l < 2 && !vim_iswordc(*ptr))
- break;
- ptr += l;
+ // Find end of the word.
+ // Japanese words may have characters in
+ // different classes, only separate words
+ // with single-byte non-word characters.
+ while (*ptr != NUL) {
+ const int l = utfc_ptr2len(ptr);
+
+ if (l < 2 && !vim_iswordc(*ptr)) {
+ break;
}
- else
- ptr = find_word_end(ptr);
+ ptr += l;
+ }
// Add the word. Skip the regexp match.
if (wstart != regmatch->startp[0]) {
@@ -3020,15 +3022,17 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags,
}
}
}
- if (add_r == OK)
- /* if dir was BACKWARD then honor it just once */
+ if (add_r == OK) {
+ // if dir was BACKWARD then honor it just once
*dir = FORWARD;
- else if (add_r == FAIL)
+ } else if (add_r == FAIL) {
break;
- /* avoid expensive call to vim_regexec() when at end
- * of line */
- if (*ptr == '\n' || got_int)
+ }
+ // avoid expensive call to vim_regexec() when at end
+ // of line
+ if (*ptr == '\n' || got_int) {
break;
+ }
}
line_breakcheck();
ins_compl_check_keys(50, false);
@@ -3275,9 +3279,10 @@ static int ins_compl_bs(void)
xfree(compl_leader);
compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col);
ins_compl_new_leader();
- if (compl_shown_match != NULL)
- /* Make sure current match is not a hidden item. */
+ if (compl_shown_match != NULL) {
+ // Make sure current match is not a hidden item.
compl_curr_match = compl_shown_match;
+ }
return NUL;
}
@@ -3321,7 +3326,7 @@ static void ins_compl_new_leader(void)
compl_enter_selects = !compl_used_match;
- /* Show the popup menu with a different set of matches. */
+ // Show the popup menu with a different set of matches.
ins_compl_show_pum();
/* Don't let Enter select the original text when there is no popup menu.
@@ -3364,9 +3369,10 @@ static void ins_compl_addleader(int c)
ins_char(c);
}
- /* If we didn't complete finding matches we must search again. */
- if (ins_compl_need_restart())
+ // If we didn't complete finding matches we must search again.
+ if (ins_compl_need_restart()) {
ins_compl_restart();
+ }
xfree(compl_leader);
compl_leader = vim_strnsave(get_cursor_line_ptr() + compl_col,
@@ -3422,9 +3428,9 @@ static void ins_compl_addfrommatch(void)
compl_T *cp;
assert(compl_shown_match != NULL);
p = compl_shown_match->cp_str;
- if ((int)STRLEN(p) <= len) { /* the match is too short */
- /* When still at the original match use the first entry that matches
- * the leader. */
+ if ((int)STRLEN(p) <= len) { // the match is too short
+ // When still at the original match use the first entry that matches
+ // the leader.
if (compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) {
p = NULL;
for (cp = compl_shown_match->cp_next; cp != NULL
@@ -3464,14 +3470,14 @@ static bool ins_compl_prep(int c)
if (c != Ctrl_R && vim_is_ctrl_x_key(c))
edit_submode_extra = NULL;
- /* Ignore end of Select mode mapping and mouse scroll buttons. */
+ // 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_EVENT
|| c == K_COMMAND) {
return retval;
}
- /* Set "compl_get_longest" when finding the first matches. */
+ // Set "compl_get_longest" when finding the first matches.
if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET
|| (ctrl_x_mode == CTRL_X_NORMAL && !compl_started)) {
compl_get_longest = (strstr((char *)p_cot, "longest") != NULL);
@@ -3504,7 +3510,7 @@ static bool ins_compl_prep(int c)
ctrl_x_mode = CTRL_X_DICTIONARY;
break;
case Ctrl_R:
- /* Simply allow ^R to happen without affecting ^X mode */
+ // Simply allow ^R to happen without affecting ^X mode
break;
case Ctrl_T:
ctrl_x_mode = CTRL_X_THESAURUS;
@@ -3518,9 +3524,9 @@ static bool ins_compl_prep(int c)
case 's':
case Ctrl_S:
ctrl_x_mode = CTRL_X_SPELL;
- ++emsg_off; /* Avoid getting the E756 error twice. */
+ emsg_off++; // Avoid getting the E756 error twice.
spell_back_to_badword();
- --emsg_off;
+ emsg_off--;
break;
case Ctrl_RSB:
ctrl_x_mode = CTRL_X_TAGS;
@@ -3619,10 +3625,10 @@ static bool ins_compl_prep(int c)
// 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 */
+ // re-indent the current line
if (want_cindent) {
do_c_expr_indent();
- want_cindent = FALSE; /* don't do it again */
+ want_cindent = false; // don't do it again
}
} else {
int prev_col = curwin->w_cursor.col;
@@ -3726,10 +3732,11 @@ static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg)
char_u *ptr = ptr_arg;
if (ptr == NULL) {
- if (compl_leader != NULL)
+ if (compl_leader != NULL) {
ptr = compl_leader;
- else
- return; /* nothing to do */
+ } else {
+ return; // nothing to do
+ }
}
if (compl_orig_text != NULL) {
p = compl_orig_text;
@@ -3758,9 +3765,10 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag)
{
static win_T *wp;
- if (flag == 'w') { /* just windows */
- if (buf == curbuf) /* first call for this flag/expansion */
+ if (flag == 'w') { // just windows
+ if (buf == curbuf) { // first call for this flag/expansion
wp = curwin;
+ }
assert(wp);
while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin
&& wp->w_buffer->b_scanned)
@@ -3838,7 +3846,7 @@ expand_by_function(
EMSG(_(e_complwin));
goto theend;
}
- curwin->w_cursor = pos; /* restore the cursor position */
+ curwin->w_cursor = pos; // restore the cursor position
validate_cursor();
if (!equalpos(curwin->w_cursor, pos)) {
EMSG(_(e_compldel));
@@ -4085,7 +4093,7 @@ static int ins_compl_get_exp(pos_T *ini)
type = CTRL_X_PATH_DEFINES;
else if (*e_cpt == ']' || *e_cpt == 't') {
type = CTRL_X_TAGS;
- vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags."));
+ vim_snprintf((char *)IObuff, IOSIZE, "%s", _("Scanning tags."));
(void)msg_trunc_attr(IObuff, true, HL_ATTR(HLF_R));
} else {
type = -1;
@@ -4476,8 +4484,7 @@ ins_compl_next (
int num_matches = -1;
int todo = count;
compl_T *found_compl = NULL;
- int found_end = FALSE;
- int advance;
+ bool found_end = false;
const bool started = compl_started;
/* When user complete function return -1 for findstart which is next
@@ -4513,17 +4520,17 @@ ins_compl_next (
if (allow_get_expansion && insert_match
&& (!(compl_get_longest || compl_restarting) || compl_used_match))
- /* Delete old text to be replaced */
+ // Delete old text to be replaced
ins_compl_delete();
- /* When finding the longest common text we stick at the original text,
- * don't let CTRL-N or CTRL-P move to the first match. */
- advance = count != 1 || !allow_get_expansion || !compl_get_longest;
+ // When finding the longest common text we stick at the original text,
+ // don't let CTRL-N or CTRL-P move to the first match.
+ bool advance = count != 1 || !allow_get_expansion || !compl_get_longest;
- /* When restarting the search don't insert the first match either. */
+ // When restarting the search don't insert the first match either.
if (compl_restarting) {
- advance = FALSE;
- compl_restarting = FALSE;
+ advance = false;
+ compl_restarting = false;
}
/* Repeat this for when <PageUp> or <PageDown> is typed. But don't wrap
@@ -4557,10 +4564,10 @@ ins_compl_next (
++compl_pending;
}
- /* Find matches. */
+ // Find matches.
num_matches = ins_compl_get_exp(&compl_startpos);
- /* handle any pending completions */
+ // handle any pending completions
while (compl_pending != 0 && compl_direction == compl_shows_dir
&& advance) {
if (compl_pending > 0 && compl_shown_match->cp_next != NULL) {
@@ -4573,7 +4580,7 @@ ins_compl_next (
} else
break;
}
- found_end = FALSE;
+ found_end = false;
}
if ((compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) == 0
&& compl_leader != NULL
@@ -4585,17 +4592,17 @@ ins_compl_next (
found_compl = compl_shown_match;
}
- /* Stop at the end of the list when we found a usable match. */
+ // Stop at the end of the list when we found a usable match.
if (found_end) {
if (found_compl != NULL) {
compl_shown_match = found_compl;
break;
}
- todo = 1; /* use first usable match after wrapping around */
+ todo = 1; // use first usable match after wrapping around
}
}
- /* Insert the text of the new completion, or the compl_leader. */
+ // Insert the text of the new completion, or the compl_leader.
if (compl_no_insert && !started) {
ins_bytes(compl_orig_text + ins_compl_len());
compl_used_match = false;
@@ -4689,9 +4696,10 @@ void ins_compl_check_keys(int frequency, int in_compl_func)
return;
}
- /* Only do this at regular intervals */
- if (++count < frequency)
+ // Only do this at regular intervals
+ if (++count < frequency) {
return;
+ }
count = 0;
/* Check for a typed key. Do use mappings, otherwise vim_is_ctrl_x_key()
@@ -4699,7 +4707,7 @@ void ins_compl_check_keys(int frequency, int in_compl_func)
int c = vpeekc_any();
if (c != NUL) {
if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R) {
- c = safe_vgetc(); /* Eat the character */
+ c = safe_vgetc(); // Eat the character
compl_shows_dir = ins_compl_key2dir(c);
(void)ins_compl_next(false, ins_compl_key2count(c),
c != K_UP && c != K_DOWN, in_compl_func);
@@ -4768,8 +4776,9 @@ static int ins_compl_key2count(int c)
if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN) {
h = pum_get_height();
- if (h > 3)
- h -= 2; /* keep some context */
+ if (h > 3) {
+ h -= 2; // keep some context
+ }
return h;
}
return 1;
@@ -4807,8 +4816,8 @@ static bool ins_compl_use_match(int c)
static int ins_complete(int c, bool enable_pum)
{
char_u *line;
- int startcol = 0; /* column where searched text starts */
- colnr_T curs_col; /* cursor column */
+ int startcol = 0; // column where searched text starts
+ colnr_T curs_col; // cursor column
int n;
int save_w_wrow;
int save_w_leftcol;
@@ -4820,7 +4829,7 @@ static int ins_complete(int c, bool enable_pum)
insert_match = ins_compl_use_match(c);
if (!compl_started) {
- /* First time we hit ^N or ^P (in a row, I mean) */
+ // First time we hit ^N or ^P (in a row, I mean)
did_ai = false;
did_si = false;
@@ -4858,7 +4867,7 @@ static int ins_complete(int c, bool enable_pum)
compl_col = (colnr_T)getwhitecols(line);
compl_startpos.col = compl_col;
compl_startpos.lnum = curwin->w_cursor.lnum;
- compl_cont_status &= ~CONT_SOL; /* clear SOL if present */
+ compl_cont_status &= ~CONT_SOL; // clear SOL if present
} else {
/* S_IPOS was set when we inserted a word that was at the
* beginning of the line, which means that we'll go to SOL
@@ -4890,7 +4899,7 @@ static int ins_complete(int c, bool enable_pum)
} else
compl_cont_status &= CONT_LOCAL;
- if (!(compl_cont_status & CONT_ADDING)) { /* normal expansion */
+ if (!(compl_cont_status & CONT_ADDING)) { // normal expansion
compl_cont_mode = ctrl_x_mode;
if (ctrl_x_mode != CTRL_X_NORMAL) {
// Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL
@@ -4919,7 +4928,7 @@ static int ins_complete(int c, bool enable_pum)
} else if (compl_cont_status & CONT_ADDING) {
char_u *prefix = (char_u *)"\\<";
- /* we need up to 2 extra chars for the prefix */
+ // we need up to 2 extra chars for the prefix
compl_pattern = xmalloc(quote_meta(NULL, line + compl_col,
compl_length) + 2);
if (!vim_iswordp(line + compl_col)
@@ -4971,14 +4980,16 @@ static int ins_complete(int c, bool enable_pum)
} else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) {
compl_col = (colnr_T)getwhitecols(line);
compl_length = (int)curs_col - (int)compl_col;
- if (compl_length < 0) /* cursor in indent: empty pattern */
+ if (compl_length < 0) { // cursor in indent: empty pattern
compl_length = 0;
- if (p_ic)
+ }
+ if (p_ic) {
compl_pattern = str_foldcase(line + compl_col, compl_length, NULL, 0);
- else
+ } else {
compl_pattern = vim_strnsave(line + compl_col, compl_length);
+ }
} else if (ctrl_x_mode == CTRL_X_FILES) {
- /* Go back to just before the first filename character. */
+ // Go back to just before the first filename character.
if (startcol > 0) {
char_u *p = line + startcol;
@@ -5050,7 +5061,7 @@ static int ins_complete(int c, bool enable_pum)
EMSG(_(e_complwin));
return FAIL;
}
- curwin->w_cursor = pos; /* restore the cursor position */
+ curwin->w_cursor = pos; // restore the cursor position
validate_cursor();
if (!equalpos(curwin->w_cursor, pos)) {
EMSG(_(e_compldel));
@@ -5102,7 +5113,7 @@ static int ins_complete(int c, bool enable_pum)
spell_expand_check_cap(compl_col);
compl_length = (int)curs_col - compl_col;
}
- /* Need to obtain "line" again, it may have become invalid. */
+ // Need to obtain "line" again, it may have become invalid.
line = ml_get(curwin->w_cursor.lnum);
compl_pattern = vim_strnsave(line + compl_col, compl_length);
} else {
@@ -5113,7 +5124,7 @@ static int ins_complete(int c, bool enable_pum)
if (compl_cont_status & CONT_ADDING) {
edit_submode_pre = (char_u *)_(" Adding");
if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) {
- /* Insert a new line, keep indentation but ignore 'comments' */
+ // Insert a new line, keep indentation but ignore 'comments'
char_u *old = curbuf->b_p_com;
curbuf->b_p_com = (char_u *)"";
@@ -5138,7 +5149,7 @@ static int ins_complete(int c, bool enable_pum)
* the redo buffer. */
ins_compl_fixRedoBufForLeader(NULL);
- /* Always add completion for the original text. */
+ // Always add completion for the original text.
xfree(compl_orig_text);
compl_orig_text = vim_strnsave(line + compl_col, compl_length);
if (p_ic) {
@@ -5175,8 +5186,9 @@ static int ins_complete(int c, bool enable_pum)
n = ins_compl_next(true, ins_compl_key2count(c), insert_match, false);
- if (n > 1) /* all matches have been found */
+ if (n > 1) { // all matches have been found
compl_matches = n;
+ }
compl_curr_match = compl_shown_match;
compl_direction = compl_shows_dir;
@@ -5187,7 +5199,7 @@ static int ins_complete(int c, bool enable_pum)
got_int = FALSE;
}
- /* we found no match if the list has only the "compl_orig_text"-entry */
+ // we found no match if the list has only the "compl_orig_text"-entry
if (compl_first_match == compl_first_match->cp_next) {
edit_submode_extra = (compl_cont_status & CONT_ADDING)
&& compl_length > 1
@@ -5223,7 +5235,7 @@ static int ins_complete(int c, bool enable_pum)
edit_submode_extra = (char_u *)_("The only match");
edit_submode_highl = HLF_COUNT;
} else {
- /* Update completion sequence number when needed. */
+ // Update completion sequence number when needed.
if (compl_curr_match->cp_number == -1) {
int number = 0;
compl_T *match;
@@ -5246,24 +5258,27 @@ static int ins_complete(int c, bool enable_pum)
match != NULL && match->cp_number == -1;
match = match->cp_next)
match->cp_number = ++number;
- } else { /* BACKWARD */
- /* search forwards (upwards) for the first valid (!= -1)
- * number. This should normally succeed already at the
- * first loop cycle, so it's fast! */
- for (match = compl_curr_match->cp_next; match != NULL
- && match != compl_first_match;
- match = match->cp_next)
+ } else { // BACKWARD
+ // search forwards (upwards) for the first valid (!= -1)
+ // number. This should normally succeed already at the
+ // first loop cycle, so it's fast!
+ for (match = compl_curr_match->cp_next;
+ match != NULL && match != compl_first_match;
+ match = match->cp_next) {
if (match->cp_number != -1) {
number = match->cp_number;
break;
}
- if (match != NULL)
- /* go down and assign all numbers which are not
- * assigned yet */
- for (match = match->cp_prev; match
- && match->cp_number == -1;
- match = match->cp_prev)
+ }
+ if (match != NULL) {
+ // go down and assign all numbers which are not
+ // assigned yet
+ for (match = match->cp_prev;
+ match && match->cp_number == -1;
+ match = match->cp_prev) {
match->cp_number = ++number;
+ }
+ }
}
}
@@ -5322,7 +5337,7 @@ static int ins_complete(int c, bool enable_pum)
*/
static unsigned quote_meta(char_u *dest, char_u *src, int len)
{
- unsigned m = (unsigned)len + 1; /* one extra for the NUL */
+ unsigned m = (unsigned)len + 1; // one extra for the NUL
for (; --len >= 0; src++) {
switch (*src) {
@@ -5334,8 +5349,9 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len)
break;
FALLTHROUGH;
case '~':
- if (!p_magic) /* quote these only if magic is set */
+ if (!p_magic) { // quote these only if magic is set
break;
+ }
FALLTHROUGH;
case '\\':
if (ctrl_x_mode == CTRL_X_DICTIONARY
@@ -5345,24 +5361,24 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len)
case '^': // currently it's not needed.
case '$':
m++;
- if (dest != NULL)
+ if (dest != NULL) {
*dest++ = '\\';
+ }
break;
}
- if (dest != NULL)
+ if (dest != NULL) {
*dest++ = *src;
- /* Copy remaining bytes of a multibyte character. */
- if (has_mbyte) {
- int i, mb_len;
-
- mb_len = (*mb_ptr2len)(src) - 1;
- if (mb_len > 0 && len >= mb_len)
- for (i = 0; i < mb_len; ++i) {
- --len;
- ++src;
- if (dest != NULL)
- *dest++ = *src;
+ }
+ // Copy remaining bytes of a multibyte character.
+ const int mb_len = utfc_ptr2len(src) - 1;
+ if (mb_len > 0 && len >= mb_len) {
+ for (int i = 0; i < mb_len; i++) {
+ len--;
+ src++;
+ if (dest != NULL) {
+ *dest++ = *src;
}
+ }
}
}
if (dest != NULL)
@@ -5389,7 +5405,7 @@ int get_literal(void)
if (got_int)
return Ctrl_C;
- ++no_mapping; /* don't map the next key hits */
+ no_mapping++; // don't map the next key hits
cc = 0;
i = 0;
for (;; ) {
@@ -5427,20 +5443,23 @@ int get_literal(void)
if (cc > 255
&& unicode == 0
)
- cc = 255; /* limit range to 0-255 */
+ cc = 255; // limit range to 0-255
nc = 0;
- if (hex) { /* hex: up to two chars */
- if (i >= 2)
+ if (hex) { // hex: up to two chars
+ if (i >= 2) {
break;
- } else if (unicode) { /* Unicode: up to four or eight chars */
- if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8))
+ }
+ } else if (unicode) { // Unicode: up to four or eight chars
+ if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8)) {
break;
- } else if (i >= 3) /* decimal or octal: up to three chars */
+ }
+ } else if (i >= 3) { // decimal or octal: up to three chars
break;
+ }
}
- if (i == 0) { /* no number entered */
- if (nc == K_ZERO) { /* NUL is stored as NL */
+ if (i == 0) { // no number entered
+ if (nc == K_ZERO) { // NUL is stored as NL
cc = '\n';
nc = 0;
} else {
@@ -5456,7 +5475,7 @@ int get_literal(void)
--no_mapping;
if (nc)
vungetc(nc);
- got_int = FALSE; /* CTRL-C typed after CTRL-V is not an interrupt */
+ got_int = false; // CTRL-C typed after CTRL-V is not an interrupt
return cc;
}
@@ -5519,11 +5538,10 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
* INSCHAR_DO_COM - format comments
* INSCHAR_COM_LIST - format comments with num list or 2nd line indent
*/
-void
-insertchar (
- int c, /* character to insert or NUL */
- int flags, /* INSCHAR_FORMAT, etc. */
- int second_indent /* indent for second line if >= 0 */
+void insertchar(
+ int c, // character to insert or NUL
+ int flags, // INSCHAR_FORMAT, etc.
+ int second_indent // indent for second line if >= 0
)
{
int textwidth;
@@ -5559,27 +5577,27 @@ insertchar (
|| ((!has_format_option(FO_INS_LONG)
|| Insstart_textlen <= (colnr_T)textwidth)
&& (!fo_ins_blank
- || Insstart_blank_vcol <= (colnr_T)textwidth
- )))))) {
- /* Format with 'formatexpr' when it's set. Use internal formatting
- * when 'formatexpr' isn't set or it returns non-zero. */
- int do_internal = TRUE;
+ || Insstart_blank_vcol <= (colnr_T)textwidth)))))) {
+ // Format with 'formatexpr' when it's set. Use internal formatting
+ // when 'formatexpr' isn't set or it returns non-zero.
+ bool do_internal = true;
colnr_T virtcol = get_nolist_virtcol()
+ char2cells(c != NUL ? c : gchar_cursor());
if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0
&& (force_format || virtcol > (colnr_T)textwidth)) {
do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
- /* It may be required to save for undo again, e.g. when setline()
- * was called. */
- ins_need_undo = TRUE;
+ // It may be required to save for undo again, e.g. when setline()
+ // was called.
+ ins_need_undo = true;
}
if (do_internal)
internal_format(textwidth, second_indent, flags, c == NUL, c);
}
- if (c == NUL) /* only formatting was wanted */
+ if (c == NUL) { // only formatting was wanted
return;
+ }
// Check whether this character should end a comment.
if (did_ai && c == end_comment_pending) {
@@ -5683,8 +5701,8 @@ insertchar (
buf[i++] = c;
}
- do_digraph(-1); /* clear digraphs */
- do_digraph(buf[i-1]); /* may be the start of a digraph */
+ do_digraph(-1); // clear digraphs
+ do_digraph(buf[i-1]); // may be the start of a digraph
buf[i] = NUL;
ins_str(buf);
if (flags & INSCHAR_CTRLV) {
@@ -5727,7 +5745,7 @@ internal_format (
int second_indent,
int flags,
int format_only,
- int c /* character to be inserted (can be NUL) */
+ int c // character to be inserted (can be NUL)
)
{
int cc;
@@ -5738,7 +5756,7 @@ internal_format (
int fo_white_par = has_format_option(FO_WHITE_PAR);
int first_line = TRUE;
colnr_T leader_len;
- int no_leader = FALSE;
+ bool no_leader = false;
int do_comments = (flags & INSCHAR_DO_COM);
int has_lbr = curwin->w_p_lbr;
@@ -5763,10 +5781,10 @@ internal_format (
* Repeat breaking lines, until the current line is not too long.
*/
while (!got_int) {
- int startcol; /* Cursor column at entry */
- int wantcol; /* column at textwidth border */
- int foundcol; /* column for start of spaces */
- int end_foundcol = 0; /* column for start of word */
+ int startcol; // Cursor column at entry
+ int wantcol; // column at textwidth border
+ int foundcol; // column for start of spaces
+ int end_foundcol = 0; // column for start of word
colnr_T len;
colnr_T virtcol;
int orig_col = 0;
@@ -5779,33 +5797,37 @@ internal_format (
if (virtcol <= (colnr_T)textwidth)
break;
- if (no_leader)
- do_comments = FALSE;
- else if (!(flags & INSCHAR_FORMAT)
- && has_format_option(FO_WRAP_COMS))
- do_comments = TRUE;
+ if (no_leader) {
+ do_comments = false;
+ } else if (!(flags & INSCHAR_FORMAT)
+ && has_format_option(FO_WRAP_COMS)) {
+ do_comments = true;
+ }
- /* Don't break until after the comment leader */
- if (do_comments)
- leader_len = get_leader_len(get_cursor_line_ptr(), NULL, FALSE, TRUE);
- else
+ // Don't break until after the comment leader
+ if (do_comments) {
+ leader_len = get_leader_len(get_cursor_line_ptr(), NULL, false, true);
+ } else {
leader_len = 0;
+ }
- /* If the line doesn't start with a comment leader, then don't
- * start one in a following broken line. Avoids that a %word
- * moved to the start of the next line causes all following lines
- * to start with %. */
- if (leader_len == 0)
- no_leader = TRUE;
+ // If the line doesn't start with a comment leader, then don't
+ // start one in a following broken line. Avoids that a %word
+ // moved to the start of the next line causes all following lines
+ // to start with %.
+ if (leader_len == 0) {
+ no_leader = true;
+ }
if (!(flags & INSCHAR_FORMAT)
&& leader_len == 0
- && !has_format_option(FO_WRAP))
-
+ && !has_format_option(FO_WRAP)) {
break;
- if ((startcol = curwin->w_cursor.col) == 0)
+ }
+ if ((startcol = curwin->w_cursor.col) == 0) {
break;
+ }
- /* find column of textwidth border */
+ // find column of textwidth border
coladvance((colnr_T)textwidth);
wantcol = curwin->w_cursor.col;
@@ -5825,7 +5847,7 @@ internal_format (
else
cc = gchar_cursor();
if (WHITECHAR(cc)) {
- /* remember position of blank just before text */
+ // remember position of blank just before text
end_col = curwin->w_cursor.col;
// find start of sequence of blanks
@@ -5856,18 +5878,21 @@ internal_format (
}
if (has_format_option(FO_ONE_LETTER)) {
- /* do not break after one-letter words */
- if (curwin->w_cursor.col == 0)
- break; /* one-letter word at begin */
- /* do not break "#a b" when 'tw' is 2 */
- if (curwin->w_cursor.col <= leader_len)
+ // do not break after one-letter words
+ if (curwin->w_cursor.col == 0) {
+ break; // one-letter word at begin
+ }
+ // do not break "#a b" when 'tw' is 2
+ if (curwin->w_cursor.col <= leader_len) {
break;
+ }
col = curwin->w_cursor.col;
dec_cursor();
cc = gchar_cursor();
- if (WHITECHAR(cc))
- continue; /* one-letter, continue */
+ if (WHITECHAR(cc)) {
+ continue; // one-letter, continue
+ }
curwin->w_cursor.col = col;
}
@@ -5878,14 +5903,15 @@ internal_format (
if (curwin->w_cursor.col <= (colnr_T)wantcol)
break;
} else if (cc >= 0x100 && fo_multibyte) {
- /* Break after or before a multi-byte character. */
+ // Break after or before a multi-byte character.
if (curwin->w_cursor.col != startcol) {
- /* Don't break until after the comment leader */
- if (curwin->w_cursor.col < leader_len)
+ // Don't break until after the comment leader
+ if (curwin->w_cursor.col < leader_len) {
break;
+ }
col = curwin->w_cursor.col;
inc_cursor();
- /* Don't change end_foundcol if already set. */
+ // Don't change end_foundcol if already set.
if (foundcol != curwin->w_cursor.col) {
foundcol = curwin->w_cursor.col;
end_foundcol = foundcol;
@@ -5903,11 +5929,13 @@ internal_format (
dec_cursor();
cc = gchar_cursor();
- if (WHITECHAR(cc))
- continue; /* break with space */
- /* Don't break until after the comment leader */
- if (curwin->w_cursor.col < leader_len)
+ if (WHITECHAR(cc)) {
+ continue; // break with space
+ }
+ // Don't break until after the comment leader
+ if (curwin->w_cursor.col < leader_len) {
break;
+ }
curwin->w_cursor.col = col;
@@ -5921,12 +5949,12 @@ internal_format (
dec_cursor();
}
- if (foundcol == 0) { /* no spaces, cannot break line */
+ if (foundcol == 0) { // no spaces, cannot break line
curwin->w_cursor.col = startcol;
break;
}
- /* Going to break the line, remove any "$" now. */
+ // Going to break the line, remove any "$" now.
undisplay_dollar();
/*
@@ -5934,10 +5962,11 @@ internal_format (
* stack functions. VREPLACE does not use this, and backspaces
* over the text instead.
*/
- if (State & VREPLACE_FLAG)
- orig_col = startcol; /* Will start backspacing from here */
- else
+ if (State & VREPLACE_FLAG) {
+ orig_col = startcol; // Will start backspacing from here
+ } else {
replace_offset = startcol - end_foundcol;
+ }
/*
* adjust startcol for spaces that will be deleted and
@@ -5960,13 +5989,15 @@ internal_format (
curwin->w_cursor.col = orig_col;
saved_text[startcol] = NUL;
- /* Backspace over characters that will move to the next line */
- if (!fo_white_par)
+ // Backspace over characters that will move to the next line
+ if (!fo_white_par) {
backspace_until_column(foundcol);
+ }
} else {
- /* put cursor after pos. to break line */
- if (!fo_white_par)
+ // put cursor after pos. to break line
+ if (!fo_white_par) {
curwin->w_cursor.col = foundcol;
+ }
}
/*
@@ -5984,32 +6015,29 @@ internal_format (
replace_offset = 0;
if (first_line) {
if (!(flags & INSCHAR_COM_LIST)) {
- /*
- * This section is for auto-wrap of numeric lists. When not
- * in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST
- * flag will be set and open_line() will handle it (as seen
- * above). The code here (and in get_number_indent()) will
- * recognize comments if needed...
- */
- if (second_indent < 0 && has_format_option(FO_Q_NUMBER))
- second_indent =
- get_number_indent(curwin->w_cursor.lnum - 1);
+ // This section is for auto-wrap of numeric lists. When not
+ // in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST
+ // flag will be set and open_line() will handle it (as seen
+ // above). The code here (and in get_number_indent()) will
+ // recognize comments if needed...
+ if (second_indent < 0 && has_format_option(FO_Q_NUMBER)) {
+ second_indent = get_number_indent(curwin->w_cursor.lnum - 1);
+ }
if (second_indent >= 0) {
- if (State & VREPLACE_FLAG)
- change_indent(INDENT_SET, second_indent,
- FALSE, NUL, TRUE);
- else if (leader_len > 0 && second_indent - leader_len > 0) {
- int i;
+ if (State & VREPLACE_FLAG) {
+ change_indent(INDENT_SET, second_indent, false, NUL, true);
+ } else if (leader_len > 0 && second_indent - leader_len > 0) {
int padding = second_indent - leader_len;
- /* We started at the first_line of a numbered list
- * that has a comment. the open_line() function has
- * inserted the proper comment leader and positioned
- * the cursor at the end of the split line. Now we
- * add the additional whitespace needed after the
- * comment leader for the numbered list. */
- for (i = 0; i < padding; i++)
+ // We started at the first_line of a numbered list
+ // that has a comment. the open_line() function has
+ // inserted the proper comment leader and positioned
+ // the cursor at the end of the split line. Now we
+ // add the additional whitespace needed after the
+ // comment leader for the numbered list.
+ for (int i = 0; i < padding; i++) {
ins_str((char_u *)" ");
+ }
changed_bytes(curwin->w_cursor.lnum, leader_len);
} else {
(void)set_indent(second_indent, SIN_CHANGED);
@@ -6047,8 +6075,9 @@ internal_format (
line_breakcheck();
}
- if (save_char != NUL) /* put back space after cursor */
+ if (save_char != NUL) { // put back space after cursor
pchar_cursor(save_char);
+ }
curwin->w_p_lbr = has_lbr;
@@ -6065,10 +6094,9 @@ internal_format (
* The caller must have saved the cursor line for undo, following ones will be
* saved here.
*/
-void
-auto_format (
- int trailblank, /* when TRUE also format with trailing blank */
- int prev_line /* may start in previous line */
+void auto_format(
+ bool trailblank, // when true also format with trailing blank
+ bool prev_line // may start in previous line
)
{
pos_T pos;
@@ -6087,11 +6115,11 @@ auto_format (
// may remove added space
check_auto_format(false);
- /* Don't format in Insert mode when the cursor is on a trailing blank, the
- * user might insert normal text next. Also skip formatting when "1" is
- * in 'formatoptions' and there is a single character before the cursor.
- * Otherwise the line would be broken and when typing another non-white
- * next they are not joined back together. */
+ // Don't format in Insert mode when the cursor is on a trailing blank, the
+ // user might insert normal text next. Also skip formatting when "1" is
+ // in 'formatoptions' and there is a single character before the cursor.
+ // Otherwise the line would be broken and when typing another non-white
+ // next they are not joined back together.
wasatend = (pos.col == (colnr_T)STRLEN(old));
if (*old != NUL && !trailblank && wasatend) {
dec_cursor();
@@ -6134,16 +6162,16 @@ auto_format (
saved_cursor.lnum = 0;
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
- /* "cannot happen" */
+ // "cannot happen"
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
coladvance((colnr_T)MAXCOL);
} else
check_cursor_col();
- /* Insert mode: If the cursor is now after the end of the line while it
- * previously wasn't, the line was broken. Because of the rule above we
- * need to add a space when 'w' is in 'formatoptions' to keep a paragraph
- * formatted. */
+ // Insert mode: If the cursor is now after the end of the line while it
+ // previously wasn't, the line was broken. Because of the rule above we
+ // need to add a space when 'w' is in 'formatoptions' to keep a paragraph
+ // formatted.
if (!wasatend && has_format_option(FO_WHITE_PAR)) {
new = get_cursor_line_ptr();
len = (colnr_T)STRLEN(new);
@@ -6202,22 +6230,21 @@ static void check_auto_format(
* if invalid value, use 0.
* Set default to window width (maximum 79) for "gq" operator.
*/
-int
-comp_textwidth (
- int ff /* force formatting (for "gq" command) */
+int comp_textwidth(
+ int ff // force formatting (for "gq" command)
)
{
int textwidth;
textwidth = curbuf->b_p_tw;
if (textwidth == 0 && curbuf->b_p_wm) {
- /* The width is the window width minus 'wrapmargin' minus all the
- * things that add to the margin. */
+ // The width is the window width minus 'wrapmargin' minus all the
+ // things that add to the margin.
textwidth = curwin->w_width_inner - curbuf->b_p_wm;
if (cmdwin_type != 0) {
textwidth -= 1;
}
- textwidth -= curwin->w_p_fdc;
+ textwidth -= win_fdccol_count(curwin);
textwidth -= win_signcol_count(curwin);
if (curwin->w_p_nu || curwin->w_p_rnu)
@@ -6253,7 +6280,9 @@ static void redo_literal(int c)
// start_arrow() is called when an arrow key is used in insert mode.
// For undo/redo it resembles hitting the <ESC> key.
-static void start_arrow(pos_T *end_insert_pos /* can be NULL */)
+static void start_arrow(
+ pos_T *end_insert_pos // can be NULL
+)
{
start_arrow_common(end_insert_pos, true);
}
@@ -6326,8 +6355,8 @@ int stop_arrow(void)
Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr());
if (u_save_cursor() == OK) {
- arrow_used = FALSE;
- ins_need_undo = FALSE;
+ arrow_used = false;
+ ins_need_undo = false;
}
ai_col = 0;
if (State & VREPLACE_FLAG) {
@@ -6338,11 +6367,12 @@ int stop_arrow(void)
AppendToRedobuff("1i"); // Pretend we start an insertion.
new_insert_skip = 2;
} else if (ins_need_undo) {
- if (u_save_cursor() == OK)
- ins_need_undo = FALSE;
+ if (u_save_cursor() == OK) {
+ ins_need_undo = false;
+ }
}
- /* Always open fold at the cursor line when inserting something. */
+ // Always open fold at the cursor line when inserting something.
foldOpenCursor();
return arrow_used || ins_need_undo ? FAIL : OK;
@@ -6356,15 +6386,15 @@ int stop_arrow(void)
static void
stop_insert (
pos_T *end_insert_pos,
- int esc, /* called by ins_esc() */
- int nomove /* <c-\><c-o>, don't move cursor */
+ int esc, // called by ins_esc()
+ int nomove // <c-\><c-o>, don't move cursor
)
{
int cc;
char_u *ptr;
stop_redo_ins();
- replace_flush(); /* abandon replace stack */
+ replace_flush(); // abandon replace stack
/*
* Save the inserted text for later redo with ^@ and CTRL-A.
@@ -6381,16 +6411,16 @@ stop_insert (
xfree(ptr);
if (!arrow_used && end_insert_pos != NULL) {
- /* Auto-format now. It may seem strange to do this when stopping an
- * insertion (or moving the cursor), but it's required when appending
- * a line and having it end in a space. But only do it when something
- * was actually inserted, otherwise undo won't work. */
+ // Auto-format now. It may seem strange to do this when stopping an
+ // insertion (or moving the cursor), but it's required when appending
+ // a line and having it end in a space. But only do it when something
+ // was actually inserted, otherwise undo won't work.
if (!ins_need_undo && has_format_option(FO_AUTO)) {
pos_T tpos = curwin->w_cursor;
- /* When the cursor is at the end of the line after a space the
- * formatting will move it to the following word. Avoid that by
- * moving the cursor onto the space. */
+ // When the cursor is at the end of the line after a space the
+ // formatting will move it to the following word. Avoid that by
+ // moving the cursor onto the space.
cc = 'x';
if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL) {
dec_cursor();
@@ -6416,11 +6446,11 @@ stop_insert (
// If a space was inserted for auto-formatting, remove it now.
check_auto_format(true);
- /* If we just did an auto-indent, remove the white space from the end
- * of the line, and put the cursor back.
- * Do this when ESC was used or moving the cursor up/down.
- * Check for the old position still being valid, just in case the text
- * got changed unexpectedly. */
+ // If we just did an auto-indent, remove the white space from the end
+ // of the line, and put the cursor back.
+ // Do this when ESC was used or moving the cursor up/down.
+ // Check for the old position still being valid, just in case the text
+ // got changed unexpectedly.
if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL
&& curwin->w_cursor.lnum !=
end_insert_pos->lnum))
@@ -6428,7 +6458,7 @@ stop_insert (
pos_T tpos = curwin->w_cursor;
curwin->w_cursor = *end_insert_pos;
- check_cursor_col(); /* make sure it is not past the line */
+ check_cursor_col(); // make sure it is not past the line
for (;; ) {
if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
--curwin->w_cursor.col;
@@ -6440,10 +6470,10 @@ stop_insert (
break; // should not happen
}
}
- if (curwin->w_cursor.lnum != tpos.lnum)
+ if (curwin->w_cursor.lnum != tpos.lnum) {
curwin->w_cursor = tpos;
- else {
- /* reset tpos, could have been invalidated in the loop above */
+ } else {
+ // reset tpos, could have been invalidated in the loop above
tpos = curwin->w_cursor;
tpos.col++;
if (cc != NUL && gchar_pos(&tpos) == NUL) {
@@ -6451,8 +6481,8 @@ stop_insert (
}
}
- /* <C-S-Right> may have started Visual mode, adjust the position for
- * deleted characters. */
+ // <C-S-Right> may have started Visual mode, adjust the position for
+ // deleted characters.
if (VIsual_active && VIsual.lnum == curwin->w_cursor.lnum) {
int len = (int)STRLEN(get_cursor_line_ptr());
@@ -6468,8 +6498,8 @@ stop_insert (
can_si = false;
can_si_back = false;
- /* Set '[ and '] to the inserted text. When end_insert_pos is NULL we are
- * now in a different buffer. */
+ // Set '[ and '] to the inserted text. When end_insert_pos is NULL we are
+ // now in a different buffer.
if (end_insert_pos != NULL) {
curbuf->b_op_start = Insstart;
curbuf->b_op_start_orig = Insstart_orig;
@@ -6488,9 +6518,10 @@ void set_last_insert(int c)
xfree(last_insert);
last_insert = xmalloc(MB_MAXBYTES * 3 + 5);
s = last_insert;
- /* Use the CTRL-V only when entering a special char */
- if (c < ' ' || c == DEL)
+ // Use the CTRL-V only when entering a special char
+ if (c < ' ' || c == DEL) {
*s++ = Ctrl_V;
+ }
s = add_char2buf(c, s);
*s++ = ESC;
*s++ = NUL;
@@ -6576,7 +6607,7 @@ int oneright(void)
if (virtual_active()) {
pos_T prevpos = curwin->w_cursor;
- /* Adjust for multi-wide char (excluding TAB) */
+ // Adjust for multi-wide char (excluding TAB)
ptr = get_cursor_pos_ptr();
coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) ?
ptr2cells(ptr) : 1));
@@ -6587,20 +6618,18 @@ int oneright(void)
}
ptr = get_cursor_pos_ptr();
- if (*ptr == NUL)
- return FAIL; /* already at the very end */
+ if (*ptr == NUL) {
+ return FAIL; // already at the very end
+ }
- if (has_mbyte)
- l = (*mb_ptr2len)(ptr);
- else
- l = 1;
+ l = utfc_ptr2len(ptr);
- /* move "l" bytes right, but don't end up on the NUL, unless 'virtualedit'
- * contains "onemore". */
+ // move "l" bytes right, but don't end up on the NUL, unless 'virtualedit'
+ // contains "onemore".
if (ptr[l] == NUL
- && (ve_flags & VE_ONEMORE) == 0
- )
+ && (ve_flags & VE_ONEMORE) == 0) {
return FAIL;
+ }
curwin->w_cursor.col += l;
curwin->w_set_curswant = TRUE;
@@ -6616,25 +6645,23 @@ int oneleft(void)
if (v == 0)
return FAIL;
- /* We might get stuck on 'showbreak', skip over it. */
+ // We might get stuck on 'showbreak', skip over it.
width = 1;
for (;; ) {
coladvance(v - width);
- /* getviscol() is slow, skip it when 'showbreak' is empty,
- 'breakindent' is not set and there are no multi-byte
- characters */
- if ((*p_sbr == NUL
- && !curwin->w_p_bri
- && !has_mbyte
- ) || getviscol() < v)
+ // getviscol() is slow, skip it when 'showbreak' is empty,
+ // 'breakindent' is not set and there are no multi-byte
+ // characters
+ if (getviscol() < v) {
break;
- ++width;
+ }
+ width++;
}
if (curwin->w_cursor.coladd == 1) {
char_u *ptr;
- /* Adjust for multi-wide char (not a TAB) */
+ // Adjust for multi-wide char (not a TAB)
ptr = get_cursor_pos_ptr();
if (*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))
&& ptr2cells(ptr) > 1) {
@@ -6652,17 +6679,16 @@ int oneleft(void)
curwin->w_set_curswant = TRUE;
--curwin->w_cursor.col;
- /* if the character on the left of the current cursor is a multi-byte
- * character, move to its first byte */
- if (has_mbyte)
- mb_adjust_cursor();
+ // if the character on the left of the current cursor is a multi-byte
+ // character, move to its first byte
+ mb_adjust_cursor();
return OK;
}
int
cursor_up (
long n,
- int upd_topline /* When TRUE: update topline */
+ int upd_topline // When TRUE: update topline
)
{
linenr_T lnum;
@@ -6680,19 +6706,21 @@ cursor_up (
/*
* Count each sequence of folded lines as one logical line.
*/
- /* go to the start of the current fold */
+ // go to the start of the current fold
(void)hasFolding(lnum, &lnum, NULL);
while (n--) {
- /* move up one line */
- --lnum;
- if (lnum <= 1)
+ // move up one line
+ lnum--;
+ if (lnum <= 1) {
break;
- /* If we entered a fold, move to the beginning, unless in
- * Insert mode or when 'foldopen' contains "all": it will open
- * in a moment. */
- if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL)))
+ }
+ // If we entered a fold, move to the beginning, unless in
+ // Insert mode or when 'foldopen' contains "all": it will open
+ // in a moment.
+ if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL))) {
(void)hasFolding(lnum, &lnum, NULL);
+ }
}
if (lnum < 1)
lnum = 1;
@@ -6701,11 +6729,12 @@ cursor_up (
curwin->w_cursor.lnum = lnum;
}
- /* try to advance to the column we want to be at */
+ // try to advance to the column we want to be at
coladvance(curwin->w_curswant);
- if (upd_topline)
- update_topline(); /* make sure curwin->w_topline is valid */
+ if (upd_topline) {
+ update_topline(); // make sure curwin->w_topline is valid
+ }
return OK;
}
@@ -6716,14 +6745,14 @@ cursor_up (
int
cursor_down (
long n,
- int upd_topline /* When TRUE: update topline */
+ int upd_topline // When TRUE: update topline
)
{
linenr_T lnum;
if (n > 0) {
lnum = curwin->w_cursor.lnum;
- /* Move to last line of fold, will fail if it's the end-of-file. */
+ // Move to last line of fold, will fail if it's the end-of-file.
(void)hasFolding(lnum, NULL, &lnum);
// This fails if the cursor is already in the last line.
@@ -6735,7 +6764,7 @@ cursor_down (
else if (hasAnyFolding(curwin)) {
linenr_T last;
- /* count each sequence of folded lines as one logical line */
+ // count each sequence of folded lines as one logical line
while (n--) {
if (hasFolding(lnum, NULL, &last))
lnum = last + 1;
@@ -6751,11 +6780,12 @@ cursor_down (
curwin->w_cursor.lnum = lnum;
}
- /* try to advance to the column we want to be at */
+ // try to advance to the column we want to be at
coladvance(curwin->w_curswant);
- if (upd_topline)
- update_topline(); /* make sure curwin->w_topline is valid */
+ if (upd_topline) {
+ update_topline(); // make sure curwin->w_topline is valid
+ }
return OK;
}
@@ -6765,11 +6795,10 @@ cursor_down (
* Last_insert actually is a copy of the redo buffer, so we
* first have to remove the command.
*/
-int
-stuff_inserted (
- int c, /* Command character to be inserted */
- long count, /* Repeat this many times */
- int no_esc /* Don't add an ESC at the end */
+int stuff_inserted(
+ int c, // Command character to be inserted
+ long count, // Repeat this many times
+ int no_esc // Don't add an ESC at the end
)
{
char_u *esc_ptr;
@@ -6783,18 +6812,18 @@ stuff_inserted (
return FAIL;
}
- /* may want to stuff the command character, to start Insert mode */
- if (c != NUL)
+ // may want to stuff the command character, to start Insert mode
+ if (c != NUL) {
stuffcharReadbuff(c);
+ }
if ((esc_ptr = STRRCHR(ptr, ESC)) != NULL) {
// remove the ESC.
*esc_ptr = NUL;
}
- /* when the last char is either "0" or "^" it will be quoted if no ESC
- * comes after it OR if it will inserted more than once and "ptr"
- * starts with ^D. -- Acevedo
- */
+ // when the last char is either "0" or "^" it will be quoted if no ESC
+ // comes after it OR if it will inserted more than once and "ptr"
+ // starts with ^D. -- Acevedo
last_ptr = (esc_ptr ? esc_ptr : ptr + STRLEN(ptr)) - 1;
if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^')
&& (no_esc || (*ptr == Ctrl_D && count > 1))) {
@@ -6815,12 +6844,14 @@ stuff_inserted (
if (last)
*last_ptr = last;
- if (esc_ptr != NULL)
- *esc_ptr = ESC; /* put the ESC back */
+ if (esc_ptr != NULL) {
+ *esc_ptr = ESC; // put the ESC back
+ }
- /* may want to stuff a trailing ESC, to get out of Insert mode */
- if (!no_esc)
+ // may want to stuff a trailing ESC, to get out of Insert mode
+ if (!no_esc) {
stuffcharReadbuff(ESC);
+ }
return OK;
}
@@ -6845,8 +6876,9 @@ char_u *get_last_insert_save(void)
return NULL;
s = vim_strsave(last_insert + last_insert_skip);
len = (int)STRLEN(s);
- if (len > 0 && s[len - 1] == ESC) /* remove trailing ESC */
+ if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC
s[len - 1] = NUL;
+ }
return s;
}
@@ -6888,8 +6920,8 @@ static bool echeck_abbr(int c)
*/
static char_u *replace_stack = NULL;
-static ssize_t replace_stack_nr = 0; /* next entry in replace stack */
-static ssize_t replace_stack_len = 0; /* max. number of entries */
+static ssize_t replace_stack_nr = 0; // next entry in replace stack
+static ssize_t replace_stack_len = 0; // max. number of entries
/// Push character that is replaced onto the the replace stack.
///
@@ -6943,9 +6975,8 @@ static int replace_pop(void)
* Join the top two items on the replace stack. This removes to "off"'th NUL
* encountered.
*/
-static void
-replace_join (
- int off /* offset for which NUL to remove */
+static void replace_join(
+ int off // offset for which NUL to remove
)
{
int i;
@@ -6968,7 +6999,7 @@ static void replace_pop_ins(void)
int cc;
int oldState = State;
- State = NORMAL; /* don't want REPLACE here */
+ State = NORMAL; // don't want REPLACE here
while ((cc = replace_pop()) > 0) {
mb_replace_pop_ins(cc);
dec_cursor();
@@ -6987,7 +7018,7 @@ static void mb_replace_pop_ins(int cc)
int i;
int c;
- if (has_mbyte && (n = MB_BYTE2LEN(cc)) > 1) {
+ if ((n = MB_BYTE2LEN(cc)) > 1) {
buf[0] = cc;
for (i = 1; i < n; ++i)
buf[i] = replace_pop();
@@ -6996,31 +7027,33 @@ static void mb_replace_pop_ins(int cc)
ins_char(cc);
}
- if (enc_utf8)
- /* Handle composing chars. */
- for (;; ) {
- c = replace_pop();
- if (c == -1) /* stack empty */
- break;
- if ((n = MB_BYTE2LEN(c)) == 1) {
- /* Not a multi-byte char, put it back. */
- replace_push(c);
- break;
+ // Handle composing chars.
+ for (;; ) {
+ c = replace_pop();
+ if (c == -1) { // stack empty
+ break;
+ }
+ if ((n = MB_BYTE2LEN(c)) == 1) {
+ // Not a multi-byte char, put it back.
+ replace_push(c);
+ break;
+ } else {
+ buf[0] = c;
+ assert(n > 1);
+ for (i = 1; i < n; i++) {
+ buf[i] = replace_pop();
+ }
+ if (utf_iscomposing(utf_ptr2char(buf))) {
+ ins_bytes_len(buf, n);
} else {
- buf[0] = c;
- assert(n > 1);
- for (i = 1; i < n; ++i)
- buf[i] = replace_pop();
- if (utf_iscomposing(utf_ptr2char(buf)))
- ins_bytes_len(buf, n);
- else {
- /* Not a composing char, put it back. */
- for (i = n - 1; i >= 0; --i)
- replace_push(buf[i]);
- break;
+ // Not a composing char, put it back.
+ for (i = n - 1; i >= 0; i--) {
+ replace_push(buf[i]);
}
+ break;
}
}
+ }
}
/*
@@ -7058,8 +7091,8 @@ static void replace_do_bs(int limit_col)
cc = replace_pop();
if (cc > 0) {
if (l_State & VREPLACE_FLAG) {
- /* Get the number of screen cells used by the character we are
- * going to delete. */
+ // Get the number of screen cells used by the character we are
+ // going to delete.
getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
orig_vcols = chartabsize(get_cursor_pos_ptr(), start_vcol);
}
@@ -7076,7 +7109,7 @@ static void replace_do_bs(int limit_col)
replace_pop_ins();
if (l_State & VREPLACE_FLAG) {
- /* Get the number of screen cells used by the inserted characters */
+ // Get the number of screen cells used by the inserted characters
p = get_cursor_pos_ptr();
ins_len = (int)STRLEN(p) - orig_len;
vcol = start_vcol;
@@ -7086,8 +7119,8 @@ static void replace_do_bs(int limit_col)
}
vcol -= start_vcol;
- /* Delete spaces that were inserted after the cursor to keep the
- * text aligned. */
+ // Delete spaces that were inserted after the cursor to keep the
+ // text aligned.
curwin->w_cursor.col += ins_len;
while (vcol > orig_vcols && gchar_cursor() == ' ') {
del_char(false);
@@ -7096,7 +7129,7 @@ static void replace_do_bs(int limit_col)
curwin->w_cursor.col -= ins_len;
}
- /* mark the buffer as changed and prepare for displaying */
+ // mark the buffer as changed and prepare for displaying
changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
} else if (cc == 0)
(void)del_char_after_col(limit_col);
@@ -7164,10 +7197,11 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
return false;
}
- if (*curbuf->b_p_inde != NUL)
- look = curbuf->b_p_indk; /* 'indentexpr' set: use 'indentkeys' */
- else
- look = curbuf->b_p_cink; /* 'indentexpr' empty: use 'cinkeys' */
+ if (*curbuf->b_p_inde != NUL) {
+ look = curbuf->b_p_indk; // 'indentexpr' set: use 'indentkeys'
+ } else {
+ look = curbuf->b_p_cink; // 'indentexpr' empty: use 'cinkeys'
+ }
while (*look) {
/*
* Find out if we want to try a match with this key, depending on
@@ -7366,10 +7400,12 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
*/
int hkmap(int c)
{
- if (p_hkmapp) { /* phonetic mapping, by Ilya Dogolazky */
- enum {hALEF=0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD,
- KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN,
- PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV};
+ if (p_hkmapp) { // phonetic mapping, by Ilya Dogolazky
+ enum {
+ hALEF = 0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD,
+ KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN,
+ PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV
+ };
static char_u map[26] =
{(char_u)hALEF /*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/,
(char_u)DALET /*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit /*f*/,
@@ -7381,28 +7417,27 @@ int hkmap(int c)
(char_u)VAV /*v*/, (char_u)hSHIN /*w*/, (char_u)-1 /*x*/,
(char_u)AIN /*y*/, (char_u)ZADI /*z*/};
- if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z')
+ if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') {
return (int)(map[CharOrd(c)] - 1 + p_aleph);
- /* '-1'='sofit' */
- else if (c == 'x')
+ } else if (c == 'x') { // '-1'='sofit'
return 'X';
- else if (c == 'q')
- return '\''; /* {geresh}={'} */
- else if (c == 246)
- return ' '; /* \"o --> ' ' for a german keyboard */
- else if (c == 228)
- return ' '; /* \"a --> ' ' -- / -- */
- else if (c == 252)
- return ' '; /* \"u --> ' ' -- / -- */
- /* NOTE: islower() does not do the right thing for us on Linux so we
- * do this the same was as 5.7 and previous, so it works correctly on
- * all systems. Specifically, the e.g. Delete and Arrow keys are
- * munged and won't work if e.g. searching for Hebrew text.
- */
- else if (c >= 'a' && c <= 'z')
+ } else if (c == 'q') {
+ return '\''; // {geresh}={'}
+ } else if (c == 246) {
+ return ' '; // \"o --> ' ' for a german keyboard
+ } else if (c == 228) {
+ return ' '; // \"a --> ' ' -- / --
+ } else if (c == 252) {
+ return ' '; // \"u --> ' ' -- / --
+ } else if (c >= 'a' && c <= 'z') {
+ // NOTE: islower() does not do the right thing for us on Linux so we
+ // do this the same was as 5.7 and previous, so it works correctly on
+ // all systems. Specifically, the e.g. Delete and Arrow keys are
+ // munged and won't work if e.g. searching for Hebrew text.
return (int)(map[CharOrdLow(c)] + p_aleph);
- else
+ } else {
return c;
+ }
} else {
switch (c) {
case '`': return ';';
@@ -7411,7 +7446,7 @@ int hkmap(int c)
case 'q': return '/';
case 'w': return '\'';
- /* Hebrew letters - set offset from 'a' */
+ // Hebrew letters - set offset from 'a'
case ',': c = '{'; break;
case '.': c = 'v'; break;
case ';': c = 't'; break;
@@ -7441,10 +7476,10 @@ static void ins_reg(void)
*/
pc_status = PC_STATUS_UNSET;
if (redrawing() && !char_avail()) {
- /* may need to redraw when no more chars available now */
- ins_redraw(FALSE);
+ // may need to redraw when no more chars available now
+ ins_redraw(false);
- edit_putchar('"', TRUE);
+ edit_putchar('"', true);
add_to_showcmd_c(Ctrl_R);
}
@@ -7457,7 +7492,7 @@ static void ins_reg(void)
regname = plain_vgetc();
LANGMAP_ADJUST(regname, TRUE);
if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) {
- /* Get a third key for literal register insertion */
+ // Get a third key for literal register insertion
literally = regname;
add_to_showcmd_c(literally);
regname = plain_vgetc();
@@ -7465,9 +7500,9 @@ static void ins_reg(void)
}
--no_mapping;
- /* Don't call u_sync() while typing the expression or giving an error
- * message for it. Only call it explicitly. */
- ++no_u_sync;
+ // Don't call u_sync() while typing the expression or giving an error
+ // message for it. Only call it explicitly.
+ no_u_sync++;
if (regname == '=') {
pos_T curpos = curwin->w_cursor;
@@ -7486,7 +7521,7 @@ static void ins_reg(void)
need_redraw = true; // remove the '"'
} else {
if (literally == Ctrl_O || literally == Ctrl_P) {
- /* Append the command to the redo buffer. */
+ // Append the command to the redo buffer.
AppendCharToRedobuff(Ctrl_R);
AppendCharToRedobuff(literally);
AppendCharToRedobuff(regname);
@@ -7503,19 +7538,22 @@ static void ins_reg(void)
need_redraw = true;
}
}
- --no_u_sync;
- if (u_sync_once == 1)
- ins_need_undo = TRUE;
+ no_u_sync--;
+ if (u_sync_once == 1) {
+ ins_need_undo = true;
+ }
u_sync_once = 0;
clear_showcmd();
- /* If the inserted register is empty, we need to remove the '"' */
- if (need_redraw || stuff_empty())
+ // If the inserted register is empty, we need to remove the '"'
+ if (need_redraw || stuff_empty()) {
edit_unputchar();
+ }
- /* Disallow starting Visual mode here, would get a weird mode. */
- if (!vis_active && VIsual_active)
+ // Disallow starting Visual mode here, would get a weird mode.
+ if (!vis_active && VIsual_active) {
end_visual_mode();
+ }
}
/*
@@ -7525,7 +7563,7 @@ static void ins_ctrl_g(void)
{
int c;
- /* Right after CTRL-X the cursor will be after the ruler. */
+ // Right after CTRL-X the cursor will be after the ruler.
setcursor();
/*
@@ -7536,24 +7574,25 @@ static void ins_ctrl_g(void)
c = plain_vgetc();
--no_mapping;
switch (c) {
- /* CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col */
+ // CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col
case K_UP:
case Ctrl_K:
case 'k': ins_up(TRUE);
break;
- /* CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col */
+ // CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col
case K_DOWN:
case Ctrl_J:
case 'j': ins_down(TRUE);
break;
- /* CTRL-G u: start new undoable edit */
- case 'u': u_sync(TRUE);
- ins_need_undo = TRUE;
+ // CTRL-G u: start new undoable edit
+ case 'u':
+ u_sync(true);
+ ins_need_undo = true;
- /* Need to reset Insstart, esp. because a BS that joins
- * a line to the previous one must save for undo. */
+ // Need to reset Insstart, esp. because a BS that joins
+ // a line to the previous one must save for undo.
update_Insstart_orig = false;
Insstart = curwin->w_cursor;
break;
@@ -7565,7 +7604,7 @@ static void ins_ctrl_g(void)
dont_sync_undo = kNone;
break;
- /* Unknown CTRL-G command, reserved for future expansion. */
+ // Unknown CTRL-G command, reserved for future expansion.
default: vim_beep(BO_CTRLG);
}
}
@@ -7587,7 +7626,7 @@ static void ins_ctrl_hat(void)
}
set_iminsert_global();
showmode();
- /* Show/unshow value of 'keymap' in status lines. */
+ // Show/unshow value of 'keymap' in status lines.
status_redraw_curbuf();
}
@@ -7628,10 +7667,11 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
*count = 0;
}
- if (--*count > 0) { /* repeat what was typed */
- /* Vi repeats the insert without replacing characters. */
- if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL)
+ if (--*count > 0) { // repeat what was typed
+ // Vi repeats the insert without replacing characters.
+ if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL) {
State &= ~REPLACE_FLAG;
+ }
(void)start_redo_ins();
if (cmdchar == 'r' || cmdchar == 'v') {
@@ -7646,12 +7686,13 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
undisplay_dollar();
}
- /* When an autoindent was removed, curswant stays after the
- * indent */
- if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col)
- curwin->w_set_curswant = TRUE;
+ // When an autoindent was removed, curswant stays after the
+ // indent
+ if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col) {
+ curwin->w_set_curswant = true;
+ }
- /* Remember the last Insert position in the '^ mark. */
+ // Remember the last Insert position in the '^ mark.
if (!cmdmod.keepjumps) {
RESET_FMARK(&curbuf->b_last_insert, curwin->w_cursor, curbuf->b_fnum);
}
@@ -7672,23 +7713,23 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
) {
if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) {
oneleft();
- if (restart_edit != NUL)
- ++curwin->w_cursor.coladd;
+ if (restart_edit != NUL) {
+ curwin->w_cursor.coladd++;
+ }
} else {
- --curwin->w_cursor.col;
- /* Correct cursor for multi-byte character. */
- if (has_mbyte)
- mb_adjust_cursor();
+ curwin->w_cursor.col--;
+ // Correct cursor for multi-byte character.
+ mb_adjust_cursor();
}
}
State = NORMAL;
- /* need to position cursor again (e.g. when on a TAB ) */
+ // need to position cursor again (e.g. when on a TAB )
changed_cline_bef_curs();
setmouse();
- ui_cursor_shape(); /* may show different cursor shape */
+ 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.
@@ -7784,7 +7825,7 @@ static void ins_insert(int replaceState)
}
AppendCharToRedobuff(K_INS);
showmode();
- ui_cursor_shape(); /* may show different cursor shape */
+ ui_cursor_shape(); // may show different cursor shape
}
/*
@@ -7798,10 +7839,11 @@ static void ins_ctrl_o(void)
restart_edit = 'R';
else
restart_edit = 'I';
- if (virtual_active())
- ins_at_eol = FALSE; /* cursor always keeps its column */
- else
+ if (virtual_active()) {
+ ins_at_eol = false; // cursor always keeps its column
+ } else {
ins_at_eol = (gchar_cursor() == NUL);
+ }
}
/*
@@ -7883,11 +7925,12 @@ static void ins_bs_one(colnr_T *vcolp)
dec_cursor();
getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL);
if (State & REPLACE_FLAG) {
- /* Don't delete characters before the insert point when in
- * Replace mode */
+ // Don't delete characters before the insert point when in
+ // Replace mode
if (curwin->w_cursor.lnum != Insstart.lnum
- || curwin->w_cursor.col >= Insstart.col)
+ || curwin->w_cursor.col >= Insstart.col) {
replace_do_bs(-1);
+ }
} else {
(void)del_char(false);
}
@@ -7906,13 +7949,13 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
{
linenr_T lnum;
int cc;
- int temp = 0; /* init for GCC */
+ int temp = 0; // init for GCC
colnr_T save_col;
colnr_T mincol;
bool did_backspace = false;
int in_indent;
int oldState;
- int cpc[MAX_MCO]; /* composing characters */
+ int cpc[MAX_MCO]; // composing characters
// can't delete anything in an empty file
// can't backup past first character in buffer
@@ -7976,23 +8019,22 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
* cc >= 0: NL was replaced, put original characters back
*/
cc = -1;
- if (State & REPLACE_FLAG)
- cc = replace_pop(); /* returns -1 if NL was inserted */
- /*
- * In replace mode, in the line we started replacing, we only move the
- * cursor.
- */
+ if (State & REPLACE_FLAG) {
+ cc = replace_pop(); // returns -1 if NL was inserted
+ }
+ // In replace mode, in the line we started replacing, we only move the
+ // cursor.
if ((State & REPLACE_FLAG) && curwin->w_cursor.lnum <= lnum) {
dec_cursor();
} else {
if (!(State & VREPLACE_FLAG)
|| curwin->w_cursor.lnum > orig_line_count) {
- temp = gchar_cursor(); /* remember current char */
- --curwin->w_cursor.lnum;
+ temp = gchar_cursor(); // remember current char
+ curwin->w_cursor.lnum--;
- /* When "aw" is in 'formatoptions' we must delete the space at
- * the end of the line, otherwise the line will be broken
- * again when auto-formatting. */
+ // When "aw" is in 'formatoptions' we must delete the space at
+ // the end of the line, otherwise the line will be broken
+ // again when auto-formatting.
if (has_format_option(FO_AUTO)
&& has_format_option(FO_WHITE_PAR)) {
char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum,
@@ -8033,20 +8075,19 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
curwin->w_cursor.col = save_col;
cc = replace_pop();
}
- /* restore the characters that NL replaced */
+ // restore the characters that NL replaced
replace_pop_ins();
State = oldState;
}
}
did_ai = false;
} else {
- /*
- * Delete character(s) before the cursor.
- */
- if (revins_on) /* put cursor on last inserted char */
+ // Delete character(s) before the cursor.
+ if (revins_on) { // put cursor on last inserted char
dec_cursor();
+ }
mincol = 0;
- /* keep indent */
+ // keep indent
if (mode == BACKSPACE_LINE
&& (curbuf->b_p_ai
|| cindent_on()
@@ -8081,9 +8122,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
ts = get_sw_value(curbuf);
else
ts = get_sts_value();
- /* Compute the virtual column where we want to be. Since
- * 'showbreak' may get in the way, need to get the last column of
- * the previous character. */
+ // Compute the virtual column where we want to be. Since
+ // 'showbreak' may get in the way, need to get the last column of
+ // the previous character.
getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
start_vcol = vcol;
dec_cursor();
@@ -8091,14 +8132,15 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
inc_cursor();
want_vcol = (want_vcol / ts) * ts;
- /* delete characters until we are at or before want_vcol */
+ // delete characters until we are at or before want_vcol
while (vcol > want_vcol
- && (cc = *(get_cursor_pos_ptr() - 1), ascii_iswhite(cc)))
+ && (cc = *(get_cursor_pos_ptr() - 1), ascii_iswhite(cc))) {
ins_bs_one(&vcol);
+ }
- /* insert extra spaces until we are at want_vcol */
+ // insert extra spaces until we are at want_vcol
while (vcol < want_vcol) {
- /* Remember the first char we inserted */
+ // Remember the first char we inserted
if (curwin->w_cursor.lnum == Insstart_orig.lnum
&& curwin->w_cursor.col < Insstart_orig.col) {
Insstart_orig.col = curwin->w_cursor.col;
@@ -8114,18 +8156,16 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
}
- /* If we are now back where we started delete one character. Can
- * happen when using 'sts' and 'linebreak'. */
- if (vcol >= start_vcol)
+ // If we are now back where we started delete one character. Can
+ // happen when using 'sts' and 'linebreak'.
+ if (vcol >= start_vcol) {
ins_bs_one(&vcol);
-
- // Delete upto starting point, start of line or previous word.
+ }
} else {
- int cclass = 0, prev_cclass = 0;
+ // Delete upto starting point, start of line or previous word.
+ int prev_cclass = 0;
- if (has_mbyte) {
- cclass = mb_get_class(get_cursor_pos_ptr());
- }
+ int cclass = mb_get_class(get_cursor_pos_ptr());
do {
if (!revins_on) { // put cursor on char to be deleted
dec_cursor();
@@ -8193,21 +8233,22 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
// with.
AppendCharToRedobuff(c);
- /* If deleted before the insertion point, adjust it */
+ // If deleted before the insertion point, adjust it
if (curwin->w_cursor.lnum == Insstart_orig.lnum
&& curwin->w_cursor.col < Insstart_orig.col) {
Insstart_orig.col = curwin->w_cursor.col;
}
- /* vi behaviour: the cursor moves backward but the character that
- * was there remains visible
- * Vim behaviour: the cursor moves backward and the character that
- * was there is erased from the screen.
- * We can emulate the vi behaviour by pretending there is a dollar
- * displayed even when there isn't.
- * --pkv Sun Jan 19 01:56:40 EST 2003 */
- if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1)
+ // vi behaviour: the cursor moves backward but the character that
+ // was there remains visible
+ // Vim behaviour: the cursor moves backward and the character that
+ // was there is erased from the screen.
+ // We can emulate the vi behaviour by pretending there is a dollar
+ // displayed even when there isn't.
+ // --pkv Sun Jan 19 01:56:40 EST 2003
+ 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
@@ -8249,7 +8290,7 @@ static void ins_mouse(int c)
can_cindent = true;
}
- /* redraw status lines (in case another window became active) */
+ // redraw status lines (in case another window became active)
redraw_statuslines();
}
@@ -8272,7 +8313,7 @@ static void ins_mousescroll(int dir)
if (curwin == old_curwin)
undisplay_dollar();
- /* Don't scroll the window in which completion is being done. */
+ // Don't scroll the window in which completion is being done.
if (!pum_visible()
|| curwin != old_curwin
) {
@@ -8314,9 +8355,10 @@ static void ins_left(void)
if (!end_change) {
AppendCharToRedobuff(K_LEFT);
}
- /* If exit reversed string, position is fixed */
- if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol)
+ // If exit reversed string, position is fixed
+ if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) {
revins_legal++;
+ }
revins_chars++;
} else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1) {
// if 'whichwrap' set for cursor in insert mode may go to previous line.
@@ -8409,14 +8451,13 @@ static void ins_right(void)
revins_legal++;
if (revins_chars)
revins_chars--;
- }
- /* if 'whichwrap' set for cursor in insert mode, may move the
- * cursor to the next line */
- else if (vim_strchr(p_ww, ']') != NULL
- && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ } else if (vim_strchr(p_ww, ']') != NULL
+ && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ // if 'whichwrap' set for cursor in insert mode, may move the
+ // cursor to the next line
start_arrow(&curwin->w_cursor);
- curwin->w_set_curswant = TRUE;
- ++curwin->w_cursor.lnum;
+ curwin->w_set_curswant = true;
+ curwin->w_cursor.lnum++;
curwin->w_cursor.col = 0;
} else {
vim_beep(BO_CRSR);
@@ -8445,9 +8486,8 @@ static void ins_s_right(void)
dont_sync_undo = kFalse;
}
-static void
-ins_up (
- int startcol /* when TRUE move to Insstart.col */
+static void ins_up(
+ bool startcol // when true move to Insstart.col
)
{
pos_T tpos;
@@ -8477,7 +8517,7 @@ static void ins_pageup(void)
undisplay_dollar();
if (mod_mask & MOD_MASK_CTRL) {
- /* <C-PageUp>: tab page back */
+ // <C-PageUp>: tab page back
if (first_tabpage->tp_next != NULL) {
start_arrow(&curwin->w_cursor);
goto_tabpage(-1);
@@ -8494,9 +8534,8 @@ static void ins_pageup(void)
}
}
-static void
-ins_down (
- int startcol /* when TRUE move to Insstart.col */
+static void ins_down(
+ bool startcol // when true move to Insstart.col
)
{
pos_T tpos;
@@ -8526,7 +8565,7 @@ static void ins_pagedown(void)
undisplay_dollar();
if (mod_mask & MOD_MASK_CTRL) {
- /* <C-PageDown>: tab page forward */
+ // <C-PageDown>: tab page forward
if (first_tabpage->tp_next != NULL) {
start_arrow(&curwin->w_cursor);
goto_tabpage(0);
@@ -8613,7 +8652,7 @@ static bool ins_tab(void)
*/
if (!curbuf->b_p_et && (get_sts_value() || (p_sta && ind))) {
char_u *ptr;
- char_u *saved_line = NULL; /* init for GCC */
+ char_u *saved_line = NULL; // init for GCC
pos_T pos;
pos_T fpos;
pos_T *cursor;
@@ -8635,18 +8674,19 @@ static bool ins_tab(void)
cursor = &curwin->w_cursor;
}
- /* When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces. */
- if (vim_strchr(p_cpo, CPO_LISTWM) == NULL)
- curwin->w_p_list = FALSE;
+ // When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces.
+ if (vim_strchr(p_cpo, CPO_LISTWM) == NULL) {
+ curwin->w_p_list = false;
+ }
- /* Find first white before the cursor */
+ // Find first white before the cursor
fpos = curwin->w_cursor;
while (fpos.col > 0 && ascii_iswhite(ptr[-1])) {
--fpos.col;
--ptr;
}
- /* In Replace mode, don't change characters before the insert point. */
+ // In Replace mode, don't change characters before the insert point.
if ((State & REPLACE_FLAG)
&& fpos.lnum == Insstart.lnum
&& fpos.col < Insstart.col) {
@@ -8654,12 +8694,12 @@ static bool ins_tab(void)
fpos.col = Insstart.col;
}
- /* compute virtual column numbers of first white and cursor */
+ // compute virtual column numbers of first white and cursor
getvcol(curwin, &fpos, &vcol, NULL, NULL);
getvcol(curwin, cursor, &want_vcol, NULL, NULL);
- /* Use as many TABs as possible. Beware of 'breakindent', 'showbreak'
- and 'linebreak' adding extra virtual columns. */
+ // Use as many TABs as possible. Beware of 'breakindent', 'showbreak'
+ // and 'linebreak' adding extra virtual columns.
while (ascii_iswhite(*ptr)) {
i = lbr_chartabsize(NULL, (char_u *)"\t", vcol);
if (vcol + i > want_vcol)
@@ -8667,10 +8707,11 @@ static bool ins_tab(void)
if (*ptr != TAB) {
*ptr = TAB;
if (change_col < 0) {
- change_col = fpos.col; /* Column of first change */
- /* May have to adjust Insstart */
- if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col)
+ change_col = fpos.col; // Column of first change
+ // May have to adjust Insstart
+ if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col) {
Insstart.col = fpos.col;
+ }
}
}
++fpos.col;
@@ -8682,29 +8723,30 @@ static bool ins_tab(void)
int repl_off = 0;
char_u *line = ptr;
- /* Skip over the spaces we need. */
+ // Skip over the spaces we need.
while (vcol < want_vcol && *ptr == ' ') {
vcol += lbr_chartabsize(line, ptr, vcol);
++ptr;
++repl_off;
}
if (vcol > want_vcol) {
- /* Must have a char with 'showbreak' just before it. */
- --ptr;
- --repl_off;
+ // Must have a char with 'showbreak' just before it.
+ ptr--;
+ repl_off--;
}
fpos.col += repl_off;
- /* Delete following spaces. */
+ // Delete following spaces.
i = cursor->col - fpos.col;
if (i > 0) {
STRMOVE(ptr, ptr + i);
- /* correct replace stack. */
+ // correct replace stack.
if ((State & REPLACE_FLAG)
- && !(State & VREPLACE_FLAG)
- )
- for (temp = i; --temp >= 0; )
+ && !(State & VREPLACE_FLAG)) {
+ for (temp = i; --temp >= 0; ) {
replace_join(repl_off);
+ }
+ }
}
cursor->col -= i;
@@ -8714,11 +8756,11 @@ static bool ins_tab(void)
* spacing.
*/
if (State & VREPLACE_FLAG) {
- /* Backspace from real cursor to change_col */
+ // Backspace from real cursor to change_col
backspace_until_column(change_col);
- /* Insert each char in saved_line from changed_col to
- * ptr-cursor */
+ // Insert each char in saved_line from changed_col to
+ // ptr-cursor
ins_bytes_len(saved_line + change_col,
cursor->col - change_col);
}
@@ -8762,10 +8804,11 @@ static bool ins_eol(int c)
* in open_line().
*/
- /* Put cursor on NUL if on the last char and coladd is 1 (happens after
- * CTRL-O). */
- if (virtual_active() && curwin->w_cursor.coladd > 0)
+ // Put cursor on NUL if on the last char and coladd is 1 (happens after
+ // CTRL-O).
+ if (virtual_active() && curwin->w_cursor.coladd > 0) {
coladvance(getviscol());
+ }
// NL in reverse insert will always start in the end of current line.
if (revins_on) {
@@ -8793,15 +8836,15 @@ static int ins_digraph(void)
{
int c;
int cc;
- int did_putchar = FALSE;
+ bool did_putchar = false;
pc_status = PC_STATUS_UNSET;
if (redrawing() && !char_avail()) {
- /* may need to redraw when no more chars available now */
- ins_redraw(FALSE);
+ // may need to redraw when no more chars available now
+ ins_redraw(false);
- edit_putchar('?', TRUE);
- did_putchar = TRUE;
+ edit_putchar('?', true);
+ did_putchar = true;
add_to_showcmd_c(Ctrl_K);
}
@@ -8817,21 +8860,21 @@ static int ins_digraph(void)
edit_unputchar();
}
- if (IS_SPECIAL(c) || mod_mask) { /* special key */
+ if (IS_SPECIAL(c) || mod_mask) { // special key
clear_showcmd();
insert_special(c, TRUE, FALSE);
return NUL;
}
if (c != ESC) {
- did_putchar = FALSE;
+ did_putchar = false;
if (redrawing() && !char_avail()) {
- /* may need to redraw when no more chars available now */
- ins_redraw(FALSE);
+ // may need to redraw when no more chars available now
+ ins_redraw(false);
if (char2cells(c) == 1) {
- ins_redraw(FALSE);
- edit_putchar(c, TRUE);
- did_putchar = TRUE;
+ ins_redraw(false);
+ edit_putchar(c, true);
+ did_putchar = true;
}
add_to_showcmd_c(c);
}
@@ -8870,7 +8913,7 @@ int ins_copychar(linenr_T lnum)
return NUL;
}
- /* try to advance to the cursor column */
+ // try to advance to the cursor column
temp = 0;
line = ptr = ml_get(lnum);
prev_ptr = ptr;
@@ -8920,8 +8963,8 @@ static int ins_ctrl_ey(int tc)
curbuf->b_p_tw = tw_save;
revins_chars++;
revins_legal++;
- c = Ctrl_V; /* pretend CTRL-V is last character */
- auto_format(FALSE, TRUE);
+ c = Ctrl_V; // pretend CTRL-V is last character
+ auto_format(false, true);
}
}
return c;
@@ -8956,9 +8999,10 @@ static void ins_try_si(int c)
*/
ptr = ml_get(pos->lnum);
i = pos->col;
- if (i > 0) /* skip blanks before '{' */
- while (--i > 0 && ascii_iswhite(ptr[i]))
- ;
+ if (i > 0) { // skip blanks before '{'
+ while (--i > 0 && ascii_iswhite(ptr[i])) {
+ }
+ }
curwin->w_cursor.lnum = pos->lnum;
curwin->w_cursor.col = i;
if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL)
@@ -8981,9 +9025,10 @@ static void ins_try_si(int c)
while (curwin->w_cursor.lnum > 1) {
ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum)));
- /* ignore empty lines and lines starting with '#'. */
- if (*ptr != '#' && *ptr != NUL)
+ // ignore empty lines and lines starting with '#'.
+ if (*ptr != '#' && *ptr != NUL) {
break;
+ }
}
if (get_indent() >= i)
temp = FALSE;
@@ -8998,14 +9043,15 @@ static void ins_try_si(int c)
* set indent of '#' always to 0
*/
if (curwin->w_cursor.col > 0 && can_si && c == '#') {
- /* remember current indent for next line */
+ // remember current indent for next line
old_indent = get_indent();
(void)set_indent(0, SIN_CHANGED);
}
- /* Adjust ai_col, the char at this position can be deleted. */
- if (ai_col > curwin->w_cursor.col)
+ // Adjust ai_col, the char at this position can be deleted.
+ if (ai_col > curwin->w_cursor.col) {
ai_col = curwin->w_cursor.col;
+ }
}
/*
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 3757dc6c04..8ec1e51297 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -55,7 +55,7 @@
// TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead
-#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */
+#define DICT_MAXNEST 100 // maximum nesting of lists and dicts
static char *e_letunexp = N_("E18: Unexpected characters in :let");
@@ -97,7 +97,7 @@ static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
#define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
#define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
-static int echo_attr = 0; /* attributes used for ":echo" */
+static int echo_attr = 0; // attributes used for ":echo"
// The names of packages that once were loaded are remembered.
static garray_T ga_loaded = { 0, 0, sizeof(char_u *), 4, NULL };
@@ -106,16 +106,16 @@ static garray_T ga_loaded = { 0, 0, sizeof(char_u *), 4, NULL };
* Info used by a ":for" loop.
*/
typedef struct {
- int fi_semicolon; /* TRUE if ending in '; var]' */
- int fi_varcount; /* nr of variables in the list */
- listwatch_T fi_lw; /* keep an eye on the item used. */
- list_T *fi_list; /* list being used */
+ int fi_semicolon; // TRUE if ending in '; var]'
+ int fi_varcount; // nr of variables in the list
+ listwatch_T fi_lw; // keep an eye on the item used.
+ list_T *fi_list; // list being used
} forinfo_T;
-/* values for vv_flags: */
-#define VV_COMPAT 1 /* compatible, also used without "v:" */
-#define VV_RO 2 /* read-only */
-#define VV_RO_SBX 4 /* read-only in the sandbox */
+// values for vv_flags:
+#define VV_COMPAT 1 // compatible, also used without "v:"
+#define VV_RO 2 // read-only
+#define VV_RO_SBX 4 // read-only in the sandbox
#define VV(idx, name, type, flags) \
[idx] = { \
@@ -232,7 +232,7 @@ static struct vimvar {
};
#undef VV
-/* shorthand */
+// shorthand
#define vv_type vv_di.di_tv.v_type
#define vv_nr vv_di.di_tv.vval.v_number
#define vv_special vv_di.di_tv.vval.v_special
@@ -337,12 +337,14 @@ void eval_init(void)
else
p->vv_di.di_flags = DI_FLAGS_FIX;
- /* add to v: scope dict, unless the value is not always available */
- if (p->vv_type != VAR_UNKNOWN)
+ // add to v: scope dict, unless the value is not always available
+ if (p->vv_type != VAR_UNKNOWN) {
hash_add(&vimvarht, p->vv_di.di_key);
- if (p->vv_flags & VV_COMPAT)
- /* add to compat scope dict */
+ }
+ if (p->vv_flags & VV_COMPAT) {
+ // add to compat scope dict
hash_add(&compat_hashtab, p->vv_di.di_key);
+ }
}
vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
@@ -416,16 +418,16 @@ void eval_clear(void)
}
}
hash_clear(&vimvarht);
- hash_init(&vimvarht); /* garbage_collect() will access it */
+ hash_init(&vimvarht); // garbage_collect() will access it
hash_clear(&compat_hashtab);
free_scriptnames();
free_locales();
- /* global variables */
+ // global variables
vars_clear(&globvarht);
- /* autoloaded script names */
+ // autoloaded script names
ga_clear_strings(&ga_loaded);
/* Script-local variables. First clear all the variables and in a second
@@ -472,25 +474,25 @@ static char_u *redir_varname = NULL;
int
var_redir_start(
char_u *name,
- int append /* append to an existing variable */
+ int append // append to an existing variable
)
{
int save_emsg;
int err;
typval_T tv;
- /* Catch a bad name early. */
+ // Catch a bad name early.
if (!eval_isnamec1(*name)) {
EMSG(_(e_invarg));
return FAIL;
}
- /* Make a copy of the name, it is used in redir_lval until redir ends. */
+ // Make a copy of the name, it is used in redir_lval until redir ends.
redir_varname = vim_strsave(name);
redir_lval = xcalloc(1, sizeof(lval_T));
- /* The output is stored in growarray "redir_ga" until redirection ends. */
+ // The output is stored in growarray "redir_ga" until redirection ends.
ga_init(&redir_ga, (int)sizeof(char), 500);
// Parse the variable name (can be a dict or list entry).
@@ -499,12 +501,13 @@ var_redir_start(
if (redir_endp == NULL || redir_lval->ll_name == NULL
|| *redir_endp != NUL) {
clear_lval(redir_lval);
- if (redir_endp != NULL && *redir_endp != NUL)
- /* Trailing characters are present after the variable name */
+ if (redir_endp != NULL && *redir_endp != NUL) {
+ // Trailing characters are present after the variable name
EMSG(_(e_trailing));
- else
+ } else {
EMSG(_(e_invarg));
- redir_endp = NULL; /* don't store a value, only cleanup */
+ }
+ redir_endp = NULL; // don't store a value, only cleanup
var_redir_stop();
return FAIL;
}
@@ -524,7 +527,7 @@ var_redir_start(
err = did_emsg;
did_emsg |= save_emsg;
if (err) {
- redir_endp = NULL; /* don't store a value, only cleanup */
+ redir_endp = NULL; // don't store a value, only cleanup
var_redir_stop();
return FAIL;
}
@@ -548,10 +551,11 @@ void var_redir_str(char_u *value, int value_len)
if (redir_lval == NULL)
return;
- if (value_len == -1)
- len = (int)STRLEN(value); /* Append the entire string */
- else
- len = value_len; /* Append only "value_len" characters */
+ if (value_len == -1) {
+ len = (int)STRLEN(value); // Append the entire string
+ } else {
+ len = value_len; // Append only "value_len" characters
+ }
ga_grow(&redir_ga, len);
memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
@@ -567,9 +571,9 @@ void var_redir_stop(void)
typval_T tv;
if (redir_lval != NULL) {
- /* If there was no error: assign the text to the variable. */
+ // If there was no error: assign the text to the variable.
if (redir_endp != NULL) {
- ga_append(&redir_ga, NUL); /* Append the trailing NUL. */
+ ga_append(&redir_ga, NUL); // Append the trailing NUL.
tv.v_type = VAR_STRING;
tv.vval.v_string = redir_ga.ga_data;
// Call get_lval() again, if it's inside a Dict or List it may
@@ -670,7 +674,7 @@ eval_to_bool(
char_u *arg,
bool *error,
char_u **nextcmd,
- int skip /* only parse, don't execute */
+ int skip // only parse, don't execute
)
{
typval_T tv;
@@ -1125,8 +1129,9 @@ void *call_func_retlist(const char_u *func, int argc, typval_T *argv)
* counted for the script/function itself.
* Should always be called in pair with prof_child_exit().
*/
-void prof_child_enter(proftime_T *tm /* place to store waittime */
- )
+void prof_child_enter(
+ proftime_T *tm // place to store waittime
+)
{
funccall_T *fc = get_current_funccal();
@@ -1141,8 +1146,9 @@ void prof_child_enter(proftime_T *tm /* place to store waittime */
* Take care of time spent in a child.
* Should always be called after prof_child_enter().
*/
-void prof_child_exit(proftime_T *tm /* where waittime was stored */
- )
+void prof_child_exit(
+ proftime_T *tm // where waittime was stored
+)
{
funccall_T *fc = get_current_funccal();
@@ -1167,7 +1173,6 @@ int eval_foldexpr(char_u *arg, int *cp)
{
typval_T tv;
varnumber_T retval;
- char_u *s;
int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
OPT_LOCAL);
@@ -1176,20 +1181,21 @@ int eval_foldexpr(char_u *arg, int *cp)
++sandbox;
++textlock;
*cp = NUL;
- if (eval0(arg, &tv, NULL, TRUE) == FAIL)
+ if (eval0(arg, &tv, NULL, true) == FAIL) {
retval = 0;
- else {
- /* If the result is a number, just return the number. */
- if (tv.v_type == VAR_NUMBER)
+ } else {
+ // If the result is a number, just return the number.
+ if (tv.v_type == VAR_NUMBER) {
retval = tv.vval.v_number;
- else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL)
+ } else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) {
retval = 0;
- else {
- /* If the result is a string, check if there is a non-digit before
- * the number. */
- s = tv.vval.v_string;
- if (!ascii_isdigit(*s) && *s != '-')
+ } else {
+ // If the result is a string, check if there is a non-digit before
+ // the number.
+ char_u *s = tv.vval.v_string;
+ if (!ascii_isdigit(*s) && *s != '-') {
*cp = *s++;
+ }
retval = atol((char *)s);
}
tv_clear(&tv);
@@ -1529,10 +1535,10 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count,
const char_u *s;
if (*arg == '[') {
- /* "[var, var]": find the matching ']'. */
+ // "[var, var]": find the matching ']'.
p = arg;
for (;; ) {
- p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */
+ p = skipwhite(p + 1); // skip whites after '[', ';' or ','
s = skip_var_one(p);
if (s == p) {
EMSG2(_(e_invarg2), p);
@@ -1959,7 +1965,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
hashtab_T *ht;
int quiet = flags & GLV_QUIET;
- /* Clear everything in "lp". */
+ // Clear everything in "lp".
memset(lp, 0, sizeof(lval_T));
if (skip) {
@@ -1977,7 +1983,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
(const char_u **)&expr_end,
fne_flags);
if (expr_start != NULL) {
- /* Don't expand the name when we already know there is an error. */
+ // Don't expand the name when we already know there is an error.
if (unlet && !ascii_iswhite(*p) && !ends_excmd(*p)
&& *p != '[' && *p != '.') {
EMSG(_(e_trailing));
@@ -2057,7 +2063,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
}
p = key + len;
} else {
- /* Get the index [expr] or the first index [expr: ]. */
+ // Get the index [expr] or the first index [expr: ].
p = skipwhite(p + 1);
if (*p == ':') {
empty1 = true;
@@ -2073,7 +2079,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
}
}
- /* Optionally get the second index [ :expr]. */
+ // Optionally get the second index [ :expr].
if (*p == ':') {
if (lp->ll_tv->v_type == VAR_DICT) {
if (!quiet) {
@@ -2119,8 +2125,8 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
return NULL;
}
- /* Skip to past ']'. */
- ++p;
+ // Skip to past ']'.
+ p++;
}
if (lp->ll_tv->v_type == VAR_DICT) {
@@ -2546,7 +2552,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
if (cmdidx == CMD_let || cmdidx == CMD_const) {
xp->xp_context = EXPAND_USER_VARS;
if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) {
- /* ":let var1 var2 ...": find last space. */
+ // ":let var1 var2 ...": find last space.
for (p = arg + STRLEN(arg); p >= arg; ) {
xp->xp_pattern = p;
MB_PTR_BACK(arg, p);
@@ -2575,7 +2581,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
}
} else if (c == '$') {
- /* environment variable */
+ // environment variable
xp->xp_context = EXPAND_ENV_VARS;
} else if (c == '=') {
got_eq = TRUE;
@@ -2587,18 +2593,20 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
} else if ((c == '<' || c == '#')
&& xp->xp_context == EXPAND_FUNCTIONS
&& vim_strchr(xp->xp_pattern, '(') == NULL) {
- /* Function name can start with "<SNR>" and contain '#'. */
+ // Function name can start with "<SNR>" and contain '#'.
break;
} else if (cmdidx != CMD_let || got_eq) {
- if (c == '"') { /* string */
- while ((c = *++xp->xp_pattern) != NUL && c != '"')
- if (c == '\\' && xp->xp_pattern[1] != NUL)
- ++xp->xp_pattern;
+ if (c == '"') { // string
+ while ((c = *++xp->xp_pattern) != NUL && c != '"') {
+ if (c == '\\' && xp->xp_pattern[1] != NUL) {
+ xp->xp_pattern++;
+ }
+ }
xp->xp_context = EXPAND_NOTHING;
- } else if (c == '\'') { /* literal string */
- /* Trick: '' is like stopping and starting a literal string. */
- while ((c = *++xp->xp_pattern) != NUL && c != '\'')
- /* skip */;
+ } else if (c == '\'') { // literal string
+ // Trick: '' is like stopping and starting a literal string.
+ while ((c = *++xp->xp_pattern) != NUL && c != '\'') {
+ }
xp->xp_context = EXPAND_NOTHING;
} else if (c == '|') {
if (xp->xp_pattern[1] == '|') {
@@ -2613,15 +2621,14 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
* anyway. */
xp->xp_context = EXPAND_EXPRESSION;
arg = xp->xp_pattern;
- if (*arg != NUL)
- while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
- /* skip */;
+ if (*arg != NUL) {
+ while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) {
+ }
+ }
}
xp->xp_pattern = arg;
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/*
* ":unlet[!] var1 ... " command.
*/
@@ -2811,8 +2818,7 @@ int do_unlet(const char *const name, const size_t name_len, const int forceit)
if (ht != NULL && *varname != NUL) {
dict_T *d = get_current_funccal_dict(ht);
- if (d == NULL)
- {
+ if (d == NULL) {
if (ht == &globvarht) {
d = &globvardict;
} else if (ht == &compat_hashtab) {
@@ -2905,7 +2911,7 @@ static int do_lock_var(lval_T *lp, char_u *const name_end, const int deep,
} else if (lp->ll_range) {
listitem_T *li = lp->ll_li;
- /* (un)lock a range of List items. */
+ // (un)lock a range of List items.
while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) {
tv_item_lock(TV_LIST_ITEM_TV(li), deep, lock);
li = TV_LIST_ITEM_NEXT(lp->ll_list, li);
@@ -2955,7 +2961,7 @@ static char_u *cat_prefix_varname(int prefix, char_u *name)
if (len > varnamebuflen) {
xfree(varnamebuf);
- len += 10; /* some additional space */
+ len += 10; // some additional space
varnamebuf = xmalloc(len);
varnamebuflen = len;
}
@@ -2984,7 +2990,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
tdone = 0;
}
- /* Global variables */
+ // Global variables
if (gdone < globvarht.ht_used) {
if (gdone++ == 0)
hi = globvarht.ht_array;
@@ -2997,7 +3003,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
return hi->hi_key;
}
- /* b: variables */
+ // b: variables
ht = &curbuf->b_vars->dv_hashtab;
if (bdone < ht->ht_used) {
if (bdone++ == 0)
@@ -3009,7 +3015,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
return cat_prefix_varname('b', hi->hi_key);
}
- /* w: variables */
+ // w: variables
ht = &curwin->w_vars->dv_hashtab;
if (wdone < ht->ht_used) {
if (wdone++ == 0)
@@ -3021,7 +3027,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
return cat_prefix_varname('w', hi->hi_key);
}
- /* t: variables */
+ // t: variables
ht = &curtab->tp_vars->dv_hashtab;
if (tdone < ht->ht_used) {
if (tdone++ == 0)
@@ -3047,7 +3053,7 @@ char_u *get_user_var_name(expand_T *xp, int idx)
/// Return TRUE if "pat" matches "text".
/// Does not use 'cpo' and always uses 'magic'.
-static int pattern_match(char_u *pat, char_u *text, int ic)
+static int pattern_match(char_u *pat, char_u *text, bool ic)
{
int matches = 0;
regmatch_T regmatch;
@@ -3162,8 +3168,9 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate)
* Get the second variable.
*/
*arg = skipwhite(*arg + 1);
- if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */
+ if (eval1(arg, rettv, evaluate && result) == FAIL) { // recursive!
return FAIL;
+ }
/*
* Check for the ":".
@@ -3357,10 +3364,10 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
char_u *p;
int i;
exptype_T type = TYPE_UNKNOWN;
- int type_is = FALSE; /* TRUE for "is" and "isnot" */
+ bool type_is = false; // true for "is" and "isnot"
int len = 2;
varnumber_T n1, n2;
- int ic;
+ bool ic;
/*
* Get the first variable.
@@ -3398,7 +3405,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
}
if (!isalnum(p[len]) && p[len] != '_') {
type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL;
- type_is = TRUE;
+ type_is = true;
}
}
break;
@@ -3408,23 +3415,18 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
* If there is a comparative operator, use it.
*/
if (type != TYPE_UNKNOWN) {
- /* extra question mark appended: ignore case */
+ // extra question mark appended: ignore case
if (p[len] == '?') {
- ic = TRUE;
- ++len;
- }
- /* extra '#' appended: match case */
- else if (p[len] == '#') {
- ic = FALSE;
- ++len;
- }
- /* nothing appended: use 'ignorecase' */
- else
+ ic = true;
+ len++;
+ } else if (p[len] == '#') { // extra '#' appended: match case
+ ic = false;
+ len++;
+ } else { // nothing appended: use 'ignorecase'
ic = p_ic;
+ }
- /*
- * Get the second variable.
- */
+ // Get the second variable.
*arg = skipwhite(p + len);
if (eval5(arg, &var2, evaluate) == FAIL) {
tv_clear(rettv);
@@ -3569,7 +3571,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
const char *const s1 = tv_get_string_buf(rettv, buf1);
const char *const s2 = tv_get_string_buf(&var2, buf2);
if (type != TYPE_MATCH && type != TYPE_NOMATCH) {
- i = mb_strcmp_ic((bool)ic, s1, s2);
+ i = mb_strcmp_ic(ic, s1, s2);
} else {
i = 0;
}
@@ -3730,7 +3732,7 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
}
tv_clear(rettv);
- /* If there is a float on either side the result is a float. */
+ // If there is a float on either side the result is a float.
if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) {
if (op == '+')
f1 = f1 + f2;
@@ -4169,7 +4171,7 @@ eval_index(
char_u **arg,
typval_T *rettv,
int evaluate,
- int verbose /* give error messages */
+ int verbose // give error messages
)
{
bool empty1 = false;
@@ -4265,7 +4267,7 @@ eval_index(
}
}
- /* Check for the ']'. */
+ // Check for the ']'.
if (**arg != ']') {
if (verbose) {
EMSG(_(e_missbrac));
@@ -4276,7 +4278,7 @@ eval_index(
}
return FAIL;
}
- *arg = skipwhite(*arg + 1); /* skip the ']' */
+ *arg = skipwhite(*arg + 1); // skip the ']'
}
if (evaluate) {
@@ -4468,28 +4470,29 @@ int get_option_tv(const char **const arg, typval_T *const rettv,
opt_type = get_option_value((char_u *)(*arg), &numval,
rettv == NULL ? NULL : &stringval, opt_flags);
- if (opt_type == -3) { /* invalid name */
- if (rettv != NULL)
+ if (opt_type == -3) { // invalid name
+ if (rettv != NULL) {
EMSG2(_("E113: Unknown option: %s"), *arg);
+ }
ret = FAIL;
} else if (rettv != NULL) {
- if (opt_type == -2) { /* hidden string option */
+ if (opt_type == -2) { // hidden string option
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- } else if (opt_type == -1) { /* hidden number option */
+ } else if (opt_type == -1) { // hidden number option
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
- } else if (opt_type == 1) { /* number option */
+ } else if (opt_type == 1) { // number option
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = numval;
- } else { /* string option */
+ } else { // string option
rettv->v_type = VAR_STRING;
rettv->vval.v_string = stringval;
}
} else if (working && (opt_type == -2 || opt_type == -1))
ret = FAIL;
- *option_end = c; /* put back for error messages */
+ *option_end = c; // put back for error messages
*arg = option_end;
return ret;
@@ -4523,7 +4526,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
return FAIL;
}
- /* If only parsing, set *arg and return here */
+ // If only parsing, set *arg and return here
if (!evaluate) {
*arg = p + 1;
return OK;
@@ -4547,9 +4550,9 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
case 'r': *name++ = CAR; ++p; break;
case 't': *name++ = TAB; ++p; break;
- case 'X': /* hex: "\x1", "\x12" */
+ case 'X': // hex: "\x1", "\x12"
case 'x':
- case 'u': /* Unicode: "\u0023" */
+ case 'u': // Unicode: "\u0023"
case 'U':
if (ascii_isxdigit(p[1])) {
int n, nr;
@@ -4578,7 +4581,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
}
break;
- /* octal: "\1", "\12", "\123" */
+ // octal: "\1", "\12", "\123"
case '0':
case '1':
case '2':
@@ -4647,7 +4650,7 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
return FAIL;
}
- /* If only parsing return after setting "*arg" */
+ // If only parsing return after setting "*arg"
if (!evaluate) {
*arg = p + 1;
return OK;
@@ -5346,10 +5349,12 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate)
* But {} is an empty Dictionary.
*/
if (*start != '}') {
- if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */
+ if (eval1(&start, &tv, false) == FAIL) { // recursive!
return FAIL;
- if (*start == '}')
+ }
+ if (*start == '}') {
return NOTDONE;
+ }
}
if (evaluate) {
@@ -5360,8 +5365,9 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate)
*arg = skipwhite(*arg + 1);
while (**arg != '}' && **arg != NUL) {
- if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */
+ if (eval1(arg, &tvkey, evaluate) == FAIL) { // recursive!
goto failret;
+ }
if (**arg != ':') {
EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg);
tv_clear(&tvkey);
@@ -6109,6 +6115,10 @@ void common_function(typval_T *argvars, typval_T *rettv,
list = argvars[arg_idx].vval.v_list;
if (tv_list_len(list) == 0) {
arg_idx = 0;
+ } else if (tv_list_len(list) > MAX_FUNC_ARGS) {
+ emsg_funcname((char *)e_toomanyarg, name);
+ xfree(name);
+ goto theend;
}
}
}
@@ -6312,7 +6322,7 @@ dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr)
win_T *
find_win_by_nr(
typval_T *vp,
- tabpage_T *tp /* NULL for current tab page */
+ tabpage_T *tp // NULL for current tab page
)
{
int nr = (int)tv_get_number_chk(vp, NULL);
@@ -6375,7 +6385,7 @@ void
getwinvar(
typval_T *argvars,
typval_T *rettv,
- int off /* 1 for gettabwinvar() */
+ int off // 1 for gettabwinvar()
)
{
win_T *win, *oldcurwin;
@@ -7102,10 +7112,16 @@ void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
bool callback_from_typval(Callback *const callback, typval_T *const arg)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
+ int r = OK;
+
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) {
callback->data.partial = arg->vval.v_partial;
callback->data.partial->pt_refcount++;
callback->type = kCallbackPartial;
+ } else if (arg->v_type == VAR_STRING
+ && arg->vval.v_string != NULL
+ && ascii_isdigit(*arg->vval.v_string)) {
+ r = FAIL;
} else if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) {
char_u *name = arg->vval.v_string;
func_ref(name);
@@ -7114,6 +7130,10 @@ bool callback_from_typval(Callback *const callback, typval_T *const arg)
} else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) {
callback->type = kCallbackNone;
} else {
+ r = FAIL;
+ }
+
+ if (r == FAIL) {
EMSG(_("E921: Invalid callback argument"));
return false;
}
@@ -7592,19 +7612,19 @@ pos_T *var2fpos(const typval_T *const tv, const int dollar_lnum,
if (name[0] == 'w' && dollar_lnum) {
pos.col = 0;
- if (name[1] == '0') { /* "w0": first visible line */
+ if (name[1] == '0') { // "w0": first visible line
update_topline();
// In silent Ex mode topline is zero, but that's not a valid line
// number; use one instead.
pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1;
return &pos;
- } else if (name[1] == '$') { /* "w$": last visible line */
+ } else if (name[1] == '$') { // "w$": last visible line
validate_botline();
// In silent Ex mode botline is zero, return zero then.
pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0;
return &pos;
}
- } else if (name[0] == '$') { /* last column or line */
+ } else if (name[0] == '$') { // last column or line
if (dollar_lnum) {
pos.lnum = curbuf->b_ml.ml_line_count;
pos.col = 0;
@@ -7744,7 +7764,7 @@ int get_name_len(const char **const arg,
{
int len;
- *alias = NULL; /* default to no alias */
+ *alias = NULL; // default to no alias
if ((*arg)[0] == (char)K_SPECIAL && (*arg)[1] == (char)KS_EXTRA
&& (*arg)[2] == (char)KE_SNR) {
@@ -7754,7 +7774,7 @@ int get_name_len(const char **const arg,
}
len = eval_fname_script(*arg);
if (len > 0) {
- /* literal "<SID>", "s:" or "<SNR>" */
+ // literal "<SID>", "s:" or "<SNR>"
*arg += len;
}
@@ -7803,7 +7823,7 @@ int get_name_len(const char **const arg,
// Return a pointer to just after the name. Equal to "arg" if there is no
// valid name.
const char_u *find_name_end(const char_u *arg, const char_u **expr_start,
- const char_u **expr_end, int flags)
+ const char_u **expr_end, int flags)
{
int mb_nest = 0;
int br_nest = 0;
@@ -7917,7 +7937,7 @@ static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start,
}
xfree(temp_result);
- *in_end = c1; /* put char back for error messages */
+ *in_end = c1; // put char back for error messages
*expr_start = '{';
*expr_end = '}';
@@ -7926,7 +7946,7 @@ static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start,
(const char_u **)&expr_start,
(const char_u **)&expr_end, 0);
if (expr_start != NULL) {
- /* Further expansion! */
+ // Further expansion!
temp_result = make_expanded_name(retval, expr_start,
expr_end, temp_result);
xfree(retval);
@@ -8140,10 +8160,7 @@ char_u *v_throwpoint(char_u *oldval)
*/
char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
{
- char_u *oldval;
- char_u *newval;
-
- oldval = vimvars[VV_CMDARG].vv_str;
+ char_u *oldval = vimvars[VV_CMDARG].vv_str;
if (eap == NULL) {
xfree(oldval);
vimvars[VV_CMDARG].vv_str = oldarg;
@@ -8159,14 +8176,18 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
if (eap->read_edit)
len += 7;
- if (eap->force_ff != 0)
- len += STRLEN(eap->cmd + eap->force_ff) + 6;
- if (eap->force_enc != 0)
+ if (eap->force_ff != 0) {
+ len += 10; // " ++ff=unix"
+ }
+ if (eap->force_enc != 0) {
len += STRLEN(eap->cmd + eap->force_enc) + 7;
- if (eap->bad_char != 0)
- len += 7 + 4; /* " ++bad=" + "keep" or "drop" */
+ }
+ if (eap->bad_char != 0) {
+ len += 7 + 4; // " ++bad=" + "keep" or "drop"
+ }
- newval = xmalloc(len + 1);
+ const size_t newval_len = len + 1;
+ char_u *newval = xmalloc(newval_len);
if (eap->force_bin == FORCE_BIN)
sprintf((char *)newval, " ++bin");
@@ -8178,18 +8199,23 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
if (eap->read_edit)
STRCAT(newval, " ++edit");
- if (eap->force_ff != 0)
- sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
- eap->cmd + eap->force_ff);
- if (eap->force_enc != 0)
- sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
- eap->cmd + eap->force_enc);
- if (eap->bad_char == BAD_KEEP)
+ if (eap->force_ff != 0) {
+ snprintf((char *)newval + STRLEN(newval), newval_len, " ++ff=%s",
+ eap->force_ff == 'u' ? "unix" :
+ eap->force_ff == 'd' ? "dos" : "mac");
+ }
+ if (eap->force_enc != 0) {
+ snprintf((char *)newval + STRLEN(newval), newval_len, " ++enc=%s",
+ eap->cmd + eap->force_enc);
+ }
+ if (eap->bad_char == BAD_KEEP) {
STRCPY(newval + STRLEN(newval), " ++bad=keep");
- else if (eap->bad_char == BAD_DROP)
+ } else if (eap->bad_char == BAD_DROP) {
STRCPY(newval + STRLEN(newval), " ++bad=drop");
- else if (eap->bad_char != 0)
- sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char);
+ } else if (eap->bad_char != 0) {
+ snprintf((char *)newval + STRLEN(newval), newval_len, " ++bad=%c",
+ eap->bad_char);
+ }
vimvars[VV_CMDARG].vv_str = newval;
return oldval;
}
@@ -8282,8 +8308,8 @@ int
handle_subscript(
const char **const arg,
typval_T *rettv,
- int evaluate, /* do more than finding the end */
- int verbose /* give error messages */
+ int evaluate, // do more than finding the end
+ int verbose // give error messages
)
{
int ret = OK;
@@ -8393,6 +8419,27 @@ void set_selfdict(typval_T *const rettv, dict_T *const selfdict)
make_partial(selfdict, rettv);
}
+// Turn a typeval into a string. Similar to tv_get_string_buf() but uses
+// string() on Dict, List, etc.
+static const char *tv_stringify(typval_T *varp, char *buf)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (varp->v_type == VAR_LIST
+ || varp->v_type == VAR_DICT
+ || varp->v_type == VAR_FUNC
+ || varp->v_type == VAR_PARTIAL
+ || varp->v_type == VAR_FLOAT) {
+ typval_T tmp;
+
+ f_string(varp, &tmp, NULL);
+ const char *const res = tv_get_string_buf(&tmp, buf);
+ tv_clear(varp);
+ *varp = tmp;
+ return res;
+ }
+ return tv_get_string_buf(varp, buf);
+}
+
// Find variable "name" in the list of variables.
// Return a pointer to it if found, NULL if not found.
// Careful: "a:0" variables don't have a name.
@@ -8421,7 +8468,8 @@ dictitem_T *find_var(const char *const name, const size_t name_len,
return find_var_in_scoped_ht(name, name_len, no_autoload || htp != NULL);
}
-/// Find variable in hashtab
+/// Find variable in hashtab.
+/// When "varname" is empty returns curwin/curtab/etc vars dictionary.
///
/// @param[in] ht Hashtab to find variable in.
/// @param[in] htname Hashtab name (first character).
@@ -9107,10 +9155,10 @@ int var_item_copy(const vimconv_T *const conv,
case VAR_DICT:
to->v_type = VAR_DICT;
to->v_lock = 0;
- if (from->vval.v_dict == NULL)
+ if (from->vval.v_dict == NULL) {
to->vval.v_dict = NULL;
- else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) {
- /* use the copy made earlier */
+ } else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) {
+ // use the copy made earlier
to->vval.v_dict = from->vval.v_dict->dv_copydict;
++to->vval.v_dict->dv_refcount;
} else {
@@ -9243,7 +9291,10 @@ void ex_execute(exarg_T *eap)
}
if (!eap->skip) {
- const char *const argstr = tv_get_string(&rettv);
+ char buf[NUMBUFLEN];
+ const char *const argstr = eap->cmdidx == CMD_execute
+ ? tv_get_string_buf(&rettv, buf)
+ : tv_stringify(&rettv, buf);
const size_t len = strlen(argstr);
ga_grow(&ga, len + 2);
if (!GA_EMPTY(&ga)) {
@@ -9270,7 +9321,7 @@ void ex_execute(exarg_T *eap)
MSG_ATTR(ga.ga_data, echo_attr);
ui_flush();
} else if (eap->cmdidx == CMD_echoerr) {
- /* We don't want to abort following commands, restore did_emsg. */
+ // We don't want to abort following commands, restore did_emsg.
save_did_emsg = did_emsg;
msg_ext_set_kind("echoerr");
EMSG((char_u *)ga.ga_data);
@@ -9325,10 +9376,7 @@ static const char *find_option_end(const char **const arg, int *const opt_flags)
return p;
}
-
-/*
- * Start profiling function "fp".
- */
+/// Start profiling function "fp".
void func_do_profile(ufunc_T *fp)
{
int len = fp->uf_lines.ga_len;
@@ -9372,8 +9420,9 @@ void func_dump_profile(FILE *fd)
int st_len = 0;
todo = (int)func_hashtab.ht_used;
- if (todo == 0)
- return; /* nothing to dump */
+ if (todo == 0) {
+ return; // nothing to dump
+ }
sorttab = xmalloc(sizeof(ufunc_T *) * todo);
@@ -9442,7 +9491,7 @@ prof_sort_list(
ufunc_T **sorttab,
int st_len,
char *title,
- int prefer_self /* when equal print only self time */
+ int prefer_self // when equal print only self time
)
{
int i;
@@ -9470,8 +9519,8 @@ static void prof_func_line(
int count,
proftime_T *total,
proftime_T *self,
- int prefer_self /* when equal print only self time */
- )
+ int prefer_self // when equal print only self time
+)
{
if (count > 0) {
fprintf(fd, "%5d ", count);
@@ -9507,6 +9556,33 @@ static int prof_self_cmp(const void *s1, const void *s2)
return profile_cmp(p1->uf_tm_self, p2->uf_tm_self);
}
+/// Return the autoload script name for a function or variable name
+/// Caller must make sure that "name" contains AUTOLOAD_CHAR.
+///
+/// @param[in] name Variable/function name.
+/// @param[in] name_len Name length.
+///
+/// @return [allocated] autoload script name.
+char *autoload_name(const char *const name, const size_t name_len)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ // Get the script file name: replace '#' with '/', append ".vim".
+ char *const scriptname = xmalloc(name_len + sizeof("autoload/.vim"));
+ memcpy(scriptname, "autoload/", sizeof("autoload/") - 1);
+ memcpy(scriptname + sizeof("autoload/") - 1, name, name_len);
+ size_t auchar_idx = 0;
+ for (size_t i = sizeof("autoload/") - 1;
+ i - sizeof("autoload/") + 1 < name_len;
+ i++) {
+ if (scriptname[i] == AUTOLOAD_CHAR) {
+ scriptname[i] = '/';
+ auchar_idx = i;
+ }
+ }
+ memcpy(scriptname + auchar_idx, ".vim", sizeof(".vim"));
+
+ return scriptname;
+}
/// If name has a package name try autoloading the script for it
///
@@ -9516,7 +9592,7 @@ static int prof_self_cmp(const void *s1, const void *s2)
///
/// @return true if a package was loaded.
bool script_autoload(const char *const name, const size_t name_len,
- const bool reload)
+ const bool reload)
{
// If there is no '#' after name[0] there is no package name.
const char *p = memchr(name, AUTOLOAD_CHAR, name_len);
@@ -9555,34 +9631,6 @@ bool script_autoload(const char *const name, const size_t name_len,
return ret;
}
-/// Return the autoload script name for a function or variable name
-/// Caller must make sure that "name" contains AUTOLOAD_CHAR.
-///
-/// @param[in] name Variable/function name.
-/// @param[in] name_len Name length.
-///
-/// @return [allocated] autoload script name.
-char *autoload_name(const char *const name, const size_t name_len)
- FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
-{
- // Get the script file name: replace '#' with '/', append ".vim".
- char *const scriptname = xmalloc(name_len + sizeof("autoload/.vim"));
- memcpy(scriptname, "autoload/", sizeof("autoload/") - 1);
- memcpy(scriptname + sizeof("autoload/") - 1, name, name_len);
- size_t auchar_idx = 0;
- for (size_t i = sizeof("autoload/") - 1;
- i - sizeof("autoload/") + 1 < name_len;
- i++) {
- if (scriptname[i] == AUTOLOAD_CHAR) {
- scriptname[i] = '/';
- auchar_idx = i;
- }
- }
- memcpy(scriptname + auchar_idx, ".vim", sizeof(".vim"));
-
- return scriptname;
-}
-
/*
* Called when starting to read a function line.
* "sourcing_lnum" must be correct!
@@ -9597,10 +9645,11 @@ void func_line_start(void *cookie)
if (fp->uf_profiling && sourcing_lnum >= 1
&& sourcing_lnum <= fp->uf_lines.ga_len) {
fp->uf_tml_idx = sourcing_lnum - 1;
- /* Skip continuation lines. */
- while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
- --fp->uf_tml_idx;
- fp->uf_tml_execed = FALSE;
+ // Skip continuation lines.
+ while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) {
+ fp->uf_tml_idx--;
+ }
+ fp->uf_tml_execed = false;
fp->uf_tml_start = profile_start();
fp->uf_tml_children = profile_zero();
fp->uf_tml_wait = profile_get_wait();
@@ -9822,14 +9871,14 @@ modify_fname(
int has_fullname = 0;
repeat:
- /* ":p" - full path/file_name */
+ // ":p" - full path/file_name
if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') {
has_fullname = 1;
valid |= VALID_PATH;
*usedlen += 2;
- /* Expand "~/path" for all systems and "~user/path" for Unix */
+ // Expand "~/path" for all systems and "~user/path" for Unix
if ((*fnamep)[0] == '~'
#if !defined(UNIX)
&& ((*fnamep)[1] == '/'
@@ -9841,7 +9890,7 @@ repeat:
&& !(tilde_file && (*fnamep)[1] == NUL)
) {
*fnamep = expand_env_save(*fnamep);
- xfree(*bufp); /* free any allocated file name */
+ xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
if (*fnamep == NULL)
return -1;
@@ -9859,20 +9908,20 @@ repeat:
}
}
- /* FullName_save() is slow, don't use it when not needed. */
+ // FullName_save() is slow, don't use it when not needed.
if (*p != NUL || !vim_isAbsName(*fnamep)) {
- *fnamep = (char_u *)FullName_save((char *)*fnamep, *p != NUL);
- xfree(*bufp); /* free any allocated file name */
+ *fnamep = (char_u *)FullName_save((char *)(*fnamep), *p != NUL);
+ xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
if (*fnamep == NULL)
return -1;
}
- /* Append a path separator to a directory. */
+ // Append a path separator to a directory.
if (os_isdir(*fnamep)) {
- /* Make room for one or two extra characters. */
+ // Make room for one or two extra characters.
*fnamep = vim_strnsave(*fnamep, STRLEN(*fnamep) + 2);
- xfree(*bufp); /* free any allocated file name */
+ xfree(*bufp); // free any allocated file name
*bufp = *fnamep;
if (*fnamep == NULL)
return -1;
@@ -9880,9 +9929,9 @@ repeat:
}
}
- /* ":." - path relative to the current directory */
- /* ":~" - path relative to the home directory */
- /* ":8" - shortname path - postponed till after */
+ // ":." - path relative to the current directory
+ // ":~" - path relative to the home directory
+ // ":8" - shortname path - postponed till after
while (src[*usedlen] == ':'
&& ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) {
*usedlen += 2;
@@ -9890,7 +9939,7 @@ repeat:
continue;
}
pbuf = NULL;
- /* Need full path first (use expand_env() to remove a "~/") */
+ // Need full path first (use expand_env() to remove a "~/")
if (!has_fullname) {
if (c == '.' && **fnamep == '~')
p = pbuf = expand_env_save(*fnamep);
@@ -9908,14 +9957,14 @@ repeat:
if (s != NULL) {
*fnamep = s;
if (pbuf != NULL) {
- xfree(*bufp); /* free any allocated file name */
+ xfree(*bufp); // free any allocated file name
*bufp = pbuf;
pbuf = NULL;
}
}
} else {
- home_replace(NULL, p, dirname, MAXPATHL, TRUE);
- /* Only replace it when it starts with '~' */
+ home_replace(NULL, p, dirname, MAXPATHL, true);
+ // Only replace it when it starts with '~'
if (*dirname == '~') {
s = vim_strsave(dirname);
*fnamep = s;
@@ -9930,8 +9979,8 @@ repeat:
tail = path_tail(*fnamep);
*fnamelen = STRLEN(*fnamep);
- /* ":h" - head, remove "/file_name", can be repeated */
- /* Don't remove the first "/" or "c:\" */
+ // ":h" - head, remove "/file_name", can be repeated
+ // Don't remove the first "/" or "c:\"
while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') {
valid |= VALID_HEAD;
*usedlen += 2;
@@ -9941,7 +9990,7 @@ repeat:
}
*fnamelen = (size_t)(tail - *fnamep);
if (*fnamelen == 0) {
- /* Result is empty. Turn it into "." to make ":cd %:h" work. */
+ // Result is empty. Turn it into "." to make ":cd %:h" work.
xfree(*bufp);
*bufp = *fnamep = tail = vim_strsave((char_u *)".");
*fnamelen = 1;
@@ -9952,21 +10001,21 @@ repeat:
}
}
- /* ":8" - shortname */
+ // ":8" - shortname
if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') {
*usedlen += 2;
}
- /* ":t" - tail, just the basename */
+ // ":t" - tail, just the basename
if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') {
*usedlen += 2;
*fnamelen -= (size_t)(tail - *fnamep);
*fnamep = tail;
}
- /* ":e" - extension, can be repeated */
- /* ":r" - root, without extension, can be repeated */
+ // ":e" - extension, can be repeated
+ // ":r" - root, without extension, can be repeated
while (src[*usedlen] == ':'
&& (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) {
/* find a '.' in the tail:
@@ -10018,8 +10067,8 @@ repeat:
*usedlen += 2;
}
- /* ":s?pat?foo?" - substitute */
- /* ":gs?pat?foo?" - global substitute */
+ // ":s?pat?foo?" - substitute
+ // ":gs?pat?foo?" - global substitute
if (src[*usedlen] == ':'
&& (src[*usedlen + 1] == 's'
|| (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) {
@@ -10039,12 +10088,12 @@ repeat:
sep = *s++;
if (sep) {
- /* find end of pattern */
+ // find end of pattern
p = vim_strchr(s, sep);
if (p != NULL) {
pat = vim_strnsave(s, (int)(p - s));
s = p + 1;
- /* find end of substitution */
+ // find end of substitution
p = vim_strchr(s, sep);
if (p != NULL) {
sub = vim_strnsave(s, (int)(p - s));
@@ -10061,9 +10110,10 @@ repeat:
}
xfree(pat);
}
- /* after using ":s", repeat all the modifiers */
- if (didit)
+ // after using ":s", repeat all the modifiers
+ if (didit) {
goto repeat;
+ }
}
}
@@ -10102,7 +10152,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
char_u *save_cpo;
char_u *zero_width = NULL;
- /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
+ // Make 'cpoptions' empty, so that the 'l' flag doesn't work here
save_cpo = p_cpo;
p_cpo = empty_option;
@@ -10116,7 +10166,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
tail = str;
end = str + STRLEN(str);
while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str))) {
- /* Skip empty match except for first match. */
+ // Skip empty match except for first match.
if (regmatch.startp[0] == regmatch.endp[0]) {
if (zero_width == regmatch.startp[0]) {
// avoid getting stuck on a match with an empty string
@@ -10138,7 +10188,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
ga_grow(&ga, (int)((end - tail) + sublen -
(regmatch.endp[0] - regmatch.startp[0])));
- /* copy the text up to where the match is */
+ // copy the text up to where the match is
int i = (int)(regmatch.startp[0] - tail);
memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
// add the substituted text
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 17d9cc56aa..d3e769a7ef 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -102,6 +102,7 @@ return {
exists={args=1},
exp={args=1, func="float_op_wrapper", data="&exp"},
expand={args={1, 3}},
+ expandcmd={args=1},
extend={args={2, 3}},
feedkeys={args={1, 2}},
file_readable={args=1, func='f_filereadable'}, -- obsolete
@@ -214,6 +215,7 @@ return {
line={args=1},
line2byte={args=1},
lispindent={args=1},
+ list2str={args={1, 2}},
localtime={},
log={args=1, func="float_op_wrapper", data="&log"},
log10={args=1, func="float_op_wrapper", data="&log10"},
@@ -321,6 +323,7 @@ return {
sqrt={args=1, func="float_op_wrapper", data="&sqrt"},
stdpath={args=1},
str2float={args=1},
+ str2list={args={1, 2}},
str2nr={args={1, 2}},
strcharpart={args={2, 3}},
strchars={args={1,2}},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index b7e02d2ce7..10f9d51599 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -972,15 +972,16 @@ static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
fp = var2fpos(&argvars[0], FALSE, &fnum);
if (fp != NULL && fnum == curbuf->b_fnum) {
if (fp->col == MAXCOL) {
- /* '> can be MAXCOL, get the length of the line then */
- if (fp->lnum <= curbuf->b_ml.ml_line_count)
+ // '> can be MAXCOL, get the length of the line then
+ if (fp->lnum <= curbuf->b_ml.ml_line_count) {
col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
- else
+ } else {
col = MAXCOL;
+ }
} else {
col = fp->col + 1;
- /* col(".") when the cursor is on the NUL at the end of the line
- * because of "coladd" can be seen as an extra column. */
+ // col(".") when the cursor is on the NUL at the end of the line
+ // because of "coladd" can be seen as an extra column.
if (virtual_active() && fp == &curwin->w_cursor) {
char_u *p = get_cursor_pos_ptr();
@@ -1665,25 +1666,29 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int filler_lines;
int col;
- if (lnum < 0) /* ignore type error in {lnum} arg */
+ if (lnum < 0) { // ignore type error in {lnum} arg
lnum = 0;
+ }
if (lnum != prev_lnum
|| changedtick != buf_get_changedtick(curbuf)
|| fnum != curbuf->b_fnum) {
- /* New line, buffer, change: need to get the values. */
+ // New line, buffer, change: need to get the values.
filler_lines = diff_check(curwin, lnum);
if (filler_lines < 0) {
if (filler_lines == -1) {
change_start = MAXCOL;
change_end = -1;
- if (diff_find_change(curwin, lnum, &change_start, &change_end))
- hlID = HLF_ADD; /* added line */
- else
- hlID = HLF_CHD; /* changed line */
- } else
- hlID = HLF_ADD; /* added line */
- } else
+ if (diff_find_change(curwin, lnum, &change_start, &change_end)) {
+ hlID = HLF_ADD; // added line
+ } else {
+ hlID = HLF_CHD; // changed line
+ }
+ } else {
+ hlID = HLF_ADD; // added line
+ }
+ } else {
hlID = (hlf_T)0;
+ }
prev_lnum = lnum;
changedtick = buf_get_changedtick(curbuf);
fnum = curbuf->b_fnum;
@@ -2061,8 +2066,8 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else
rettv->vval.v_string = result;
} else {
- /* When the optional second argument is non-zero, don't remove matches
- * for 'wildignore' and don't put matches for 'suffixes' at the end. */
+ // When the optional second argument is non-zero, don't remove matches
+ // for 'wildignore' and don't put matches for 'suffixes' at the end.
if (argvars[1].v_type != VAR_UNKNOWN
&& tv_get_number_chk(&argvars[1], &error)) {
options |= WILD_KEEP_ALL;
@@ -2104,6 +2109,31 @@ static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
menu_get((char_u *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
}
+// "expandcmd()" function
+// Expand all the special characters in a command string.
+static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ char_u *errormsg = NULL;
+
+ rettv->v_type = VAR_STRING;
+ char_u *cmdstr = (char_u *)xstrdup(tv_get_string(&argvars[0]));
+
+ exarg_T eap = {
+ .cmd = cmdstr,
+ .arg = cmdstr,
+ .usefilter = false,
+ .nextcmd = NULL,
+ .cmdidx = CMD_USER,
+ };
+ eap.argt |= NOSPC;
+
+ expand_filename(&eap, &cmdstr, &errormsg);
+ if (errormsg != NULL && *errormsg != NUL) {
+ EMSG(errormsg);
+ }
+ rettv->vval.v_string = cmdstr;
+}
+
/*
* "extend(list, list [, idx])" function
* "extend(dict, dict [, action])" function
@@ -2456,9 +2486,9 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
- /* Find interesting text in this line. */
+ // Find interesting text in this line.
s = skipwhite(ml_get(lnum));
- /* skip C comment-start */
+ // skip C comment-start
if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) {
s = skipwhite(s + 2);
if (*skipwhite(s) == NUL && lnum + 1 < foldend) {
@@ -2476,7 +2506,7 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
sprintf((char *)r, txt, dashes, count);
len = (int)STRLEN(r);
STRCAT(r, s);
- /* remove 'foldmarker' and 'commentstring' */
+ // remove 'foldmarker' and 'commentstring'
foldtext_cleanup(r + len);
rettv->vval.v_string = r;
}
@@ -2778,11 +2808,12 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
buf_T *const buf = tv_get_buf(&argvars[0], false);
if (buf != NULL && varname != NULL) {
- // set curbuf to be our buf, temporarily
- buf_T *const save_curbuf = curbuf;
- curbuf = buf;
-
if (*varname == '&') { // buffer-local-option
+ buf_T *const save_curbuf = curbuf;
+
+ // set curbuf to be our buf, temporarily
+ curbuf = buf;
+
if (varname[1] == NUL) {
// get all buffer-local options in a dict
dict_T *opts = get_winbuf_options(true);
@@ -2795,19 +2826,21 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// buffer-local-option
done = true;
}
+
+ // restore previous notion of curbuf
+ curbuf = save_curbuf;
} else {
// Look up the variable.
// Let getbufvar({nr}, "") return the "b:" dictionary.
- dictitem_T *const v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, 'b',
- varname, strlen(varname), false);
+ dictitem_T *const v = *varname == NUL
+ ? (dictitem_T *)&buf->b_bufvar
+ : find_var_in_ht(&buf->b_vars->dv_hashtab, 'b',
+ varname, strlen(varname), false);
if (v != NULL) {
tv_copy(&v->di_tv, rettv);
done = true;
}
}
-
- // restore previous notion of curbuf
- curbuf = save_curbuf;
}
emsg_off--;
@@ -2901,10 +2934,10 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = n;
if (IS_SPECIAL(n) || mod_mask != 0) {
- char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */
+ char_u temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1
int i = 0;
- /* Turn a special key into three bytes, plus modifier. */
+ // Turn a special key into three bytes, plus modifier.
if (mod_mask != 0) {
temp[i++] = K_SPECIAL;
temp[i++] = KS_MODIFIER;
@@ -3253,7 +3286,7 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else {
rettv->vval.v_number = (varnumber_T)filesize;
- /* non-perfect check for overflow */
+ // non-perfect check for overflow
if ((uint64_t)rettv->vval.v_number != filesize) {
rettv->vval.v_number = -2;
}
@@ -4002,7 +4035,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"dialog_con",
"diff",
"digraphs",
- "eval", /* always present, of course! */
+ "eval", // always present, of course!
"ex_extra",
"extra_search",
"file_in_path",
@@ -4070,7 +4103,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
"textobjects",
"timers",
"title",
- "user-commands", /* was accidentally included in 5.4 */
+ "user-commands", // was accidentally included in 5.4
"user_commands",
"vertsplit",
"virtualedit",
@@ -4293,7 +4326,7 @@ static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
HistoryType histype;
rettv->vval.v_number = false;
- if (check_restricted() || check_secure()) {
+ if (check_secure()) {
return;
}
const char *str = tv_get_string_chk(&argvars[0]); // NULL on type error
@@ -4526,9 +4559,9 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
msg_start();
- msg_row = Rows - 1; /* for when 'cmdheight' > 1 */
- lines_left = Rows; /* avoid more prompt */
- msg_scroll = TRUE;
+ msg_row = Rows - 1; // for when 'cmdheight' > 1
+ lines_left = Rows; // avoid more prompt
+ msg_scroll = true;
msg_clr_eos();
TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
@@ -5247,6 +5280,35 @@ static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+// "list2str()" function
+static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ garray_T ga;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ if (argvars[0].v_type != VAR_LIST) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ list_T *const l = argvars[0].vval.v_list;
+ if (l == NULL) {
+ return; // empty list results in empty string
+ }
+
+ ga_init(&ga, 1, 80);
+ char_u buf[MB_MAXBYTES + 1];
+
+ TV_LIST_ITER_CONST(l, li, {
+ buf[utf_char2bytes(tv_get_number(TV_LIST_ITEM_TV(li)), buf)] = NUL;
+ ga_concat(&ga, buf);
+ });
+ ga_append(&ga, NUL);
+
+ rettv->vval.v_string = ga.ga_data;
+}
+
/*
* "localtime()" function
*/
@@ -5373,7 +5435,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
long idx = 0;
char_u *tofree = NULL;
- /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+ // Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
p_cpo = (char_u *)"";
@@ -5439,12 +5501,12 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
start = 0;
if (start > len)
goto theend;
- /* When "count" argument is there ignore matches before "start",
- * otherwise skip part of the string. Differs when pattern is "^"
- * or "\<". */
- if (argvars[3].v_type != VAR_UNKNOWN)
+ // When "count" argument is there ignore matches before "start",
+ // otherwise skip part of the string. Differs when pattern is "^"
+ // or "\<".
+ if (argvars[3].v_type != VAR_UNKNOWN) {
startcol = start;
- else {
+ } else {
str += start;
len -= start;
}
@@ -5483,7 +5545,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv,
if (l == NULL && !match)
break;
- /* Advance to just after the match. */
+ // Advance to just after the match.
if (l != NULL) {
li = TV_LIST_ITEM_NEXT(l, li);
idx++;
@@ -5590,8 +5652,11 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char grpbuf[NUMBUFLEN];
char patbuf[NUMBUFLEN];
+ // group
const char *const grp = tv_get_string_buf_chk(&argvars[0], grpbuf);
+ // pattern
const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ // default priority
int prio = 10;
int id = -1;
bool error = false;
@@ -6256,12 +6321,12 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool binary = false;
FILE *fd;
- char_u buf[(IOSIZE/256)*256]; /* rounded to avoid odd + 1 */
+ char_u buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1
int io_size = sizeof(buf);
- int readlen; /* size of last fread() */
- char_u *prev = NULL; /* previously read bytes, if any */
- long prevlen = 0; /* length of data in prev */
- long prevsize = 0; /* size of prev buffer */
+ int readlen; // size of last fread()
+ char_u *prev = NULL; // previously read bytes, if any
+ long prevlen = 0; // length of data in prev
+ long prevsize = 0; // size of prev buffer
long maxline = MAXLNUM;
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -6300,14 +6365,17 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
char_u *s = NULL;
size_t len = p - start;
- /* Finished a line. Remove CRs before NL. */
+ // Finished a line. Remove CRs before NL.
if (readlen > 0 && !binary) {
- while (len > 0 && start[len - 1] == '\r')
- --len;
- /* removal may cross back to the "prev" string */
- if (len == 0)
- while (prevlen > 0 && prev[prevlen - 1] == '\r')
- --prevlen;
+ while (len > 0 && start[len - 1] == '\r') {
+ len--;
+ }
+ // removal may cross back to the "prev" string
+ if (len == 0) {
+ while (prevlen > 0 && prev[prevlen - 1] == '\r') {
+ prevlen--;
+ }
+ }
}
if (prevlen == 0) {
assert(len < INT_MAX);
@@ -6319,7 +6387,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
s = xrealloc(prev, prevlen + len + 1);
memcpy(s + prevlen, start, len);
s[prevlen + len] = NUL;
- prev = NULL; /* the list will own the string */
+ prev = NULL; // the list will own the string
prevlen = prevsize = 0;
}
@@ -6358,13 +6426,12 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (back2 == 0xef && back1 == 0xbb) {
char_u *dest = p - 2;
- /* Usually a BOM is at the beginning of a file, and so at
- * the beginning of a line; then we can just step over it.
- */
- if (start == dest)
+ // Usually a BOM is at the beginning of a file, and so at
+ // the beginning of a line; then we can just step over it.
+ if (start == dest) {
start = p + 1;
- else {
- /* have to shuffle buf to close gap */
+ } else {
+ // have to shuffle buf to close gap
int adjust_prevlen = 0;
if (dest < buf) { // -V782
@@ -6380,13 +6447,13 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
}
- } /* for */
+ } // for
if ((maxline >= 0 && tv_list_len(l) >= maxline) || readlen <= 0) {
break;
}
if (start < p) {
- /* There's part of a line in buf, store it in "prev". */
+ // There's part of a line in buf, store it in "prev".
if (p - start + prevlen >= prevsize) {
/* A common use case is ordinary text files and "prev" gets a
* fragment of a line, so the first allocation is made
@@ -6401,11 +6468,11 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
prev = xrealloc(prev, prevsize);
}
- /* Add the line part to end of "prev". */
+ // Add the line part to end of "prev".
memmove(prev + prevlen, start, p - start);
prevlen += (long)(p - start);
}
- } /* while */
+ } // while
xfree(prev);
fclose(fd);
@@ -6656,7 +6723,12 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_STRING;
const char *fname = tv_get_string(&argvars[0]);
#ifdef WIN32
- char *const v = os_resolve_shortcut(fname);
+ char *v = os_resolve_shortcut(fname);
+ if (v == NULL) {
+ if (os_is_reparse_point_include(fname)) {
+ v = os_realpath(fname, v);
+ }
+ }
rettv->vval.v_string = (char_u *)(v == NULL ? xstrdup(fname) : v);
#else
# ifdef HAVE_READLINK
@@ -6897,7 +6969,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
pos_T save_cursor;
bool save_p_ws = p_ws;
int dir;
- int retval = 0; /* default: FAIL */
+ int retval = 0; // default: FAIL
long lnum_stop = 0;
proftime_T tm;
long time_limit = 0;
@@ -6921,7 +6993,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
options |= SEARCH_COL;
}
- /* Optional arguments: line number to stop searching and timeout. */
+ // Optional arguments: line number to stop searching and timeout.
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
lnum_stop = tv_get_number_chk(&argvars[2], NULL);
if (lnum_stop < 0) {
@@ -6935,7 +7007,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
}
}
- /* Set the time limit, if there is one. */
+ // Set the time limit, if there is one.
tm = profile_setlimit(time_limit);
/*
@@ -6965,20 +7037,21 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
setpcmark();
curwin->w_cursor = pos;
if (match_pos != NULL) {
- /* Store the match cursor position */
+ // Store the match cursor position
match_pos->lnum = pos.lnum;
match_pos->col = pos.col + 1;
}
- /* "/$" will put the cursor after the end of the line, may need to
- * correct that here */
+ // "/$" will put the cursor after the end of the line, may need to
+ // correct that here
check_cursor();
}
- /* If 'n' flag is used: restore cursor position. */
- if (flags & SP_NOMOVE)
+ // If 'n' flag is used: restore cursor position.
+ if (flags & SP_NOMOVE) {
curwin->w_cursor = save_cursor;
- else
- curwin->w_set_curswant = TRUE;
+ } else {
+ curwin->w_set_curswant = true;
+ }
theend:
p_ws = save_p_ws;
@@ -7317,7 +7390,7 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int thisblock = 0;
bool error = false;
- rettv->vval.v_number = 1; /* default: FAIL */
+ rettv->vval.v_number = 1; // default: FAIL
const char *const name = tv_get_string_chk(&argvars[0]);
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -7475,11 +7548,11 @@ do_searchpair(
size_t pat2_len;
size_t pat3_len;
- /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+ // Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
p_cpo = empty_option;
- /* Set the time limit, if there is one. */
+ // Set the time limit, if there is one.
tm = profile_setlimit(time_limit);
// Make two search patterns: start/end (pat2, for in nested pairs) and
@@ -7527,17 +7600,18 @@ do_searchpair(
if (firstpos.lnum == 0)
firstpos = pos;
if (equalpos(pos, foundpos)) {
- /* Found the same position again. Can happen with a pattern that
- * has "\zs" at the end and searching backwards. Advance one
- * character and try again. */
- if (dir == BACKWARD)
+ // Found the same position again. Can happen with a pattern that
+ // has "\zs" at the end and searching backwards. Advance one
+ // character and try again.
+ if (dir == BACKWARD) {
decl(&pos);
- else
+ } else {
incl(&pos);
+ }
}
foundpos = pos;
- /* clear the start flag to avoid getting stuck here */
+ // clear the start flag to avoid getting stuck here
options &= ~SEARCH_START;
// If the skip pattern matches, ignore this match.
@@ -7548,7 +7622,7 @@ do_searchpair(
const bool r = eval_expr_to_bool(skip, &err);
curwin->w_cursor = save_pos;
if (err) {
- /* Evaluating {skip} caused an error, break here. */
+ // Evaluating {skip} caused an error, break here.
curwin->w_cursor = save_cursor;
retval = -1;
break;
@@ -7558,49 +7632,54 @@ do_searchpair(
}
if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) {
- /* Found end when searching backwards or start when searching
- * forward: nested pair. */
- ++nest;
- pat = pat2; /* nested, don't search for middle */
+ // Found end when searching backwards or start when searching
+ // forward: nested pair.
+ nest++;
+ pat = pat2; // nested, don't search for middle
} else {
- /* Found end when searching forward or start when searching
- * backward: end of (nested) pair; or found middle in outer pair. */
- if (--nest == 1)
- pat = pat3; /* outer level, search for middle */
+ // Found end when searching forward or start when searching
+ // backward: end of (nested) pair; or found middle in outer pair.
+ if (--nest == 1) {
+ pat = pat3; // outer level, search for middle
+ }
}
if (nest == 0) {
- /* Found the match: return matchcount or line number. */
- if (flags & SP_RETCOUNT)
- ++retval;
- else
+ // Found the match: return matchcount or line number.
+ if (flags & SP_RETCOUNT) {
+ retval++;
+ } else {
retval = pos.lnum;
- if (flags & SP_SETPCMARK)
+ }
+ if (flags & SP_SETPCMARK) {
setpcmark();
+ }
curwin->w_cursor = pos;
if (!(flags & SP_REPEAT))
break;
- nest = 1; /* search for next unmatched */
+ nest = 1; // search for next unmatched
}
}
if (match_pos != NULL) {
- /* Store the match cursor position */
+ // Store the match cursor position
match_pos->lnum = curwin->w_cursor.lnum;
match_pos->col = curwin->w_cursor.col + 1;
}
- /* If 'n' flag is used or search failed: restore cursor position. */
- if ((flags & SP_NOMOVE) || retval == 0)
+ // If 'n' flag is used or search failed: restore cursor position.
+ if ((flags & SP_NOMOVE) || retval == 0) {
curwin->w_cursor = save_cursor;
+ }
xfree(pat2);
xfree(pat3);
- if (p_cpo == empty_option)
+ if (p_cpo == empty_option) {
p_cpo = save_cpo;
- else
- /* Darn, evaluating the {skip} expression changed the value. */
+ } else {
+ // Darn, evaluating the {skip} expression changed the value.
free_string_option(save_cpo);
+ }
return retval;
}
@@ -7726,8 +7805,7 @@ static void f_setbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (check_restricted()
- || check_secure()
+ if (check_secure()
|| !tv_check_str_or_nr(&argvars[0])) {
return;
}
@@ -7755,10 +7833,9 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// reset notion of buffer
aucmd_restbuf(&aco);
} else {
- buf_T *save_curbuf = curbuf;
-
const size_t varname_len = STRLEN(varname);
char *const bufvarname = xmalloc(varname_len + 3);
+ buf_T *const save_curbuf = curbuf;
curbuf = buf;
memcpy(bufvarname, "b:", 2);
memcpy(bufvarname + 2, varname, varname_len + 1);
@@ -8231,7 +8308,7 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 0;
- if (check_restricted() || check_secure()) {
+ if (check_secure()) {
return;
}
@@ -8979,7 +9056,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
info.item_compare_selfdict = NULL;
if (argvars[1].v_type != VAR_UNKNOWN) {
- /* optional second argument: {func} */
+ // optional second argument: {func}
if (argvars[1].v_type == VAR_FUNC) {
info.item_compare_func = (const char *)argvars[1].vval.v_string;
} else if (argvars[1].v_type == VAR_PARTIAL) {
@@ -9240,7 +9317,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool keepempty = false;
bool typeerr = false;
- /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+ // Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
p_cpo = (char_u *)"";
@@ -9354,6 +9431,17 @@ static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->v_type = VAR_FLOAT;
}
+// "str2list()" function
+static void f_str2list(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tv_list_alloc_ret(rettv, kListLenUnknown);
+ const char_u *p = (const char_u *)tv_get_string(&argvars[0]);
+
+ for (; *p != NUL; p += utf_ptr2len(p)) {
+ tv_list_append_number(rettv->vval.v_list, utf_ptr2char(p));
+ }
+}
+
// "str2nr()" function
static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -9417,10 +9505,10 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
struct tm curtime;
struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime);
- /* MSVC returns NULL for an invalid value of seconds. */
- if (curtime_ptr == NULL)
+ // MSVC returns NULL for an invalid value of seconds.
+ if (curtime_ptr == NULL) {
rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
- else {
+ } else {
vimconv_T conv;
char_u *enc;
@@ -9518,7 +9606,7 @@ static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
/*
* "string()" function
*/
-static void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = (char_u *)encode_tv2string(&argvars[0], NULL);
@@ -10117,7 +10205,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
wp != twin; wp = wp->w_next) {
if (wp == NULL) {
- /* didn't find it in this tabpage */
+ // didn't find it in this tabpage
nr = 0;
break;
}
@@ -10706,9 +10794,10 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
str[1] = NUL;
rettv->vval.v_string = vim_strsave(str);
- /* A non-zero number or non-empty string argument: reset mode. */
- if (non_zero_arg(&argvars[0]))
+ // A non-zero number or non-empty string argument: reset mode.
+ if (non_zero_arg(&argvars[0])) {
curbuf->b_visual_mode_eval = NUL;
+ }
}
/*
@@ -10941,7 +11030,7 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
- if (check_restricted() || check_secure()) {
+ if (check_secure()) {
return;
}
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index cc12ad08fa..4390db1b71 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -33,7 +33,7 @@ typedef double float_T;
enum { DO_NOT_FREE_CNT = (INT_MAX / 2) };
/// Additional values for tv_list_alloc() len argument
-enum {
+enum ListLenSpecials {
/// List length is not known in advance
///
/// To be used when there is neither a way to know how many elements will be
@@ -49,7 +49,7 @@ enum {
///
/// To be used when it looks impractical to determine list length.
kListLenMayKnow = -3,
-} ListLenSpecials;
+};
/// Maximal possible value of varnumber_T variable
#define VARNUMBER_MAX INT64_MAX
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 2c1cf3eedf..c55a29c67c 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -42,7 +42,7 @@ hashtab_T func_hashtab;
// Used by get_func_tv()
static garray_T funcargs = GA_EMPTY_INIT_VALUE;
-/* pointer to funccal for currently active function */
+// pointer to funccal for currently active function
funccall_T *current_funccal = NULL;
// Pointer to list of previously used funccal, still around because some
@@ -333,7 +333,7 @@ char_u *deref_func_name(const char *name, int *lenp,
///
/// @param ermsg must be passed without translation (use N_() instead of _()).
/// @param name function name
-static void emsg_funcname(char *ermsg, const char_u *name)
+void emsg_funcname(char *ermsg, const char_u *name)
{
char_u *p;
@@ -547,7 +547,7 @@ static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)
static void
free_funccal(
funccall_T *fc,
- int free_val /* a: vars were allocated */
+ int free_val // a: vars were allocated
)
{
for (int i = 0; i < fc->fc_funcs.ga_len; i++) {
@@ -726,7 +726,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
int save_did_emsg;
static int depth = 0;
dictitem_T *v;
- int fixvar_idx = 0; /* index in fixvar[] */
+ int fixvar_idx = 0; // index in fixvar[]
int ai;
bool islambda = false;
char_u numbuf[NUMBUFLEN];
@@ -737,7 +737,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
bool did_save_redo = false;
save_redo_T save_redo;
- /* If depth of calling is getting too high, don't execute the function */
+ // If depth of calling is getting too high, don't execute the function
if (depth >= p_mfd) {
EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
rettv->v_type = VAR_NUMBER;
@@ -764,8 +764,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
fc->linenr = 0;
fc->returned = FALSE;
fc->level = ex_nesting_level;
- /* Check if this function has a breakpoint. */
- fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
+ // Check if this function has a breakpoint.
+ fc->breakpoint = dbg_find_breakpoint(false, fp->uf_name, (linenr_T)0);
fc->dbg_tick = debug_tick;
// Set up fields for closure.
@@ -876,8 +876,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
}
}
- /* Don't redraw while executing the function. */
- ++RedrawingDisabled;
+ // Don't redraw while executing the function.
+ RedrawingDisabled++;
save_sourcing_name = sourcing_name;
save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 1;
@@ -979,7 +979,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
save_did_emsg = did_emsg;
did_emsg = FALSE;
- /* call do_cmdline() to execute the lines */
+ // call do_cmdline() to execute the lines
do_cmdline(NULL, get_func_line, (void *)fc,
DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
@@ -1011,7 +1011,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
}
}
- /* when being verbose, mention the return value */
+ // when being verbose, mention the return value
if (p_verbose >= 12) {
++no_wait_return;
verbose_enter_scroll();
@@ -1298,6 +1298,10 @@ call_func(
}
if (error == ERROR_NONE && partial->pt_argc > 0) {
for (argv_clear = 0; argv_clear < partial->pt_argc; argv_clear++) {
+ if (argv_clear + argcount_in >= MAX_FUNC_ARGS) {
+ error = ERROR_TOOMANY;
+ goto theend;
+ }
tv_copy(&partial->pt_argv[argv_clear], &argv[argv_clear]);
}
for (int i = 0; i < argcount_in; i++) {
@@ -1311,12 +1315,12 @@ call_func(
if (error == ERROR_NONE && evaluate) {
char_u *rfname = fname;
- /* Ignore "g:" before a function name. */
+ // Ignore "g:" before a function name.
if (fname[0] == 'g' && fname[1] == ':') {
rfname = fname + 2;
}
- rettv->v_type = VAR_NUMBER; /* default rettv is number zero */
+ rettv->v_type = VAR_NUMBER; // default rettv is number zero
rettv->vval.v_number = 0;
error = ERROR_UNKNOWN;
@@ -1338,7 +1342,7 @@ call_func(
if (fp == NULL
&& apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, TRUE, NULL)
&& !aborting()) {
- /* executed an autocommand, search for the function again */
+ // executed an autocommand, search for the function again
fp = find_func(rfname);
}
// Try loading a package.
@@ -1352,7 +1356,9 @@ call_func(
error = ERROR_DELETED;
} else if (fp != NULL) {
if (argv_func != NULL) {
- argcount = argv_func(argcount, argvars, fp->uf_args.ga_len);
+ // postponed filling in the arguments, do it now
+ argcount = argv_func(argcount, argvars, argv_clear,
+ fp->uf_args.ga_len);
}
if (fp->uf_flags & FC_RANGE) {
*doesrange = true;
@@ -1400,10 +1406,9 @@ call_func(
if (error == ERROR_NONE)
ret = OK;
- /*
- * Report an error unless the argument evaluation or function call has been
- * cancelled due to an aborting error, an interrupt, or an exception.
- */
+theend:
+ // Report an error unless the argument evaluation or function call has been
+ // cancelled due to an aborting error, an interrupt, or an exception.
if (!aborting()) {
switch (error) {
case ERROR_UNKNOWN:
@@ -1735,7 +1740,7 @@ void ex_function(exarg_T *eap)
int nesting;
dictitem_T *v;
funcdict_T fudi;
- static int func_nr = 0; /* number for nameless function */
+ static int func_nr = 0; // number for nameless function
int paren;
hashtab_T *ht;
int todo;
@@ -1898,9 +1903,10 @@ void ex_function(exarg_T *eap)
EMSG2(_("E124: Missing '(': %s"), eap->arg);
goto ret_free;
}
- /* attempt to continue by skipping some text */
- if (vim_strchr(p, '(') != NULL)
+ // attempt to continue by skipping some text
+ if (vim_strchr(p, '(') != NULL) {
p = vim_strchr(p, '(');
+ }
}
p = skipwhite(p + 1);
@@ -1922,9 +1928,10 @@ void ex_function(exarg_T *eap)
if (arg[j] != NUL)
emsg_funcname((char *)e_invarg2, arg);
}
- /* Disallow using the g: dict. */
- if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE)
+ // Disallow using the g: dict.
+ if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) {
EMSG(_("E862: Cannot use g: here"));
+ }
}
if (get_function_args(&p, ')', &newargs, &varargs, eap->skip) == FAIL) {
@@ -2006,7 +2013,7 @@ void ex_function(exarg_T *eap)
need_wait_return = false;
if (line_arg != NULL) {
- /* Use eap->arg, split up in parts by line breaks. */
+ // Use eap->arg, split up in parts by line breaks.
theline = line_arg;
p = vim_strchr(theline, '\n');
if (p == NULL)
@@ -2069,11 +2076,11 @@ void ex_function(exarg_T *eap)
}
}
} else {
- /* skip ':' and blanks*/
- for (p = theline; ascii_iswhite(*p) || *p == ':'; ++p)
- ;
+ // skip ':' and blanks
+ for (p = theline; ascii_iswhite(*p) || *p == ':'; p++) {
+ }
- /* Check for "endfunction". */
+ // Check for "endfunction".
if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) {
if (*p == '!') {
p++;
@@ -2111,7 +2118,7 @@ void ex_function(exarg_T *eap)
|| STRNCMP(p, "try", 3) == 0)
indent += 2;
- /* Check for defining a function inside this function. */
+ // Check for defining a function inside this function.
if (checkforcmd(&p, "function", 2)) {
if (*p == '!') {
p = skipwhite(p + 1);
@@ -2156,9 +2163,8 @@ void ex_function(exarg_T *eap)
|| (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
&& (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
|| (p[0] == 'm' && p[1] == 'z'
- && (!ASCII_ISALPHA(p[2]) || p[2] == 's'))
- )) {
- /* ":python <<" continues until a dot, like ":append" */
+ && (!ASCII_ISALPHA(p[2]) || p[2] == 's')))) {
+ // ":python <<" continues until a dot, like ":append"
p = skipwhite(arg + 2);
if (*p == NUL)
skip_until = vim_strsave((char_u *)".");
@@ -2195,7 +2201,7 @@ void ex_function(exarg_T *eap)
}
}
- /* Add the line to the function. */
+ // Add the line to the function.
ga_grow(&newlines, 1 + sourcing_lnum_off);
/* Copy the line to newly allocated memory. get_one_sourceline()
@@ -2209,9 +2215,10 @@ void ex_function(exarg_T *eap)
while (sourcing_lnum_off-- > 0)
((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
- /* Check for end of eap->arg. */
- if (line_arg != NULL && *line_arg == NUL)
+ // Check for end of eap->arg.
+ if (line_arg != NULL && *line_arg == NUL) {
line_arg = NULL;
+ }
}
/* Don't define the function when skipping commands or when an error was
@@ -2292,7 +2299,7 @@ void ex_function(exarg_T *eap)
int slen, plen;
char_u *scriptname;
- /* Check that the autoload name matches the script name. */
+ // Check that the autoload name matches the script name.
int j = FAIL;
if (sourcing_name != NULL) {
scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name));
@@ -2330,11 +2337,11 @@ void ex_function(exarg_T *eap)
fudi.fd_di->di_tv.v_type = VAR_FUNC;
fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
- /* behave like "dict" was used */
+ // behave like "dict" was used
flags |= FC_DICT;
}
- /* insert the new function in the function list */
+ // insert the new function in the function list
STRCPY(fp->uf_name, name);
if (overwrite) {
hi = hash_find(&func_hashtab, name);
@@ -2688,10 +2695,11 @@ void ex_return(exarg_T *eap)
/* When skipping or the return gets pending, advance to the next command
* in this line (!returning). Otherwise, ignore the rest of the line.
* Following lines will be ignored by get_func_line(). */
- if (returning)
+ if (returning) {
eap->nextcmd = NULL;
- else if (eap->nextcmd == NULL) /* no argument */
+ } else if (eap->nextcmd == NULL) { // no argument
eap->nextcmd = check_nextcmd(arg);
+ }
if (eap->skip)
--emsg_skip;
@@ -2803,7 +2811,8 @@ void ex_call(exarg_T *eap)
}
}
- if (!failed) {
+ // When inside :try we need to check for following "| catch".
+ if (!failed || eap->cstack->cs_trylevel > 0) {
// Check for trailing illegal characters and a following command.
if (!ends_excmd(*arg)) {
emsg_severe = TRUE;
@@ -2831,9 +2840,10 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
int idx;
cstack_T *const cstack = eap->cstack;
- if (reanimate)
- /* Undo the return. */
- current_funccal->returned = FALSE;
+ if (reanimate) {
+ // Undo the return.
+ current_funccal->returned = false;
+ }
/*
* Cleanup (and inactivate) conditionals, but stop when a try conditional
@@ -2859,7 +2869,7 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
}
if (rettv != NULL) {
- /* Store the value of the pending return. */
+ // Store the value of the pending return.
cstack->cs_rettv[idx] = xcalloc(1, sizeof(typval_T));
*(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
} else
@@ -2925,9 +2935,9 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
char_u *retval;
- garray_T *gap; /* growarray with function lines */
+ garray_T *gap; // growarray with function lines
- /* If breakpoints have been added/deleted need to check for it. */
+ // If breakpoints have been added/deleted need to check for it.
if (fcp->dbg_tick != debug_tick) {
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
sourcing_lnum);
@@ -2938,16 +2948,17 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
gap = &fp->uf_lines;
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
- || fcp->returned)
+ || fcp->returned) {
retval = NULL;
- else {
- /* Skip NULL lines (continuation lines). */
+ } else {
+ // Skip NULL lines (continuation lines).
while (fcp->linenr < gap->ga_len
- && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL)
- ++fcp->linenr;
- if (fcp->linenr >= gap->ga_len)
+ && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) {
+ fcp->linenr++;
+ }
+ if (fcp->linenr >= gap->ga_len) {
retval = NULL;
- else {
+ } else {
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
sourcing_lnum = fcp->linenr;
if (do_profiling == PROF_YES)
@@ -2955,12 +2966,12 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
}
}
- /* Did we encounter a breakpoint? */
+ // Did we encounter a breakpoint?
if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) {
dbg_breakpoint(fp->uf_name, sourcing_lnum);
- /* Find next breakpoint. */
- fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
- sourcing_lnum);
+ // Find next breakpoint.
+ fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name,
+ sourcing_lnum);
fcp->dbg_tick = debug_tick;
}
diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h
index db4e02ee98..ad8e071548 100644
--- a/src/nvim/eval/userfunc.h
+++ b/src/nvim/eval/userfunc.h
@@ -24,7 +24,7 @@ typedef enum {
ERROR_DELETED,
} FnameTransError;
-typedef int (*ArgvFunc)(int current_argcount, typval_T *argv,
+typedef int (*ArgvFunc)(int current_argcount, typval_T *argv, int argskip,
int called_func_argcount);
#define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j]
diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c
index c2be472acd..e341513ae1 100644
--- a/src/nvim/event/loop.c
+++ b/src/nvim/event/loop.c
@@ -116,6 +116,20 @@ void loop_on_put(MultiQueue *queue, void *data)
uv_stop(&loop->uv);
}
+#if !defined(EXITFREE)
+static void loop_walk_cb(uv_handle_t *handle, void *arg)
+{
+ if (!uv_is_closing(handle)) {
+ uv_close(handle, NULL);
+ }
+}
+#endif
+
+/// Closes `loop` and its handles, and frees its structures.
+///
+/// @param loop Loop to destroy
+/// @param wait Wait briefly for handles to deref
+///
/// @returns false if the loop could not be closed gracefully
bool loop_close(Loop *loop, bool wait)
{
@@ -126,18 +140,34 @@ bool loop_close(Loop *loop, bool wait)
uv_close((uv_handle_t *)&loop->poll_timer, timer_close_cb);
uv_close((uv_handle_t *)&loop->async, NULL);
uint64_t start = wait ? os_hrtime() : 0;
+ bool didstop = false;
while (true) {
- uv_run(&loop->uv, wait ? UV_RUN_DEFAULT : UV_RUN_NOWAIT);
- if (!uv_loop_close(&loop->uv) || !wait) {
+ // Run the loop to tickle close-callbacks (which should then free memory).
+ // Use UV_RUN_NOWAIT to avoid a hang. #11820
+ uv_run(&loop->uv, didstop ? UV_RUN_DEFAULT : UV_RUN_NOWAIT);
+ if ((uv_loop_close(&loop->uv) != UV_EBUSY) || !wait) {
break;
}
- if (os_hrtime() - start >= 2 * 1000000000) {
+ uint64_t elapsed_s = (os_hrtime() - start) / 1000000000; // seconds
+ if (elapsed_s >= 2) {
// Some libuv resource was not correctly deref'd. Log and bail.
rv = false;
ELOG("uv_loop_close() hang?");
log_uv_handles(&loop->uv);
break;
}
+#if defined(EXITFREE)
+ (void)didstop;
+#else
+ if (!didstop) {
+ // Loop won’t block for I/O after this.
+ uv_stop(&loop->uv);
+ // XXX: Close all (lua/luv!) handles. But loop_walk_cb() does not call
+ // resource-specific close-callbacks, so this leaks memory...
+ uv_walk(&loop->uv, loop_walk_cb, NULL);
+ didstop = true;
+ }
+#endif
}
multiqueue_free(loop->fast_events);
multiqueue_free(loop->thread_events);
diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
index d1a53fa4b6..0e87f7c6c1 100644
--- a/src/nvim/event/stream.c
+++ b/src/nvim/event/stream.c
@@ -16,6 +16,11 @@
# include "event/stream.c.generated.h"
#endif
+// For compatbility with libuv < 1.19.0 (tested on 1.18.0)
+#if UV_VERSION_MINOR < 19
+#define uv_stream_get_write_queue_size(stream) stream->write_queue_size
+#endif
+
/// Sets the stream associated with `fd` to "blocking" mode.
///
/// @return `0` on success, or libuv error code on failure.
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index bc6821f60f..d26d3387f8 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -882,7 +882,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L, kExtmarkNOOP);
FOR_ALL_TAB_WINDOWS(tab, win) {
if (win->w_buffer == curbuf) {
- foldMoveRange(&win->w_folds, line1, line2, dest);
+ foldMoveRange(win, &win->w_folds, line1, line2, dest);
}
}
curbuf->b_op_start.lnum = dest - num_lines + 1;
@@ -891,7 +891,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L, kExtmarkNOOP);
FOR_ALL_TAB_WINDOWS(tab, win) {
if (win->w_buffer == curbuf) {
- foldMoveRange(&win->w_folds, dest + 1, line1 - 1, line2);
+ foldMoveRange(win, &win->w_folds, dest + 1, line1 - 1, line2);
}
}
curbuf->b_op_start.lnum = dest + 1;
@@ -2177,6 +2177,7 @@ int do_ecmd(
int did_get_winopts = FALSE;
int readfile_flags = 0;
bool did_inc_redrawing_disabled = false;
+ long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
if (eap != NULL)
command = eap->do_ecmd_cmd;
@@ -2678,13 +2679,14 @@ int do_ecmd(
RedrawingDisabled--;
did_inc_redrawing_disabled = false;
if (!skip_redraw) {
- n = p_so;
- if (topline == 0 && command == NULL)
- p_so = 999; // force cursor to be vertically centered in the window
+ n = *so_ptr;
+ if (topline == 0 && command == NULL) {
+ *so_ptr = 999; // force cursor to be vertically centered in the window
+ }
update_topline();
curwin->w_scbind_pos = curwin->w_topline;
- p_so = n;
- redraw_curbuf_later(NOT_VALID); /* redraw this buffer later */
+ *so_ptr = n;
+ redraw_curbuf_later(NOT_VALID); // redraw this buffer later
}
if (p_im)
@@ -3008,18 +3010,18 @@ void ex_z(exarg_T *eap)
ex_no_reprint = true;
}
-/*
- * Check if the restricted flag is set.
- * If so, give an error message and return TRUE.
- * Otherwise, return FALSE.
- */
-int check_restricted(void)
+// Check if the restricted flag is set.
+// If so, give an error message and return true.
+// Otherwise, return false.
+bool check_restricted(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (restricted) {
- EMSG(_("E145: Shell commands not allowed in restricted mode"));
- return TRUE;
+ EMSG(_("E145: Shell commands and some functionality not allowed"
+ " in restricted mode"));
+ return true;
}
- return FALSE;
+ return false;
}
/*
@@ -4482,8 +4484,9 @@ prepare_tagpreview (
curwin->w_p_wfh = TRUE;
RESET_BINDING(curwin); /* don't take over 'scrollbind'
and 'cursorbind' */
- curwin->w_p_diff = FALSE; /* no 'diff' */
- curwin->w_p_fdc = 0; /* no 'foldcolumn' */
+ curwin->w_p_diff = false; // no 'diff'
+ set_string_option_direct((char_u *)"fdc", -1, // no 'foldcolumn'
+ (char_u *)"0", OPT_FREE, SID_NONE);
return true;
}
}
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index f7aa8a994a..252af409c0 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -24,6 +24,7 @@ local SBOXOK = 0x80000
local CMDWIN = 0x100000
local MODIFY = 0x200000
local EXFLAGS = 0x400000
+local RESTRICT = 0x800000
local FILES = bit.bor(XFILE, EXTRA)
local WORD1 = bit.bor(EXTRA, NOSPC)
local FILE1 = bit.bor(FILES, NOSPC)
@@ -1582,19 +1583,19 @@ return {
},
{
command='lua',
- flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_lua',
},
{
command='luado',
- flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_luado',
},
{
command='luafile',
- flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_luafile',
},
@@ -1924,13 +1925,13 @@ return {
},
{
command='perl',
- flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, SBOXOK, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, SBOXOK, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_script_ni',
},
{
command='perldo',
- flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_ni',
},
@@ -2056,67 +2057,67 @@ return {
},
{
command='python',
- flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_python',
},
{
command='pydo',
- flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_pydo',
},
{
command='pyfile',
- flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_pyfile',
},
{
command='py3',
- flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_python3',
},
{
command='py3do',
- flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_pydo3',
},
{
command='python3',
- flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_python3',
},
{
command='py3file',
- flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_py3file',
},
{
command='pyx',
- flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_pyx',
},
{
command='pyxdo',
- flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_pyxdo',
},
{
command='pythonx',
- flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_pyx',
},
{
command='pyxfile',
- flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_pyxfile',
},
@@ -2242,19 +2243,19 @@ return {
},
{
command='ruby',
- flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_ruby',
},
{
command='rubydo',
- flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_rubydo',
},
{
command='rubyfile',
- flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
+ flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, RESTRICT),
addr_type=ADDR_LINES,
func='ex_rubyfile',
},
diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h
index 4a40cc54b4..1f0560ae48 100644
--- a/src/nvim/ex_cmds_defs.h
+++ b/src/nvim/ex_cmds_defs.h
@@ -36,35 +36,36 @@
// 4. Add documentation in ../doc/xxx.txt. Add a tag for both the short and
// long name of the command.
-#define RANGE 0x001 /* allow a linespecs */
-#define BANG 0x002 /* allow a ! after the command name */
-#define EXTRA 0x004 /* allow extra args after command name */
-#define XFILE 0x008 /* expand wildcards in extra part */
-#define NOSPC 0x010 /* no spaces allowed in the extra part */
-#define DFLALL 0x020 /* default file range is 1,$ */
-#define WHOLEFOLD 0x040 /* extend range to include whole fold also
- when less than two numbers given */
-#define NEEDARG 0x080 /* argument required */
-#define TRLBAR 0x100 /* check for trailing vertical bar */
-#define REGSTR 0x200 /* allow "x for register designation */
-#define COUNT 0x400 /* allow count in argument, after command */
-#define NOTRLCOM 0x800 /* no trailing comment allowed */
-#define ZEROR 0x1000 /* zero line number allowed */
-#define USECTRLV 0x2000 /* do not remove CTRL-V from argument */
-#define NOTADR 0x4000 /* number before command is not an address */
-#define EDITCMD 0x8000 /* allow "+command" argument */
-#define BUFNAME 0x10000 /* accepts buffer name */
-#define BUFUNL 0x20000 /* accepts unlisted buffer too */
-#define ARGOPT 0x40000 /* allow "++opt=val" argument */
-#define SBOXOK 0x80000 /* allowed in the sandbox */
-#define CMDWIN 0x100000 /* allowed in cmdline window; when missing
- * disallows editing another buffer when
- * curbuf_lock is set */
-#define MODIFY 0x200000 /* forbidden in non-'modifiable' buffer */
-#define EXFLAGS 0x400000 /* allow flags after count in argument */
-#define FILES (XFILE | EXTRA) /* multiple extra files allowed */
-#define WORD1 (EXTRA | NOSPC) /* one extra word allowed */
-#define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */
+#define RANGE 0x001 // allow a linespecs
+#define BANG 0x002 // allow a ! after the command name
+#define EXTRA 0x004 // allow extra args after command name
+#define XFILE 0x008 // expand wildcards in extra part
+#define NOSPC 0x010 // no spaces allowed in the extra part
+#define DFLALL 0x020 // default file range is 1,$
+#define WHOLEFOLD 0x040 // extend range to include whole fold also
+ // when less than two numbers given
+#define NEEDARG 0x080 // argument required
+#define TRLBAR 0x100 // check for trailing vertical bar
+#define REGSTR 0x200 // allow "x for register designation
+#define COUNT 0x400 // allow count in argument, after command
+#define NOTRLCOM 0x800 // no trailing comment allowed
+#define ZEROR 0x1000 // zero line number allowed
+#define USECTRLV 0x2000 // do not remove CTRL-V from argument
+#define NOTADR 0x4000 // number before command is not an address
+#define EDITCMD 0x8000 // allow "+command" argument
+#define BUFNAME 0x10000 // accepts buffer name
+#define BUFUNL 0x20000 // accepts unlisted buffer too
+#define ARGOPT 0x40000 // allow "++opt=val" argument
+#define SBOXOK 0x80000 // allowed in the sandbox
+#define CMDWIN 0x100000 // allowed in cmdline window; when missing
+ // disallows editing another buffer when
+ // curbuf_lock is set
+#define MODIFY 0x200000 // forbidden in non-'modifiable' buffer
+#define EXFLAGS 0x400000 // allow flags after count in argument
+#define RESTRICT 0x800000L // forbidden in restricted mode
+#define FILES (XFILE | EXTRA) // multiple extra files allowed
+#define WORD1 (EXTRA | NOSPC) // one extra word allowed
+#define FILE1 (FILES | NOSPC) // 1 file allowed, defaults to current file
// values for cmd_addr_type
#define ADDR_LINES 0
@@ -160,7 +161,7 @@ struct exarg {
int regname; ///< register name (NUL if none)
int force_bin; ///< 0, FORCE_BIN or FORCE_NOBIN
int read_edit; ///< ++edit argument
- int force_ff; ///< ++ff= argument (index in cmd[])
+ int force_ff; ///< ++ff= argument (first char of argument)
int force_enc; ///< ++enc= argument (index in cmd[])
int bad_char; ///< BAD_KEEP, BAD_DROP or replacement byte
int useridx; ///< user command index
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index fa01e06471..362163aaf0 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -198,7 +198,7 @@ static void save_dbg_stuff(struct dbg_stuff *dsp)
static void restore_dbg_stuff(struct dbg_stuff *dsp)
{
- suppress_errthrow = FALSE;
+ suppress_errthrow = false;
trylevel = dsp->trylevel;
force_abort = dsp->force_abort;
caught_stack = dsp->caught_stack;
@@ -395,8 +395,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* Initialize "force_abort" and "suppress_errthrow" at the top level.
*/
if (!recursive) {
- force_abort = FALSE;
- suppress_errthrow = FALSE;
+ force_abort = false;
+ suppress_errthrow = false;
}
// If requested, store and reset the global values controlling the
@@ -880,16 +880,14 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
xfree(sourcing_name);
sourcing_name = saved_sourcing_name;
sourcing_lnum = saved_sourcing_lnum;
+ } else if (got_int || (did_emsg && force_abort)) {
+ // On an interrupt or an aborting error not converted to an exception,
+ // disable the conversion of errors to exceptions. (Interrupts are not
+ // converted any more, here.) This enables also the interrupt message
+ // when force_abort is set and did_emsg unset in case of an interrupt
+ // from a finally clause after an error.
+ suppress_errthrow = true;
}
- /*
- * On an interrupt or an aborting error not converted to an exception,
- * disable the conversion of errors to exceptions. (Interrupts are not
- * converted any more, here.) This enables also the interrupt message
- * when force_abort is set and did_emsg unset in case of an interrupt
- * from a finally clause after an error.
- */
- else if (got_int || (did_emsg && force_abort))
- suppress_errthrow = TRUE;
}
// The current cstack will be freed when do_cmdline() returns. An uncaught
@@ -1784,10 +1782,14 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (!ea.skip) {
if (sandbox != 0 && !(ea.argt & SBOXOK)) {
- /* Command not allowed in sandbox. */
+ // Command not allowed in sandbox.
errormsg = (char_u *)_(e_sandbox);
goto doend;
}
+ if (restricted != 0 && (ea.argt & RESTRICT)) {
+ errormsg = (char_u *)_("E981: Command not allowed in restricted mode");
+ goto doend;
+ }
if (!MODIFIABLE(curbuf) && (ea.argt & MODIFY)
// allow :put in terminals
&& (!curbuf->terminal || ea.cmdidx != CMD_put)) {
@@ -4374,7 +4376,7 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
if (has_wildcards) {
expand_T xpc;
- int options = WILD_LIST_NOTFOUND|WILD_ADD_SLASH;
+ int options = WILD_LIST_NOTFOUND | WILD_NOERROR | WILD_ADD_SLASH;
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
@@ -4539,6 +4541,21 @@ skip_cmd_arg (
return p;
}
+int get_bad_opt(const char_u *p, exarg_T *eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (STRICMP(p, "keep") == 0) {
+ eap->bad_char = BAD_KEEP;
+ } else if (STRICMP(p, "drop") == 0) {
+ eap->bad_char = BAD_DROP;
+ } else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL) {
+ eap->bad_char = *p;
+ } else {
+ return FAIL;
+ }
+ return OK;
+}
+
/*
* Get "++opt=arg" argument.
* Return FAIL or OK.
@@ -4597,8 +4614,10 @@ static int getargopt(exarg_T *eap)
*arg = NUL;
if (pp == &eap->force_ff) {
- if (check_ff_value(eap->cmd + eap->force_ff) == FAIL)
+ if (check_ff_value(eap->cmd + eap->force_ff) == FAIL) {
return FAIL;
+ }
+ eap->force_ff = eap->cmd[eap->force_ff];
} else if (pp == &eap->force_enc) {
/* Make 'fileencoding' lower case. */
for (p = eap->cmd + eap->force_enc; *p != NUL; ++p)
@@ -4606,15 +4625,9 @@ static int getargopt(exarg_T *eap)
} else {
/* Check ++bad= argument. Must be a single-byte character, "keep" or
* "drop". */
- p = eap->cmd + bad_char_idx;
- if (STRICMP(p, "keep") == 0)
- eap->bad_char = BAD_KEEP;
- else if (STRICMP(p, "drop") == 0)
- eap->bad_char = BAD_DROP;
- else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
- eap->bad_char = *p;
- else
+ if (get_bad_opt(eap->cmd + bad_char_idx, eap) == FAIL) {
return FAIL;
+ }
}
return OK;
@@ -5131,9 +5144,8 @@ static char *get_command_complete(int arg)
static void uc_list(char_u *name, size_t name_len)
{
int i, j;
- int found = FALSE;
+ bool found = false;
ucmd_T *cmd;
- int len;
uint32_t a;
// In cmdwin, the alternative buffer should be used.
@@ -5152,62 +5164,96 @@ static void uc_list(char_u *name, size_t name_len)
continue;
}
- /* Put out the title first time */
- if (!found)
- MSG_PUTS_TITLE(_("\n Name Args Address Complete Definition"));
- found = TRUE;
+ // Put out the title first time
+ if (!found) {
+ MSG_PUTS_TITLE(_("\n Name Args Address "
+ "Complete Definition"));
+ }
+ found = true;
msg_putchar('\n');
if (got_int)
break;
- /* Special cases */
- msg_putchar(a & BANG ? '!' : ' ');
- msg_putchar(a & REGSTR ? '"' : ' ');
- msg_putchar(gap != &ucmds ? 'b' : ' ');
- msg_putchar(' ');
+ // Special cases
+ int len = 4;
+ if (a & BANG) {
+ msg_putchar('!');
+ len--;
+ }
+ if (a & REGSTR) {
+ msg_putchar('"');
+ len--;
+ }
+ if (gap != &ucmds) {
+ msg_putchar('b');
+ len--;
+ }
+ if (a & TRLBAR) {
+ msg_putchar('|');
+ len--;
+ }
+ while (len-- > 0) {
+ msg_putchar(' ');
+ }
msg_outtrans_attr(cmd->uc_name, HL_ATTR(HLF_D));
len = (int)STRLEN(cmd->uc_name) + 4;
do {
msg_putchar(' ');
- ++len;
- } while (len < 16);
+ len++;
+ } while (len < 22);
+ // "over" is how much longer the name is than the column width for
+ // the name, we'll try to align what comes after.
+ const int over = len - 22;
len = 0;
- /* Arguments */
+ // Arguments
switch (a & (EXTRA|NOSPC|NEEDARG)) {
- case 0: IObuff[len++] = '0'; break;
- case (EXTRA): IObuff[len++] = '*'; break;
- case (EXTRA|NOSPC): IObuff[len++] = '?'; break;
- case (EXTRA|NEEDARG): IObuff[len++] = '+'; break;
- case (EXTRA|NOSPC|NEEDARG): IObuff[len++] = '1'; break;
+ case 0:
+ IObuff[len++] = '0';
+ break;
+ case (EXTRA):
+ IObuff[len++] = '*';
+ break;
+ case (EXTRA|NOSPC):
+ IObuff[len++] = '?';
+ break;
+ case (EXTRA|NEEDARG):
+ IObuff[len++] = '+';
+ break;
+ case (EXTRA|NOSPC|NEEDARG):
+ IObuff[len++] = '1';
+ break;
}
do {
IObuff[len++] = ' ';
- } while (len < 5);
+ } while (len < 5 - over);
- /* Range */
+ // Address / Range
if (a & (RANGE|COUNT)) {
if (a & COUNT) {
- /* -count=N */
- sprintf((char *)IObuff + len, "%" PRId64 "c", (int64_t)cmd->uc_def);
+ // -count=N
+ snprintf((char *)IObuff + len, IOSIZE, "%" PRId64 "c",
+ (int64_t)cmd->uc_def);
len += (int)STRLEN(IObuff + len);
- } else if (a & DFLALL)
+ } else if (a & DFLALL) {
IObuff[len++] = '%';
- else if (cmd->uc_def >= 0) {
- /* -range=N */
- sprintf((char *)IObuff + len, "%" PRId64 "", (int64_t)cmd->uc_def);
+ } else if (cmd->uc_def >= 0) {
+ // -range=N
+ snprintf((char *)IObuff + len, IOSIZE, "%" PRId64 "",
+ (int64_t)cmd->uc_def);
len += (int)STRLEN(IObuff + len);
- } else
+ } else {
IObuff[len++] = '.';
+ }
}
do {
IObuff[len++] = ' ';
- } while (len < 11);
+ } while (len < 9 - over);
// Address Type
for (j = 0; addr_type_complete[j].expand != -1; j++) {
@@ -5221,7 +5267,7 @@ static void uc_list(char_u *name, size_t name_len)
do {
IObuff[len++] = ' ';
- } while (len < 21);
+ } while (len < 13 - over);
// Completion
char *cmd_compl = get_command_complete(cmd->uc_compl);
@@ -5232,12 +5278,13 @@ static void uc_list(char_u *name, size_t name_len)
do {
IObuff[len++] = ' ';
- } while (len < 35);
+ } while (len < 24 - over);
IObuff[len] = '\0';
msg_outtrans(IObuff);
- msg_outtrans_special(cmd->uc_rep, false);
+ msg_outtrans_special(cmd->uc_rep, false,
+ name_len == 0 ? Columns - 46 : 0);
if (p_verbose > 0) {
last_set_msg(cmd->uc_script_ctx);
}
@@ -5425,9 +5472,8 @@ static void ex_command(exarg_T *eap)
end = p;
name_len = (int)(end - name);
- /* If there is nothing after the name, and no attributes were specified,
- * we are listing commands
- */
+ // If there is nothing after the name, and no attributes were specified,
+ // we are listing commands
p = skipwhite(end);
if (!has_attr && ends_excmd(*p)) {
uc_list(name, end - name);
@@ -7320,7 +7366,7 @@ static void ex_syncbind(exarg_T *eap)
topline = curwin->w_topline;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_p_scb && wp->w_buffer) {
- y = wp->w_buffer->b_ml.ml_line_count - p_so;
+ y = wp->w_buffer->b_ml.ml_line_count - get_scrolloff_value();
if (topline > y) {
topline = y;
}
@@ -9246,8 +9292,9 @@ static void ex_match(exarg_T *eap)
static void ex_fold(exarg_T *eap)
{
- if (foldManualAllowed(TRUE))
- foldCreate(eap->line1, eap->line2);
+ if (foldManualAllowed(true)) {
+ foldCreate(curwin, eap->line1, eap->line2);
+ }
}
static void ex_foldopen(exarg_T *eap)
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 3f1270692e..81274fcf2a 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -508,7 +508,7 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname)
nomem:
xfree(excp);
- suppress_errthrow = TRUE;
+ suppress_errthrow = true;
EMSG(_(e_outofmem));
fail:
current_exception = NULL;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index e02443e061..581be96364 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -622,6 +622,16 @@ static int command_line_execute(VimState *state, int key)
s->c = Ctrl_N;
}
}
+ if (compl_match_array || s->did_wild_list) {
+ if (s->c == Ctrl_E) {
+ s->res = nextwild(&s->xpc, WILD_CANCEL, WILD_NO_BEEP,
+ s->firstc != '@');
+ } else if (s->c == Ctrl_Y) {
+ s->res = nextwild(&s->xpc, WILD_APPLY, WILD_NO_BEEP,
+ s->firstc != '@');
+ s->c = Ctrl_E;
+ }
+ }
// Hitting CR after "emenu Name.": complete submenu
if (s->xpc.xp_context == EXPAND_MENUNAMES && p_wmnu
@@ -2438,9 +2448,10 @@ redraw:
/* make following messages go to the next line */
msg_didout = FALSE;
msg_col = 0;
- if (msg_row < Rows - 1)
- ++msg_row;
- emsg_on_display = FALSE; /* don't want os_delay() */
+ if (msg_row < Rows - 1) {
+ msg_row++;
+ }
+ emsg_on_display = false; // don't want os_delay()
if (got_int)
ga_clear(&line_ga);
@@ -2702,7 +2713,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline)
goto color_cmdline_error;
}
if (tv.v_type != VAR_LIST) {
- PRINT_ERRMSG(_("E5400: Callback should return list"));
+ PRINT_ERRMSG("%s", _("E5400: Callback should return list"));
goto color_cmdline_error;
}
if (tv.vval.v_list == NULL) {
@@ -3791,6 +3802,12 @@ ExpandOne (
return NULL;
}
+ if (mode == WILD_CANCEL) {
+ ss = vim_strsave(orig_save);
+ } else if (mode == WILD_APPLY) {
+ ss = vim_strsave(findex == -1 ? orig_save : xp->xp_files[findex]);
+ }
+
/* free old names */
if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) {
FreeWild(xp->xp_numfiles, xp->xp_files);
@@ -3802,7 +3819,7 @@ ExpandOne (
if (mode == WILD_FREE) /* only release file name */
return NULL;
- if (xp->xp_numfiles == -1) {
+ if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) {
xfree(orig_save);
orig_save = orig;
orig_saved = TRUE;
@@ -4694,6 +4711,9 @@ ExpandFromContext (
flags |= EW_KEEPALL;
if (options & WILD_SILENT)
flags |= EW_SILENT;
+ if (options & WILD_NOERROR) {
+ flags |= EW_NOERROR;
+ }
if (options & WILD_ALLLINKS) {
flags |= EW_ALLLINKS;
}
diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h
index 99d5a7786d..84b2b41f30 100644
--- a/src/nvim/ex_getln.h
+++ b/src/nvim/ex_getln.h
@@ -16,6 +16,8 @@
#define WILD_ALL 6
#define WILD_LONGEST 7
#define WILD_ALL_KEEP 8
+#define WILD_CANCEL 9
+#define WILD_APPLY 10
#define WILD_LIST_NOTFOUND 0x01
#define WILD_HOME_REPLACE 0x02
diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c
index b8f2927480..1b797c6168 100644
--- a/src/nvim/ex_session.c
+++ b/src/nvim/ex_session.c
@@ -799,7 +799,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
//
if (fprintf(fd, "%s",
"let s:sx = expand(\"<sfile>:p:r\").\"x.vim\"\n"
- "if file_readable(s:sx)\n"
+ "if filereadable(s:sx)\n"
" exe \"source \" . fnameescape(s:sx)\n"
"endif\n") < 0) {
return FAIL;
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index d00943c1be..1457a1172d 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -86,7 +86,7 @@ uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id,
extmark_del(buf, ns_id, id);
} else {
// TODO(bfredl): we need to do more if "revising" a decoration mark.
- MarkTreeIter itr[1];
+ MarkTreeIter itr[1] = { 0 };
old_pos = marktree_lookup(buf->b_marktree, old_mark, itr);
assert(itr->node);
if (old_pos.row == row && old_pos.col == col) {
@@ -119,7 +119,7 @@ revised:
static bool extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col)
{
- MarkTreeIter itr[1];
+ MarkTreeIter itr[1] = { 0 };
mtpos_t pos = marktree_lookup(buf->b_marktree, mark, itr);
if (pos.row == -1) {
return false;
@@ -147,7 +147,7 @@ bool extmark_del(buf_T *buf, uint64_t ns_id, uint64_t id)
return false;
}
- MarkTreeIter itr[1];
+ MarkTreeIter itr[1] = { 0 };
mtpos_t pos = marktree_lookup(buf->b_marktree, mark, itr);
assert(pos.row >= 0);
marktree_del_itr(buf->b_marktree, itr, false);
@@ -207,7 +207,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id,
delete_set = map_new(uint64_t, uint64_t)();
}
- MarkTreeIter itr[1];
+ MarkTreeIter itr[1] = { 0 };
marktree_itr_get(buf->b_marktree, l_row, l_col, itr);
while (true) {
mtmark_t mark = marktree_itr_current(itr);
@@ -276,7 +276,7 @@ ExtmarkArray extmark_get(buf_T *buf, uint64_t ns_id,
int64_t amount, bool reverse)
{
ExtmarkArray array = KV_INITIAL_VALUE;
- MarkTreeIter itr[1];
+ MarkTreeIter itr[1] = { 0 };
// Find all the marks
marktree_itr_get_ext(buf->b_marktree, (mtpos_t){ l_row, l_col },
itr, reverse, false, NULL);
@@ -396,7 +396,7 @@ void u_extmark_copy(buf_T *buf,
ExtmarkUndoObject undo;
- MarkTreeIter itr[1];
+ MarkTreeIter itr[1] = { 0 };
marktree_itr_get(buf->b_marktree, l_row, l_col, itr);
while (true) {
mtmark_t mark = marktree_itr_current(itr);
@@ -578,6 +578,15 @@ void extmark_splice(buf_T *buf,
}
}
+void extmark_splice_cols(buf_T *buf,
+ int start_row, colnr_T start_col,
+ colnr_T old_col, colnr_T new_col,
+ ExtmarkOp undo)
+{
+ extmark_splice(buf, start_row, start_col,
+ 0, old_col,
+ 0, new_col, undo);
+}
void extmark_move_region(buf_T *buf,
int start_row, colnr_T start_col,
@@ -738,7 +747,7 @@ void clear_virttext(VirtText *text)
VirtText *extmark_find_virttext(buf_T *buf, int row, uint64_t ns_id)
{
- MarkTreeIter itr[1];
+ MarkTreeIter itr[1] = { 0 };
marktree_itr_get(buf->b_marktree, row, 0, itr);
while (true) {
mtmark_t mark = marktree_itr_current(itr);
@@ -789,7 +798,7 @@ bool decorations_redraw_start(buf_T *buf, int top_row,
ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index,
start_id, false);
if ((!(mark.id&MARKTREE_END_FLAG) && altpos.row < top_row
- && !kv_size(item->virt_text))
+ && item && !kv_size(item->virt_text))
|| ((mark.id&MARKTREE_END_FLAG) && altpos.row >= top_row)) {
goto next_mark;
}
@@ -854,7 +863,7 @@ int decorations_redraw_col(buf_T *buf, int col, DecorationRedrawState *state)
if (endpos.row < mark.row
|| (endpos.row == mark.row && endpos.col <= mark.col)) {
- if (!kv_size(item->virt_text)) {
+ if (item && !kv_size(item->virt_text)) {
goto next_mark;
}
}
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 2443fa000d..2335aba6dd 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -62,6 +62,11 @@
#define BUFSIZE 8192 /* size of normal write buffer */
#define SMBUFSIZE 256 /* size of emergency write buffer */
+// For compatibility with libuv < 1.20.0 (tested on 1.18.0)
+#ifndef UV_FS_COPYFILE_FICLONE
+#define UV_FS_COPYFILE_FICLONE 0
+#endif
+
//
// The autocommands are stored in a list for each event.
// Autocommands for the same pattern, that are consecutive, are joined
@@ -407,11 +412,27 @@ readfile(
if (newfile) {
if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname,
- FALSE, curbuf, eap))
- return aborting() ? FAIL : OK;
+ false, curbuf, eap)) {
+ int status = OK;
+
+ if (aborting()) {
+ status = FAIL;
+ }
+
+ // The BufReadCmd code usually uses ":read" to get the text and
+ // perhaps ":file" to change the buffer name. But we should
+ // consider this to work like ":edit", thus reset the
+ // BF_NOTEDITED flag. Then ":write" will work to overwrite the
+ // same file.
+ if (status == OK) {
+ curbuf->b_flags &= ~BF_NOTEDITED;
+ }
+ return status;
+ }
} else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname,
- FALSE, NULL, eap))
+ false, NULL, eap)) {
return aborting() ? FAIL : OK;
+ }
curbuf->b_op_start = pos;
}
@@ -2032,14 +2053,16 @@ readfile_linenr(
* Fill "*eap" to force the 'fileencoding', 'fileformat' and 'binary to be
* equal to the buffer "buf". Used for calling readfile().
*/
-void prep_exarg(exarg_T *eap, buf_T *buf)
+void prep_exarg(exarg_T *eap, const buf_T *buf)
+ FUNC_ATTR_NONNULL_ALL
{
- eap->cmd = xmalloc(STRLEN(buf->b_p_ff) + STRLEN(buf->b_p_fenc) + 15);
+ const size_t cmd_len = 15 + STRLEN(buf->b_p_fenc);
+ eap->cmd = xmalloc(cmd_len);
- sprintf((char *)eap->cmd, "e ++ff=%s ++enc=%s", buf->b_p_ff, buf->b_p_fenc);
- eap->force_enc = 14 + (int)STRLEN(buf->b_p_ff);
+ snprintf((char *)eap->cmd, cmd_len, "e ++enc=%s", buf->b_p_fenc);
+ eap->force_enc = 8;
eap->bad_char = buf->b_bad_char;
- eap->force_ff = 7;
+ eap->force_ff = *buf->b_p_ff;
eap->force_bin = buf->b_p_bin ? FORCE_BIN : FORCE_NOBIN;
eap->read_edit = FALSE;
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 331d7f9e29..61a85171e8 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -539,12 +539,10 @@ int foldManualAllowed(int create)
return FALSE;
}
-/* foldCreate() {{{2 */
-/*
- * Create a fold from line "start" to line "end" (inclusive) in the current
- * window.
- */
-void foldCreate(linenr_T start, linenr_T end)
+// foldCreate() {{{2
+/// Create a fold from line "start" to line "end" (inclusive) in the current
+/// window.
+void foldCreate(win_T *wp, linenr_T start, linenr_T end)
{
fold_T *fp;
garray_T *gap;
@@ -565,16 +563,16 @@ void foldCreate(linenr_T start, linenr_T end)
end_rel = end;
}
- /* When 'foldmethod' is "marker" add markers, which creates the folds. */
- if (foldmethodIsMarker(curwin)) {
- foldCreateMarkers(start, end);
+ // When 'foldmethod' is "marker" add markers, which creates the folds.
+ if (foldmethodIsMarker(wp)) {
+ foldCreateMarkers(wp, start, end);
return;
}
- checkupdate(curwin);
+ checkupdate(wp);
- /* Find the place to insert the new fold. */
- gap = &curwin->w_folds;
+ // Find the place to insert the new fold
+ gap = &wp->w_folds;
for (;; ) {
if (!foldFind(gap, start_rel, &fp))
break;
@@ -584,12 +582,14 @@ void foldCreate(linenr_T start, linenr_T end)
start_rel -= fp->fd_top;
end_rel -= fp->fd_top;
if (use_level || fp->fd_flags == FD_LEVEL) {
- use_level = TRUE;
- if (level >= curwin->w_p_fdl)
- closed = TRUE;
- } else if (fp->fd_flags == FD_CLOSED)
- closed = TRUE;
- ++level;
+ use_level = true;
+ if (level >= wp->w_p_fdl) {
+ closed = true;
+ }
+ } else if (fp->fd_flags == FD_CLOSED) {
+ closed = true;
+ }
+ level++;
} else {
/* This fold and new fold overlap: Insert here and move some folds
* inside the new fold. */
@@ -642,26 +642,28 @@ void foldCreate(linenr_T start, linenr_T end)
/* We want the new fold to be closed. If it would remain open because
* of using 'foldlevel', need to adjust fd_flags of containing folds.
*/
- if (use_level && !closed && level < curwin->w_p_fdl)
+ if (use_level && !closed && level < wp->w_p_fdl) {
closeFold(start, 1L);
- if (!use_level)
- curwin->w_fold_manual = true;
+ }
+ if (!use_level) {
+ wp->w_fold_manual = true;
+ }
fp->fd_flags = FD_CLOSED;
fp->fd_small = kNone;
- /* redraw */
- changed_window_setting();
+ // redraw
+ changed_window_setting_win(wp);
}
}
-/* deleteFold() {{{2 */
-/*
- * Delete a fold at line "start" in the current window.
- * When "end" is not 0, delete all folds from "start" to "end".
- * When "recursive" is TRUE delete recursively.
- */
+// deleteFold() {{{2
+/// @param start delete all folds from start to end when not 0
+/// @param end delete all folds from start to end when not 0
+/// @param recursive delete recursively if true
+/// @param had_visual true when Visual selection used
void deleteFold(
+ win_T *const wp,
const linenr_T start,
const linenr_T end,
const int recursive,
@@ -678,11 +680,11 @@ void deleteFold(
linenr_T first_lnum = MAXLNUM;
linenr_T last_lnum = 0;
- checkupdate(curwin);
+ checkupdate(wp);
while (lnum <= end) {
// Find the deepest fold for "start".
- garray_T *gap = &curwin->w_folds;
+ garray_T *gap = &wp->w_folds;
garray_T *found_ga = NULL;
linenr_T lnum_off = 0;
bool use_level = false;
@@ -694,10 +696,11 @@ void deleteFold(
found_fp = fp;
found_off = lnum_off;
- /* if "lnum" is folded, don't check nesting */
- if (check_closed(curwin, fp, &use_level, level,
- &maybe_small, lnum_off))
+ // if "lnum" is folded, don't check nesting
+ if (check_closed(wp, fp, &use_level, level,
+ &maybe_small, lnum_off)) {
break;
+ }
/* check nested folds */
gap = &fp->fd_nested;
@@ -709,34 +712,41 @@ void deleteFold(
} else {
lnum = found_fp->fd_top + found_fp->fd_len + found_off;
- if (foldmethodIsManual(curwin))
- deleteFoldEntry(found_ga,
- (int)(found_fp - (fold_T *)found_ga->ga_data), recursive);
- else {
- if (first_lnum > found_fp->fd_top + found_off)
+ if (foldmethodIsManual(wp)) {
+ deleteFoldEntry(wp, found_ga,
+ (int)(found_fp - (fold_T *)found_ga->ga_data),
+ recursive);
+ } else {
+ if (first_lnum > found_fp->fd_top + found_off) {
first_lnum = found_fp->fd_top + found_off;
- if (last_lnum < lnum)
+ }
+ if (last_lnum < lnum) {
last_lnum = lnum;
- if (!did_one)
- parseMarker(curwin);
- deleteFoldMarkers(found_fp, recursive, found_off);
+ }
+ if (!did_one) {
+ parseMarker(wp);
+ }
+ deleteFoldMarkers(wp, found_fp, recursive, found_off);
}
did_one = true;
- /* redraw window */
- changed_window_setting();
+ // redraw window
+ changed_window_setting_win(wp);
}
}
if (!did_one) {
EMSG(_(e_nofold));
- /* Force a redraw to remove the Visual highlighting. */
- if (had_visual)
- redraw_curbuf_later(INVERTED);
- } else
- /* Deleting markers may make cursor column invalid. */
- check_cursor_col();
+ // Force a redraw to remove the Visual highlighting.
+ if (had_visual) {
+ redraw_buf_later(wp->w_buffer, INVERTED);
+ }
+ } else {
+ // Deleting markers may make cursor column invalid
+ check_cursor_col_win(wp);
+ }
if (last_lnum > 0) {
+ // TODO(teto): pass the buffer
changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L, false);
// send one nvim_buf_lines_event at the end
@@ -745,7 +755,7 @@ void deleteFold(
// the modification of the *first* line of the fold, but we send through a
// notification that includes every line that was part of the fold
int64_t num_changed = last_lnum - first_lnum;
- buf_updates_send_changes(curbuf, first_lnum, num_changed,
+ buf_updates_send_changes(wp->w_buffer, first_lnum, num_changed,
num_changed, true);
}
}
@@ -1048,7 +1058,7 @@ void cloneFoldGrowArray(garray_T *from, garray_T *to)
* the first fold below it (careful: it can be beyond the end of the array!).
* Returns FALSE when there is no fold that contains "lnum".
*/
-static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp)
+static int foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp)
{
linenr_T low, high;
fold_T *fp;
@@ -1297,7 +1307,7 @@ static void foldOpenNested(fold_T *fpr)
// Delete fold "idx" from growarray "gap".
// When "recursive" is true also delete all the folds contained in it.
// When "recursive" is false contained folds are moved one level up.
-static void deleteFoldEntry(garray_T *const gap, const int idx,
+static void deleteFoldEntry(win_T *const wp, garray_T *const gap, const int idx,
const bool recursive)
{
fold_T *fp = (fold_T *)gap->ga_data + idx;
@@ -1363,13 +1373,17 @@ void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long
line2 = line1 - amount_after - 1;
/* If appending a line in Insert mode, it should be included in the fold
* just above the line. */
- if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
- --line1;
- foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after);
+ if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) {
+ line1--;
+ }
+ foldMarkAdjustRecurse(wp, &wp->w_folds, line1, line2, amount, amount_after);
}
-/* foldMarkAdjustRecurse() {{{2 */
-static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2, long amount, long amount_after)
+// foldMarkAdjustRecurse() {{{2
+static void foldMarkAdjustRecurse(
+ win_T *wp, garray_T *gap,
+ linenr_T line1, linenr_T line2, long amount, long amount_after
+)
{
fold_T *fp;
linenr_T last;
@@ -1417,7 +1431,7 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2,
// 4. fold completely contained in range
if (amount == MAXLNUM) {
// Deleting lines: delete the fold completely
- deleteFoldEntry(gap, i, true);
+ deleteFoldEntry(wp, gap, i, true);
i--; // adjust index for deletion
fp--;
} else {
@@ -1425,9 +1439,9 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2,
}
} else {
if (fp->fd_top < top) {
- /* 2 or 3: need to correct nested folds too */
- foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
- line2 - fp->fd_top, amount, amount_after);
+ // 2 or 3: need to correct nested folds too
+ foldMarkAdjustRecurse(wp, &fp->fd_nested, line1 - fp->fd_top,
+ line2 - fp->fd_top, amount, amount_after);
if (last <= line2) {
/* 2. fold contains line1, line2 is below fold */
if (amount == MAXLNUM)
@@ -1442,13 +1456,13 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2,
/* 5. fold is below line1 and contains line2; need to
* correct nested folds too */
if (amount == MAXLNUM) {
- foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ foldMarkAdjustRecurse(wp, &fp->fd_nested, line1 - fp->fd_top,
line2 - fp->fd_top, amount,
amount_after + (fp->fd_top - top));
fp->fd_len -= line2 - fp->fd_top + 1;
fp->fd_top = line1;
} else {
- foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ foldMarkAdjustRecurse(wp, &fp->fd_nested, line1 - fp->fd_top,
line2 - fp->fd_top, amount,
amount_after - amount);
fp->fd_len += amount_after - amount;
@@ -1465,10 +1479,10 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2,
* Get the lowest 'foldlevel' value that makes the deepest nested fold in the
* current window open.
*/
-int getDeepestNesting(void)
+int getDeepestNesting(win_T *wp)
{
- checkupdate(curwin);
- return getDeepestNestingRecurse(&curwin->w_folds);
+ checkupdate(wp);
+ return getDeepestNestingRecurse(&wp->w_folds);
}
static int getDeepestNestingRecurse(garray_T *gap)
@@ -1487,17 +1501,22 @@ static int getDeepestNestingRecurse(garray_T *gap)
return maxlevel;
}
-/* check_closed() {{{2 */
-/*
- * Check if a fold is closed and update the info needed to check nested folds.
- */
+// check_closed() {{{2
+/// Check if a fold is closed and update the info needed to check nested folds.
+///
+/// @param[in,out] use_levelp true: outer fold had FD_LEVEL
+/// @param[in,out] fp fold to check
+/// @param level folding depth
+/// @param[out] maybe_smallp true: outer this had fd_small == kNone
+/// @param lnum_off line number offset for fp->fd_top
+/// @return true if fold is closed
static bool check_closed(
- win_T *const win,
+ win_T *const wp,
fold_T *const fp,
- bool *const use_levelp, // true: outer fold had FD_LEVEL
- const int level, // folding depth
- bool *const maybe_smallp, // true: outer this had fd_small == kNone
- const linenr_T lnum_off // line number offset for fp->fd_top
+ bool *const use_levelp,
+ const int level,
+ bool *const maybe_smallp,
+ const linenr_T lnum_off
)
{
bool closed = false;
@@ -1506,7 +1525,7 @@ static bool check_closed(
* fold and all folds it contains depend on 'foldlevel'. */
if (*use_levelp || fp->fd_flags == FD_LEVEL) {
*use_levelp = true;
- if (level >= win->w_p_fdl) {
+ if (level >= wp->w_p_fdl) {
closed = true;
}
} else if (fp->fd_flags == FD_CLOSED) {
@@ -1521,7 +1540,7 @@ static bool check_closed(
if (*maybe_smallp) {
fp->fd_small = kNone;
}
- checkSmall(win, fp, lnum_off);
+ checkSmall(wp, fp, lnum_off);
if (fp->fd_small == kTrue) {
closed = false;
}
@@ -1529,10 +1548,9 @@ static bool check_closed(
return closed;
}
-/* checkSmall() {{{2 */
-/*
- * Update fd_small field of fold "fp".
- */
+// checkSmall() {{{2
+/// Update fd_small field of fold "fp".
+/// @param lnum_off offset for fp->fd_top
static void
checkSmall(
win_T *const wp,
@@ -1544,13 +1562,13 @@ checkSmall(
// Mark any nested folds to maybe-small
setSmallMaybe(&fp->fd_nested);
- if (fp->fd_len > curwin->w_p_fml) {
+ if (fp->fd_len > wp->w_p_fml) {
fp->fd_small = kFalse;
} else {
int count = 0;
for (int n = 0; n < fp->fd_len; n++) {
count += plines_win_nofold(wp, fp->fd_top + lnum_off + n);
- if (count > curwin->w_p_fml) {
+ if (count > wp->w_p_fml) {
fp->fd_small = kFalse;
return;
}
@@ -1575,42 +1593,45 @@ static void setSmallMaybe(garray_T *gap)
* Create a fold from line "start" to line "end" (inclusive) in the current
* window by adding markers.
*/
-static void foldCreateMarkers(linenr_T start, linenr_T end)
+static void foldCreateMarkers(win_T *wp, linenr_T start, linenr_T end)
{
- if (!MODIFIABLE(curbuf)) {
+ buf_T *buf = wp->w_buffer;
+ if (!MODIFIABLE(buf)) {
EMSG(_(e_modifiable));
return;
}
- parseMarker(curwin);
+ parseMarker(wp);
- foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen);
- foldAddMarker(end, foldendmarker, foldendmarkerlen);
+ foldAddMarker(buf, start, wp->w_p_fmr, foldstartmarkerlen);
+ foldAddMarker(buf, end, foldendmarker, foldendmarkerlen);
/* Update both changes here, to avoid all folds after the start are
* changed when the start marker is inserted and the end isn't. */
+ // TODO(teto): pass the buffer
changed_lines(start, (colnr_T)0, end, 0L, false);
// Note: foldAddMarker() may not actually change start and/or end if
// u_save() is unable to save the buffer line, but we send the
// nvim_buf_lines_event anyway since it won't do any harm.
int64_t num_changed = 1 + end - start;
- buf_updates_send_changes(curbuf, start, num_changed, num_changed, true);
+ buf_updates_send_changes(buf, start, num_changed, num_changed, true);
}
/* foldAddMarker() {{{2 */
/*
* Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/
-static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
+static void foldAddMarker(
+ buf_T *buf, linenr_T lnum, const char_u *marker, size_t markerlen)
{
- char_u *cms = curbuf->b_p_cms;
+ char_u *cms = buf->b_p_cms;
char_u *line;
char_u *newline;
- char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
+ char_u *p = (char_u *)strstr((char *)buf->b_p_cms, "%s");
bool line_is_comment = false;
// Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
- line = ml_get(lnum);
+ line = ml_get_buf(buf, lnum, false);
size_t line_len = STRLEN(line);
size_t added = 0;
@@ -1629,11 +1650,10 @@ static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
added = markerlen + STRLEN(cms)-2;
}
- ml_replace(lnum, newline, false);
+ ml_replace_buf(buf, lnum, newline, false);
if (added) {
- extmark_splice(curbuf, (int)lnum-1, (int)line_len,
- 0, 0,
- 0, (int)added, kExtmarkUndo);
+ extmark_splice_cols(buf, (int)lnum-1, (int)line_len,
+ 0, (int)added, kExtmarkUndo);
}
}
}
@@ -1644,20 +1664,22 @@ static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
*/
static void
deleteFoldMarkers(
+ win_T *wp,
fold_T *fp,
int recursive,
linenr_T lnum_off // offset for fp->fd_top
)
{
if (recursive) {
- for (int i = 0; i < fp->fd_nested.ga_len; ++i) {
- deleteFoldMarkers((fold_T *)fp->fd_nested.ga_data + i, TRUE,
+ for (int i = 0; i < fp->fd_nested.ga_len; i++) {
+ deleteFoldMarkers(wp, (fold_T *)fp->fd_nested.ga_data + i, true,
lnum_off + fp->fd_top);
}
}
- foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen);
- foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1, foldendmarker,
- foldendmarkerlen);
+ foldDelMarker(wp->w_buffer, fp->fd_top+lnum_off, wp->w_p_fmr,
+ foldstartmarkerlen);
+ foldDelMarker(wp->w_buffer, fp->fd_top + lnum_off + fp->fd_len - 1,
+ foldendmarker, foldendmarkerlen);
}
// foldDelMarker() {{{2
@@ -1666,18 +1688,20 @@ deleteFoldMarkers(
// Delete 'commentstring' if it matches.
// If the marker is not found, there is no error message. Could be a missing
// close-marker.
-static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
+static void foldDelMarker(
+ buf_T *buf, linenr_T lnum, char_u *marker, size_t markerlen
+)
{
char_u *newline;
- char_u *cms = curbuf->b_p_cms;
+ char_u *cms = buf->b_p_cms;
char_u *cms2;
// end marker may be missing and fold extends below the last line
- if (lnum > curbuf->b_ml.ml_line_count) {
+ if (lnum > buf->b_ml.ml_line_count) {
return;
}
- char_u *line = ml_get(lnum);
- for (char_u *p = line; *p != NUL; ++p) {
+ char_u *line = ml_get_buf(buf, lnum, false);
+ for (char_u *p = line; *p != NUL; p++) {
if (STRNCMP(p, marker, markerlen) != 0) {
continue;
}
@@ -1701,10 +1725,10 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
assert(p >= line);
memcpy(newline, line, (size_t)(p - line));
STRCPY(newline + (p - line), p + len);
- ml_replace(lnum, newline, false);
- extmark_splice(curbuf, (int)lnum-1, (int)(p - line),
- 0, (int)len,
- 0, 0, kExtmarkUndo);
+ ml_replace_buf(buf, lnum, newline, false);
+ extmark_splice_cols(buf, (int)lnum-1, (int)(p - line),
+ (int)len,
+ 0, kExtmarkUndo);
}
break;
}
@@ -1892,12 +1916,12 @@ void foldtext_cleanup(char_u *str)
/* foldUpdateIEMS() {{{2 */
/*
* Update the folding for window "wp", at least from lines "top" to "bot".
- * Return TRUE if any folds did change.
+ * IEMS = "Indent Expr Marker Syntax"
*/
static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
{
fline_T fline;
- void (*getlevel)(fline_T *);
+ LevelGetter getlevel = NULL;
fold_T *fp;
/* Avoid problems when being called recursively. */
@@ -2079,8 +2103,8 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
}
}
- /* There can't be any folds from start until end now. */
- foldRemove(&wp->w_folds, start, end);
+ // There can't be any folds from start until end now.
+ foldRemove(wp, &wp->w_folds, start, end);
/* If some fold changed, need to redraw and position cursor. */
if (fold_changed && wp->w_p_fen)
@@ -2260,12 +2284,12 @@ static linenr_T foldUpdateIEMSRecurse(
if (fp->fd_top > firstlnum) {
// We will move the start of this fold up, hence we move all
// nested folds (with relative line numbers) down.
- foldMarkAdjustRecurse(&fp->fd_nested,
+ foldMarkAdjustRecurse(flp->wp, &fp->fd_nested,
(linenr_T)0, (linenr_T)MAXLNUM,
(long)(fp->fd_top - firstlnum), 0L);
} else {
// Will move fold down, move nested folds relatively up.
- foldMarkAdjustRecurse(&fp->fd_nested,
+ foldMarkAdjustRecurse(flp->wp, &fp->fd_nested,
(linenr_T)0,
(long)(firstlnum - fp->fd_top - 1),
(linenr_T)MAXLNUM,
@@ -2295,10 +2319,10 @@ static linenr_T foldUpdateIEMSRecurse(
breakstart = flp->lnum;
breakend = flp->lnum;
}
- foldRemove(&fp->fd_nested, breakstart - fp->fd_top,
+ foldRemove(flp->wp, &fp->fd_nested, breakstart - fp->fd_top,
breakend - fp->fd_top);
i = (int)(fp - (fold_T *)gap->ga_data);
- foldSplit(gap, i, breakstart, breakend - 1);
+ foldSplit(flp->wp->w_buffer, gap, i, breakstart, breakend - 1);
fp = (fold_T *)gap->ga_data + i + 1;
/* If using the "marker" or "syntax" method, we
* need to continue until the end of the fold is
@@ -2314,7 +2338,7 @@ static linenr_T foldUpdateIEMSRecurse(
if (i != 0) {
fp2 = fp - 1;
if (fp2->fd_top + fp2->fd_len == fp->fd_top) {
- foldMerge(fp2, gap, fp);
+ foldMerge(flp->wp, fp2, gap, fp);
fp = fp2;
}
}
@@ -2325,12 +2349,13 @@ static linenr_T foldUpdateIEMSRecurse(
// A fold that starts at or after startlnum and stops
// before the new fold must be deleted. Continue
// looking for the next one.
- deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), true);
+ deleteFoldEntry(flp->wp, gap,
+ (int)(fp - (fold_T *)gap->ga_data), true);
} else {
/* A fold has some lines above startlnum, truncate it
* to stop just above startlnum. */
fp->fd_len = startlnum - fp->fd_top;
- foldMarkAdjustRecurse(&fp->fd_nested,
+ foldMarkAdjustRecurse(flp->wp, &fp->fd_nested,
(linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
(linenr_T)MAXLNUM, 0L);
fold_changed = true;
@@ -2459,8 +2484,8 @@ static linenr_T foldUpdateIEMSRecurse(
// Delete contained folds from the end of the last one found until where
// we stopped looking.
- foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top,
- flp->lnum - 1 - fp->fd_top);
+ foldRemove(flp->wp, &fp->fd_nested, startlnum2 - fp->fd_top,
+ flp->lnum - 1 - fp->fd_top);
if (lvl < level) {
// End of fold found, update the length when it got shorter.
@@ -2478,7 +2503,7 @@ static linenr_T foldUpdateIEMSRecurse(
// indent or expr method: split fold to create a new one
// below bot
i = (int)(fp - (fold_T *)gap->ga_data);
- foldSplit(gap, i, flp->lnum, bot);
+ foldSplit(flp->wp->w_buffer, gap, i, flp->lnum, bot);
fp = (fold_T *)gap->ga_data + i;
}
} else {
@@ -2496,23 +2521,23 @@ static linenr_T foldUpdateIEMSRecurse(
break;
if (fp2->fd_top + fp2->fd_len > flp->lnum) {
if (fp2->fd_top < flp->lnum) {
- /* Make fold that includes lnum start at lnum. */
- foldMarkAdjustRecurse(&fp2->fd_nested,
- (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1),
- (linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum));
+ // Make fold that includes lnum start at lnum.
+ foldMarkAdjustRecurse(flp->wp, &fp2->fd_nested,
+ (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1),
+ (linenr_T)MAXLNUM, (long)(fp2->fd_top-flp->lnum));
fp2->fd_len -= flp->lnum - fp2->fd_top;
fp2->fd_top = flp->lnum;
fold_changed = true;
}
if (lvl >= level) {
- /* merge new fold with existing fold that follows */
- foldMerge(fp, gap, fp2);
+ // merge new fold with existing fold that follows
+ foldMerge(flp->wp, fp, gap, fp2);
}
break;
}
fold_changed = true;
- deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
+ deleteFoldEntry(flp->wp, gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
}
/* Need to redraw the lines we inspected, which might be further down than
@@ -2548,8 +2573,10 @@ static void foldInsert(garray_T *gap, int i)
* The caller must first have taken care of any nested folds from "top" to
* "bot"!
*/
-static void foldSplit(garray_T *const gap, const int i, const linenr_T top,
- const linenr_T bot)
+static void foldSplit(buf_T *buf, garray_T *const gap,
+ const int i, const linenr_T top,
+ const linenr_T bot
+ )
{
fold_T *fp2;
@@ -2604,7 +2631,9 @@ static void foldSplit(garray_T *const gap, const int i, const linenr_T top,
* 5: made to start below "bot".
* 6: not changed
*/
-static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
+static void foldRemove(
+ win_T *const wp, garray_T *gap, linenr_T top, linenr_T bot
+)
{
fold_T *fp = NULL;
@@ -2616,10 +2645,11 @@ static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
// Find fold that includes top or a following one.
if (foldFind(gap, top, &fp) && fp->fd_top < top) {
// 2: or 3: need to delete nested folds
- foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top);
+ foldRemove(wp, &fp->fd_nested, top - fp->fd_top, bot - fp->fd_top);
if (fp->fd_top + fp->fd_len - 1 > bot) {
// 3: need to split it.
- foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot);
+ foldSplit(wp->w_buffer, gap,
+ (int)(fp - (fold_T *)gap->ga_data), top, bot);
} else {
// 2: truncate fold at "top".
fp->fd_len = top - fp->fd_top;
@@ -2637,7 +2667,8 @@ static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
fold_changed = true;
if (fp->fd_top + fp->fd_len - 1 > bot) {
// 5: Make fold that includes bot start below bot.
- foldMarkAdjustRecurse(&fp->fd_nested,
+ foldMarkAdjustRecurse(
+ wp, &fp->fd_nested,
(linenr_T)0, (long)(bot - fp->fd_top),
(linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1));
fp->fd_len -= bot - fp->fd_top + 1;
@@ -2646,7 +2677,7 @@ static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
}
// 4: Delete completely contained fold.
- deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), true);
+ deleteFoldEntry(wp, gap, (int)(fp - (fold_T *)gap->ga_data), true);
}
}
}
@@ -2698,19 +2729,22 @@ static void foldReverseOrder(
// 8. truncated below dest and shifted up.
// 9. shifted up
// 10. not changed
-static void truncate_fold(fold_T *fp, linenr_T end)
+static void truncate_fold(win_T *const wp, fold_T *fp, linenr_T end)
{
// I want to stop *at here*, foldRemove() stops *above* top
end += 1;
- foldRemove(&fp->fd_nested, end - fp->fd_top, MAXLNUM);
+ foldRemove(wp, &fp->fd_nested, end - fp->fd_top, MAXLNUM);
fp->fd_len = end - fp->fd_top;
}
#define FOLD_END(fp) ((fp)->fd_top + (fp)->fd_len - 1)
#define VALID_FOLD(fp, gap) ((fp) < ((fold_T *)(gap)->ga_data + (gap)->ga_len))
#define FOLD_INDEX(fp, gap) ((size_t)(fp - ((fold_T *)(gap)->ga_data)))
-void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2,
- const linenr_T dest)
+void foldMoveRange(
+ win_T *const wp, garray_T *gap,
+ const linenr_T line1, const linenr_T line2,
+ const linenr_T dest
+)
{
fold_T *fp;
const linenr_T range_len = line2 - line1 + 1;
@@ -2721,20 +2755,20 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2,
if (FOLD_END(fp) > dest) {
// Case 4 -- don't have to change this fold, but have to move nested
// folds.
- foldMoveRange(&fp->fd_nested, line1 - fp->fd_top, line2 -
+ foldMoveRange(wp, &fp->fd_nested, line1 - fp->fd_top, line2 -
fp->fd_top, dest - fp->fd_top);
return;
} else if (FOLD_END(fp) > line2) {
// Case 3 -- Remove nested folds between line1 and line2 & reduce the
// length of fold by "range_len".
// Folds after this one must be dealt with.
- foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ foldMarkAdjustRecurse(wp, &fp->fd_nested, line1 - fp->fd_top,
line2 - fp->fd_top, MAXLNUM, -range_len);
fp->fd_len -= range_len;
} else {
// Case 2 -- truncate fold *above* line1.
// Folds after this one must be dealt with.
- truncate_fold(fp, line1 - 1);
+ truncate_fold(wp, fp, line1 - 1);
}
// Look at the next fold, and treat that one as if it were the first after
// "line1" (because now it is).
@@ -2752,13 +2786,13 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2,
}
if (VALID_FOLD(fp, gap) && fp->fd_top <= dest) {
// Case 8. -- ensure truncated at dest, shift up
- truncate_fold(fp, dest);
+ truncate_fold(wp, fp, dest);
fp->fd_top -= range_len;
}
return;
} else if (FOLD_END(fp) > dest) {
// Case 7 -- remove nested folds and shrink
- foldMarkAdjustRecurse(&fp->fd_nested, line2 + 1 - fp->fd_top,
+ foldMarkAdjustRecurse(wp, &fp->fd_nested, line2 + 1 - fp->fd_top,
dest - fp->fd_top, MAXLNUM, -move_len);
fp->fd_len -= move_len;
fp->fd_top += move_len;
@@ -2774,7 +2808,7 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2,
// 5, or 6
if (FOLD_END(fp) > line2) {
// 6, truncate before moving
- truncate_fold(fp, line2);
+ truncate_fold(wp, fp, line2);
}
fp->fd_top += move_len;
continue;
@@ -2786,7 +2820,7 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2,
}
if (FOLD_END(fp) > dest) {
- truncate_fold(fp, dest);
+ truncate_fold(wp, fp, dest);
}
fp->fd_top -= range_len;
@@ -2818,7 +2852,7 @@ void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2,
* The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1".
* Fold entry "fp2" in "gap" is deleted.
*/
-static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2)
+static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2)
{
fold_T *fp3;
fold_T *fp4;
@@ -2828,8 +2862,9 @@ static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2)
/* If the last nested fold in fp1 touches the first nested fold in fp2,
* merge them recursively. */
- if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4))
- foldMerge(fp3, gap2, fp4);
+ if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4)) {
+ foldMerge(wp, fp3, gap2, fp4);
+ }
/* Move nested folds in fp2 to the end of fp1. */
if (!GA_EMPTY(gap2)) {
@@ -2844,7 +2879,7 @@ static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2)
}
fp1->fd_len += fp2->fd_len;
- deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
+ deleteFoldEntry(wp, gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
fold_changed = true;
}
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index d70d04cb4b..0debd39555 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -3361,7 +3361,7 @@ showmap (
msg_putchar(' ');
// Display the LHS. Get length of what we write.
- len = (size_t)msg_outtrans_special(mp->m_keys, true);
+ len = (size_t)msg_outtrans_special(mp->m_keys, true, 0);
do {
msg_putchar(' '); /* padd with blanks */
++len;
@@ -3389,7 +3389,7 @@ showmap (
// as typeahead.
char_u *s = vim_strsave(mp->m_str);
vim_unescape_csi(s);
- msg_outtrans_special(s, FALSE);
+ msg_outtrans_special(s, false, 0);
xfree(s);
}
if (p_verbose > 0) {
diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h
index 01f60ccf49..f0b52079aa 100644
--- a/src/nvim/getchar.h
+++ b/src/nvim/getchar.h
@@ -10,12 +10,12 @@
/// Values for "noremap" argument of ins_typebuf()
///
/// Also used for map->m_noremap and menu->noremap[].
-enum {
+enum RemapValues {
REMAP_YES = 0, ///< Allow remapping.
REMAP_NONE = -1, ///< No remapping.
REMAP_SCRIPT = -2, ///< Remap script-local mappings only.
REMAP_SKIP = -3, ///< No remapping for first char.
-} RemapValues;
+};
// Argument for flush_buffers().
typedef enum {
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 323c6cf9c3..f102c3ddd8 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -120,24 +120,20 @@ typedef off_t off_T;
# endif
#endif
-/*
- * When vgetc() is called, it sets mod_mask to the set of modifiers that are
- * held down based on the MOD_MASK_* symbols that are read first.
- */
-EXTERN int mod_mask INIT(= 0x0); /* current key modifiers */
+// When vgetc() is called, it sets mod_mask to the set of modifiers that are
+// held down based on the MOD_MASK_* symbols that are read first.
+EXTERN int mod_mask INIT(= 0x0); // current key modifiers
EXTERN bool lua_attr_active INIT(= false);
-/*
- * Cmdline_row is the row where the command line starts, just below the
- * last window.
- * When the cmdline gets longer than the available space the screen gets
- * scrolled up. After a CTRL-D (show matches), after hitting ':' after
- * "hit return", and for the :global command, the command line is
- * temporarily moved. The old position is restored with the next call to
- * update_screen().
- */
+// Cmdline_row is the row where the command line starts, just below the
+// last window.
+// When the cmdline gets longer than the available space the screen gets
+// scrolled up. After a CTRL-D (show matches), after hitting ':' after
+// "hit return", and for the :global command, the command line is
+// temporarily moved. The old position is restored with the next call to
+// update_screen().
EXTERN int cmdline_row;
EXTERN int redraw_cmdline INIT(= false); // cmdline must be redrawn
@@ -149,42 +145,38 @@ EXTERN int cmdline_was_last_drawn INIT(= false); // cmdline was last drawn
EXTERN int exec_from_reg INIT(= false); // executing register
-/*
- * When '$' is included in 'cpoptions' option set:
- * When a change command is given that deletes only part of a line, a dollar
- * is put at the end of the changed text. dollar_vcol is set to the virtual
- * column of this '$'. -1 is used to indicate no $ is being displayed.
- */
+// When '$' is included in 'cpoptions' option set:
+// When a change command is given that deletes only part of a line, a dollar
+// is put at the end of the changed text. dollar_vcol is set to the virtual
+// column of this '$'. -1 is used to indicate no $ is being displayed.
EXTERN colnr_T dollar_vcol INIT(= -1);
-/*
- * Variables for Insert mode completion.
- */
+// Variables for Insert mode completion.
-/* Length in bytes of the text being completed (this is deleted to be replaced
- * by the match.) */
+// Length in bytes of the text being completed (this is deleted to be replaced
+// by the match.)
EXTERN int compl_length INIT(= 0);
-/* Set when character typed while looking for matches and it means we should
- * stop looking for matches. */
-EXTERN int compl_interrupted INIT(= FALSE);
+// Set when character typed while looking for matches and it means we should
+// 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. */
+// List of flags for method of completion.
EXTERN int compl_cont_status INIT(= 0);
-# define CONT_ADDING 1 /* "normal" or "adding" expansion */
-# define CONT_INTRPT (2 + 4) /* a ^X interrupted the current expansion */
- /* it's set only iff N_ADDS is set */
-# define CONT_N_ADDS 4 /* next ^X<> will add-new or expand-current */
-# define CONT_S_IPOS 8 /* next ^X<> will set initial_pos?
- * if so, word-wise-expansion will set SOL */
-# define CONT_SOL 16 /* pattern includes start of line, just for
- * word-wise expansion, not set for ^X^L */
-# define CONT_LOCAL 32 /* for ctrl_x_mode 0, ^X^P/^X^N do a local
- * expansion, (eg use complete=.) */
+# define CONT_ADDING 1 // "normal" or "adding" expansion
+# define CONT_INTRPT (2 + 4) // a ^X interrupted the current expansion
+ // it's set only iff N_ADDS is set
+# define CONT_N_ADDS 4 // next ^X<> will add-new or expand-current
+# define CONT_S_IPOS 8 // next ^X<> will set initial_pos?
+ // if so, word-wise-expansion will set SOL
+# define CONT_SOL 16 // pattern includes start of line, just for
+ // word-wise expansion, not set for ^X^L
+# define CONT_LOCAL 32 // for ctrl_x_mode 0, ^X^P/^X^N do a local
+ // expansion, (eg use complete=.)
// state for putting characters in the message area
EXTERN int cmdmsg_rl INIT(= false); // cmdline is drawn right to left
@@ -200,49 +192,49 @@ EXTERN bool msg_scrolled_ign INIT(= false);
EXTERN bool msg_did_scroll INIT(= false);
-EXTERN char_u *keep_msg INIT(= NULL); /* msg to be shown after redraw */
-EXTERN int keep_msg_attr INIT(= 0); /* highlight attr for keep_msg */
-EXTERN int keep_msg_more INIT(= FALSE); /* keep_msg was set by msgmore() */
-EXTERN int need_fileinfo INIT(= FALSE); /* do fileinfo() after redraw */
-EXTERN int msg_scroll INIT(= FALSE); /* msg_start() will scroll */
-EXTERN int msg_didout INIT(= FALSE); /* msg_outstr() was used in line */
-EXTERN int msg_didany INIT(= FALSE); /* msg_outstr() was used at all */
-EXTERN int msg_nowait INIT(= FALSE); /* don't wait for this msg */
-EXTERN int emsg_off INIT(= 0); /* don't display errors for now,
- unless 'debug' is set. */
-EXTERN int info_message INIT(= FALSE); /* printing informative message */
-EXTERN int msg_hist_off INIT(= FALSE); /* don't add messages to history */
-EXTERN int need_clr_eos INIT(= FALSE); /* need to clear text before
- displaying a message. */
-EXTERN int emsg_skip INIT(= 0); /* don't display errors for
- expression that is skipped */
-EXTERN int emsg_severe INIT(= FALSE); /* use message of next of several
- emsg() calls for throw */
-EXTERN int did_endif INIT(= FALSE); /* just had ":endif" */
-EXTERN dict_T vimvardict; /* Dictionary with v: variables */
-EXTERN dict_T globvardict; /* Dictionary with g: variables */
-EXTERN int did_emsg; /* set by emsg() when the message
- is displayed or thrown */
+EXTERN char_u *keep_msg INIT(= NULL); // msg to be shown after redraw
+EXTERN int keep_msg_attr INIT(= 0); // highlight attr for keep_msg
+EXTERN int keep_msg_more INIT(= false); // keep_msg was set by msgmore()
+EXTERN int need_fileinfo INIT(= false); // do fileinfo() after redraw
+EXTERN int msg_scroll INIT(= false); // msg_start() will scroll
+EXTERN int msg_didout INIT(= false); // msg_outstr() was used in line
+EXTERN int msg_didany INIT(= false); // msg_outstr() was used at all
+EXTERN int msg_nowait INIT(= false); // don't wait for this msg
+EXTERN int emsg_off INIT(= 0); // don't display errors for now,
+ // unless 'debug' is set.
+EXTERN int info_message INIT(= false); // printing informative message
+EXTERN int msg_hist_off INIT(= false); // don't add messages to history
+EXTERN int need_clr_eos INIT(= false); // need to clear text before
+ // displaying a message.
+EXTERN int emsg_skip INIT(= 0); // don't display errors for
+ // expression that is skipped
+EXTERN int emsg_severe INIT(= false); // use message of next of several
+ // emsg() calls for throw
+EXTERN int did_endif INIT(= false); // just had ":endif"
+EXTERN dict_T vimvardict; // Dictionary with v: variables
+EXTERN dict_T globvardict; // Dictionary with g: variables
+EXTERN int did_emsg; // set by emsg() when the message
+ // is displayed or thrown
EXTERN bool called_vim_beep; // set if vim_beep() is called
-EXTERN int did_emsg_syntax; /* did_emsg set because of a
- syntax error */
-EXTERN int called_emsg; /* always set by emsg() */
-EXTERN int ex_exitval INIT(= 0); /* exit value for ex mode */
-EXTERN int emsg_on_display INIT(= FALSE); /* there is an error message */
-EXTERN int rc_did_emsg INIT(= FALSE); /* vim_regcomp() called emsg() */
-
-EXTERN int no_wait_return INIT(= 0); /* don't wait for return for now */
-EXTERN int need_wait_return INIT(= 0); /* need to wait for return later */
-EXTERN int did_wait_return INIT(= FALSE); /* wait_return() was used and
- nothing written since then */
-EXTERN int need_maketitle INIT(= TRUE); /* call maketitle() soon */
+EXTERN int did_emsg_syntax; // did_emsg set because of a
+ // syntax error
+EXTERN int called_emsg; // always set by emsg()
+EXTERN int ex_exitval INIT(= 0); // exit value for ex mode
+EXTERN bool emsg_on_display INIT(= false); // there is an error message
+EXTERN int rc_did_emsg INIT(= false); // vim_regcomp() called emsg()
+
+EXTERN int no_wait_return INIT(= 0); // don't wait for return for now
+EXTERN int need_wait_return INIT(= 0); // need to wait for return later
+EXTERN int did_wait_return INIT(= false); // wait_return() was used and
+ // nothing written since then
+EXTERN int need_maketitle INIT(= true); // call maketitle() soon
EXTERN int quit_more INIT(= false); // 'q' hit at "--more--" msg
EXTERN int ex_keep_indent INIT(= false); // getexmodeline(): keep indent
EXTERN int vgetc_busy INIT(= 0); // when inside vgetc() then > 0
-EXTERN int didset_vim INIT(= FALSE); /* did set $VIM ourselves */
-EXTERN int didset_vimruntime INIT(= FALSE); /* idem for $VIMRUNTIME */
+EXTERN int didset_vim INIT(= false); // did set $VIM ourselves
+EXTERN int didset_vimruntime INIT(= false); // idem for $VIMRUNTIME
/// Lines left before a "more" message. Ex mode needs to be able to reset this
/// after you type something.
@@ -250,8 +242,8 @@ EXTERN int lines_left INIT(= -1); // lines left for listing
EXTERN int msg_no_more INIT(= false); // don't use more prompt, truncate
// messages
-EXTERN char_u *sourcing_name INIT( = NULL); /* name of error message source */
-EXTERN linenr_T sourcing_lnum INIT(= 0); /* line number of the source file */
+EXTERN char_u *sourcing_name INIT(= NULL); // name of error message source
+EXTERN linenr_T sourcing_lnum INIT(= 0); // line number of the source file
EXTERN int ex_nesting_level INIT(= 0); // nesting level
EXTERN int debug_break_level INIT(= -1); // break below this level
@@ -282,11 +274,11 @@ EXTERN int check_cstack INIT(= false);
/// commands).
EXTERN int trylevel INIT(= 0);
-/// When "force_abort" is TRUE, always skip commands after an error message,
+/// When "force_abort" is true, always skip commands after an error message,
/// even after the outermost ":endif", ":endwhile" or ":endfor" or for a
-/// function without the "abort" flag. It is set to TRUE when "trylevel" is
+/// function without the "abort" flag. It is set to true when "trylevel" is
/// non-zero (and ":silent!" was not used) or an exception is being thrown at
-/// the time an error is detected. It is set to FALSE when "trylevel" gets
+/// the time an error is detected. It is set to false when "trylevel" gets
/// zero again and there was no error or interrupt or throw.
EXTERN int force_abort INIT(= false);
@@ -304,7 +296,7 @@ EXTERN struct msglist **msg_list INIT(= NULL);
/// interrupt message or reporting an exception that is still uncaught at the
/// top level (which has already been discarded then). Also used for the error
/// message when no exception can be thrown.
-EXTERN int suppress_errthrow INIT(= false);
+EXTERN bool suppress_errthrow INIT(= false);
/// The stack of all caught and not finished exceptions. The exception on the
/// top of the stack is the one got by evaluation of v:exception. The complete
@@ -357,41 +349,38 @@ EXTERN int provider_call_nesting INIT(= 0);
EXTERN int t_colors INIT(= 256); // int value of T_CCO
-/*
- * When highlight_match is TRUE, highlight a match, starting at the cursor
- * position. Search_match_lines is the number of lines after the match (0 for
- * a match within one line), search_match_endcol the column number of the
- * character just after the match in the last line.
- */
-EXTERN int highlight_match INIT(= FALSE); /* show search match pos */
-EXTERN linenr_T search_match_lines; /* lines of of matched string */
-EXTERN colnr_T search_match_endcol; /* col nr of match end */
-
-EXTERN int no_smartcase INIT(= FALSE); /* don't use 'smartcase' once */
-
-EXTERN int need_check_timestamps INIT(= FALSE); /* need to check file
- timestamps asap */
-EXTERN int did_check_timestamps INIT(= FALSE); /* did check timestamps
- recently */
-EXTERN int no_check_timestamps INIT(= 0); /* Don't check timestamps */
-
-EXTERN int autocmd_busy INIT(= FALSE); /* Is apply_autocmds() busy? */
-EXTERN int autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */
-EXTERN int autocmd_no_leave INIT(= FALSE); /* *Leave autocmds disabled */
-EXTERN int modified_was_set; /* did ":set modified" */
-EXTERN int did_filetype INIT(= FALSE); /* FileType event found */
-EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
- starting to execute
- autocommands */
+// When highlight_match is true, highlight a match, starting at the cursor
+// position. Search_match_lines is the number of lines after the match (0 for
+// a match within one line), search_match_endcol the column number of the
+// character just after the match in the last line.
+EXTERN int highlight_match INIT(= false); // show search match pos
+EXTERN linenr_T search_match_lines; // lines of of matched string
+EXTERN colnr_T search_match_endcol; // col nr of match end
+
+EXTERN int no_smartcase INIT(= false); // don't use 'smartcase' once
+
+EXTERN int need_check_timestamps INIT(= false); // need to check file
+ // timestamps asap
+EXTERN int did_check_timestamps INIT(= false); // did check timestamps
+ // recently
+EXTERN int no_check_timestamps INIT(= 0); // Don't check timestamps
+
+EXTERN int autocmd_busy INIT(= false); // Is apply_autocmds() busy?
+EXTERN int autocmd_no_enter INIT(= false); // *Enter autocmds disabled
+EXTERN int autocmd_no_leave INIT(= false); // *Leave autocmds disabled
+EXTERN int modified_was_set; // did ":set modified"
+EXTERN int did_filetype INIT(= false); // FileType event found
+// value for did_filetype when starting to execute autocommands
+EXTERN int keep_filetype INIT(= false);
// When deleting the current buffer, another one must be loaded.
// If we know which one is preferred, au_new_curbuf is set to it.
EXTERN bufref_T au_new_curbuf INIT(= { NULL, 0, 0 });
-// When deleting a buffer/window and autocmd_busy is TRUE, do not free the
+// When deleting a buffer/window and autocmd_busy is true, do not free the
// buffer/window. but link it in the list starting with
// au_pending_free_buf/ap_pending_free_win, using b_next/w_next.
-// Free the buffer/window when autocmd_busy is being set to FALSE.
+// Free the buffer/window when autocmd_busy is being set to false.
EXTERN buf_T *au_pending_free_buf INIT(= NULL);
EXTERN win_T *au_pending_free_win INIT(= NULL);
@@ -399,31 +388,27 @@ EXTERN win_T *au_pending_free_win INIT(= NULL);
EXTERN int mouse_grid;
EXTERN int mouse_row;
EXTERN int mouse_col;
-EXTERN bool mouse_past_bottom INIT(= false); /* mouse below last line */
-EXTERN bool mouse_past_eol INIT(= false); /* mouse right of line */
-EXTERN int mouse_dragging INIT(= 0); /* extending Visual area with
- mouse dragging */
+EXTERN bool mouse_past_bottom INIT(= false); // mouse below last line
+EXTERN bool mouse_past_eol INIT(= false); // mouse right of line
+EXTERN int mouse_dragging INIT(= 0); // extending Visual area with
+ // mouse dragging
-/* The root of the menu hierarchy. */
+// The root of the menu hierarchy.
EXTERN vimmenu_T *root_menu INIT(= NULL);
-/*
- * While defining the system menu, sys_menu is TRUE. This avoids
- * overruling of menus that the user already defined.
- */
-EXTERN int sys_menu INIT(= FALSE);
-
-/* While redrawing the screen this flag is set. It means the screen size
- * ('lines' and 'rows') must not be changed. */
-EXTERN int updating_screen INIT(= FALSE);
-
-/*
- * All windows are linked in a list. firstwin points to the first entry,
- * lastwin to the last entry (can be the same as firstwin) and curwin to the
- * currently active window.
- */
-EXTERN win_T *firstwin; /* first window */
-EXTERN win_T *lastwin; /* last window */
-EXTERN win_T *prevwin INIT(= NULL); /* previous window */
+// While defining the system menu, sys_menu is true. This avoids
+// overruling of menus that the user already defined.
+EXTERN int sys_menu INIT(= false);
+
+// While redrawing the screen this flag is set. It means the screen size
+// ('lines' and 'rows') must not be changed.
+EXTERN int updating_screen INIT(= 0);
+
+// All windows are linked in a list. firstwin points to the first entry,
+// lastwin to the last entry (can be the same as firstwin) and curwin to the
+// currently active window.
+EXTERN win_T *firstwin; // first window
+EXTERN win_T *lastwin; // last window
+EXTERN win_T *prevwin INIT(= NULL); // previous window
# define ONE_WINDOW (firstwin == lastwin)
# define FOR_ALL_FRAMES(frp, first_frame) \
for (frp = first_frame; frp != NULL; frp = frp->fr_next) // NOLINT
@@ -439,33 +424,27 @@ EXTERN win_T *prevwin INIT(= NULL); /* previous window */
for (win_T *wp = ((tp) == curtab) \
? firstwin : (tp)->tp_firstwin; wp != NULL; wp = wp->w_next)
-EXTERN win_T *curwin; /* currently active window */
+EXTERN win_T *curwin; // currently active window
-EXTERN win_T *aucmd_win; /* window used in aucmd_prepbuf() */
-EXTERN int aucmd_win_used INIT(= FALSE); /* aucmd_win is being used */
+EXTERN win_T *aucmd_win; // window used in aucmd_prepbuf()
+EXTERN int aucmd_win_used INIT(= false); // aucmd_win is being used
-/*
- * The window layout is kept in a tree of frames. topframe points to the top
- * of the tree.
- */
-EXTERN frame_T *topframe; /* top of the window frame tree */
+// The window layout is kept in a tree of frames. topframe points to the top
+// of the tree.
+EXTERN frame_T *topframe; // top of the window frame tree
-/*
- * Tab pages are alternative topframes. "first_tabpage" points to the first
- * one in the list, "curtab" is the current one.
- */
+// Tab pages are alternative topframes. "first_tabpage" points to the first
+// one in the list, "curtab" is the current one.
EXTERN tabpage_T *first_tabpage;
EXTERN tabpage_T *lastused_tabpage;
EXTERN tabpage_T *curtab;
-EXTERN int redraw_tabline INIT(= FALSE); /* need to redraw tabline */
+EXTERN int redraw_tabline INIT(= false); // need to redraw tabline
// Iterates over all tabs in the tab list
# define FOR_ALL_TABS(tp) for (tabpage_T *tp = first_tabpage; tp != NULL; tp = tp->tp_next)
-/*
- * All buffers are linked in a list. 'firstbuf' points to the first entry,
- * 'lastbuf' to the last entry and 'curbuf' to the currently active buffer.
- */
+// All buffers are linked in a list. 'firstbuf' points to the first entry,
+// 'lastbuf' to the last entry and 'curbuf' to the currently active buffer.
EXTERN buf_T *firstbuf INIT(= NULL); // first buffer
EXTERN buf_T *lastbuf INIT(= NULL); // last buffer
EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
@@ -481,23 +460,19 @@ EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
for (sign = buf->b_signlist; sign != NULL; sign = sign->next) // NOLINT
-/*
- * List of files being edited (global argument list). curwin->w_alist points
- * to this when the window is using the global argument list.
- */
-EXTERN alist_T global_alist; /* global argument list */
+// List of files being edited (global argument list). curwin->w_alist points
+// to this when the window is using the global argument list.
+EXTERN alist_T global_alist; // global argument list
EXTERN int max_alist_id INIT(= 0); ///< the previous argument list id
EXTERN bool arg_had_last INIT(= false); // accessed last file in
// global_alist
-EXTERN int ru_col; /* column for ruler */
-EXTERN int ru_wid; /* 'rulerfmt' width of ruler when non-zero */
-EXTERN int sc_col; /* column for shown command */
+EXTERN int ru_col; // column for ruler
+EXTERN int ru_wid; // 'rulerfmt' width of ruler when non-zero
+EXTERN int sc_col; // column for shown command
-//
// When starting or exiting some things are done differently (e.g. screen
// updating).
-//
// First NO_SCREEN, then NO_BUFFERS, then 0 when startup finished.
EXTERN int starting INIT(= NO_SCREEN);
@@ -546,98 +521,78 @@ EXTERN int VIsual_select INIT(= false);
EXTERN int VIsual_reselect;
/// Type of Visual mode.
EXTERN int VIsual_mode INIT(= 'v');
-/// TRUE when redoing Visual.
+/// true when redoing Visual.
EXTERN int redo_VIsual_busy INIT(= false);
/// When pasting text with the middle mouse button in visual mode with
/// restart_edit set, remember where it started so we can set Insstart.
EXTERN pos_T where_paste_started;
-/*
- * This flag is used to make auto-indent work right on lines where only a
- * <RETURN> or <ESC> is typed. It is set when an auto-indent is done, and
- * reset when any other editing is done on the line. If an <ESC> or <RETURN>
- * is received, and did_ai is TRUE, the line is truncated.
- */
+// This flag is used to make auto-indent work right on lines where only a
+// <RETURN> or <ESC> is typed. It is set when an auto-indent is done, and
+// reset when any other editing is done on the line. If an <ESC> or <RETURN>
+// is received, and did_ai is true, the line is truncated.
EXTERN bool did_ai INIT(= false);
-/*
- * Column of first char after autoindent. 0 when no autoindent done. Used
- * when 'backspace' is 0, to avoid backspacing over autoindent.
- */
+// Column of first char after autoindent. 0 when no autoindent done. Used
+// when 'backspace' is 0, to avoid backspacing over autoindent.
EXTERN colnr_T ai_col INIT(= 0);
-/*
- * This is a character which will end a start-middle-end comment when typed as
- * the first character on a new line. It is taken from the last character of
- * the "end" comment leader when the COM_AUTO_END flag is given for that
- * comment end in 'comments'. It is only valid when did_ai is TRUE.
- */
+// This is a character which will end a start-middle-end comment when typed as
+// the first character on a new line. It is taken from the last character of
+// the "end" comment leader when the COM_AUTO_END flag is given for that
+// comment end in 'comments'. It is only valid when did_ai is true.
EXTERN int end_comment_pending INIT(= NUL);
-/*
- * This flag is set after a ":syncbind" to let the check_scrollbind() function
- * know that it should not attempt to perform scrollbinding due to the scroll
- * that was a result of the ":syncbind." (Otherwise, check_scrollbind() will
- * undo some of the work done by ":syncbind.") -ralston
- */
-EXTERN int did_syncbind INIT(= FALSE);
-
-/*
- * This flag is set when a smart indent has been performed. When the next typed
- * character is a '{' the inserted tab will be deleted again.
- */
+// This flag is set after a ":syncbind" to let the check_scrollbind() function
+// know that it should not attempt to perform scrollbinding due to the scroll
+// that was a result of the ":syncbind." (Otherwise, check_scrollbind() will
+// undo some of the work done by ":syncbind.") -ralston
+EXTERN int did_syncbind INIT(= false);
+
+// This flag is set when a smart indent has been performed. When the next typed
+// character is a '{' the inserted tab will be deleted again.
EXTERN bool did_si INIT(= false);
-/*
- * This flag is set after an auto indent. If the next typed character is a '}'
- * one indent will be removed.
- */
+// This flag is set after an auto indent. If the next typed character is a '}'
+// one indent will be removed.
EXTERN bool can_si INIT(= false);
-/*
- * This flag is set after an "O" command. If the next typed character is a '{'
- * one indent will be removed.
- */
+// This flag is set after an "O" command. If the next typed character is a '{'
+// one indent will be removed.
EXTERN bool can_si_back INIT(= false);
// w_cursor before formatting text.
EXTERN pos_T saved_cursor INIT(= { 0, 0, 0 });
-/*
- * Stuff for insert mode.
- */
-EXTERN pos_T Insstart; /* This is where the latest
- * insert/append mode started. */
+// Stuff for insert mode.
+EXTERN pos_T Insstart; // This is where the latest
+ // insert/append mode started.
// This is where the latest insert/append mode started. In contrast to
// Insstart, this won't be reset by certain keys and is needed for
// op_insert(), to detect correctly where inserting by the user started.
EXTERN pos_T Insstart_orig;
-/*
- * Stuff for VREPLACE mode.
- */
-EXTERN int orig_line_count INIT(= 0); /* Line count when "gR" started */
-EXTERN int vr_lines_changed INIT(= 0); /* #Lines changed by "gR" so far */
+// Stuff for VREPLACE mode.
+EXTERN int orig_line_count INIT(= 0); // Line count when "gR" started
+EXTERN int vr_lines_changed INIT(= 0); // #Lines changed by "gR" so far
// increase around internal delete/replace
EXTERN int inhibit_delete_count INIT(= 0);
-/*
- * These flags are set based upon 'fileencoding'.
- * Note that "enc_utf8" is also set for "unicode", because the characters are
- * internally stored as UTF-8 (to avoid trouble with NUL bytes).
- */
-# define DBCS_JPN 932 /* japan */
-# define DBCS_JPNU 9932 /* euc-jp */
-# define DBCS_KOR 949 /* korea */
-# define DBCS_KORU 9949 /* euc-kr */
-# define DBCS_CHS 936 /* chinese */
-# define DBCS_CHSU 9936 /* euc-cn */
-# define DBCS_CHT 950 /* taiwan */
-# define DBCS_CHTU 9950 /* euc-tw */
-# define DBCS_2BYTE 1 /* 2byte- */
+// These flags are set based upon 'fileencoding'.
+// Note that "enc_utf8" is also set for "unicode", because the characters are
+// internally stored as UTF-8 (to avoid trouble with NUL bytes).
+# define DBCS_JPN 932 // japan
+# define DBCS_JPNU 9932 // euc-jp
+# define DBCS_KOR 949 // korea
+# define DBCS_KORU 9949 // euc-kr
+# define DBCS_CHS 936 // chinese
+# define DBCS_CHSU 9936 // euc-cn
+# define DBCS_CHT 950 // taiwan
+# define DBCS_CHTU 9950 // euc-tw
+# define DBCS_2BYTE 1 // 2byte-
# define DBCS_DEBUG -1
// mbyte flags that used to depend on 'encoding'. These are now deprecated, as
@@ -678,40 +633,40 @@ EXTERN int u_sync_once INIT(= 0); // Call u_sync() once when evaluating
EXTERN bool force_restart_edit INIT(= false); // force restart_edit after
// ex_normal returns
-EXTERN int restart_edit INIT(= 0); /* call edit when next cmd finished */
-EXTERN int arrow_used; /* Normally FALSE, set to TRUE after
- * hitting cursor key in insert mode.
- * Used by vgetorpeek() to decide when
- * to call u_sync() */
-EXTERN int ins_at_eol INIT(= FALSE); /* put cursor after eol when
- restarting edit after CTRL-O */
+EXTERN int restart_edit INIT(= 0); // call edit when next cmd finished
+EXTERN int arrow_used; // Normally false, set to true after
+ // hitting cursor key in insert mode.
+ // Used by vgetorpeek() to decide when
+ // to call u_sync()
+EXTERN bool ins_at_eol INIT(= false); // put cursor after eol when
+ // restarting edit after CTRL-O
EXTERN char_u *edit_submode INIT(= NULL); // msg for CTRL-X submode
EXTERN char_u *edit_submode_pre INIT(= NULL); // prepended to edit_submode
EXTERN char_u *edit_submode_extra INIT(= NULL); // appended to edit_submode
EXTERN hlf_T edit_submode_highl; // highl. method for extra info
-EXTERN int no_abbr INIT(= TRUE); /* TRUE when no abbreviations loaded */
+EXTERN int no_abbr INIT(= true); // true when no abbreviations loaded
EXTERN int mapped_ctrl_c INIT(= 0); // Modes where CTRL-C is mapped.
-EXTERN cmdmod_T cmdmod; /* Ex command modifiers */
+EXTERN cmdmod_T cmdmod; // Ex command modifiers
EXTERN int msg_silent INIT(= 0); // don't print messages
EXTERN int emsg_silent INIT(= 0); // don't print error messages
EXTERN bool emsg_noredir INIT(= false); // don't redirect error messages
EXTERN bool cmd_silent INIT(= false); // don't echo the command line
-/* Values for swap_exists_action: what to do when swap file already exists */
-#define SEA_NONE 0 /* don't use dialog */
-#define SEA_DIALOG 1 /* use dialog when possible */
-#define SEA_QUIT 2 /* quit editing the file */
-#define SEA_RECOVER 3 /* recover the file */
+// Values for swap_exists_action: what to do when swap file already exists
+#define SEA_NONE 0 // don't use dialog
+#define SEA_DIALOG 1 // use dialog when possible
+#define SEA_QUIT 2 // quit editing the file
+#define SEA_RECOVER 3 // recover the file
EXTERN int swap_exists_action INIT(= SEA_NONE);
-/* For dialog when swap file already
- * exists. */
-EXTERN int swap_exists_did_quit INIT(= FALSE);
-/* Selected "quit" at the dialog. */
+// For dialog when swap file already
+// exists.
+EXTERN int swap_exists_did_quit INIT(= false);
+// Selected "quit" at the dialog.
EXTERN char_u IObuff[IOSIZE]; ///< Buffer for sprintf, I/O, etc.
EXTERN char_u NameBuff[MAXPATHL]; ///< Buffer for expanding file names
@@ -724,11 +679,11 @@ IOSIZE
#endif
];
-/* When non-zero, postpone redrawing. */
+// When non-zero, postpone redrawing.
EXTERN int RedrawingDisabled INIT(= 0);
-EXTERN int readonlymode INIT(= FALSE); /* Set to TRUE for "view" */
-EXTERN int recoverymode INIT(= FALSE); /* Set to TRUE for "-r" option */
+EXTERN int readonlymode INIT(= false); // Set to true for "view"
+EXTERN int recoverymode INIT(= false); // Set to true for "-r" option
// typeahead buffer
EXTERN typebuf_T typebuf INIT(= { NULL, NULL, 0, 0, 0, 0, 0, 0, 0 });
@@ -738,7 +693,7 @@ EXTERN int ex_normal_lock INIT(= 0); // forbid use of ex_normal()
EXTERN int ignore_script INIT(= false); // ignore script input
EXTERN int stop_insert_mode; // for ":stopinsert" and 'insertmode'
EXTERN bool KeyTyped; // true if user typed current char
-EXTERN int KeyStuffed; // TRUE if current char from stuffbuf
+EXTERN int KeyStuffed; // true if current char from stuffbuf
EXTERN int maptick INIT(= 0); // tick for each non-mapped char
EXTERN int must_redraw INIT(= 0); // type of redraw necessary
@@ -754,15 +709,15 @@ EXTERN FILE *scriptout INIT(= NULL); ///< Stream to write script to.
// volatile because it is used in a signal handler.
EXTERN volatile int got_int INIT(= false); // set to true when interrupt
// signal occurred
-EXTERN int bangredo INIT(= FALSE); /* set to TRUE with ! command */
-EXTERN int searchcmdlen; /* length of previous search cmd */
-EXTERN int reg_do_extmatch INIT(= 0); /* Used when compiling regexp:
- * REX_SET to allow \z\(...\),
- * REX_USE to allow \z\1 et al. */
-EXTERN reg_extmatch_T *re_extmatch_in INIT(= NULL); /* Used by vim_regexec():
- * strings for \z\1...\z\9 */
-EXTERN reg_extmatch_T *re_extmatch_out INIT(= NULL); /* Set by vim_regexec()
- * to store \z\(...\) matches */
+EXTERN int bangredo INIT(= false); // set to true with ! command
+EXTERN int searchcmdlen; // length of previous search cmd
+EXTERN int reg_do_extmatch INIT(= 0); // Used when compiling regexp:
+ // REX_SET to allow \z\(...\),
+ // REX_USE to allow \z\1 et al.
+// Used by vim_regexec(): strings for \z\1...\z\9
+EXTERN reg_extmatch_T *re_extmatch_in INIT(= NULL);
+// Set by vim_regexec() to store \z\(...\) matches
+EXTERN reg_extmatch_T *re_extmatch_out INIT(= NULL);
EXTERN int did_outofmem_msg INIT(= false);
// set after out of memory msg
@@ -781,11 +736,11 @@ EXTERN int autocmd_bufnr INIT(= 0); // fnum for <abuf> on cmdline
EXTERN char_u *autocmd_match INIT(= NULL); // name for <amatch> on cmdline
EXTERN int did_cursorhold INIT(= false); // set when CursorHold t'gerd
-EXTERN int postponed_split INIT(= 0); /* for CTRL-W CTRL-] command */
-EXTERN int postponed_split_flags INIT(= 0); /* args for win_split() */
-EXTERN int postponed_split_tab INIT(= 0); /* cmdmod.tab */
-EXTERN int g_do_tagpreview INIT(= 0); /* for tag preview commands:
- height of preview window */
+EXTERN int postponed_split INIT(= 0); // for CTRL-W CTRL-] command
+EXTERN int postponed_split_flags INIT(= 0); // args for win_split()
+EXTERN int postponed_split_tab INIT(= 0); // cmdmod.tab
+EXTERN int g_do_tagpreview INIT(= 0); // for tag preview commands:
+ // height of preview window
EXTERN int g_tag_at_cursor INIT(= false); // whether the tag command comes
// from the command line (0) or was
// invoked as a normal command (1)
@@ -793,15 +748,13 @@ EXTERN int g_tag_at_cursor INIT(= false); // whether the tag command comes
EXTERN int replace_offset INIT(= 0); // offset for replace_push()
EXTERN char_u *escape_chars INIT(= (char_u *)" \t\\\"|");
-/* need backslash in cmd line */
+// need backslash in cmd line
-EXTERN int keep_help_flag INIT(= FALSE); /* doing :ta from help file */
+EXTERN int keep_help_flag INIT(= false); // doing :ta from help file
-/*
- * When a string option is NULL (which only happens in out-of-memory
- * situations), it is set to empty_option, to avoid having to check for NULL
- * everywhere.
- */
+// When a string option is NULL (which only happens in out-of-memory
+// situations), it is set to empty_option, to avoid having to check for NULL
+// everywhere.
EXTERN char_u *empty_option INIT(= (char_u *)"");
EXTERN int redir_off INIT(= false); // no redirection for a moment
@@ -810,10 +763,10 @@ EXTERN int redir_reg INIT(= 0); // message redirection register
EXTERN int redir_vname INIT(= 0); // message redirection variable
EXTERN garray_T *capture_ga INIT(= NULL); // captured output for execute()
-EXTERN char_u langmap_mapchar[256]; /* mapping for language keys */
+EXTERN char_u langmap_mapchar[256]; // mapping for language keys
-EXTERN int save_p_ls INIT(= -1); /* Save 'laststatus' setting */
-EXTERN int save_p_wmh INIT(= -1); /* Save 'winminheight' setting */
+EXTERN int save_p_ls INIT(= -1); // Save 'laststatus' setting
+EXTERN int save_p_wmh INIT(= -1); // Save 'winminheight' setting
EXTERN int wild_menu_showing INIT(= 0);
enum {
WM_SHOWN = 1, ///< wildmenu showing
@@ -822,10 +775,8 @@ enum {
};
-/*
- * Some file names are stored in pathdef.c, which is generated from the
- * Makefile to make their value depend on the Makefile.
- */
+// Some file names are stored in pathdef.c, which is generated from the
+// Makefile to make their value depend on the Makefile.
#ifdef HAVE_PATHDEF
extern char *default_vim_dir;
extern char *default_vimruntime_dir;
@@ -834,14 +785,14 @@ extern char_u *compiled_user;
extern char_u *compiled_sys;
#endif
-/* When a window has a local directory, the absolute path of the global
- * current directory is stored here (in allocated memory). If the current
- * directory is not a local directory, globaldir is NULL. */
+// When a window has a local directory, the absolute path of the global
+// current directory is stored here (in allocated memory). If the current
+// directory is not a local directory, globaldir is NULL.
EXTERN char_u *globaldir INIT(= NULL);
-/* Whether 'keymodel' contains "stopsel" and "startsel". */
-EXTERN int km_stopsel INIT(= FALSE);
-EXTERN int km_startsel INIT(= FALSE);
+// Whether 'keymodel' contains "stopsel" and "startsel".
+EXTERN int km_stopsel INIT(= false);
+EXTERN int km_startsel INIT(= false);
EXTERN int cedit_key INIT(= -1); ///< key value of 'cedit' option
EXTERN int cmdwin_type INIT(= 0); ///< type of cmdline window or 0
@@ -850,18 +801,16 @@ EXTERN int cmdwin_level INIT(= 0); ///< cmdline recursion level
EXTERN char_u no_lines_msg[] INIT(= N_("--No lines in buffer--"));
-/*
- * When ":global" is used to number of substitutions and changed lines is
- * accumulated until it's finished.
- * Also used for ":spellrepall".
- */
-EXTERN long sub_nsubs; /* total number of substitutions */
-EXTERN linenr_T sub_nlines; /* total number of lines changed */
+// When ":global" is used to number of substitutions and changed lines is
+// accumulated until it's finished.
+// Also used for ":spellrepall".
+EXTERN long sub_nsubs; // total number of substitutions
+EXTERN linenr_T sub_nlines; // total number of lines changed
-/* table to store parsed 'wildmode' */
+// table to store parsed 'wildmode'
EXTERN char_u wim_flags[4];
-/* whether titlestring and iconstring contains statusline syntax */
+// whether titlestring and iconstring contains statusline syntax
# define STL_IN_ICON 1
# define STL_IN_TITLE 2
EXTERN int stl_syntax INIT(= 0);
@@ -869,7 +818,7 @@ EXTERN int stl_syntax INIT(= 0);
// don't use 'hlsearch' temporarily
EXTERN bool no_hlsearch INIT(= false);
-/* Page number used for %N in 'pageheader' and 'guitablabel'. */
+// Page number used for %N in 'pageheader' and 'guitablabel'.
EXTERN linenr_T printer_page_num;
@@ -887,18 +836,16 @@ EXTERN char pseps[2] INIT(= { '\\', 0 }); // normal path separator string
// kNone when no operator is being executed, kFalse otherwise.
EXTERN TriState virtual_op INIT(= kNone);
-/* Display tick, incremented for each call to update_screen() */
+// Display tick, incremented for each call to update_screen()
EXTERN disptick_T display_tick INIT(= 0);
-/* Line in which spell checking wasn't highlighted because it touched the
- * cursor position in Insert mode. */
+// Line in which spell checking wasn't highlighted because it touched the
+// cursor position in Insert mode.
EXTERN linenr_T spell_redraw_lnum INIT(= 0);
-/*
- * The error messages that can be shared are included here.
- * Excluded are errors that are only used once and debugging messages.
- */
+// The error messages that can be shared are included here.
+// Excluded are errors that are only used once and debugging messages.
EXTERN char_u e_abort[] INIT(= N_("E470: Command aborted"));
EXTERN char_u e_afterinit[] INIT(= N_(
"E905: Cannot set this option after startup"));
@@ -1070,7 +1017,7 @@ EXTERN char line_msg[] INIT(= N_(" line "));
// For undo we need to know the lowest time possible.
EXTERN time_t starttime;
-EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
+EXTERN FILE *time_fd INIT(= NULL); // where to write startup timing
// Some compilers warn for not using a return value, but in some situations we
// can't do anything useful with the value. Assign to this variable to avoid
@@ -1106,4 +1053,4 @@ typedef enum {
#define MIN_CD_SCOPE kCdScopeWindow
#define MAX_CD_SCOPE kCdScopeGlobal
-#endif /* NVIM_GLOBALS_H */
+#endif // NVIM_GLOBALS_H
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index cb5c5338a1..f1f84e63be 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -162,21 +162,21 @@ static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] =
* These values determine the print position on a page.
*/
typedef struct {
- int lead_spaces; /* remaining spaces for a TAB */
- int print_pos; /* virtual column for computing TABs */
- colnr_T column; /* byte column */
- linenr_T file_line; /* line nr in the buffer */
- size_t bytes_printed; /* bytes printed so far */
- int ff; /* seen form feed character */
+ int lead_spaces; // remaining spaces for a TAB
+ int print_pos; // virtual column for computing TABs
+ colnr_T column; // byte column
+ linenr_T file_line; // line nr in the buffer
+ size_t bytes_printed; // bytes printed so far
+ int ff; // seen form feed character
} prt_pos_T;
struct prt_mediasize_S {
char *name;
- double width; /* width and height in points for portrait */
+ double width; // width and height in points for portrait
double height;
};
-/* PS font names, must be in Roman, Bold, Italic, Bold-Italic order */
+// PS font names, must be in Roman, Bold, Italic, Bold-Italic order
struct prt_ps_font_S {
int wx;
int uline_offset;
@@ -200,7 +200,7 @@ struct prt_ps_charset_S {
int has_charset;
};
-/* Collections of encodings and charsets for multi-byte printing */
+// Collections of encodings and charsets for multi-byte printing
struct prt_ps_mbfont_S {
int num_encodings;
struct prt_ps_encoding_S *encodings;
@@ -361,9 +361,10 @@ static uint32_t darken_rgb(uint32_t rgb)
static uint32_t prt_get_term_color(int colorindex)
{
- /* TODO: Should check for xterm with 88 or 256 colors. */
- if (t_colors > 8)
+ // TODO(vim): Should check for xterm with 88 or 256 colors.
+ if (t_colors > 8) {
return cterm_color_16[colorindex % 16];
+ }
return cterm_color_8[colorindex % 8];
}
@@ -535,7 +536,7 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum,
p_header, use_sandbox,
' ', width, NULL, NULL);
- /* Reset line numbers */
+ // Reset line numbers
curwin->w_cursor.lnum = tmp_lnum;
curwin->w_topline = tmp_topline;
curwin->w_botline = tmp_botline;
@@ -602,7 +603,7 @@ void ex_hardcopy(exarg_T *eap)
if (*eap->arg == '>') {
char_u *errormsg = NULL;
- /* Expand things like "%.ps". */
+ // Expand things like "%.ps".
if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL) {
if (errormsg != NULL)
EMSG(errormsg);
@@ -666,7 +667,7 @@ void ex_hardcopy(exarg_T *eap)
goto print_fail_no_begin;
}
- /* Set colors and font to normal. */
+ // Set colors and font to normal.
curr_bg = 0xffffffff;
curr_fg = 0xffffffff;
curr_italic = kNone;
@@ -691,8 +692,8 @@ void ex_hardcopy(exarg_T *eap)
for (collated_copies = 0;
collated_copies < settings.n_collated_copies;
collated_copies++) {
- prt_pos_T prtpos; /* current print position */
- prt_pos_T page_prtpos; /* print position at page start */
+ prt_pos_T prtpos; // current print position
+ prt_pos_T page_prtpos; // print position at page start
int side;
memset(&page_prtpos, 0, sizeof(prt_pos_T));
@@ -700,7 +701,7 @@ void ex_hardcopy(exarg_T *eap)
prtpos = page_prtpos;
if (jobsplit && collated_copies > 0) {
- /* Splitting jobs: Stop a previous job and start a new one. */
+ // Splitting jobs: Stop a previous job and start a new one.
mch_print_end(&settings);
if (!mch_print_begin(&settings))
goto print_fail_no_begin;
@@ -717,7 +718,7 @@ void ex_hardcopy(exarg_T *eap)
for (uncollated_copies = 0;
uncollated_copies < settings.n_uncollated_copies;
uncollated_copies++) {
- /* Set the print position to the start of this page. */
+ // Set the print position to the start of this page.
prtpos = page_prtpos;
/*
@@ -728,7 +729,7 @@ void ex_hardcopy(exarg_T *eap)
* Print one page.
*/
- /* Check for interrupt character every page. */
+ // Check for interrupt character every page.
os_breakcheck();
if (got_int || settings.user_abort)
goto print_fail;
@@ -759,11 +760,12 @@ void ex_hardcopy(exarg_T *eap)
prtpos.column = hardcopy_line(&settings,
page_line, &prtpos);
if (prtpos.column == 0) {
- /* finished a file line */
+ // finished a file line
prtpos.bytes_printed +=
STRLEN(skipwhite(ml_get(prtpos.file_line)));
- if (++prtpos.file_line > eap->line2)
- break; /* reached the end */
+ if (++prtpos.file_line > eap->line2) {
+ break; // reached the end
+ }
} else if (prtpos.ff) {
/* Line had a formfeed in it - start new page but
* stay on the current line */
@@ -771,10 +773,12 @@ void ex_hardcopy(exarg_T *eap)
}
}
- if (!mch_print_end_page())
+ if (!mch_print_end_page()) {
goto print_fail;
- if (prtpos.file_line > eap->line2)
- break; /* reached the end */
+ }
+ if (prtpos.file_line > eap->line2) {
+ break; // reached the end
+ }
}
/*
@@ -791,7 +795,7 @@ void ex_hardcopy(exarg_T *eap)
if (settings.duplex && prtpos.file_line <= eap->line2)
++page_count;
- /* Remember the position where the next page starts. */
+ // Remember the position where the next page starts.
page_prtpos = prtpos;
}
@@ -855,7 +859,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
id = syn_get_final_id(id);
else
id = 0;
- /* Get the line again, a multi-line regexp may invalidate it. */
+ // Get the line again, a multi-line regexp may invalidate it.
line = ml_get(ppos->file_line);
if (id != current_syn_id) {
@@ -881,9 +885,10 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
if (need_break)
break;
}
- /* Keep the TAB if we didn't finish it. */
- if (need_break && tab_spaces > 0)
+ // Keep the TAB if we didn't finish it.
+ if (need_break && tab_spaces > 0) {
break;
+ }
} else if (line[col] == FF
&& printer_opts[OPT_PRINT_FORMFEED].present
&& TOLOWER_ASC(printer_opts[OPT_PRINT_FORMFEED].string[0])
@@ -942,7 +947,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
* http://www.adobe.com
*/
-#define PRT_PS_DEFAULT_DPI (72) /* Default user space resolution */
+#define PRT_PS_DEFAULT_DPI (72) // Default user space resolution
#define PRT_PS_DEFAULT_FONTSIZE (10)
#define PRT_PS_DEFAULT_BUFFER_SIZE (80)
@@ -951,20 +956,20 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
static struct prt_mediasize_S prt_mediasize[] =
{
- {"A4", 595.0, 842.0},
- {"letter", 612.0, 792.0},
- {"10x14", 720.0, 1008.0},
- {"A3", 842.0, 1191.0},
- {"A5", 420.0, 595.0},
- {"B4", 729.0, 1032.0},
- {"B5", 516.0, 729.0},
- {"executive", 522.0, 756.0},
- {"folio", 595.0, 935.0},
- {"ledger", 1224.0, 792.0}, /* Yes, it is wider than taller! */
- {"legal", 612.0, 1008.0},
- {"quarto", 610.0, 780.0},
- {"statement", 396.0, 612.0},
- {"tabloid", 792.0, 1224.0}
+ { "A4", 595.0, 842.0 },
+ { "letter", 612.0, 792.0 },
+ { "10x14", 720.0, 1008.0 },
+ { "A3", 842.0, 1191.0 },
+ { "A5", 420.0, 595.0 },
+ { "B4", 729.0, 1032.0 },
+ { "B5", 516.0, 729.0 },
+ { "executive", 522.0, 756.0 },
+ { "folio", 595.0, 935.0 },
+ { "ledger", 1224.0, 792.0 }, // Yes, it is wider than taller!
+ { "legal", 612.0, 1008.0 },
+ { "quarto", 610.0, 780.0 },
+ { "statement", 396.0, 612.0 },
+ { "tabloid", 792.0, 1224.0 }
};
#define PRT_PS_FONT_ROMAN (0)
@@ -972,7 +977,7 @@ static struct prt_mediasize_S prt_mediasize[] =
#define PRT_PS_FONT_OBLIQUE (2)
#define PRT_PS_FONT_BOLDOBLIQUE (3)
-/* Standard font metrics for Courier family */
+// Standard font metrics for Courier family
static struct prt_ps_font_S prt_ps_courier_font =
{
600,
@@ -981,7 +986,7 @@ static struct prt_ps_font_S prt_ps_courier_font =
{"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique"}
};
-/* Generic font metrics for multi-byte fonts */
+// Generic font metrics for multi-byte fonts
static struct prt_ps_font_S prt_ps_mb_font =
{
1000,
@@ -990,9 +995,8 @@ static struct prt_ps_font_S prt_ps_mb_font =
{NULL, NULL, NULL, NULL}
};
-/* Pointer to current font set being used */
-static struct prt_ps_font_S* prt_ps_font;
-
+// Pointer to current font set being used
+static struct prt_ps_font_S *prt_ps_font;
#define CS_JIS_C_1978 (0x01)
#define CS_JIS_X_1983 (0x02)
@@ -1003,7 +1007,7 @@ static struct prt_ps_font_S* prt_ps_font;
#define CS_KANJITALK6 (0x40)
#define CS_KANJITALK7 (0x80)
-/* Japanese encodings and charsets */
+// Japanese encodings and charsets
static struct prt_ps_encoding_S j_encodings[] =
{
{"iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990|
@@ -1035,7 +1039,7 @@ static struct prt_ps_charset_S j_charsets[] =
#define CS_GBK (0x20)
#define CS_SC_ISO10646 (0x40)
-/* Simplified Chinese encodings and charsets */
+// Simplified Chinese encodings and charsets
static struct prt_ps_encoding_S sc_encodings[] =
{
{"iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90)},
@@ -1071,7 +1075,7 @@ static struct prt_ps_charset_S sc_charsets[] =
#define CS_DLHKS (0x800)
#define CS_TC_ISO10646 (0x1000)
-/* Traditional Chinese encodings and charsets */
+// Traditional Chinese encodings and charsets
static struct prt_ps_encoding_S tc_encodings[] =
{
{"iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2)},
@@ -1108,7 +1112,7 @@ static struct prt_ps_charset_S tc_charsets[] =
#define CS_KR_X_1992_MS (0x04)
#define CS_KR_ISO10646 (0x08)
-/* Korean encodings and charsets */
+// Korean encodings and charsets
static struct prt_ps_encoding_S k_encodings[] =
{
{"iso-2022-kr", NULL, CS_KR_X_1992},
@@ -1167,7 +1171,7 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] =
}
};
-/* Types of PS resource file currently used */
+// Types of PS resource file currently used
#define PRT_RESOURCE_TYPE_PROCSET (0)
#define PRT_RESOURCE_TYPE_ENCODING (1)
#define PRT_RESOURCE_TYPE_CMAP (2)
@@ -1195,7 +1199,7 @@ static char *prt_resource_types[] =
"cmap"
};
-/* Strings to look for in a PS resource file */
+// Strings to look for in a PS resource file
#define PRT_RESOURCE_HEADER "%!PS-Adobe-"
#define PRT_RESOURCE_RESOURCE "Resource-"
#define PRT_RESOURCE_PROCSET "ProcSet"
@@ -1255,20 +1259,20 @@ static double prt_pos_y_moveto = 0.0;
* Various control variables used to decide when and how to change the
* PostScript graphics state.
*/
-static int prt_need_moveto;
-static int prt_do_moveto;
-static int prt_need_font;
+static bool prt_need_moveto;
+static bool prt_do_moveto;
+static bool prt_need_font;
static int prt_font;
-static int prt_need_underline;
+static bool prt_need_underline;
static TriState prt_underline;
static TriState prt_do_underline;
-static int prt_need_fgcol;
+static bool prt_need_fgcol;
static uint32_t prt_fgcol;
-static int prt_need_bgcol;
-static int prt_do_bgcol;
+static bool prt_need_bgcol;
+static bool prt_do_bgcol;
static uint32_t prt_bgcol;
static uint32_t prt_new_bgcol;
-static int prt_attribute_change;
+static bool prt_attribute_change;
static double prt_text_run;
static int prt_page_num;
static int prt_bufsiz;
@@ -1296,8 +1300,8 @@ static int prt_out_mbyte;
static int prt_custom_cmap;
static char prt_cmap[80];
static int prt_use_courier;
-static int prt_in_ascii;
-static int prt_half_width;
+static bool prt_in_ascii;
+static bool prt_half_width;
static char *prt_ascii_encoding;
static char_u prt_hexchar[] = "0123456789abcdef";
@@ -1416,18 +1420,19 @@ static void prt_write_real(double val, int prec)
int fraction;
prt_real_bits(val, prec, &integer, &fraction);
- /* Emit integer part */
- sprintf((char *)prt_line_buffer, "%d", integer);
+ // Emit integer part
+ snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%d", integer);
prt_write_file(prt_line_buffer);
- /* Only emit fraction if necessary */
+ // Only emit fraction if necessary
if (fraction != 0) {
- /* Remove any trailing zeros */
+ // Remove any trailing zeros
while ((fraction % 10) == 0) {
prec--;
fraction /= 10;
}
- /* Emit fraction left padded with zeros */
- sprintf((char *)prt_line_buffer, ".%0*d", prec, fraction);
+ // Emit fraction left padded with zeros
+ snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), ".%0*d",
+ prec, fraction);
prt_write_file(prt_line_buffer);
}
sprintf((char *)prt_line_buffer, " ");
@@ -1447,13 +1452,13 @@ static void prt_def_var(char *name, double value, int prec)
prt_write_file(prt_line_buffer);
}
-/* Convert size from font space to user space at current font scale */
+// Convert size from font space to user space at current font scale
#define PRT_PS_FONT_TO_USER(scale, size) ((size) * ((scale)/1000.0))
static void prt_flush_buffer(void)
{
if (!GA_EMPTY(&prt_ps_buffer)) {
- /* Any background color must be drawn first */
+ // Any background color must be drawn first
if (prt_do_bgcol && (prt_new_bgcol != PRCOLOR_WHITE)) {
unsigned int r, g, b;
@@ -1461,14 +1466,14 @@ static void prt_flush_buffer(void)
prt_write_real(prt_pos_x_moveto, 2);
prt_write_real(prt_pos_y_moveto, 2);
prt_write_string("m\n");
- prt_do_moveto = FALSE;
+ prt_do_moveto = false;
}
- /* Size of rect of background color on which text is printed */
+ // Size of rect of background color on which text is printed
prt_write_real(prt_text_run, 2);
prt_write_real(prt_line_height, 2);
- /* Lastly add the color of the background */
+ // Lastly add the color of the background
r = (prt_new_bgcol & 0xff0000) >> 16;
g = (prt_new_bgcol & 0xff00) >> 8;
b = prt_new_bgcol & 0xff;
@@ -1485,10 +1490,10 @@ static void prt_flush_buffer(void)
prt_write_real(prt_pos_x_moveto, 2);
prt_write_real(prt_pos_y_moveto, 2);
prt_write_string("m\n");
- prt_do_moveto = FALSE;
+ prt_do_moveto = false;
}
- /* Underline length of text run */
+ // Underline length of text run
prt_write_real(prt_text_run, 2);
prt_write_string("ul\n");
}
@@ -1503,16 +1508,16 @@ static void prt_flush_buffer(void)
prt_write_string(">");
else
prt_write_string(")");
- /* Add a moveto if need be and use the appropriate show procedure */
+ // Add a moveto if need be and use the appropriate show procedure
if (prt_do_moveto) {
prt_write_real(prt_pos_x_moveto, 2);
prt_write_real(prt_pos_y_moveto, 2);
- /* moveto and a show */
+ // moveto and a show
prt_write_string("ms\n");
- prt_do_moveto = FALSE;
- } else /* Simple show */
+ prt_do_moveto = false;
+ } else { // Simple show
prt_write_string("s\n");
-
+ }
ga_clear(&prt_ps_buffer);
ga_init(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz);
}
@@ -1536,7 +1541,7 @@ static int prt_find_resource(char *name, struct prt_ps_resource_S *resource)
buffer = xmallocz(MAXPATHL);
STRLCPY(resource->name, name, 64);
- /* Look for named resource file in runtimepath */
+ // Look for named resource file in runtimepath
STRCPY(buffer, "print");
add_pathsep((char *)buffer);
xstrlcat((char *)buffer, name, MAXPATHL);
@@ -1548,7 +1553,7 @@ static int prt_find_resource(char *name, struct prt_ps_resource_S *resource)
return retval;
}
-/* PS CR and LF characters have platform independent values */
+// PS CR and LF characters have platform independent values
#define PSLF (0x0a)
#define PSCR (0x0d)
@@ -1558,7 +1563,7 @@ static int prt_resfile_next_line(void)
{
int idx;
- /* Move to start of next line and then find end of line */
+ // Move to start of next line and then find end of line
idx = prt_resfile.line_end + 1;
while (idx < prt_resfile.len) {
if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR)
@@ -1577,12 +1582,13 @@ static int prt_resfile_next_line(void)
return idx < prt_resfile.len;
}
-static int prt_resfile_strncmp(int offset, char *string, int len)
+static int prt_resfile_strncmp(int offset, const char *string, int len)
+ FUNC_ATTR_NONNULL_ALL
{
- /* Force not equal if string is longer than remainder of line */
- if (len > (prt_resfile.line_end - (prt_resfile.line_start + offset)))
+ // Force not equal if string is longer than remainder of line
+ if (len > (prt_resfile.line_end - (prt_resfile.line_start + offset))) {
return 1;
-
+ }
return STRNCMP(&prt_resfile.buffer[prt_resfile.line_start + offset],
string, len);
}
@@ -1615,178 +1621,182 @@ static int prt_resfile_skip_ws(int offset)
/* prt_next_dsc() - returns detail on next DSC comment line found. Returns true
* if a DSC comment is found, else false */
-static int prt_next_dsc(struct prt_dsc_line_S *p_dsc_line)
+static bool prt_next_dsc(struct prt_dsc_line_S *p_dsc_line)
+ FUNC_ATTR_NONNULL_ALL
{
int comment;
int offset;
- /* Move to start of next line */
- if (!prt_resfile_next_line())
- return FALSE;
-
- /* DSC comments always start %% */
- if (prt_resfile_strncmp(0, "%%", 2) != 0)
- return FALSE;
-
- /* Find type of DSC comment */
- for (comment = 0; comment < (int)ARRAY_SIZE(prt_dsc_table); comment++)
+ // Move to start of next line
+ if (!prt_resfile_next_line()) {
+ return false;
+ }
+ // DSC comments always start %%
+ if (prt_resfile_strncmp(0, "%%", 2) != 0) {
+ return false;
+ }
+ // Find type of DSC comment
+ for (comment = 0; comment < (int)ARRAY_SIZE(prt_dsc_table); comment++) {
if (prt_resfile_strncmp(0, prt_dsc_table[comment].string,
- prt_dsc_table[comment].len) == 0)
+ prt_dsc_table[comment].len) == 0) {
break;
-
+ }
+ }
if (comment != ARRAY_SIZE(prt_dsc_table)) {
- /* Return type of comment */
+ // Return type of comment
p_dsc_line->type = prt_dsc_table[comment].type;
offset = prt_dsc_table[comment].len;
} else {
- /* Unrecognised DSC comment, skip to ws after comment leader */
+ // Unrecognised DSC comment, skip to ws after comment leader
p_dsc_line->type = PRT_DSC_MISC_TYPE;
offset = prt_resfile_skip_nonws(0);
- if (offset == -1)
- return FALSE;
+ if (offset == -1) {
+ return false;
+ }
}
- /* Skip ws to comment value */
+ // Skip ws to comment value
offset = prt_resfile_skip_ws(offset);
- if (offset == -1)
- return FALSE;
-
+ if (offset == -1) {
+ return false;
+ }
p_dsc_line->string = &prt_resfile.buffer[prt_resfile.line_start + offset];
p_dsc_line->len = prt_resfile.line_end - (prt_resfile.line_start + offset);
- return TRUE;
+ return true;
}
/* Improved hand crafted parser to get the type, title, and version number of a
* PS resource file so the file details can be added to the DSC header comments.
*/
-static int prt_open_resource(struct prt_ps_resource_S *resource)
+static bool prt_open_resource(struct prt_ps_resource_S *resource)
+ FUNC_ATTR_NONNULL_ALL
{
- int offset;
- int seen_all;
- int seen_title;
- int seen_version;
- FILE *fd_resource;
struct prt_dsc_line_S dsc_line;
- fd_resource = os_fopen((char *)resource->filename, READBIN);
+ FILE *fd_resource = os_fopen((char *)resource->filename, READBIN);
if (fd_resource == NULL) {
EMSG2(_("E624: Can't open file \"%s\""), resource->filename);
- return FALSE;
+ return false;
}
memset(prt_resfile.buffer, NUL, PRT_FILE_BUFFER_LEN);
- /* Parse first line to ensure valid resource file */
+ // Parse first line to ensure valid resource file
prt_resfile.len = (int)fread((char *)prt_resfile.buffer, sizeof(char_u),
PRT_FILE_BUFFER_LEN, fd_resource);
if (ferror(fd_resource)) {
EMSG2(_("E457: Can't read PostScript resource file \"%s\""),
resource->filename);
fclose(fd_resource);
- return FALSE;
+ return false;
}
fclose(fd_resource);
prt_resfile.line_end = -1;
prt_resfile.line_start = 0;
- if (!prt_resfile_next_line())
- return FALSE;
-
- offset = 0;
+ if (!prt_resfile_next_line()) {
+ return false;
+ }
+ int offset = 0;
if (prt_resfile_strncmp(offset, PRT_RESOURCE_HEADER,
(int)STRLEN(PRT_RESOURCE_HEADER)) != 0) {
EMSG2(_("E618: file \"%s\" is not a PostScript resource file"),
- resource->filename);
- return FALSE;
+ resource->filename);
+ return false;
}
- /* Skip over any version numbers and following ws */
+ // Skip over any version numbers and following ws
offset += (int)STRLEN(PRT_RESOURCE_HEADER);
offset = prt_resfile_skip_nonws(offset);
- if (offset == -1)
- return FALSE;
+ if (offset == -1) {
+ return false;
+ }
offset = prt_resfile_skip_ws(offset);
- if (offset == -1)
- return FALSE;
-
+ if (offset == -1) {
+ return false;
+ }
if (prt_resfile_strncmp(offset, PRT_RESOURCE_RESOURCE,
(int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) {
EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
- resource->filename);
- return FALSE;
+ resource->filename);
+ return false;
}
offset += (int)STRLEN(PRT_RESOURCE_RESOURCE);
- /* Decide type of resource in the file */
+ // Decide type of resource in the file
if (prt_resfile_strncmp(offset, PRT_RESOURCE_PROCSET,
- (int)STRLEN(PRT_RESOURCE_PROCSET)) == 0)
+ (int)STRLEN(PRT_RESOURCE_PROCSET)) == 0) {
resource->type = PRT_RESOURCE_TYPE_PROCSET;
- else if (prt_resfile_strncmp(offset, PRT_RESOURCE_ENCODING,
- (int)STRLEN(PRT_RESOURCE_ENCODING)) == 0)
+ } else if (prt_resfile_strncmp(offset, PRT_RESOURCE_ENCODING,
+ (int)STRLEN(PRT_RESOURCE_ENCODING)) == 0) {
resource->type = PRT_RESOURCE_TYPE_ENCODING;
- else if (prt_resfile_strncmp(offset, PRT_RESOURCE_CMAP,
- (int)STRLEN(PRT_RESOURCE_CMAP)) == 0)
+ } else if (prt_resfile_strncmp(offset, PRT_RESOURCE_CMAP,
+ (int)STRLEN(PRT_RESOURCE_CMAP)) == 0) {
resource->type = PRT_RESOURCE_TYPE_CMAP;
- else {
+ } else {
EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
- resource->filename);
- return FALSE;
+ resource->filename);
+ return false;
}
- /* Look for title and version of resource */
+ // Look for title and version of resource
resource->title[0] = '\0';
resource->version[0] = '\0';
- seen_title = FALSE;
- seen_version = FALSE;
- seen_all = FALSE;
+ bool seen_title = false;
+ bool seen_version = false;
+ bool seen_all = false;
while (!seen_all && prt_next_dsc(&dsc_line)) {
switch (dsc_line.type) {
case PRT_DSC_TITLE_TYPE:
STRLCPY(resource->title, dsc_line.string, dsc_line.len + 1);
- seen_title = TRUE;
- if (seen_version)
- seen_all = TRUE;
+ seen_title = true;
+ if (seen_version) {
+ seen_all = true;
+ }
break;
case PRT_DSC_VERSION_TYPE:
STRLCPY(resource->version, dsc_line.string, dsc_line.len + 1);
- seen_version = TRUE;
- if (seen_title)
- seen_all = TRUE;
+ seen_version = true;
+ if (seen_title) {
+ seen_all = true;
+ }
break;
case PRT_DSC_ENDCOMMENTS_TYPE:
- /* Wont find title or resource after this comment, stop searching */
- seen_all = TRUE;
+ // Wont find title or resource after this comment, stop searching
+ seen_all = true;
break;
case PRT_DSC_MISC_TYPE:
- /* Not interested in whatever comment this line had */
+ // Not interested in whatever comment this line had
break;
}
}
if (!seen_title || !seen_version) {
EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"),
- resource->filename);
- return FALSE;
+ resource->filename);
+ return false;
}
- return TRUE;
+ return true;
}
-static int prt_check_resource(struct prt_ps_resource_S *resource, char_u *version)
+static bool prt_check_resource(const struct prt_ps_resource_S *resource,
+ const char_u *version)
+ FUNC_ATTR_NONNULL_ALL
{
- /* Version number m.n should match, the revision number does not matter */
+ // Version number m.n should match, the revision number does not matter
if (STRNCMP(resource->version, version, STRLEN(version))) {
EMSG2(_("E621: \"%s\" resource file has wrong version"),
- resource->name);
- return FALSE;
+ resource->name);
+ return false;
}
- /* Other checks to be added as needed */
- return TRUE;
+ // Other checks to be added as needed
+ return true;
}
static void prt_dsc_start(void)
@@ -1810,7 +1820,7 @@ static void prt_dsc_textline(char *comment, char *text)
static void prt_dsc_text(char *comment, char *text)
{
- /* TODO - should scan 'text' for any chars needing escaping! */
+ // TODO(vim): - should scan 'text' for any chars needing escaping!
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
"%%%%%s: (%s)\n", comment, text);
prt_write_file(prt_line_buffer);
@@ -1834,9 +1844,8 @@ static void prt_dsc_ints(char *comment, int count, int *ints)
prt_write_string("\n");
}
-static void
-prt_dsc_resources (
- char *comment, /* if NULL add to previous */
+static void prt_dsc_resources(
+ char *comment, // if NULL add to previous
char *type,
char *string
)
@@ -1887,8 +1896,9 @@ static void prt_dsc_requirements(int duplex, int tumble, int collate, int color,
prt_write_string(" color");
if (num_copies > 1) {
prt_write_string(" numcopies(");
- /* Note: no space wanted so don't use prt_write_int() */
- sprintf((char *)prt_line_buffer, "%d", num_copies);
+ // Note: no space wanted so don't use prt_write_int()
+ snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%d",
+ num_copies);
prt_write_file(prt_line_buffer);
prt_write_string(")");
}
@@ -2038,13 +2048,13 @@ static int prt_get_lpp(void)
prt_ps_font->bbox_min_y)) / 2);
}
- /* Get height for topmost line based on background rect offset. */
+ // Get height for topmost line based on background rect offset.
prt_first_line_height = prt_line_height + prt_bgcol_offset;
- /* Calculate lpp */
+ // Calculate lpp
lpp = (int)((prt_top_margin - prt_bottom_margin) / prt_line_height);
- /* Adjust top margin if there is a header */
+ // Adjust top margin if there is a header
prt_top_margin -= prt_line_height * prt_header_height();
return lpp - prt_header_height();
@@ -2057,7 +2067,7 @@ static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap,
struct prt_ps_encoding_S *p_mbenc;
*pp_mbenc = NULL;
- /* Look for recognised encoding */
+ // Look for recognised encoding
enc_len = (int)STRLEN(p_encoding);
p_mbenc = p_cmap->encodings;
for (mbenc = 0; mbenc < p_cmap->num_encodings; mbenc++) {
@@ -2076,9 +2086,10 @@ static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, st
int char_len;
struct prt_ps_charset_S *p_mbchar;
- /* Look for recognised character set, using default if one is not given */
- if (*p_charset == NUL)
+ // Look for recognised character set, using default if one is not given
+ if (*p_charset == NUL) {
p_charset = p_cmap->defcs;
+ }
char_len = (int)STRLEN(p_charset);
p_mbchar = p_cmap->charsets;
for (mbchar = 0; mbchar < p_cmap->num_charsets; mbchar++) {
@@ -2133,7 +2144,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
break;
}
- /* Use first encoding matched if no charset matched */
+ // Use first encoding matched if no charset matched
if (p_mbenc_first != NULL && p_mbchar == NULL) {
p_mbenc = p_mbenc_first;
cmap = effective_cmap;
@@ -2144,24 +2155,24 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
prt_out_mbyte = (p_mbenc != NULL);
if (prt_out_mbyte) {
- /* Build CMap name - will be same for all multi-byte fonts used */
+ // Build CMap name - will be same for all multi-byte fonts used
prt_cmap[0] = NUL;
prt_custom_cmap = (p_mbchar == NULL);
if (!prt_custom_cmap) {
- /* Check encoding and character set are compatible */
+ // Check encoding and character set are compatible
if ((p_mbenc->needs_charset & p_mbchar->has_charset) == 0) {
EMSG(_("E673: Incompatible multi-byte encoding and character set."));
return FALSE;
}
- /* Add charset name if not empty */
+ // Add charset name if not empty
if (p_mbchar->cmap_charset != NULL) {
STRLCPY(prt_cmap, p_mbchar->cmap_charset, sizeof(prt_cmap) - 2);
STRCAT(prt_cmap, "-");
}
} else {
- /* Add custom CMap character set name */
+ // Add custom CMap character set name
if (*p_pmcs == NUL) {
EMSG(_("E674: printmbcharset cannot be empty with multi-byte encoding."));
return FALSE;
@@ -2170,7 +2181,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
STRCAT(prt_cmap, "-");
}
- /* CMap name ends with (optional) encoding name and -H for horizontal */
+ // CMap name ends with (optional) encoding name and -H for horizontal
if (p_mbenc->cmap_encoding != NULL && STRLEN(prt_cmap)
+ STRLEN(p_mbenc->cmap_encoding) + 3 < sizeof(prt_cmap)) {
STRCAT(prt_cmap, p_mbenc->cmap_encoding);
@@ -2183,7 +2194,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
return FALSE;
}
- /* Derive CID font names with fallbacks if not defined */
+ // Derive CID font names with fallbacks if not defined
prt_build_cid_fontname(PRT_PS_FONT_ROMAN,
mbfont_opts[OPT_MBFONT_REGULAR].string,
mbfont_opts[OPT_MBFONT_REGULAR].strlen);
@@ -2288,9 +2299,10 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
psettings->chars_per_line = prt_get_cpl();
psettings->lines_per_page = prt_get_lpp();
- /* Catch margin settings that leave no space for output! */
- if (psettings->chars_per_line <= 0 || psettings->lines_per_page <= 0)
+ // Catch margin settings that leave no space for output!
+ if (psettings->chars_per_line <= 0 || psettings->lines_per_page <= 0) {
return FAIL;
+ }
/*
* Sort out the number of copies to be printed. PS by default will do
@@ -2329,10 +2341,10 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
prt_tumble = TRUE;
}
- /* For now user abort not supported */
+ // For now user abort not supported
psettings->user_abort = 0;
- /* If the user didn't specify a file name, use a temp file. */
+ // If the user didn't specify a file name, use a temp file.
if (psettings->outfile == NULL) {
prt_ps_file_name = vim_tempname();
if (prt_ps_file_name == NULL) {
@@ -2360,12 +2372,12 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
prt_page_num = 0;
- prt_attribute_change = FALSE;
- prt_need_moveto = FALSE;
- prt_need_font = FALSE;
- prt_need_fgcol = FALSE;
- prt_need_bgcol = FALSE;
- prt_need_underline = FALSE;
+ prt_attribute_change = false;
+ prt_need_moveto = false;
+ prt_need_font = false;
+ prt_need_fgcol = false;
+ prt_need_bgcol = false;
+ prt_need_underline = false;
prt_file_error = FALSE;
@@ -2416,9 +2428,7 @@ static int prt_add_resource(struct prt_ps_resource_S *resource)
int mch_print_begin(prt_settings_T *psettings)
{
- time_t now;
int bbox[4];
- char *p_time;
double left;
double right;
double top;
@@ -2442,10 +2452,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
prt_dsc_textline("For", buffer);
prt_dsc_textline("Creator", longVersion);
- /* Note: to ensure Clean8bit I don't think we can use LC_TIME */
- now = time(NULL);
- p_time = ctime(&now);
- /* Note: ctime() adds a \n so we have to remove it :-( */
+ // Note: to ensure Clean8bit I don't think we can use LC_TIME
+ char ctime_buf[50];
+ char *p_time = os_ctime(ctime_buf, sizeof(ctime_buf));
+ // Note: os_ctime() adds a \n so we have to remove it :-(
p = vim_strchr((char_u *)p_time, '\n');
if (p != NULL)
*p = NUL;
@@ -2483,14 +2493,15 @@ int mch_print_begin(prt_settings_T *psettings)
+ 0.5);
}
prt_dsc_ints("BoundingBox", 4, bbox);
- /* The media width and height does not change with landscape printing! */
+ // The media width and height does not change with landscape printing!
prt_dsc_docmedia(prt_mediasize[prt_media].name,
- prt_mediasize[prt_media].width,
- prt_mediasize[prt_media].height,
- (double)0, NULL, NULL);
- /* Define fonts needed */
- if (!prt_out_mbyte || prt_use_courier)
+ prt_mediasize[prt_media].width,
+ prt_mediasize[prt_media].height,
+ (double)0, NULL, NULL);
+ // Define fonts needed
+ if (!prt_out_mbyte || prt_use_courier) {
prt_dsc_font_resource("DocumentNeededResources", &prt_ps_courier_font);
+ }
if (prt_out_mbyte) {
prt_dsc_font_resource((prt_use_courier ? NULL
: "DocumentNeededResources"), &prt_ps_mb_font);
@@ -2498,7 +2509,7 @@ int mch_print_begin(prt_settings_T *psettings)
prt_dsc_resources(NULL, "cmap", prt_cmap);
}
- /* Search for external resources VIM supplies */
+ // Search for external resources VIM supplies
if (!prt_find_resource("prolog", &res_prolog)) {
EMSG(_("E456: Can't find PostScript resource file \"prolog.ps\""));
return FALSE;
@@ -2508,7 +2519,7 @@ int mch_print_begin(prt_settings_T *psettings)
if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION))
return FALSE;
if (prt_out_mbyte) {
- /* Look for required version of multi-byte printing procset */
+ // Look for required version of multi-byte printing procset
if (!prt_find_resource("cidfont", &res_cidfont)) {
EMSG(_("E456: Can't find PostScript resource file \"cidfont.ps\""));
return FALSE;
@@ -2528,15 +2539,15 @@ int mch_print_begin(prt_settings_T *psettings)
p_encoding = enc_skip(p_penc);
if (*p_encoding == NUL
|| !prt_find_resource((char *)p_encoding, &res_encoding)) {
- /* 'printencoding' not set or not supported - find alternate */
+ // 'printencoding' not set or not supported - find alternate
int props;
p_encoding = enc_skip(p_enc);
props = enc_canon_props(p_encoding);
if (!(props & ENC_8BIT)
|| !prt_find_resource((char *)p_encoding, &res_encoding)) {
- /* 8-bit 'encoding' is not supported */
- /* Use latin1 as default printing encoding */
+ // 8-bit 'encoding' is not supported
+ // Use latin1 as default printing encoding
p_encoding = (char_u *)"latin1";
if (!prt_find_resource((char *)p_encoding, &res_encoding)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
@@ -2554,7 +2565,7 @@ int mch_print_begin(prt_settings_T *psettings)
if (*p_encoding == NUL)
p_encoding = enc_skip(p_enc);
if (prt_use_courier) {
- /* Include ASCII range encoding vector */
+ // Include ASCII range encoding vector
if (!prt_find_resource(prt_ascii_encoding, &res_encoding)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
prt_ascii_encoding);
@@ -2579,7 +2590,7 @@ int mch_print_begin(prt_settings_T *psettings)
prt_do_conv = prt_conv.vc_type != CONV_NONE;
if (prt_out_mbyte && prt_custom_cmap) {
- /* Find user supplied CMap */
+ // Find user supplied CMap
if (!prt_find_resource(prt_cmap, &res_cmap)) {
EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""),
prt_cmap);
@@ -2589,7 +2600,7 @@ int mch_print_begin(prt_settings_T *psettings)
return FALSE;
}
- /* List resources supplied */
+ // List resources supplied
STRCPY(buffer, res_prolog.title);
STRCAT(buffer, " ");
STRCAT(buffer, res_prolog.version);
@@ -2623,9 +2634,10 @@ int mch_print_begin(prt_settings_T *psettings)
*/
prt_dsc_noarg("BeginDefaults");
- /* List font resources most likely common to all pages */
- if (!prt_out_mbyte || prt_use_courier)
+ // List font resources most likely common to all pages
+ if (!prt_out_mbyte || prt_use_courier) {
prt_dsc_font_resource("PageResources", &prt_ps_courier_font);
+ }
if (prt_out_mbyte) {
prt_dsc_font_resource((prt_use_courier ? NULL : "PageResources"),
&prt_ps_mb_font);
@@ -2633,7 +2645,7 @@ int mch_print_begin(prt_settings_T *psettings)
prt_dsc_resources(NULL, "cmap", prt_cmap);
}
- /* Paper will be used for all pages */
+ // Paper will be used for all pages
prt_dsc_textline("PageMedia", prt_mediasize[prt_media].name);
prt_dsc_noarg("EndDefaults");
@@ -2643,15 +2655,18 @@ int mch_print_begin(prt_settings_T *psettings)
*/
prt_dsc_noarg("BeginProlog");
- /* Add required procsets - NOTE: order is important! */
- if (!prt_add_resource(&res_prolog))
- return FALSE;
+ // Add required procsets - NOTE: order is important!
+ if (!prt_add_resource(&res_prolog)) {
+ return false;
+ }
if (prt_out_mbyte) {
- /* Add CID font procset, and any user supplied CMap */
- if (!prt_add_resource(&res_cidfont))
- return FALSE;
- if (prt_custom_cmap && !prt_add_resource(&res_cmap))
- return FALSE;
+ // Add CID font procset, and any user supplied CMap
+ if (!prt_add_resource(&res_cidfont)) {
+ return false;
+ }
+ if (prt_custom_cmap && !prt_add_resource(&res_cmap)) {
+ return false;
+ }
}
if (!prt_out_mbyte || prt_use_courier)
@@ -2667,7 +2682,7 @@ int mch_print_begin(prt_settings_T *psettings)
*/
prt_dsc_noarg("BeginSetup");
- /* Device setup - page size and number of uncollated copies */
+ // Device setup - page size and number of uncollated copies
prt_write_int((int)prt_mediasize[prt_media].width);
prt_write_int((int)prt_mediasize[prt_media].height);
prt_write_int(0);
@@ -2680,7 +2695,7 @@ int mch_print_begin(prt_settings_T *psettings)
prt_write_boolean(prt_collate);
prt_write_string("c\n");
- /* Font resource inclusion and definition */
+ // Font resource inclusion and definition
if (!prt_out_mbyte || prt_use_courier) {
/* When using Courier for ASCII range when printing multi-byte, need to
* pick up ASCII encoding to use with it. */
@@ -2723,35 +2738,36 @@ int mch_print_begin(prt_settings_T *psettings)
if (!prt_custom_cmap)
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
prt_def_cidfont("CF1", (int)prt_line_height,
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
- } else
- /* Use ROMAN for BOLD */
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]);
+ } else {
+ // Use ROMAN for BOLD
prt_dup_cidfont("CF0", "CF1");
-
+ }
if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE] != NULL) {
prt_dsc_resources("IncludeResource", "font",
prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
if (!prt_custom_cmap)
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
prt_def_cidfont("CF2", (int)prt_line_height,
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
- } else
- /* Use ROMAN for OBLIQUE */
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]);
+ } else {
+ // Use ROMAN for OBLIQUE
prt_dup_cidfont("CF0", "CF2");
-
+ }
if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE] != NULL) {
prt_dsc_resources("IncludeResource", "font",
prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
if (!prt_custom_cmap)
prt_dsc_resources("IncludeResource", "cmap", prt_cmap);
prt_def_cidfont("CF3", (int)prt_line_height,
- prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
- } else
- /* Use BOLD for BOLDOBLIQUE */
+ prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]);
+ } else {
+ // Use BOLD for BOLDOBLIQUE
prt_dup_cidfont("CF1", "CF3");
+ }
}
- /* Misc constant vars used for underlining and background rects */
+ // Misc constant vars used for underlining and background rects
prt_def_var("UO", PRT_PS_FONT_TO_USER(prt_line_height,
prt_ps_font->uline_offset), 2);
prt_def_var("UW", PRT_PS_FONT_TO_USER(prt_line_height,
@@ -2760,7 +2776,7 @@ int mch_print_begin(prt_settings_T *psettings)
prt_dsc_noarg("EndSetup");
- /* Fail if any problems writing out to the PS file */
+ // Fail if any problems writing out to the PS file
retval = !prt_file_error;
return retval;
@@ -2783,7 +2799,7 @@ void mch_print_end(prt_settings_T *psettings)
if (!prt_file_error && psettings->outfile == NULL
&& !got_int && !psettings->user_abort) {
- /* Close the file first. */
+ // Close the file first.
if (prt_ps_fd != NULL) {
fclose(prt_ps_fd);
prt_ps_fd = NULL;
@@ -2834,7 +2850,7 @@ int mch_print_begin_page(char_u *str)
prt_bgcol = PRCOLOR_WHITE;
prt_font = PRT_PS_FONT_ROMAN;
- /* Set up page transformation for landscape printing. */
+ // Set up page transformation for landscape printing.
if (!prt_portrait) {
prt_write_int(-((int)prt_mediasize[prt_media].width));
prt_write_string("sl\n");
@@ -2842,7 +2858,7 @@ int mch_print_begin_page(char_u *str)
prt_dsc_noarg("EndPageSetup");
- /* We have reset the font attributes, force setting them again. */
+ // We have reset the font attributes, force setting them again.
curr_bg = 0xffffffff;
curr_fg = 0xffffffff;
curr_bold = kNone;
@@ -2868,9 +2884,9 @@ void mch_print_start_line(const bool margin, const int page_line)
prt_pos_y = prt_top_margin - prt_first_line_height -
page_line * prt_line_height;
- prt_attribute_change = TRUE;
- prt_need_moveto = TRUE;
- prt_half_width = FALSE;
+ prt_attribute_change = true;
+ prt_need_moveto = true;
+ prt_half_width = false;
}
int mch_print_text_out(char_u *const textp, size_t len)
@@ -2892,16 +2908,16 @@ int mch_print_text_out(char_u *const textp, size_t len)
const bool in_ascii = (len == 1 && *p < 0x80);
if (prt_in_ascii) {
if (!in_ascii) {
- /* No longer in ASCII range - need to switch font */
- prt_in_ascii = FALSE;
- prt_need_font = TRUE;
- prt_attribute_change = TRUE;
+ // No longer in ASCII range - need to switch font
+ prt_in_ascii = false;
+ prt_need_font = true;
+ prt_attribute_change = true;
}
} else if (in_ascii) {
- /* Now in ASCII range - need to switch font */
- prt_in_ascii = TRUE;
- prt_need_font = TRUE;
- prt_attribute_change = TRUE;
+ // Now in ASCII range - need to switch font
+ prt_in_ascii = true;
+ prt_need_font = true;
+ prt_attribute_change = true;
}
}
if (prt_out_mbyte) {
@@ -2911,16 +2927,16 @@ int mch_print_text_out(char_u *const textp, size_t len)
}
if (prt_half_width) {
if (!half_width) {
- prt_half_width = FALSE;
+ prt_half_width = false;
prt_pos_x += prt_char_width/4;
- prt_need_moveto = TRUE;
- prt_attribute_change = TRUE;
+ prt_need_moveto = true;
+ prt_attribute_change = true;
}
} else if (half_width) {
- prt_half_width = TRUE;
+ prt_half_width = true;
prt_pos_x += prt_char_width/4;
- prt_need_moveto = TRUE;
- prt_attribute_change = TRUE;
+ prt_need_moveto = true;
+ prt_attribute_change = true;
}
}
@@ -2929,24 +2945,25 @@ int mch_print_text_out(char_u *const textp, size_t len)
*/
if (prt_attribute_change) {
prt_flush_buffer();
- /* Reset count of number of chars that will be printed */
+ // Reset count of number of chars that will be printed
prt_text_run = 0;
if (prt_need_moveto) {
prt_pos_x_moveto = prt_pos_x;
prt_pos_y_moveto = prt_pos_y;
- prt_do_moveto = TRUE;
+ prt_do_moveto = true;
- prt_need_moveto = FALSE;
+ prt_need_moveto = false;
}
if (prt_need_font) {
- if (!prt_in_ascii)
+ if (!prt_in_ascii) {
prt_write_string("CF");
- else
+ } else {
prt_write_string("F");
+ }
prt_write_int(prt_font);
prt_write_string("sf\n");
- prt_need_font = FALSE;
+ prt_need_font = false;
}
if (prt_need_fgcol) {
unsigned int r, g, b;
@@ -2962,22 +2979,24 @@ int mch_print_text_out(char_u *const textp, size_t len)
prt_write_real(b / 255.0, 3);
prt_write_string("r\n");
}
- prt_need_fgcol = FALSE;
+ prt_need_fgcol = false;
}
if (prt_bgcol != PRCOLOR_WHITE) {
prt_new_bgcol = prt_bgcol;
- if (prt_need_bgcol)
- prt_do_bgcol = TRUE;
- } else
- prt_do_bgcol = FALSE;
- prt_need_bgcol = FALSE;
+ if (prt_need_bgcol) {
+ prt_do_bgcol = true;
+ }
+ } else {
+ prt_do_bgcol = false;
+ }
+ prt_need_bgcol = false;
if (prt_need_underline)
prt_do_underline = prt_underline;
- prt_need_underline = FALSE;
+ prt_need_underline = false;
- prt_attribute_change = FALSE;
+ prt_attribute_change = false;
}
if (prt_do_conv) {
@@ -3062,29 +3081,29 @@ void mch_print_set_font(const TriState iBold, const TriState iItalic,
if (font != prt_font) {
prt_font = font;
- prt_attribute_change = TRUE;
- prt_need_font = TRUE;
+ prt_attribute_change = true;
+ prt_need_font = true;
}
if (prt_underline != iUnderline) {
prt_underline = iUnderline;
- prt_attribute_change = TRUE;
- prt_need_underline = TRUE;
+ prt_attribute_change = true;
+ prt_need_underline = true;
}
}
void mch_print_set_bg(uint32_t bgcol)
{
prt_bgcol = bgcol;
- prt_attribute_change = TRUE;
- prt_need_bgcol = TRUE;
+ prt_attribute_change = true;
+ prt_need_bgcol = true;
}
void mch_print_set_fg(uint32_t fgcol)
{
if (fgcol != prt_fgcol) {
prt_fgcol = fgcol;
- prt_attribute_change = TRUE;
- prt_need_fgcol = TRUE;
+ prt_attribute_change = true;
+ prt_need_fgcol = true;
}
}
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index 0f9984ec38..2af09f10cb 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.c
@@ -71,10 +71,10 @@ static void cs_usage_msg(csid_e x)
static enum {
- EXP_CSCOPE_SUBCMD, /* expand ":cscope" sub-commands */
- EXP_SCSCOPE_SUBCMD, /* expand ":scscope" sub-commands */
- EXP_CSCOPE_FIND, /* expand ":cscope find" arguments */
- EXP_CSCOPE_KILL /* expand ":cscope kill" arguments */
+ EXP_CSCOPE_SUBCMD, // expand ":cscope" sub-commands
+ EXP_SCSCOPE_SUBCMD, // expand ":scscope" sub-commands
+ EXP_CSCOPE_FIND, // expand ":cscope find" arguments
+ EXP_CSCOPE_KILL // expand ":cscope kill" arguments
} expand_what;
/*
@@ -87,13 +87,13 @@ char_u *get_cscope_name(expand_T *xp, int idx)
switch (expand_what) {
case EXP_CSCOPE_SUBCMD:
- /* Complete with sub-commands of ":cscope":
- * add, find, help, kill, reset, show */
+ // Complete with sub-commands of ":cscope":
+ // add, find, help, kill, reset, show
return (char_u *)cs_cmds[idx].name;
case EXP_SCSCOPE_SUBCMD:
{
- /* Complete with sub-commands of ":scscope": same sub-commands as
- * ":cscope" but skip commands which don't support split windows */
+ // Complete with sub-commands of ":scscope": same sub-commands as
+ // ":cscope" but skip commands which don't support split windows
int i;
for (i = 0, current_idx = 0; cs_cmds[i].name != NULL; i++)
if (cs_cmds[i].cansplit)
@@ -118,10 +118,10 @@ char_u *get_cscope_name(expand_T *xp, int idx)
{
static char connection[5];
- /* ":cscope kill" accepts connection numbers or partial names of
- * the pathname of the cscope database as argument. Only complete
- * with connection numbers. -1 can also be used to kill all
- * connections. */
+ // ":cscope kill" accepts connection numbers or partial names of
+ // the pathname of the cscope database as argument. Only complete
+ // with connection numbers. -1 can also be used to kill all
+ // connections.
size_t i;
for (i = 0, current_idx = 0; i < csinfo_size; i++) {
if (csinfo[i].fname == NULL)
@@ -149,7 +149,7 @@ void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
expand_what = ((cmdidx == CMD_scscope)
? EXP_SCSCOPE_SUBCMD : EXP_CSCOPE_SUBCMD);
- /* (part of) subcommand already typed */
+ // (part of) subcommand already typed
if (*arg != NUL) {
const char *p = (const char *)skiptowhite((const char_u *)arg);
if (*p != NUL) { // Past first word.
@@ -175,7 +175,7 @@ void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
static void
do_cscope_general(
exarg_T *eap,
- int make_split /* whether to split window */
+ int make_split // whether to split window
)
{
cscmd_T *cmdp;
@@ -276,17 +276,19 @@ void ex_cstag(exarg_T *eap)
/// This simulates a vim_fgets(), but for cscope, returns the next line
/// from the cscope output. should only be called from find_tags()
///
-/// @return TRUE if eof, FALSE otherwise
-int cs_fgets(char_u *buf, int size)
+/// @return true if eof, FALSE otherwise
+bool cs_fgets(char_u *buf, int size)
+ FUNC_ATTR_NONNULL_ALL
{
char *p;
- if ((p = cs_manage_matches(NULL, NULL, 0, Get)) == NULL)
+ if ((p = cs_manage_matches(NULL, NULL, 0, Get)) == NULL) {
return true;
+ }
STRLCPY(buf, p, size);
- return FALSE;
-} /* cs_fgets */
+ return false;
+}
/// Called only from do_tag(), when popping the tag stack.
@@ -328,48 +330,53 @@ void cs_print_tags(void)
*
* Note: All string comparisons are case sensitive!
*/
-int cs_connection(int num, char_u *dbpath, char_u *ppath)
+bool cs_connection(int num, char_u *dbpath, char_u *ppath)
{
- if (num < 0 || num > 4 || (num > 0 && !dbpath))
+ if (num < 0 || num > 4 || (num > 0 && !dbpath)) {
return false;
+ }
for (size_t i = 0; i < csinfo_size; i++) {
- if (!csinfo[i].fname)
+ if (!csinfo[i].fname) {
continue;
-
- if (num == 0)
- return TRUE;
-
+ }
+ if (num == 0) {
+ return true;
+ }
switch (num) {
case 1:
- if (strstr(csinfo[i].fname, (char *)dbpath))
- return TRUE;
+ if (strstr(csinfo[i].fname, (char *)dbpath)) {
+ return true;
+ }
break;
case 2:
- if (strcmp(csinfo[i].fname, (char *)dbpath) == 0)
- return TRUE;
+ if (strcmp(csinfo[i].fname, (char *)dbpath) == 0) {
+ return true;
+ }
break;
case 3:
if (strstr(csinfo[i].fname, (char *)dbpath)
&& ((!ppath && !csinfo[i].ppath)
|| (ppath
&& csinfo[i].ppath
- && strstr(csinfo[i].ppath, (char *)ppath))))
- return TRUE;
+ && strstr(csinfo[i].ppath, (char *)ppath)))) {
+ return true;
+ }
break;
case 4:
if ((strcmp(csinfo[i].fname, (char *)dbpath) == 0)
&& ((!ppath && !csinfo[i].ppath)
|| (ppath
&& csinfo[i].ppath
- && (strcmp(csinfo[i].ppath, (char *)ppath) == 0))))
- return TRUE;
+ && (strcmp(csinfo[i].ppath, (char *)ppath) == 0)))) {
+ return true;
+ }
break;
}
}
- return FALSE;
-} /* cs_connection */
+ return false;
+} // cs_connection
/*
@@ -419,7 +426,7 @@ cs_add_common(
size_t usedlen = 0;
char_u *fbuf = NULL;
- /* get the filename (arg1), expand it, and try to stat it */
+ // get the filename (arg1), expand it, and try to stat it
fname = xmalloc(MAXPATHL + 1);
expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL);
@@ -451,7 +458,7 @@ staterr:
}
int i;
- /* if filename is a directory, append the cscope database name to it */
+ // if filename is a directory, append the cscope database name to it
if ((file_info.stat.st_mode & S_IFMT) == S_IFDIR) {
fname2 = (char *)xmalloc(strlen(CSCOPE_DBFILE) + strlen(fname) + 2);
@@ -512,18 +519,18 @@ add_err:
xfree(fname);
xfree(ppath);
return CSCOPE_FAILURE;
-} /* cs_add_common */
+}
static int cs_check_for_connections(void)
{
return cs_cnt_connections() > 0;
-} /* cs_check_for_connections */
+}
static int cs_check_for_tags(void)
{
return p_tags[0] != NUL && curbuf->b_p_tags != NULL;
-} /* cs_check_for_tags */
+}
/// Count the number of cscope connections.
static size_t cs_cnt_connections(void)
@@ -535,10 +542,10 @@ static size_t cs_cnt_connections(void)
cnt++;
}
return cnt;
-} /* cs_cnt_connections */
+}
static void cs_reading_emsg(
- size_t idx /* connection index */
+ size_t idx // connection index
)
{
EMSGU(_("E262: error reading cscope connection %" PRIu64), idx);
@@ -602,7 +609,7 @@ static int cs_cnt_matches(size_t idx)
xfree(buf);
return nlines;
-} /* cs_cnt_matches */
+}
/// Creates the actual cscope command query from what the user entered.
@@ -646,8 +653,8 @@ static char *cs_create_cmd(char *csoption, char *pattern)
return NULL;
}
- /* Skip white space before the patter, except for text and pattern search,
- * they may want to use the leading white space. */
+ // Skip white space before the patter, except for text and pattern search,
+ // they may want to use the leading white space.
pat = pattern;
if (search != 4 && search != 6)
while (ascii_iswhite(*pat))
@@ -658,7 +665,7 @@ static char *cs_create_cmd(char *csoption, char *pattern)
(void)sprintf(cmd, "%d%s", search, pat);
return cmd;
-} /* cs_create_cmd */
+}
/// This piece of code was taken/adapted from nvi. do we need to add
@@ -694,15 +701,18 @@ err_closing:
case -1:
(void)EMSG(_("E622: Could not fork for cscope"));
goto err_closing;
- case 0: /* child: run cscope. */
- if (dup2(to_cs[0], STDIN_FILENO) == -1)
+ case 0: // child: run cscope.
+ if (dup2(to_cs[0], STDIN_FILENO) == -1) {
PERROR("cs_create_connection 1");
- if (dup2(from_cs[1], STDOUT_FILENO) == -1)
+ }
+ if (dup2(from_cs[1], STDOUT_FILENO) == -1) {
PERROR("cs_create_connection 2");
- if (dup2(from_cs[1], STDERR_FILENO) == -1)
+ }
+ if (dup2(from_cs[1], STDERR_FILENO) == -1) {
PERROR("cs_create_connection 3");
+ }
- /* close unused */
+ // close unused
(void)close(to_cs[1]);
(void)close(from_cs[0]);
#else
@@ -735,14 +745,14 @@ err_closing:
return CSCOPE_FAILURE;
}
#endif
- /* expand the cscope exec for env var's */
+ // expand the cscope exec for env var's
prog = xmalloc(MAXPATHL + 1);
expand_env(p_csprg, (char_u *)prog, MAXPATHL);
- /* alloc space to hold the cscope command */
+ // alloc space to hold the cscope command
size_t len = strlen(prog) + strlen(csinfo[i].fname) + 32;
if (csinfo[i].ppath) {
- /* expand the prepend path for env var's */
+ // expand the prepend path for env var's
ppath = xmalloc(MAXPATHL + 1);
expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL);
@@ -754,12 +764,12 @@ err_closing:
cmd = xmalloc(len);
- /* run the cscope command; is there execl for non-unix systems? */
+ // run the cscope command; is there execl for non-unix systems?
#if defined(UNIX)
- (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname);
+ (void)snprintf(cmd, len, "exec %s -dl -f %s", prog, csinfo[i].fname);
#else
- /* WIN32 */
- (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname);
+ // WIN32
+ (void)snprintf(cmd, len, "%s -dl -f %s", prog, csinfo[i].fname);
#endif
if (csinfo[i].ppath != NULL) {
(void)strcat(cmd, " -P");
@@ -770,14 +780,14 @@ err_closing:
(void)strcat(cmd, csinfo[i].flags);
}
# ifdef UNIX
- /* on Win32 we still need prog */
+ // on Win32 we still need prog
xfree(prog);
# endif
xfree(ppath);
#if defined(UNIX)
# if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
- /* Change our process group to avoid cscope receiving SIGWINCH. */
+ // Change our process group to avoid cscope receiving SIGWINCH.
# if defined(HAVE_SETSID)
(void)setsid();
# else
@@ -789,18 +799,18 @@ err_closing:
PERROR(_("cs_create_connection exec failed"));
exit(127);
- /* NOTREACHED */
- default: /* parent. */
- /*
- * Save the file descriptors for later duplication, and
- * reopen as streams.
- */
- if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL)
+ // NOTREACHED
+ default: // parent.
+ // Save the file descriptors for later duplication, and
+ // reopen as streams.
+ if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL) {
PERROR(_("cs_create_connection: fdopen for to_fp failed"));
- if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL)
+ }
+ if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) {
PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
+ }
- /* close unused */
+ // close unused
(void)close(to_cs[0]);
(void)close(from_cs[1]);
@@ -808,11 +818,11 @@ err_closing:
}
#else
- /* WIN32 */
- /* Create a new process to run cscope and use pipes to talk with it */
+ // WIN32
+ // Create a new process to run cscope and use pipes to talk with it
GetStartupInfo(&si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_HIDE; /* Hide child application window */
+ si.wShowWindow = SW_HIDE; // Hide child application window
si.hStdOutput = stdout_wr;
si.hStdError = stdout_wr;
si.hStdInput = stdin_rd;
@@ -826,7 +836,7 @@ err_closing:
(void)EMSG(_("E623: Could not spawn cscope process"));
goto err_closing;
}
- /* else */
+ // else
csinfo[i].pid = pi.dwProcessId;
csinfo[i].hProc = pi.hProcess;
CloseHandle(pi.hThread);
@@ -844,10 +854,10 @@ err_closing:
CloseHandle(stdin_rd);
CloseHandle(stdout_wr);
-#endif /* !UNIX */
+#endif // !UNIX
return CSCOPE_SUCCESS;
-} /* cs_create_connection */
+}
/// Query cscope using command line interface. Parse the output and use tselect
@@ -882,9 +892,9 @@ static int cs_find(exarg_T *eap)
if (NUL == eap->arg[i])
eap->arg[i] = ' ';
- return cs_find_common(opt, pat, eap->forceit, TRUE,
- eap->cmdidx == CMD_lcscope, *eap->cmdlinep);
-} /* cs_find */
+ return cs_find_common(opt, pat, eap->forceit, true,
+ eap->cmdidx == CMD_lcscope, *eap->cmdlinep);
+}
/// Common code for cscope find, shared by cs_find() and ex_cstag().
@@ -897,7 +907,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
char cmdletter;
char *qfpos;
- /* get cmd letter */
+ // get cmd letter
switch (opt[0]) {
case '0':
cmdletter = 's';
@@ -933,10 +943,10 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
qfpos = (char *)vim_strchr(p_csqf, cmdletter);
if (qfpos != NULL) {
qfpos++;
- /* next symbol must be + or - */
+ // next symbol must be + or -
if (strchr(CSQF_FLAGS, *qfpos) == NULL) {
char *nf = _("E469: invalid cscopequickfix flag %c for %c");
- /* strlen will be enough because we use chars */
+ // strlen will be enough because we use chars
char *buf = xmalloc(strlen(nf));
sprintf(buf, nf, *qfpos, *(qfpos-1));
@@ -954,23 +964,24 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
}
}
- /* create the actual command to send to cscope */
+ // create the actual command to send to cscope
cmd = cs_create_cmd(opt, pat);
if (cmd == NULL)
return FALSE;
nummatches = xmalloc(sizeof(int) * csinfo_size);
- /* Send query to all open connections, then count the total number
- * of matches so we can alloc all in one swell foop. */
- for (size_t i = 0; i < csinfo_size; i++)
+ // Send query to all open connections, then count the total number
+ // of matches so we can alloc all in one swell foop.
+ for (size_t i = 0; i < csinfo_size; i++) {
nummatches[i] = 0;
+ }
totmatches = 0;
for (size_t i = 0; i < csinfo_size; i++) {
if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL)
continue;
- /* send cmd to cscope */
+ // send cmd to cscope
(void)fprintf(csinfo[i].to_fp, "%s\n", cmd);
(void)fflush(csinfo[i].to_fp);
@@ -1014,8 +1025,9 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
} else {
cs_file_results(f, nummatches);
fclose(f);
- if (use_ll) /* Use location list */
+ if (use_ll) { // Use location list
wp = curwin;
+ }
// '-' starts a new error list
if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m",
*qfpos == '-', cmdline, NULL) > 0) {
@@ -1046,7 +1058,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
char **matches = NULL, **contexts = NULL;
size_t matched = 0;
- /* read output */
+ // read output
cs_fill_results((char *)pat, totmatches, nummatches, &matches,
&contexts, &matched);
xfree(nummatches);
@@ -1057,8 +1069,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
return do_tag((char_u *)pat, DT_CSCOPE, 0, forceit, verbose);
}
-
-} /* cs_find_common */
+}
/// Print help.
static int cs_help(exarg_T *eap)
@@ -1070,9 +1081,10 @@ static int cs_help(exarg_T *eap)
char *help = _(cmdp->help);
int space_cnt = 30 - vim_strsize((char_u *)help);
- /* Use %*s rather than %30s to ensure proper alignment in utf-8 */
- if (space_cnt < 0)
+ // Use %*s rather than %30s to ensure proper alignment in utf-8
+ if (space_cnt < 0) {
space_cnt = 0;
+ }
(void)smsg(_("%-5s: %s%*s (Usage: %s)"),
cmdp->name,
help, space_cnt, " ",
@@ -1094,7 +1106,7 @@ static int cs_help(exarg_T *eap)
wait_return(TRUE);
return CSCOPE_SUCCESS;
-} /* cs_help */
+}
static void clear_csinfo(size_t i)
@@ -1124,7 +1136,7 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
}
if (csinfo[j].fname == NULL && !empty_found) {
- i = j; /* remember first empty entry */
+ i = j; // remember first empty entry
empty_found = true;
}
}
@@ -1132,13 +1144,13 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
if (!empty_found) {
i = csinfo_size;
if (csinfo_size == 0) {
- /* First time allocation: allocate only 1 connection. It should
- * be enough for most users. If more is needed, csinfo will be
- * reallocated. */
+ // First time allocation: allocate only 1 connection. It should
+ // be enough for most users. If more is needed, csinfo will be
+ // reallocated.
csinfo_size = 1;
csinfo = xcalloc(1, sizeof(csinfo_T));
} else {
- /* Reallocate space for more connections. */
+ // Reallocate space for more connections.
csinfo_size *= 2;
csinfo = xrealloc(csinfo, sizeof(csinfo_T)*csinfo_size);
}
@@ -1165,7 +1177,7 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
os_fileinfo_id(file_info, &(csinfo[i].file_id));
assert(i <= INT_MAX);
return (int)i;
-} /* cs_insert_filelist */
+}
/// Find cscope command in command table.
@@ -1178,7 +1190,7 @@ static cscmd_T * cs_lookup_cmd(exarg_T *eap)
if (eap->arg == NULL)
return NULL;
- /* Store length of eap->arg before it gets modified by strtok(). */
+ // Store length of eap->arg before it gets modified by strtok().
eap_arg_len = (int)STRLEN(eap->arg);
if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL)
@@ -1190,7 +1202,7 @@ static cscmd_T * cs_lookup_cmd(exarg_T *eap)
return cmdp;
}
return NULL;
-} /* cs_lookup_cmd */
+}
/// Nuke em.
@@ -1247,13 +1259,13 @@ static int cs_kill(exarg_T *eap)
}
return CSCOPE_SUCCESS;
-} /* cs_kill */
+}
/// Actually kills a specific cscope connection.
static void cs_kill_execute(
- size_t i, /* cscope table index */
- char *cname /* cscope database name */
+ size_t i, // cscope table index
+ char *cname // cscope database name
)
{
if (p_csverbose) {
@@ -1284,17 +1296,16 @@ static void cs_kill_execute(
static char *cs_make_vim_style_matches(char *fname, char *slno, char *search,
char *tagstr)
{
- /* vim style is ctags:
- *
- * <tagstr>\t<filename>\t<linenum_or_search>"\t<extra>
- *
- * but as mentioned above, we'll always use the line number and
- * put the search pattern (if one exists) as "extra"
- *
- * buf is used as part of vim's method of handling tags, and
- * (i think) vim frees it when you pop your tags and get replaced
- * by new ones on the tag stack.
- */
+ // vim style is ctags:
+ //
+ // <tagstr>\t<filename>\t<linenum_or_search>"\t<extra>
+ //
+ // but as mentioned above, we'll always use the line number and
+ // put the search pattern (if one exists) as "extra"
+ //
+ // buf is used as part of vim's method of handling tags, and
+ // (i think) vim frees it when you pop your tags and get replaced
+ // by new ones on the tag stack.
char *buf;
size_t amt;
@@ -1311,7 +1322,7 @@ static char *cs_make_vim_style_matches(char *fname, char *slno, char *search,
}
return buf;
-} /* cs_make_vim_style_matches */
+}
/// This is kind of hokey, but i don't see an easy way round this.
@@ -1381,7 +1392,7 @@ static char *cs_manage_matches(char **matches, char **contexts,
}
return p;
-} /* cs_manage_matches */
+}
/// Parse cscope output.
@@ -1408,7 +1419,7 @@ retry:
return NULL;
}
- /* If the line's too long for the buffer, discard it. */
+ // If the line's too long for the buffer, discard it.
if ((p = strchr(buf, '\n')) == NULL) {
while ((ch = getc(csinfo[cnumber].fr_fp)) != EOF && ch != '\n')
;
@@ -1427,15 +1438,15 @@ retry:
return NULL;
if ((*linenumber = strtok(NULL, (const char *)" ")) == NULL)
return NULL;
- *search = *linenumber + strlen(*linenumber) + 1; /* +1 to skip \0 */
+ *search = *linenumber + strlen(*linenumber) + 1; // +1 to skip \0
- /* --- nvi ---
- * If the file is older than the cscope database, that is,
- * the database was built since the file was last modified,
- * or there wasn't a search string, use the line number.
- */
- if (strcmp(*search, "<unknown>") == 0)
+ // --- nvi ---
+ // If the file is older than the cscope database, that is,
+ // the database was built since the file was last modified,
+ // or there wasn't a search string, use the line number.
+ if (strcmp(*search, "<unknown>") == 0) {
*search = NULL;
+ }
name = cs_resolve_file(cnumber, name);
return name;
@@ -1474,11 +1485,10 @@ static void cs_file_results(FILE *f, int *nummatches_a)
xfree(context);
xfree(fullname);
- } /* for all matches */
+ } // for all matches
(void)cs_read_prompt(i);
-
- } /* for all cscope connections */
+ } // for all cscope connections
xfree(buf);
}
@@ -1539,10 +1549,10 @@ static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a,
*cntxts_p = cntxts;
xfree(buf);
-} // cs_fill_results
+}
-/* get the requested path components */
+// get the requested path components
static char *cs_pathcomponents(char *path)
{
if (p_cspc == 0) {
@@ -1688,7 +1698,7 @@ static int cs_read_prompt(size_t i)
static char *eprompt = "Press the RETURN key to continue:";
size_t epromptlen = strlen(eprompt);
- /* compute maximum allowed len for Cscope error message */
+ // compute maximum allowed len for Cscope error message
assert(IOSIZE >= cs_emsg_len);
size_t maxlen = IOSIZE - cs_emsg_len;
@@ -1738,11 +1748,12 @@ static int cs_read_prompt(size_t i)
}
if (ch == EOF) {
PERROR("cs_read_prompt EOF");
- if (buf != NULL && buf[0] != NUL)
+ if (buf != NULL && buf[0] != NUL) {
(void)EMSG2(cs_emsg, buf);
- else if (p_csverbose)
- cs_reading_emsg(i); /* don't have additional information */
- cs_release_csp(i, TRUE);
+ } else if (p_csverbose) {
+ cs_reading_emsg(i); // don't have additional information
+ }
+ cs_release_csp(i, true);
xfree(buf);
return CSCOPE_FAILURE;
}
@@ -1753,9 +1764,10 @@ static int cs_read_prompt(size_t i)
}
}
- if (ch == EOF)
- continue; /* didn't find the prompt */
- break; /* did find the prompt */
+ if (ch == EOF) {
+ continue; // didn't find the prompt
+ }
+ break; // did find the prompt
}
xfree(buf);
@@ -1766,8 +1778,9 @@ static int cs_read_prompt(size_t i)
/*
* Used to catch and ignore SIGALRM below.
*/
-static void sig_handler(int s) {
- /* do nothing */
+static void sig_handler(int s)
+{
+ // do nothing
return;
}
@@ -1775,7 +1788,7 @@ static void sig_handler(int s) {
/// Does the actual free'ing for the cs ptr with an optional flag of whether
/// or not to free the filename. Called by cs_kill and cs_reset.
-static void cs_release_csp(size_t i, int freefnpp)
+static void cs_release_csp(size_t i, bool freefnpp)
{
// Trying to exit normally (not sure whether it is fit to Unix cscope)
if (csinfo[i].to_fp != NULL) {
@@ -1791,7 +1804,7 @@ static void cs_release_csp(size_t i, int freefnpp)
# if defined(HAVE_SIGACTION)
struct sigaction sa, old;
- /* Use sigaction() to limit the waiting time to two seconds. */
+ // Use sigaction() to limit the waiting time to two seconds.
sigemptyset(&sa.sa_mask);
sa.sa_handler = sig_handler;
# ifdef SA_NODEFER
@@ -1800,27 +1813,28 @@ static void cs_release_csp(size_t i, int freefnpp)
sa.sa_flags = 0;
# endif
sigaction(SIGALRM, &sa, &old);
- alarm(2); /* 2 sec timeout */
+ alarm(2); // 2 sec timeout
- /* Block until cscope exits or until timer expires */
+ // Block until cscope exits or until timer expires
pid = waitpid(csinfo[i].pid, &pstat, 0);
waitpid_errno = errno;
- /* cancel pending alarm if still there and restore signal */
+ // cancel pending alarm if still there and restore signal
alarm(0);
sigaction(SIGALRM, &old, NULL);
# else
int waited;
- /* Can't use sigaction(), loop for two seconds. First yield the CPU
- * to give cscope a chance to exit quickly. */
+ // Can't use sigaction(), loop for two seconds. First yield the CPU
+ // to give cscope a chance to exit quickly.
sleep(0);
for (waited = 0; waited < 40; ++waited) {
pid = waitpid(csinfo[i].pid, &pstat, WNOHANG);
waitpid_errno = errno;
- if (pid != 0)
- break; /* break unless the process is still running */
- os_delay(50L, false); /* sleep 50 ms */
+ if (pid != 0) {
+ break; // break unless the process is still running
+ }
+ os_delay(50L, false); // sleep 50 ms
}
# endif
/*
@@ -1830,7 +1844,7 @@ static void cs_release_csp(size_t i, int freefnpp)
*/
if (pid < 0 && csinfo[i].pid > 1) {
# ifdef ECHILD
- int alive = TRUE;
+ bool alive = true;
if (waitpid_errno == ECHILD) {
/*
@@ -1845,13 +1859,13 @@ static void cs_release_csp(size_t i, int freefnpp)
int waited;
sleep(0);
- for (waited = 0; waited < 40; ++waited) {
- /* Check whether cscope process is still alive */
+ for (waited = 0; waited < 40; waited++) {
+ // Check whether cscope process is still alive
if (kill(csinfo[i].pid, 0) != 0) {
- alive = FALSE; /* cscope process no longer exists */
+ alive = false; // cscope process no longer exists
break;
}
- os_delay(50L, false); /* sleep 50ms */
+ os_delay(50L, false); // sleep 50ms
}
}
if (alive)
@@ -1862,11 +1876,12 @@ static void cs_release_csp(size_t i, int freefnpp)
}
}
}
-#else /* !UNIX */
+#else // !UNIX
if (csinfo[i].hProc != NULL) {
- /* Give cscope a chance to exit normally */
- if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
+ // Give cscope a chance to exit normally
+ if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) {
TerminateProcess(csinfo[i].hProc, 0);
+ }
CloseHandle(csinfo[i].hProc);
}
#endif
@@ -1883,7 +1898,7 @@ static void cs_release_csp(size_t i, int freefnpp)
}
clear_csinfo(i);
-} /* cs_release_csp */
+}
/// Calls cs_kill on all cscope connections then reinits.
@@ -1895,7 +1910,7 @@ static int cs_reset(exarg_T *eap)
if (csinfo_size == 0)
return CSCOPE_SUCCESS;
- /* malloc our db and ppath list */
+ // malloc our db and ppath list
dblist = xmalloc(csinfo_size * sizeof(char *));
pplist = xmalloc(csinfo_size * sizeof(char *));
fllist = xmalloc(csinfo_size * sizeof(char *));
@@ -1908,15 +1923,14 @@ static int cs_reset(exarg_T *eap)
cs_release_csp(i, FALSE);
}
- /* rebuild the cscope connection list */
+ // rebuild the cscope connection list
for (size_t i = 0; i < csinfo_size; i++) {
if (dblist[i] != NULL) {
cs_add_common(dblist[i], pplist[i], fllist[i]);
if (p_csverbose) {
- /* don't use smsg_attr() because we want to display the
- * connection number in the same line as
- * "Added cscope database..."
- */
+ // don't use smsg_attr() because we want to display the
+ // connection number in the same line as
+ // "Added cscope database..."
snprintf(buf, ARRAY_SIZE(buf), " (#%zu)", i);
MSG_PUTS_ATTR(buf, HL_ATTR(HLF_R));
}
@@ -1933,7 +1947,7 @@ static int cs_reset(exarg_T *eap)
msg_attr(_("All cscope databases reset"), HL_ATTR(HLF_R) | MSG_HIST);
}
return CSCOPE_SUCCESS;
-} /* cs_reset */
+}
/// Construct the full pathname to a file found in the cscope database.
@@ -1954,11 +1968,11 @@ static char *cs_resolve_file(size_t i, char *name)
* copied into the tag buffer used by Vim.
*/
size_t len = strlen(name) + 2;
- if (csinfo[i].ppath != NULL)
+ if (csinfo[i].ppath != NULL) {
len += strlen(csinfo[i].ppath);
- else if (p_csre && csinfo[i].fname != NULL) {
- /* If 'cscoperelative' is set and ppath is not set, use cscope.out
- * path in path resolution. */
+ } else if (p_csre && csinfo[i].fname != NULL) {
+ // If 'cscoperelative' is set and ppath is not set, use cscope.out
+ // path in path resolution.
csdir = xmalloc(MAXPATHL);
STRLCPY(csdir, csinfo[i].fname,
path_tail((char_u *)csinfo[i].fname)
@@ -1966,9 +1980,9 @@ static char *cs_resolve_file(size_t i, char *name)
len += STRLEN(csdir);
}
- /* Note/example: this won't work if the cscope output already starts
- * "../.." and the prefix path is also "../..". if something like this
- * happens, you are screwed up and need to fix how you're using cscope. */
+ // Note/example: this won't work if the cscope output already starts
+ // "../.." and the prefix path is also "../..". if something like this
+ // happens, you are screwed up and need to fix how you're using cscope.
if (csinfo[i].ppath != NULL
&& (strncmp(name, csinfo[i].ppath, strlen(csinfo[i].ppath)) != 0)
&& (name[0] != '/')
@@ -1976,9 +1990,9 @@ static char *cs_resolve_file(size_t i, char *name)
fullname = xmalloc(len);
(void)sprintf(fullname, "%s/%s", csinfo[i].ppath, name);
} else if (csdir != NULL && csinfo[i].fname != NULL && *csdir != NUL) {
- /* Check for csdir to be non empty to avoid empty path concatenated to
- * cscope output. */
- fullname = concat_fnames((char *)csdir, name, TRUE);
+ // Check for csdir to be non empty to avoid empty path concatenated to
+ // cscope output.
+ fullname = concat_fnames((char *)csdir, name, true);
} else {
fullname = xstrdup(name);
}
@@ -2013,7 +2027,7 @@ static int cs_show(exarg_T *eap)
wait_return(TRUE);
return CSCOPE_SUCCESS;
-} /* cs_show */
+}
/// Only called when VIM exits to quit any cscope sessions.
@@ -2025,4 +2039,4 @@ void cs_end(void)
csinfo_size = 0;
}
-/* the end */
+// the end
diff --git a/src/nvim/if_cscope_defs.h b/src/nvim/if_cscope_defs.h
index fa18866840..d2d8b0fb62 100644
--- a/src/nvim/if_cscope_defs.h
+++ b/src/nvim/if_cscope_defs.h
@@ -1,19 +1,16 @@
#ifndef NVIM_IF_CSCOPE_DEFS_H
#define NVIM_IF_CSCOPE_DEFS_H
-/*
- * CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
- * Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
- *
- * The basic idea/structure of cscope for Vim was borrowed from Nvi.
- * There might be a few lines of code that look similar to what Nvi
- * has. If this is a problem and requires inclusion of the annoying
- * BSD license, then sue me; I'm not worth much anyway.
- */
-
+// CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
+// Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
+//
+// The basic idea/structure of cscope for Vim was borrowed from Nvi.
+// There might be a few lines of code that look similar to what Nvi
+// has. If this is a problem and requires inclusion of the annoying
+// BSD license, then sue me; I'm not worth much anyway.
#if defined(UNIX)
-# include <sys/types.h> /* pid_t */
+# include <sys/types.h> // pid_t
#endif
#include "nvim/os/os_defs.h"
@@ -33,13 +30,13 @@ typedef struct {
int (*func)(exarg_T *eap);
char * help;
char * usage;
- int cansplit; /* if supports splitting window */
+ int cansplit; // if supports splitting window
} cscmd_T;
typedef struct csi {
- char * fname; /* cscope db name */
- char * ppath; /* path to prepend (the -P option) */
- char * flags; /* additional cscope flags/options (e.g, -p2) */
+ char * fname; // cscope db name
+ char * ppath; // path to prepend (the -P option)
+ char * flags; // additional cscope flags/options (e.g, -p2)
#if defined(UNIX)
pid_t pid; // PID of the connected cscope process
#else
@@ -51,8 +48,8 @@ typedef struct csi {
#endif
FileID file_id;
- FILE * fr_fp; /* from cscope: FILE. */
- FILE * to_fp; /* to cscope: FILE. */
+ FILE * fr_fp; // from cscope: FILE.
+ FILE * to_fp; // to cscope: FILE.
} csinfo_T;
typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e;
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index f8018c039d..7f17fb0035 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -56,7 +56,8 @@ int get_indent_buf(buf_T *buf, linenr_T lnum)
// Count the size (in window cells) of the indent in line "ptr", with
// 'tabstop' at "ts".
// If @param list is TRUE, count only screen size for tabs.
-int get_indent_str(char_u *ptr, int ts, int list)
+int get_indent_str(const char_u *ptr, int ts, int list)
+ FUNC_ATTR_NONNULL_ALL
{
int count = 0;
@@ -375,12 +376,12 @@ int get_number_indent(linenr_T lnum)
* parameters into account. Window must be specified, since it is not
* necessarily always the current one.
*/
-int get_breakindent_win(win_T *wp, char_u *line)
- FUNC_ATTR_NONNULL_ARG(1)
+int get_breakindent_win(win_T *wp, const char_u *line)
+ FUNC_ATTR_NONNULL_ALL
{
static int prev_indent = 0; // Cached indent value.
static long prev_ts = 0; // Cached tabstop value.
- static char_u *prev_line = NULL; // cached pointer to line.
+ static const char_u *prev_line = NULL; // cached pointer to line.
static varnumber_T prev_tick = 0; // Changedtick of cached value.
int bri = 0;
// window width minus window margin space, i.e. what rests for text
@@ -389,7 +390,7 @@ int get_breakindent_win(win_T *wp, char_u *line)
&& (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
? number_width(wp) + 1 : 0);
- /* used cached indent, unless pointer or 'tabstop' changed */
+ // used cached indent, unless pointer or 'tabstop' changed
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|| prev_tick != buf_get_changedtick(wp->w_buffer)) {
prev_line = line;
@@ -399,21 +400,22 @@ int get_breakindent_win(win_T *wp, char_u *line)
}
bri = prev_indent + wp->w_p_brishift;
- /* indent minus the length of the showbreak string */
- if (wp->w_p_brisbr)
+ // indent minus the length of the showbreak string
+ if (wp->w_p_brisbr) {
bri -= vim_strsize(p_sbr);
-
- /* Add offset for number column, if 'n' is in 'cpoptions' */
+ }
+ // Add offset for number column, if 'n' is in 'cpoptions'
bri += win_col_off2(wp);
- /* never indent past left window margin */
- if (bri < 0)
+ // never indent past left window margin
+ if (bri < 0) {
bri = 0;
- /* always leave at least bri_min characters on the left,
- * if text width is sufficient */
- else if (bri > eff_wwidth - wp->w_p_brimin)
+ } else if (bri > eff_wwidth - wp->w_p_brimin) {
+ // always leave at least bri_min characters on the left,
+ // if text width is sufficient
bri = (eff_wwidth - wp->w_p_brimin < 0)
? 0 : eff_wwidth - wp->w_p_brimin;
+ }
return bri;
}
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index 67a7e58ed7..bb443161ef 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.c
@@ -3372,11 +3372,9 @@ term_again:
continue;
}
- /*
- * Are we at the start of a cpp base class declaration or
- * constructor initialization?
- */ /* XXX */
- n = false;
+ // Are we at the start of a cpp base class declaration or
+ // constructor initialization? XXX
+ n = 0;
if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{') {
n = cin_is_cpp_baseclass(&cache_cpp_baseclass);
l = get_cursor_line_ptr();
@@ -3409,7 +3407,6 @@ term_again:
* } foo,
* bar;
*/
- n = 0;
if (cin_ends_in(l, (char_u *)",", NULL)
|| (*l != NUL && (n = l[STRLEN(l) - 1]) == '\\')) {
/* take us back to opening paren */
diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h
index d3e887badc..ada9bc5780 100644
--- a/src/nvim/keymap.h
+++ b/src/nvim/keymap.h
@@ -13,7 +13,7 @@
* For MSDOS some keys produce codes larger than 0xff. They are split into two
* chars, the first one is K_NUL.
*/
-#define K_NUL (0xce) /* for MSDOS: special key follows */
+#define K_NUL (0xce) // for MSDOS: special key follows
/*
* K_SPECIAL is the first byte of a special key code and is always followed by
@@ -78,13 +78,13 @@
#define KS_SELECT 245
#define K_SELECT_STRING (char_u *)"\200\365X"
-/* Used a termcap entry that produces a normal character. */
+// Used a termcap entry that produces a normal character.
#define KS_KEY 242
-/* Used for click in a tab pages label. */
+// Used for click in a tab pages label.
#define KS_TABLINE 240
-/* Used for menu in a tab pages line. */
+// Used for menu in a tab pages line.
#define KS_TABMENU 239
/*
@@ -274,13 +274,13 @@ enum key_extra {
#define K_TAB TERMCAP2KEY(KS_EXTRA, KE_TAB)
#define K_S_TAB TERMCAP2KEY('k', 'B')
-/* extra set of function keys F1-F4, for vt100 compatible xterm */
+// extra set of function keys F1-F4, for vt100 compatible xterm
#define K_XF1 TERMCAP2KEY(KS_EXTRA, KE_XF1)
#define K_XF2 TERMCAP2KEY(KS_EXTRA, KE_XF2)
#define K_XF3 TERMCAP2KEY(KS_EXTRA, KE_XF3)
#define K_XF4 TERMCAP2KEY(KS_EXTRA, KE_XF4)
-/* extra set of cursor keys for vt100 compatible xterm */
+// extra set of cursor keys for vt100 compatible xterm
#define K_XUP TERMCAP2KEY(KS_EXTRA, KE_XUP)
#define K_XDOWN TERMCAP2KEY(KS_EXTRA, KE_XDOWN)
#define K_XLEFT TERMCAP2KEY(KS_EXTRA, KE_XLEFT)
@@ -327,7 +327,7 @@ enum key_extra {
#define K_F36 TERMCAP2KEY('F', 'Q')
#define K_F37 TERMCAP2KEY('F', 'R')
-/* extra set of shifted function keys F1-F4, for vt100 compatible xterm */
+// extra set of shifted function keys F1-F4, for vt100 compatible xterm
#define K_S_XF1 TERMCAP2KEY(KS_EXTRA, KE_S_XF1)
#define K_S_XF2 TERMCAP2KEY(KS_EXTRA, KE_S_XF2)
#define K_S_XF3 TERMCAP2KEY(KS_EXTRA, KE_S_XF3)
@@ -346,7 +346,7 @@ enum key_extra {
#define K_S_F11 TERMCAP2KEY(KS_EXTRA, KE_S_F11)
#define K_S_F12 TERMCAP2KEY(KS_EXTRA, KE_S_F12)
-/* K_S_F13 to K_S_F37 are currently not used */
+// K_S_F13 to K_S_F37 are currently not used
#define K_HELP TERMCAP2KEY('%', '1')
#define K_UNDO TERMCAP2KEY('&', '8')
@@ -443,8 +443,8 @@ enum key_extra {
#define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT)
#define K_COMMAND TERMCAP2KEY(KS_EXTRA, KE_COMMAND)
-/* Bits for modifier mask */
-/* 0x01 cannot be used, because the modifier must be 0x02 or higher */
+// Bits for modifier mask
+// 0x01 cannot be used, because the modifier must be 0x02 or higher
#define MOD_MASK_SHIFT 0x02
#define MOD_MASK_CTRL 0x04
#define MOD_MASK_ALT 0x08 // aka META
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 632832416b..144646fca2 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -11,6 +11,7 @@
#include "nvim/func_attr.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/private/handle.h"
#include "nvim/api/vim.h"
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/vim.h"
@@ -19,6 +20,7 @@
#include "nvim/message.h"
#include "nvim/memline.h"
#include "nvim/buffer_defs.h"
+#include "nvim/regexp.h"
#include "nvim/macros.h"
#include "nvim/screen.h"
#include "nvim/cursor.h"
@@ -245,6 +247,14 @@ static int nlua_schedule(lua_State *const lstate)
return 0;
}
+static struct luaL_Reg regex_meta[] = {
+ { "__gc", regex_gc },
+ { "__tostring", regex_tostring },
+ { "match_str", regex_match_str },
+ { "match_line", regex_match_line },
+ { NULL, NULL }
+};
+
/// Initialize lua interpreter state
///
/// Called by lua interpreter itself to initialize state.
@@ -292,6 +302,15 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
// call
lua_pushcfunction(lstate, &nlua_call);
lua_setfield(lstate, -2, "call");
+ // regex
+ lua_pushcfunction(lstate, &nlua_regex);
+ lua_setfield(lstate, -2, "regex");
+
+ luaL_newmetatable(lstate, "nvim_regex");
+ luaL_register(lstate, NULL, regex_meta);
+ lua_pushvalue(lstate, -1); // [meta, meta]
+ lua_setfield(lstate, -2, "__index"); // [meta]
+ lua_pop(lstate, 1); // don't use metatable now
// rpcrequest
lua_pushcfunction(lstate, &nlua_rpcrequest);
@@ -1038,3 +1057,136 @@ static void nlua_add_treesitter(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_pushcfunction(lstate, ts_lua_parse_query);
lua_setfield(lstate, -2, "_ts_parse_query");
}
+
+static int nlua_regex(lua_State *lstate)
+{
+ Error err = ERROR_INIT;
+ const char *text = luaL_checkstring(lstate, 1);
+ regprog_T *prog = NULL;
+
+ TRY_WRAP({
+ try_start();
+ prog = vim_regcomp((char_u *)text, RE_AUTO | RE_MAGIC | RE_STRICT);
+ try_end(&err);
+ });
+
+ if (ERROR_SET(&err)) {
+ return luaL_error(lstate, "couldn't parse regex: %s", err.msg);
+ }
+ assert(prog);
+
+ regprog_T **p = lua_newuserdata(lstate, sizeof(regprog_T *));
+ *p = prog;
+
+ lua_getfield(lstate, LUA_REGISTRYINDEX, "nvim_regex"); // [udata, meta]
+ lua_setmetatable(lstate, -2); // [udata]
+ return 1;
+}
+
+static regprog_T **regex_check(lua_State *L)
+{
+ return luaL_checkudata(L, 1, "nvim_regex");
+}
+
+
+static int regex_gc(lua_State *lstate)
+{
+ regprog_T **prog = regex_check(lstate);
+ vim_regfree(*prog);
+ return 0;
+}
+
+static int regex_tostring(lua_State *lstate)
+{
+ lua_pushstring(lstate, "<regex>");
+ return 1;
+}
+
+static int regex_match(lua_State *lstate, regprog_T **prog, char_u *str)
+{
+ regmatch_T rm;
+ rm.regprog = *prog;
+ rm.rm_ic = false;
+ bool match = vim_regexec(&rm, str, 0);
+ *prog = rm.regprog;
+
+ if (match) {
+ lua_pushinteger(lstate, (lua_Integer)(rm.startp[0]-str));
+ lua_pushinteger(lstate, (lua_Integer)(rm.endp[0]-str));
+ return 2;
+ }
+ return 0;
+}
+
+static int regex_match_str(lua_State *lstate)
+{
+ regprog_T **prog = regex_check(lstate);
+ const char *str = luaL_checkstring(lstate, 2);
+ int nret = regex_match(lstate, prog, (char_u *)str);
+
+ if (!*prog) {
+ return luaL_error(lstate, "regex: internal error");
+ }
+
+ return nret;
+}
+
+static int regex_match_line(lua_State *lstate)
+{
+ regprog_T **prog = regex_check(lstate);
+
+ int narg = lua_gettop(lstate);
+ if (narg < 3) {
+ return luaL_error(lstate, "not enough args");
+ }
+
+ long bufnr = luaL_checkinteger(lstate, 2);
+ long rownr = luaL_checkinteger(lstate, 3);
+ long start = 0, end = -1;
+ if (narg >= 4) {
+ start = luaL_checkinteger(lstate, 4);
+ }
+ if (narg >= 5) {
+ end = luaL_checkinteger(lstate, 5);
+ if (end < 0) {
+ return luaL_error(lstate, "invalid end");
+ }
+ }
+
+ buf_T *buf = bufnr ? handle_get_buffer((int)bufnr) : curbuf;
+ if (!buf || buf->b_ml.ml_mfp == NULL) {
+ return luaL_error(lstate, "invalid buffer");
+ }
+
+ if (rownr >= buf->b_ml.ml_line_count) {
+ return luaL_error(lstate, "invalid row");
+ }
+
+ char_u *line = ml_get_buf(buf, rownr+1, false);
+ size_t len = STRLEN(line);
+
+ if (start < 0 || (size_t)start > len) {
+ return luaL_error(lstate, "invalid start");
+ }
+
+ char_u save = NUL;
+ if (end >= 0) {
+ if ((size_t)end > len || end < start) {
+ return luaL_error(lstate, "invalid end");
+ }
+ save = line[end];
+ line[end] = NUL;
+ }
+
+ int nret = regex_match(lstate, prog, line+start);
+
+ if (end >= 0) {
+ line[end] = save;
+ }
+
+ if (!*prog) {
+ return luaL_error(lstate, "regex: internal error");
+ }
+
+ return nret;
+}
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index a420f79ffd..51d9549033 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -93,10 +93,7 @@ static PMap(cstr_t) *langs;
static void build_meta(lua_State *L, const char *tname, const luaL_Reg *meta)
{
if (luaL_newmetatable(L, tname)) { // [meta]
- for (size_t i = 0; meta[i].name != NULL; i++) {
- lua_pushcfunction(L, meta[i].func); // [meta, func]
- lua_setfield(L, -2, meta[i].name); // [meta]
- }
+ luaL_register(L, NULL, meta);
lua_pushvalue(L, -1); // [meta, meta]
lua_setfield(L, -2, "__index"); // [meta]
@@ -274,17 +271,22 @@ static const char *input_cb(void *payload, uint32_t byte_index,
}
char_u *line = ml_get_buf(bp, position.row+1, false);
size_t len = STRLEN(line);
- size_t tocopy = MIN(len-position.column, BUFSIZE);
-
- memcpy(buf, line+position.column, tocopy);
- // Translate embedded \n to NUL
- memchrsub(buf, '\n', '\0', tocopy);
- *bytes_read = (uint32_t)tocopy;
- if (tocopy < BUFSIZE) {
- // now add the final \n. If it didn't fit, input_cb will be called again
- // on the same line with advanced column.
- buf[tocopy] = '\n';
- (*bytes_read)++;
+
+ if (position.column > len) {
+ *bytes_read = 0;
+ } else {
+ size_t tocopy = MIN(len-position.column, BUFSIZE);
+
+ memcpy(buf, line+position.column, tocopy);
+ // Translate embedded \n to NUL
+ memchrsub(buf, '\n', '\0', tocopy);
+ *bytes_read = (uint32_t)tocopy;
+ if (tocopy < BUFSIZE) {
+ // now add the final \n. If it didn't fit, input_cb will be called again
+ // on the same line with advanced column.
+ buf[tocopy] = '\n';
+ (*bytes_read)++;
+ }
}
return buf;
#undef BUFSIZE
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index f6c8c0a4a0..3df7fa768d 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -36,38 +36,34 @@
#define BUFEMPTY() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == \
NUL)
-/*
- * toupper() and tolower() that use the current locale.
- * Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
- * range 0 - 255. toupper()/tolower() on some systems can't handle others.
- * Note: It is often better to use mb_tolower() and mb_toupper(), because many
- * toupper() and tolower() implementations only work for ASCII.
- */
+// toupper() and tolower() that use the current locale.
+// Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
+// range 0 - 255. toupper()/tolower() on some systems can't handle others.
+// Note: It is often better to use mb_tolower() and mb_toupper(), because many
+// toupper() and tolower() implementations only work for ASCII.
#define TOUPPER_LOC toupper
#define TOLOWER_LOC tolower
-/* toupper() and tolower() for ASCII only and ignore the current locale. */
+// toupper() and tolower() for ASCII only and ignore the current locale.
# define TOUPPER_ASC(c) (((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A'))
# define TOLOWER_ASC(c) (((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A'))
-/* Like isalpha() but reject non-ASCII characters. Can't be used with a
- * special key (negative value). */
+// Like isalpha() but reject non-ASCII characters. Can't be used with a
+// special key (negative value).
# define ASCII_ISLOWER(c) ((unsigned)(c) >= 'a' && (unsigned)(c) <= 'z')
# define ASCII_ISUPPER(c) ((unsigned)(c) >= 'A' && (unsigned)(c) <= 'Z')
# define ASCII_ISALPHA(c) (ASCII_ISUPPER(c) || ASCII_ISLOWER(c))
# define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || ascii_isdigit(c))
-/* Returns empty string if it is NULL. */
+// Returns empty string if it is NULL.
#define EMPTY_IF_NULL(x) ((x) ? (x) : (char_u *)"")
-/*
- * Adjust chars in a language according to 'langmap' option.
- * NOTE that there is no noticeable overhead if 'langmap' is not set.
- * When set the overhead for characters < 256 is small.
- * Don't apply 'langmap' if the character comes from the Stuff buffer or from a
- * mapping and the langnoremap option was set.
- * The do-while is just to ignore a ';' after the macro.
- */
+// Adjust chars in a language according to 'langmap' option.
+// NOTE that there is no noticeable overhead if 'langmap' is not set.
+// When set the overhead for characters < 256 is small.
+// Don't apply 'langmap' if the character comes from the Stuff buffer or from a
+// mapping and the langnoremap option was set.
+// The do-while is just to ignore a ';' after the macro.
# define LANGMAP_ADJUST(c, condition) \
do { \
if (*p_langmap \
@@ -83,12 +79,12 @@
} \
} while (0)
-#define WRITEBIN "wb" /* no CR-LF translation */
+#define WRITEBIN "wb" // no CR-LF translation
#define READBIN "rb"
#define APPENDBIN "ab"
-/* mch_open_rw(): invoke os_open() with third argument for user R/W. */
-#if defined(UNIX) /* open in rw------- mode */
+// mch_open_rw(): invoke os_open() with third argument for user R/W.
+#if defined(UNIX) // open in rw------- mode
# define mch_open_rw(n, f) os_open((n), (f), (mode_t)0600)
#elif defined(WIN32)
# define mch_open_rw(n, f) os_open((n), (f), S_IREAD | S_IWRITE)
@@ -100,7 +96,7 @@
# define UTF_COMPOSINGLIKE(p1, p2) utf_composinglike((p1), (p2))
-/* Whether to draw the vertical bar on the right side of the cell. */
+// Whether to draw the vertical bar on the right side of the cell.
# define CURSOR_BAR_RIGHT (curwin->w_p_rl && (!(State & CMDLINE) || cmdmsg_rl))
// MB_PTR_ADV(): advance a pointer to the next character, taking care of
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 56d9030a7f..4a9f2371a2 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -10,6 +10,7 @@
#include <msgpack.h>
#include "nvim/ascii.h"
+#include "nvim/channel.h"
#include "nvim/vim.h"
#include "nvim/main.h"
#include "nvim/aucmd.h"
diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c
index 52e602cd94..6dd452b5af 100644
--- a/src/nvim/marktree.c
+++ b/src/nvim/marktree.c
@@ -197,7 +197,7 @@ static inline void split_node(MarkTree *b, mtnode_t *x, const int i)
// x must not be a full node (even if there might be internal space)
static inline void marktree_putp_aux(MarkTree *b, mtnode_t *x, mtkey_t k)
{
- int i = x->n - 1;
+ int i;
if (x->level == 0) {
i = marktree_getp_aux(x, k, 0);
if (i != x->n - 1) {
@@ -849,7 +849,8 @@ bool marktree_splice(MarkTree *b,
bool same_line = old_extent.row == 0 && new_extent.row == 0;
unrelative(start, &old_extent);
unrelative(start, &new_extent);
- MarkTreeIter itr[1], enditr[1];
+ MarkTreeIter itr[1] = { 0 };
+ MarkTreeIter enditr[1] = { 0 };
mtpos_t oldbase[MT_MAX_DEPTH];
@@ -905,7 +906,7 @@ continue_same_node:
refkey(b, itr->node, itr->i);
refkey(b, enditr->node, enditr->i);
} else {
- past_right = true;
+ past_right = true; // NOLINT
break;
}
}
@@ -1003,7 +1004,7 @@ void marktree_move_region(MarkTree *b,
mtpos_t start = { start_row, start_col }, size = { extent_row, extent_col };
mtpos_t end = size;
unrelative(start, &end);
- MarkTreeIter itr[1];
+ MarkTreeIter itr[1] = { 0 };
marktree_itr_get_ext(b, start, itr, false, true, NULL);
kvec_t(mtkey_t) saved = KV_INITIAL_VALUE;
while (itr->node) {
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 85e6697bfb..e67be60aa6 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -265,68 +265,70 @@ static struct
{ const char *name; int canon; }
enc_alias_table[] =
{
- {"ansi", IDX_LATIN_1},
- {"iso-8859-1", IDX_LATIN_1},
- {"latin2", IDX_ISO_2},
- {"latin3", IDX_ISO_3},
- {"latin4", IDX_ISO_4},
- {"cyrillic", IDX_ISO_5},
- {"arabic", IDX_ISO_6},
- {"greek", IDX_ISO_7},
- {"hebrew", IDX_ISO_8},
- {"latin5", IDX_ISO_9},
- {"turkish", IDX_ISO_9}, /* ? */
- {"latin6", IDX_ISO_10},
- {"nordic", IDX_ISO_10}, /* ? */
- {"thai", IDX_ISO_11}, /* ? */
- {"latin7", IDX_ISO_13},
- {"latin8", IDX_ISO_14},
- {"latin9", IDX_ISO_15},
- {"utf8", IDX_UTF8},
- {"unicode", IDX_UCS2},
- {"ucs2", IDX_UCS2},
- {"ucs2be", IDX_UCS2},
- {"ucs-2be", IDX_UCS2},
- {"ucs2le", IDX_UCS2LE},
- {"utf16", IDX_UTF16},
- {"utf16be", IDX_UTF16},
- {"utf-16be", IDX_UTF16},
- {"utf16le", IDX_UTF16LE},
- {"ucs4", IDX_UCS4},
- {"ucs4be", IDX_UCS4},
- {"ucs-4be", IDX_UCS4},
- {"ucs4le", IDX_UCS4LE},
- {"utf32", IDX_UCS4},
- {"utf-32", IDX_UCS4},
- {"utf32be", IDX_UCS4},
- {"utf-32be", IDX_UCS4},
- {"utf32le", IDX_UCS4LE},
- {"utf-32le", IDX_UCS4LE},
- {"932", IDX_CP932},
- {"949", IDX_CP949},
- {"936", IDX_CP936},
- {"gbk", IDX_CP936},
- {"950", IDX_CP950},
- {"eucjp", IDX_EUC_JP},
- {"unix-jis", IDX_EUC_JP},
- {"ujis", IDX_EUC_JP},
- {"shift-jis", IDX_SJIS},
- {"pck", IDX_SJIS}, /* Sun: PCK */
- {"euckr", IDX_EUC_KR},
- {"5601", IDX_EUC_KR}, /* Sun: KS C 5601 */
- {"euccn", IDX_EUC_CN},
- {"gb2312", IDX_EUC_CN},
- {"euctw", IDX_EUC_TW},
- {"japan", IDX_EUC_JP},
- {"korea", IDX_EUC_KR},
- {"prc", IDX_EUC_CN},
- {"chinese", IDX_EUC_CN},
- {"taiwan", IDX_EUC_TW},
- {"cp950", IDX_BIG5},
- {"950", IDX_BIG5},
- {"mac", IDX_MACROMAN},
- {"mac-roman", IDX_MACROMAN},
- {NULL, 0}
+ { "ansi", IDX_LATIN_1 },
+ { "iso-8859-1", IDX_LATIN_1 },
+ { "latin2", IDX_ISO_2 },
+ { "latin3", IDX_ISO_3 },
+ { "latin4", IDX_ISO_4 },
+ { "cyrillic", IDX_ISO_5 },
+ { "arabic", IDX_ISO_6 },
+ { "greek", IDX_ISO_7 },
+ { "hebrew", IDX_ISO_8 },
+ { "latin5", IDX_ISO_9 },
+ { "turkish", IDX_ISO_9 }, // ?
+ { "latin6", IDX_ISO_10 },
+ { "nordic", IDX_ISO_10 }, // ?
+ { "thai", IDX_ISO_11 }, // ?
+ { "latin7", IDX_ISO_13 },
+ { "latin8", IDX_ISO_14 },
+ { "latin9", IDX_ISO_15 },
+ { "utf8", IDX_UTF8 },
+ { "unicode", IDX_UCS2 },
+ { "ucs2", IDX_UCS2 },
+ { "ucs2be", IDX_UCS2 },
+ { "ucs-2be", IDX_UCS2 },
+ { "ucs2le", IDX_UCS2LE },
+ { "utf16", IDX_UTF16 },
+ { "utf16be", IDX_UTF16 },
+ { "utf-16be", IDX_UTF16 },
+ { "utf16le", IDX_UTF16LE },
+ { "ucs4", IDX_UCS4 },
+ { "ucs4be", IDX_UCS4 },
+ { "ucs-4be", IDX_UCS4 },
+ { "ucs4le", IDX_UCS4LE },
+ { "utf32", IDX_UCS4 },
+ { "utf-32", IDX_UCS4 },
+ { "utf32be", IDX_UCS4 },
+ { "utf-32be", IDX_UCS4 },
+ { "utf32le", IDX_UCS4LE },
+ { "utf-32le", IDX_UCS4LE },
+ { "932", IDX_CP932 },
+ { "949", IDX_CP949 },
+ { "936", IDX_CP936 },
+ { "gbk", IDX_CP936 },
+ { "950", IDX_CP950 },
+ { "eucjp", IDX_EUC_JP },
+ { "unix-jis", IDX_EUC_JP },
+ { "ujis", IDX_EUC_JP },
+ { "shift-jis", IDX_SJIS },
+ { "pck", IDX_SJIS }, // Sun: PCK
+ { "euckr", IDX_EUC_KR },
+ { "5601", IDX_EUC_KR }, // Sun: KS C 5601
+ { "euccn", IDX_EUC_CN },
+ { "gb2312", IDX_EUC_CN },
+ { "euctw", IDX_EUC_TW },
+ { "japan", IDX_EUC_JP },
+ { "korea", IDX_EUC_KR },
+ { "prc", IDX_EUC_CN },
+ { "zh-cn", IDX_EUC_CN },
+ { "chinese", IDX_EUC_CN },
+ { "zh-tw", IDX_EUC_TW },
+ { "taiwan", IDX_EUC_TW },
+ { "cp950", IDX_BIG5 },
+ { "950", IDX_BIG5 },
+ { "mac", IDX_MACROMAN },
+ { "mac-roman", IDX_MACROMAN },
+ { NULL, 0 }
};
/*
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 922b684120..6e074b3249 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -1504,16 +1504,15 @@ static time_t swapfile_info(char_u *fname)
int fd;
struct block0 b0;
time_t x = (time_t)0;
- char *p;
#ifdef UNIX
char uname[B0_UNAME_SIZE];
#endif
- /* print the swap file date */
+ // print the swap file date
FileInfo file_info;
if (os_fileinfo((char *)fname, &file_info)) {
#ifdef UNIX
- /* print name of owner of the file */
+ // print name of owner of the file
if (os_get_uname(file_info.stat.st_uid, uname, B0_UNAME_SIZE) == OK) {
MSG_PUTS(_(" owned by: "));
msg_outtrans((char_u *)uname);
@@ -1522,11 +1521,8 @@ static time_t swapfile_info(char_u *fname)
#endif
MSG_PUTS(_(" dated: "));
x = file_info.stat.st_mtim.tv_sec;
- p = ctime(&x); // includes '\n'
- if (p == NULL)
- MSG_PUTS("(invalid)\n");
- else
- MSG_PUTS(p);
+ char ctime_buf[50];
+ MSG_PUTS(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf)));
}
/*
@@ -1863,7 +1859,10 @@ errorret:
// Avoid giving this message for a recursive call, may happen
// when the GUI redraws part of the text.
recursive++;
- IEMSGN(_("E316: ml_get: cannot find line %" PRId64), lnum);
+ get_trans_bufname(buf);
+ shorten_dir(NameBuff);
+ iemsgf(_("E316: ml_get: cannot find line %" PRId64 " in buffer %d %s"),
+ lnum, buf->b_fnum, NameBuff);
recursive--;
}
goto errorret;
@@ -2391,21 +2390,32 @@ static int ml_append_int(
void ml_add_deleted_len(char_u *ptr, ssize_t len)
{
+ ml_add_deleted_len_buf(curbuf, ptr, len);
+}
+
+void ml_add_deleted_len_buf(buf_T *buf, char_u *ptr, ssize_t len)
+{
if (inhibit_delete_count) {
return;
}
if (len == -1) {
len = STRLEN(ptr);
}
- curbuf->deleted_bytes += len+1;
- if (curbuf->update_need_codepoints) {
- mb_utflen(ptr, len, &curbuf->deleted_codepoints,
- &curbuf->deleted_codeunits);
- curbuf->deleted_codepoints++; // NL char
- curbuf->deleted_codeunits++;
+ buf->deleted_bytes += len+1;
+ if (buf->update_need_codepoints) {
+ mb_utflen(ptr, len, &buf->deleted_codepoints,
+ &buf->deleted_codeunits);
+ buf->deleted_codepoints++; // NL char
+ buf->deleted_codeunits++;
}
}
+
+int ml_replace(linenr_T lnum, char_u *line, bool copy)
+{
+ return ml_replace_buf(curbuf, lnum, line, copy);
+}
+
/*
* Replace line lnum, with buffering, in current buffer.
*
@@ -2417,36 +2427,37 @@ void ml_add_deleted_len(char_u *ptr, ssize_t len)
*
* return FAIL for failure, OK otherwise
*/
-int ml_replace(linenr_T lnum, char_u *line, bool copy)
+int ml_replace_buf(buf_T *buf, linenr_T lnum, char_u *line, bool copy)
{
if (line == NULL) /* just checking... */
return FAIL;
- /* When starting up, we might still need to create the memfile */
- if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
+ // When starting up, we might still need to create the memfile
+ if (buf->b_ml.ml_mfp == NULL && open_buffer(false, NULL, 0) == FAIL) {
return FAIL;
+ }
bool readlen = true;
if (copy) {
line = vim_strsave(line);
}
- if (curbuf->b_ml.ml_line_lnum != lnum) { // other line buffered
- ml_flush_line(curbuf); // flush it
- } else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) { // same line allocated
- ml_add_deleted_len(curbuf->b_ml.ml_line_ptr, -1);
+ if (buf->b_ml.ml_line_lnum != lnum) { // other line buffered
+ ml_flush_line(buf); // flush it
+ } else if (buf->b_ml.ml_flags & ML_LINE_DIRTY) { // same line allocated
+ ml_add_deleted_len(buf->b_ml.ml_line_ptr, -1);
readlen = false; // already added the length
- xfree(curbuf->b_ml.ml_line_ptr); // free it
+ xfree(buf->b_ml.ml_line_ptr); // free it
}
- if (readlen && kv_size(curbuf->update_callbacks)) {
- ml_add_deleted_len(ml_get_buf(curbuf, lnum, false), -1);
+ if (readlen && kv_size(buf->update_callbacks)) {
+ ml_add_deleted_len(ml_get_buf(buf, lnum, false), -1);
}
- curbuf->b_ml.ml_line_ptr = line;
- curbuf->b_ml.ml_line_lnum = lnum;
- curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
+ buf->b_ml.ml_line_ptr = line;
+ buf->b_ml.ml_line_lnum = lnum;
+ buf->b_ml.ml_flags = (buf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
return OK;
}
@@ -3264,15 +3275,13 @@ attention_message (
)
{
assert(buf->b_fname != NULL);
- time_t x, sx;
- char *p;
++no_wait_return;
(void)EMSG(_("E325: ATTENTION"));
MSG_PUTS(_("\nFound a swap file by the name \""));
msg_home_replace(fname);
MSG_PUTS("\"\n");
- sx = swapfile_info(fname);
+ const time_t swap_mtime = swapfile_info(fname);
MSG_PUTS(_("While opening file \""));
msg_outtrans(buf->b_fname);
MSG_PUTS("\"\n");
@@ -3281,14 +3290,12 @@ attention_message (
MSG_PUTS(_(" CANNOT BE FOUND"));
} else {
MSG_PUTS(_(" dated: "));
- x = file_info.stat.st_mtim.tv_sec;
- p = ctime(&x); // includes '\n'
- if (p == NULL)
- MSG_PUTS("(invalid)\n");
- else
- MSG_PUTS(p);
- if (sx != 0 && x > sx)
+ time_t x = file_info.stat.st_mtim.tv_sec;
+ char ctime_buf[50];
+ MSG_PUTS(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf)));
+ if (swap_mtime != 0 && x > swap_mtime) {
MSG_PUTS(_(" NEWER than swap file!\n"));
+ }
}
/* Some of these messages are long to allow translation to
* other languages. */
@@ -3994,8 +4001,8 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
int ffdos = !no_ff && (get_fileformat(buf) == EOL_DOS);
int extra = 0;
- /* take care of cached line first */
- ml_flush_line(curbuf);
+ // take care of cached line first
+ ml_flush_line(buf);
if (buf->b_ml.ml_usedchunks == -1
|| buf->b_ml.ml_chunksize == NULL
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 18c4f1fff1..a3e0130465 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -868,7 +868,7 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
if (*menu->strings[bit] == NUL) {
msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
} else {
- msg_outtrans_special(menu->strings[bit], false);
+ msg_outtrans_special(menu->strings[bit], false, 0);
}
}
} else {
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 94729dfd2a..a12e665099 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1521,7 +1521,8 @@ void msg_make(char_u *arg)
/// the character/string -- webb
int msg_outtrans_special(
const char_u *strstart,
- int from ///< true for LHS of a mapping
+ bool from, ///< true for LHS of a mapping
+ int maxlen ///< screen columns, 0 for unlimeted
)
{
if (strstart == NULL) {
@@ -1541,6 +1542,9 @@ int msg_outtrans_special(
string = str2special((const char **)&str, from, false);
}
const int len = vim_strsize((char_u *)string);
+ if (maxlen > 0 && retval + len >= maxlen) {
+ break;
+ }
// Highlight special keys
msg_puts_attr(string, (len > 1
&& (*mb_ptr2len)((char_u *)string) <= 1
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 8c19a2de66..e7fb38e801 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -73,7 +73,8 @@ static garray_T ga_users = GA_EMPTY_INIT_VALUE;
* If "include_space" is set, include trailing whitespace while calculating the
* length.
*/
-int get_leader_len(char_u *line, char_u **flags, int backward, int include_space)
+int get_leader_len(char_u *line, char_u **flags,
+ bool backward, bool include_space)
{
int i, j;
int result;
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index dab2e44890..32d8352d9b 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -73,6 +73,7 @@ int jump_to_mouse(int flags,
int col = mouse_col;
int grid = mouse_grid;
int mouse_char;
+ int fdc = 0;
mouse_past_bottom = false;
mouse_past_eol = false;
@@ -109,12 +110,12 @@ retnomove:
if (flags & MOUSE_SETPOS)
goto retnomove; // ugly goto...
- // Remember the character under the mouse, it might be a '-' or '+' in the
- // fold column. NB: only works for ASCII chars!
+ // Remember the character under the mouse, might be one of foldclose or
+ // foldopen fillchars in the fold column.
if (row >= 0 && row < Rows && col >= 0 && col <= Columns
&& default_grid.chars != NULL) {
- mouse_char = default_grid.chars[default_grid.line_offset[row]
- + (unsigned)col][0];
+ mouse_char = utf_ptr2char(default_grid.chars[default_grid.line_offset[row]
+ + (unsigned)col]);
} else {
mouse_char = ' ';
}
@@ -131,6 +132,7 @@ retnomove:
if (wp == NULL) {
return IN_UNKNOWN;
}
+ fdc = win_fdccol_count(wp);
dragwin = NULL;
// winpos and height may change in win_enter()!
if (grid == DEFAULT_GRID_HANDLE && row >= wp->w_height) {
@@ -165,9 +167,8 @@ retnomove:
|| (!on_status_line
&& !on_sep_line
&& (wp->w_p_rl
- ? col < wp->w_width_inner - wp->w_p_fdc
- : col >= wp->w_p_fdc + (cmdwin_type == 0 && wp == curwin
- ? 0 : 1))
+ ? col < wp->w_width_inner - fdc
+ : col >= fdc + (cmdwin_type == 0 && wp == curwin ? 0 : 1))
&& (flags & MOUSE_MAY_STOP_VIS)))) {
end_visual_mode();
redraw_curbuf_later(INVERTED); // delete the inversion
@@ -305,8 +306,8 @@ retnomove:
}
// Check for position outside of the fold column.
- if (curwin->w_p_rl ? col < curwin->w_width_inner - curwin->w_p_fdc :
- col >= curwin->w_p_fdc + (cmdwin_type == 0 ? 0 : 1)) {
+ if (curwin->w_p_rl ? col < curwin->w_width_inner - fdc :
+ col >= fdc + (cmdwin_type == 0 ? 0 : 1)) {
mouse_char = ' ';
}
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 3ae4f32a83..d4f82bc601 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -86,6 +86,7 @@ static void comp_botline(win_T *wp)
/* wp->w_botline is the line that is just below the window */
wp->w_botline = lnum;
wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+ wp->w_viewport_invalid = true;
set_empty_rows(wp, done);
@@ -142,7 +143,8 @@ void update_topline(void)
int old_topfill;
bool check_topline = false;
bool check_botline = false;
- long save_so = p_so;
+ long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
+ long save_so = *so_ptr;
// If there is no valid screen and when the window height is zero just use
// the cursor line.
@@ -150,6 +152,7 @@ void update_topline(void)
curwin->w_topline = curwin->w_cursor.lnum;
curwin->w_botline = curwin->w_topline;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+ curwin->w_viewport_invalid = true;
curwin->w_scbind_pos = 1;
return;
}
@@ -158,9 +161,10 @@ void update_topline(void)
if (curwin->w_valid & VALID_TOPLINE)
return;
- /* When dragging with the mouse, don't scroll that quickly */
- if (mouse_dragging > 0)
- p_so = mouse_dragging - 1;
+ // When dragging with the mouse, don't scroll that quickly
+ if (mouse_dragging > 0) {
+ *so_ptr = mouse_dragging - 1;
+ }
old_topline = curwin->w_topline;
old_topfill = curwin->w_topfill;
@@ -173,6 +177,7 @@ void update_topline(void)
curwin->w_topline = 1;
curwin->w_botline = 2;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+ curwin->w_viewport_invalid = true;
curwin->w_scbind_pos = 1;
}
/*
@@ -206,15 +211,17 @@ void update_topline(void)
* scrolled). */
n = 0;
for (linenr_T lnum = curwin->w_cursor.lnum;
- lnum < curwin->w_topline + p_so; ++lnum) {
- ++n;
- /* stop at end of file or when we know we are far off */
- if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight)
+ lnum < curwin->w_topline + *so_ptr; lnum++) {
+ n++;
+ // stop at end of file or when we know we are far off
+ if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight) {
break;
+ }
(void)hasFolding(lnum, NULL, &lnum);
}
- } else
- n = curwin->w_topline + p_so - curwin->w_cursor.lnum;
+ } else {
+ n = curwin->w_topline + *so_ptr - curwin->w_cursor.lnum;
+ }
/* If we weren't very close to begin with, we scroll to put the
* cursor in the middle of the window. Otherwise put the cursor
@@ -247,7 +254,7 @@ void update_topline(void)
if (curwin->w_botline <= curbuf->b_ml.ml_line_count) {
if (curwin->w_cursor.lnum < curwin->w_botline) {
if (((long)curwin->w_cursor.lnum
- >= (long)curwin->w_botline - p_so
+ >= (long)curwin->w_botline - *so_ptr
|| hasAnyFolding(curwin)
)) {
lineoff_T loff;
@@ -266,13 +273,15 @@ void update_topline(void)
&& (loff.lnum + 1 < curwin->w_botline || loff.fill == 0)
) {
n += loff.height;
- if (n >= p_so)
+ if (n >= *so_ptr) {
break;
+ }
botline_forw(&loff);
}
- if (n >= p_so)
- /* sufficient context, no need to scroll */
+ if (n >= *so_ptr) {
+ // sufficient context, no need to scroll
check_botline = false;
+ }
} else {
/* sufficient context, no need to scroll */
check_botline = false;
@@ -285,7 +294,7 @@ void update_topline(void)
* botline - p_so (approximation of how much will be
* scrolled). */
for (linenr_T lnum = curwin->w_cursor.lnum;
- lnum >= curwin->w_botline - p_so; lnum--) {
+ lnum >= curwin->w_botline - *so_ptr; lnum--) {
line_count++;
// stop at end of file or when we know we are far off
if (lnum <= 0 || line_count > curwin->w_height_inner + 1) {
@@ -295,7 +304,7 @@ void update_topline(void)
}
} else
line_count = curwin->w_cursor.lnum - curwin->w_botline
- + 1 + p_so;
+ + 1 + *so_ptr;
if (line_count <= curwin->w_height_inner + 1) {
scroll_cursor_bot(scrolljump_value(), false);
} else {
@@ -305,6 +314,7 @@ void update_topline(void)
}
}
curwin->w_valid |= VALID_TOPLINE;
+ curwin->w_viewport_invalid = true;
win_check_anchored_floats(curwin);
/*
@@ -324,7 +334,7 @@ void update_topline(void)
validate_cursor();
}
- p_so = save_so;
+ *so_ptr = save_so;
}
/*
@@ -356,25 +366,28 @@ static int scrolljump_value(void)
*/
static bool check_top_offset(void)
{
- if (curwin->w_cursor.lnum < curwin->w_topline + p_so
+ long so = get_scrolloff_value();
+ if (curwin->w_cursor.lnum < curwin->w_topline + so
|| hasAnyFolding(curwin)
) {
lineoff_T loff;
loff.lnum = curwin->w_cursor.lnum;
loff.fill = 0;
- int n = curwin->w_topfill; /* always have this context */
- /* Count the visible screen lines above the cursor line. */
- while (n < p_so) {
+ int n = curwin->w_topfill; // always have this context
+ // Count the visible screen lines above the cursor line.
+ while (n < so) {
topline_back(&loff);
- /* Stop when included a line above the window. */
+ // Stop when included a line above the window.
if (loff.lnum < curwin->w_topline
|| (loff.lnum == curwin->w_topline && loff.fill > 0)
- )
+ ) {
break;
+ }
n += loff.height;
}
- if (n < p_so)
+ if (n < so) {
return true;
+ }
}
return false;
}
@@ -398,6 +411,7 @@ void check_cursor_moved(win_T *wp)
|VALID_CHEIGHT|VALID_CROW|VALID_TOPLINE);
wp->w_valid_cursor = wp->w_cursor;
wp->w_valid_leftcol = wp->w_leftcol;
+ wp->w_viewport_invalid = true;
} else if (wp->w_cursor.col != wp->w_valid_cursor.col
|| wp->w_leftcol != wp->w_valid_leftcol
|| wp->w_cursor.coladd != wp->w_valid_cursor.coladd
@@ -406,6 +420,7 @@ void check_cursor_moved(win_T *wp)
wp->w_valid_cursor.col = wp->w_cursor.col;
wp->w_valid_leftcol = wp->w_leftcol;
wp->w_valid_cursor.coladd = wp->w_cursor.coladd;
+ wp->w_viewport_invalid = true;
}
}
@@ -674,7 +689,7 @@ int win_col_off(win_T *wp)
{
return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0)
+ (cmdwin_type == 0 || wp != curwin ? 0 : 1)
- + (int)wp->w_p_fdc
+ + win_fdccol_count(wp)
+ (win_signcol_count(wp) * win_signcol_width(wp));
}
@@ -714,6 +729,8 @@ void curs_columns(
colnr_T startcol;
colnr_T endcol;
colnr_T prev_skipcol;
+ long so = get_scrolloff_value();
+ long siso = get_sidescrolloff_value();
/*
* First make sure that w_topline is valid (after moving the cursor).
@@ -785,10 +802,10 @@ void curs_columns(
* If we get closer to the edge than 'sidescrolloff', scroll a little
* extra
*/
- assert(p_siso <= INT_MAX);
- int off_left = startcol - curwin->w_leftcol - (int)p_siso;
+ assert(siso <= INT_MAX);
+ int off_left = startcol - curwin->w_leftcol - (int)siso;
int off_right =
- endcol - curwin->w_leftcol - curwin->w_width_inner + (int)p_siso + 1;
+ endcol - curwin->w_leftcol - curwin->w_width_inner + (int)siso + 1;
if (off_left < 0 || off_right > 0) {
int diff = (off_left < 0) ? -off_left: off_right;
@@ -834,7 +851,7 @@ void curs_columns(
int plines = 0;
if ((curwin->w_wrow >= curwin->w_height_inner
|| ((prev_skipcol > 0
- || curwin->w_wrow + p_so >= curwin->w_height_inner)
+ || curwin->w_wrow + so >= curwin->w_height_inner)
&& (plines =
plines_win_nofill(curwin, curwin->w_cursor.lnum, false)) - 1
>= curwin->w_height_inner))
@@ -850,17 +867,18 @@ void curs_columns(
* 2: Less than "p_so" lines below
* 3: both of them */
extra = 0;
- if (curwin->w_skipcol + p_so * width > curwin->w_virtcol)
+ if (curwin->w_skipcol + so * width > curwin->w_virtcol) {
extra = 1;
- /* Compute last display line of the buffer line that we want at the
- * bottom of the window. */
+ }
+ // Compute last display line of the buffer line that we want at the
+ // bottom of the window.
if (plines == 0) {
plines = plines_win(curwin, curwin->w_cursor.lnum, false);
}
plines--;
- if (plines > curwin->w_wrow + p_so) {
- assert(p_so <= INT_MAX);
- n = curwin->w_wrow + (int)p_so;
+ if (plines > curwin->w_wrow + so) {
+ assert(so <= INT_MAX);
+ n = curwin->w_wrow + (int)so;
} else {
n = plines;
}
@@ -868,7 +886,7 @@ void curs_columns(
extra += 2;
}
- if (extra == 3 || plines < p_so * 2) {
+ if (extra == 3 || plines < so * 2) {
// not enough room for 'scrolloff', put cursor in the middle
n = curwin->w_virtcol / width;
if (n > curwin->w_height_inner / 2) {
@@ -882,9 +900,9 @@ void curs_columns(
}
curwin->w_skipcol = n * width;
} else if (extra == 1) {
- /* less then 'scrolloff' lines above, decrease skipcol */
- assert(p_so <= INT_MAX);
- extra = (curwin->w_skipcol + (int)p_so * width - curwin->w_virtcol
+ // less then 'scrolloff' lines above, decrease skipcol
+ assert(so <= INT_MAX);
+ extra = (curwin->w_skipcol + (int)so * width - curwin->w_virtcol
+ width - 1) / width;
if (extra > 0) {
if ((colnr_T)(extra * width) > curwin->w_skipcol)
@@ -1206,7 +1224,7 @@ void scrolldown_clamp(void)
end_row += curwin->w_cline_height - 1 -
curwin->w_virtcol / curwin->w_width_inner;
}
- if (end_row < curwin->w_height_inner - p_so) {
+ if (end_row < curwin->w_height_inner - get_scrolloff_value()) {
if (can_fill) {
++curwin->w_topfill;
check_topfill(curwin, true);
@@ -1246,14 +1264,14 @@ void scrollup_clamp(void)
validate_virtcol();
start_row -= curwin->w_virtcol / curwin->w_width_inner;
}
- if (start_row >= p_so) {
- if (curwin->w_topfill > 0)
- --curwin->w_topfill;
- else {
+ if (start_row >= get_scrolloff_value()) {
+ if (curwin->w_topfill > 0) {
+ curwin->w_topfill--;
+ } else {
(void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
- ++curwin->w_topline;
+ curwin->w_topline++;
}
- ++curwin->w_botline; /* approximate w_botline */
+ curwin->w_botline++; // approximate w_botline
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
}
}
@@ -1349,8 +1367,7 @@ void scroll_cursor_top(int min_scroll, int always)
linenr_T old_topline = curwin->w_topline;
linenr_T old_topfill = curwin->w_topfill;
linenr_T new_topline;
- assert(p_so <= INT_MAX);
- int off = (int)p_so;
+ int off = (int)get_scrolloff_value();
if (mouse_dragging > 0)
off = mouse_dragging - 1;
@@ -1447,6 +1464,7 @@ void scroll_cursor_top(int min_scroll, int always)
curwin->w_valid &=
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
curwin->w_valid |= VALID_TOPLINE;
+ curwin->w_viewport_invalid = true;
}
}
@@ -1492,7 +1510,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
linenr_T old_botline = curwin->w_botline;
int old_valid = curwin->w_valid;
int old_empty_rows = curwin->w_empty_rows;
- linenr_T cln = curwin->w_cursor.lnum; /* Cursor Line Number */
+ linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
+ long so = get_scrolloff_value();
if (set_topbot) {
used = 0;
@@ -1551,7 +1570,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
/* Stop when scrolled nothing or at least "min_scroll", found "extra"
* context for 'scrolloff' and counted all lines below the window. */
if ((((scrolled <= 0 || scrolled >= min_scroll)
- && extra >= (mouse_dragging > 0 ? mouse_dragging - 1 : p_so))
+ && extra >= (mouse_dragging > 0 ? mouse_dragging - 1 : so))
|| boff.lnum + 1 > curbuf->b_ml.ml_line_count)
&& loff.lnum <= curwin->w_botline
&& (loff.lnum < curwin->w_botline
@@ -1589,7 +1608,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
if (used > curwin->w_height_inner) {
break;
}
- if (extra < (mouse_dragging > 0 ? mouse_dragging - 1 : p_so)
+ if (extra < (mouse_dragging > 0 ? mouse_dragging - 1 : so)
|| scrolled < min_scroll) {
extra += boff.height;
if (boff.lnum >= curwin->w_botline
@@ -1650,6 +1669,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
curwin->w_valid = old_valid;
}
curwin->w_valid |= VALID_TOPLINE;
+ curwin->w_viewport_invalid = true;
}
/// Recompute topline to put the cursor halfway across the window
@@ -1724,9 +1744,8 @@ void cursor_correct(void)
* How many lines we would like to have above/below the cursor depends on
* whether the first/last line of the file is on screen.
*/
- assert(p_so <= INT_MAX);
- int above_wanted = (int)p_so;
- int below_wanted = (int)p_so;
+ int above_wanted = (int)get_scrolloff_value();
+ int below_wanted = (int)get_scrolloff_value();
if (mouse_dragging > 0) {
above_wanted = mouse_dragging - 1;
below_wanted = mouse_dragging - 1;
@@ -1807,6 +1826,7 @@ void cursor_correct(void)
}
}
curwin->w_valid |= VALID_TOPLINE;
+ curwin->w_viewport_invalid = true;
}
@@ -1821,6 +1841,7 @@ int onepage(Direction dir, long count)
int retval = OK;
lineoff_T loff;
linenr_T old_topline = curwin->w_topline;
+ long so = get_scrolloff_value();
if (curbuf->b_ml.ml_line_count == 1) { /* nothing to do */
beep_flush();
@@ -1836,7 +1857,7 @@ int onepage(Direction dir, long count)
* last line.
*/
if (dir == FORWARD
- ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - p_so)
+ ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - so)
&& curwin->w_botline > curbuf->b_ml.ml_line_count)
: (curwin->w_topline == 1
&& curwin->w_topfill ==
diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h
index 9ff5abdc5f..90e1c7d48b 100644
--- a/src/nvim/msgpack_rpc/channel.h
+++ b/src/nvim/msgpack_rpc/channel.h
@@ -15,7 +15,7 @@
/// HACK: os/input.c drains this queue immediately before blocking for input.
/// Events on this queue are async-safe, but they need the resolved state
/// of os_inchar(), so they are processed "just-in-time".
-MultiQueue *ch_before_blocking_events;
+EXTERN MultiQueue *ch_before_blocking_events INIT(= NULL);
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c
index 6168f097a7..062ea784ca 100644
--- a/src/nvim/msgpack_rpc/server.c
+++ b/src/nvim/msgpack_rpc/server.c
@@ -151,7 +151,7 @@ int server_start(const char *endpoint)
result = socket_watcher_start(watcher, MAX_CONNECTIONS, connection_cb);
if (result < 0) {
- WLOG("Failed to start server: %s", uv_strerror(result));
+ WLOG("Failed to start server: %s: %s", uv_strerror(result), watcher->addr);
socket_watcher_close(watcher, free_server);
return result;
}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index c53348db0d..2cc492b652 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -615,7 +615,9 @@ static void normal_redraw_mode_message(NormalState *s)
kmsg = keep_msg;
keep_msg = NULL;
- // showmode() will clear keep_msg, but we want to use it anyway
+ // Showmode() will clear keep_msg, but we want to use it anyway.
+ // First update w_topline.
+ setcursor();
update_screen(0);
// now reset it, otherwise it's put in the history again
keep_msg = kmsg;
@@ -623,6 +625,7 @@ static void normal_redraw_mode_message(NormalState *s)
xfree(kmsg);
}
setcursor();
+ ui_cursor_shape(); // show different cursor shape
ui_flush();
if (msg_scroll || emsg_on_display) {
os_delay(1000L, true); // wait at least one second
@@ -1964,8 +1967,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FOLD:
- VIsual_reselect = false; /* don't reselect now */
- foldCreate(oap->start.lnum, oap->end.lnum);
+ VIsual_reselect = false; // don't reselect now
+ foldCreate(curwin, oap->start.lnum, oap->end.lnum);
break;
case OP_FOLDOPEN:
@@ -1983,9 +1986,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
case OP_FOLDDEL:
case OP_FOLDDELREC:
- VIsual_reselect = false; /* don't reselect now */
- deleteFold(oap->start.lnum, oap->end.lnum,
- oap->op_type == OP_FOLDDELREC, oap->is_VIsual);
+ VIsual_reselect = false; // don't reselect now
+ deleteFold(curwin, oap->start.lnum, oap->end.lnum,
+ oap->op_type == OP_FOLDDELREC, oap->is_VIsual);
break;
case OP_NR_ADD:
@@ -2584,12 +2587,13 @@ do_mouse (
/* Set global flag that we are extending the Visual area with mouse
* dragging; temporarily minimize 'scrolloff'. */
- if (VIsual_active && is_drag && p_so) {
- /* In the very first line, allow scrolling one line */
- if (mouse_row == 0)
+ if (VIsual_active && is_drag && get_scrolloff_value()) {
+ // In the very first line, allow scrolling one line
+ if (mouse_row == 0) {
mouse_dragging = 2;
- else
+ } else {
mouse_dragging = 1;
+ }
}
/* When dragging the mouse above the window, scroll down. */
@@ -4089,9 +4093,9 @@ void scroll_redraw(int up, long count)
scrollup(count, true);
else
scrolldown(count, true);
- if (p_so) {
- /* Adjust the cursor position for 'scrolloff'. Mark w_topline as
- * valid, otherwise the screen jumps back at the end of the file. */
+ if (get_scrolloff_value()) {
+ // Adjust the cursor position for 'scrolloff'. Mark w_topline as
+ // valid, otherwise the screen jumps back at the end of the file.
cursor_correct();
check_cursor_moved(curwin);
curwin->w_valid |= VALID_TOPLINE;
@@ -4120,6 +4124,7 @@ void scroll_redraw(int up, long count)
}
if (curwin->w_cursor.lnum != prev_lnum)
coladvance(curwin->w_curswant);
+ curwin->w_viewport_invalid = true;
redraw_later(VALID);
}
@@ -4135,8 +4140,8 @@ static void nv_zet(cmdarg_T *cap)
int old_fen = curwin->w_p_fen;
bool undo = false;
- assert(p_siso <= INT_MAX);
- int l_p_siso = (int)p_siso;
+ int l_p_siso = (int)get_sidescrolloff_value();
+ assert(l_p_siso <= INT_MAX);
if (ascii_isdigit(nchar)) {
/*
@@ -4340,11 +4345,12 @@ dozet:
/* "zD": delete fold at cursor recursively */
case 'd':
case 'D': if (foldManualAllowed(false)) {
- if (VIsual_active)
+ if (VIsual_active) {
nv_operator(cap);
- else
- deleteFold(curwin->w_cursor.lnum,
- curwin->w_cursor.lnum, nchar == 'D', false);
+ } else {
+ deleteFold(curwin, curwin->w_cursor.lnum,
+ curwin->w_cursor.lnum, nchar == 'D', false);
+ }
}
break;
@@ -4352,11 +4358,11 @@ dozet:
case 'E': if (foldmethodIsManual(curwin)) {
clearFolding(curwin);
changed_window_setting();
- } else if (foldmethodIsMarker(curwin))
- deleteFold((linenr_T)1, curbuf->b_ml.ml_line_count,
- true, false);
- else
+ } else if (foldmethodIsMarker(curwin)) {
+ deleteFold(curwin, (linenr_T)1, curbuf->b_ml.ml_line_count, true, false);
+ } else {
EMSG(_("E352: Cannot erase folds with current 'foldmethod'"));
+ }
break;
/* "zn": fold none: reset 'foldenable' */
@@ -4458,16 +4464,16 @@ dozet:
case 'r':
curwin->w_p_fdl += cap->count1;
{
- int d = getDeepestNesting();
+ int d = getDeepestNesting(curwin);
if (curwin->w_p_fdl >= d) {
curwin->w_p_fdl = d;
}
}
break;
- /* "zR": open all folds */
- case 'R': curwin->w_p_fdl = getDeepestNesting();
- old_fdl = -1; /* force an update */
+ case 'R': // "zR": open all folds
+ curwin->w_p_fdl = getDeepestNesting(curwin);
+ old_fdl = -1; // force an update
break;
case 'j': /* "zj" move to next fold downwards */
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 735a33ca97..a70224f98b 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -261,7 +261,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
sprintf((char *)IObuff, _("%" PRId64 " lines %sed %d times"),
(int64_t)oap->line_count, s, amount);
}
- msg(IObuff);
+ msg_attr_keep(IObuff, 0, true, false);
}
/*
@@ -842,6 +842,15 @@ static bool is_append_register(int regname)
return ASCII_ISUPPER(regname);
}
+/// @see get_yank_register
+/// @returns true when register should be inserted literally
+/// (selection or clipboard)
+static inline bool is_literal_register(int regname)
+ FUNC_ATTR_CONST
+{
+ return regname == '*' || regname == '+';
+}
+
/// Returns a copy of contents in register `name`
/// for use in do_put. Should be freed by caller.
yankreg_T *copy_register(int name)
@@ -1152,11 +1161,12 @@ static int put_in_typebuf(
*/
int insert_reg(
int regname,
- int literally /* insert literally, not as if typed */
+ bool literally_arg // insert literally, not as if typed
)
{
int retval = OK;
bool allocated;
+ const bool literally = literally_arg || is_literal_register(regname);
/*
* It is possible to get into an endless loop by having CTRL-R a in
@@ -1326,12 +1336,14 @@ bool get_spec_reg(
/// register contents will be interpreted as commands.
///
/// @param regname Register name.
-/// @param literally Insert text literally instead of "as typed".
+/// @param literally_arg 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)
+bool cmdline_paste_reg(int regname, bool literally_arg, bool remcr)
{
+ const bool literally = literally_arg || is_literal_register(regname);
+
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
if (reg->y_array == NULL)
return FAIL;
@@ -2534,7 +2546,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
case kMTCharWise:
{
colnr_T startcol = 0, endcol = MAXCOL;
- int is_oneChar = FALSE;
+ int is_oneChar = false;
colnr_T cs, ce;
p = ml_get(lnum);
bd.startspaces = 0;
@@ -2565,8 +2577,8 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
&& utf_head_off(p, p + endcol) == 0)) {
if (oap->start.lnum == oap->end.lnum
&& oap->start.col == oap->end.col) {
- /* Special case: inside a single char */
- is_oneChar = TRUE;
+ // Special case: inside a single char
+ is_oneChar = true;
bd.startspaces = oap->end.coladd
- oap->start.coladd + oap->inclusive;
endcol = startcol;
@@ -4425,8 +4437,8 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
bdp->textlen = 0;
bdp->start_vcol = 0;
bdp->end_vcol = 0;
- bdp->is_short = FALSE;
- bdp->is_oneChar = FALSE;
+ bdp->is_short = false;
+ bdp->is_oneChar = false;
bdp->pre_whitesp = 0;
bdp->pre_whitesp_c = 0;
bdp->end_char_vcols = 0;
@@ -4452,9 +4464,10 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
bdp->start_char_vcols = incr;
if (bdp->start_vcol < oap->start_vcol) { /* line too short */
bdp->end_vcol = bdp->start_vcol;
- bdp->is_short = TRUE;
- if (!is_del || oap->op_type == OP_APPEND)
+ bdp->is_short = true;
+ if (!is_del || oap->op_type == OP_APPEND) {
bdp->endspaces = oap->end_vcol - oap->start_vcol + 1;
+ }
} else {
/* notice: this converts partly selected Multibyte characters to
* spaces, too. */
@@ -4463,11 +4476,11 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
bdp->startspaces = bdp->start_char_vcols - bdp->startspaces;
pend = pstart;
bdp->end_vcol = bdp->start_vcol;
- if (bdp->end_vcol > oap->end_vcol) { /* it's all in one character */
- bdp->is_oneChar = TRUE;
- if (oap->op_type == OP_INSERT)
+ if (bdp->end_vcol > oap->end_vcol) { // it's all in one character
+ bdp->is_oneChar = true;
+ if (oap->op_type == OP_INSERT) {
bdp->endspaces = bdp->start_char_vcols - bdp->startspaces;
- else if (oap->op_type == OP_APPEND) {
+ } else if (oap->op_type == OP_APPEND) {
bdp->startspaces += oap->end_vcol - oap->start_vcol + 1;
bdp->endspaces = bdp->start_char_vcols - bdp->startspaces;
} else {
@@ -4492,17 +4505,16 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
if (bdp->end_vcol <= oap->end_vcol
&& (!is_del
|| oap->op_type == OP_APPEND
- || oap->op_type == OP_REPLACE)) { /* line too short */
- bdp->is_short = TRUE;
- /* Alternative: include spaces to fill up the block.
- * Disadvantage: can lead to trailing spaces when the line is
- * short where the text is put */
- /* if (!is_del || oap->op_type == OP_APPEND) */
- if (oap->op_type == OP_APPEND || virtual_op)
+ || oap->op_type == OP_REPLACE)) { // line too short
+ bdp->is_short = true;
+ // Alternative: include spaces to fill up the block.
+ // Disadvantage: can lead to trailing spaces when the line is
+ // short where the text is put
+ // if (!is_del || oap->op_type == OP_APPEND)
+ if (oap->op_type == OP_APPEND || virtual_op) {
bdp->endspaces = oap->end_vcol - bdp->end_vcol
+ oap->inclusive;
- else
- bdp->endspaces = 0; /* replace doesn't add characters */
+ }
} else if (bdp->end_vcol > oap->end_vcol) {
bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
if (!is_del && bdp->endspaces) {
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 100902897a..25a8d432ee 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -315,6 +315,9 @@ static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2",
"auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9",
"yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6", "yes:7", "yes:8",
"yes:9", NULL };
+static char *(p_fdc_values[]) = { "auto:1", "auto:2",
+ "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9",
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
/// All possible flags for 'shm'.
static char_u SHM_ALL[] = {
@@ -616,11 +619,9 @@ static void set_runtimepath_default(void)
#undef NVIM_SIZE
-/*
- * Initialize the options, first part.
- *
- * Called only once from main(), just after creating the first buffer.
- */
+/// Initialize the options, first part.
+///
+/// Called only once from main(), just after creating the first buffer.
void set_init_1(void)
{
int opt_idx;
@@ -865,10 +866,8 @@ void set_init_1(void)
set_helplang_default(get_mess_lang());
}
-/*
- * Set an option to its default value.
- * This does not take care of side effects!
- */
+/// Set an option to its default value.
+/// This does not take care of side effects!
static void
set_option_default(
int opt_idx,
@@ -901,11 +900,19 @@ set_option_default(
if (options[opt_idx].indir == PV_SCROLL) {
win_comp_scroll(curwin);
} else {
- *(long *)varp = (long)(intptr_t)options[opt_idx].def_val[dvi];
+ long def_val = (long)options[opt_idx].def_val[dvi];
+ if ((long *)varp == &curwin->w_p_so
+ || (long *)varp == &curwin->w_p_siso) {
+ // 'scrolloff' and 'sidescrolloff' local values have a
+ // different default value than the global default.
+ *(long *)varp = -1;
+ } else {
+ *(long *)varp = def_val;
+ }
// May also set global value for local option.
if (both) {
*(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
- *(long *)varp;
+ def_val;
}
}
} else { // P_BOOL
@@ -931,9 +938,7 @@ set_option_default(
set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
}
-/*
- * Set all options (except terminal options) to their default value.
- */
+/// Set all options (except terminal options) to their default value.
static void
set_options_default(
int opt_flags // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
@@ -976,10 +981,8 @@ static void set_string_default(const char *name, char *val, bool allocated)
}
}
-/*
- * Set the Vi-default value of a number option.
- * Used for 'lines' and 'columns'.
- */
+/// Set the Vi-default value of a number option.
+/// Used for 'lines' and 'columns'.
void set_number_default(char *name, long val)
{
int opt_idx;
@@ -1106,10 +1109,8 @@ void set_init_3(void)
set_title_defaults(); // 'title', 'icon'
}
-/*
- * When 'helplang' is still at its default value, set it to "lang".
- * Only the first two characters of "lang" are used.
- */
+/// When 'helplang' is still at its default value, set it to "lang".
+/// Only the first two characters of "lang" are used.
void set_helplang_default(const char *lang)
{
if (lang == NULL) {
@@ -1141,13 +1142,11 @@ void set_helplang_default(const char *lang)
}
-/*
- * 'title' and 'icon' only default to true if they have not been set or reset
- * in .vimrc and we can read the old value.
- * When 'title' and 'icon' have been reset in .vimrc, we won't even check if
- * they can be reset. This reduces startup time when using X on a remote
- * machine.
- */
+/// 'title' and 'icon' only default to true if they have not been set or reset
+/// in .vimrc and we can read the old value.
+/// When 'title' and 'icon' have been reset in .vimrc, we won't even check if
+/// they can be reset. This reduces startup time when using X on a remote
+/// machine.
void set_title_defaults(void)
{
int idx1;
@@ -2012,10 +2011,8 @@ static char_u *illegal_char(char_u *errbuf, size_t errbuflen, int c)
return errbuf;
}
-/*
- * Convert a key name or string into a key value.
- * Used for 'wildchar' and 'cedit' options.
- */
+/// Convert a key name or string into a key value.
+/// Used for 'wildchar' and 'cedit' options.
static int string_to_key(char_u *arg)
{
if (*arg == '<') {
@@ -2027,10 +2024,8 @@ static int string_to_key(char_u *arg)
return *arg;
}
-/*
- * Check value of 'cedit' and set cedit_key.
- * Returns NULL if value is OK, error message otherwise.
- */
+/// Check value of 'cedit' and set cedit_key.
+/// Returns NULL if value is OK, error message otherwise.
static char_u *check_cedit(void)
{
int n;
@@ -2114,13 +2109,11 @@ void set_options_bin(
}
}
-/*
- * Find the parameter represented by the given character (eg ', :, ", or /),
- * and return its associated value in the 'shada' string.
- * Only works for number parameters, not for 'r' or 'n'.
- * If the parameter is not specified in the string or there is no following
- * number, return -1.
- */
+/// Find the parameter represented by the given character (eg ', :, ", or /),
+/// and return its associated value in the 'shada' string.
+/// Only works for number parameters, not for 'r' or 'n'.
+/// If the parameter is not specified in the string or there is no following
+/// number, return -1.
int get_shada_parameter(int type)
{
char_u *p;
@@ -2132,11 +2125,9 @@ int get_shada_parameter(int type)
return -1;
}
-/*
- * Find the parameter represented by the given character (eg ''', ':', '"', or
- * '/') in the 'shada' option and return a pointer to the string after it.
- * Return NULL if the parameter is not specified in the string.
- */
+/// Find the parameter represented by the given character (eg ''', ':', '"', or
+/// '/') in the 'shada' option and return a pointer to the string after it.
+/// Return NULL if the parameter is not specified in the string.
char_u *find_shada_parameter(int type)
{
char_u *p;
@@ -2156,12 +2147,10 @@ char_u *find_shada_parameter(int type)
return NULL;
}
-/*
- * Expand environment variables for some string options.
- * These string options cannot be indirect!
- * If "val" is NULL expand the current value of the option.
- * Return pointer to NameBuff, or NULL when not expanded.
- */
+/// Expand environment variables for some string options.
+/// These string options cannot be indirect!
+/// If "val" is NULL expand the current value of the option.
+/// Return pointer to NameBuff, or NULL when not expanded.
static char_u *option_expand(int opt_idx, char_u *val)
{
// if option doesn't need expansion nothing to do
@@ -2245,9 +2234,7 @@ static void didset_options2(void)
check_opt_wim();
}
-/*
- * Check for string options that are NULL (normally only termcap options).
- */
+/// Check for string options that are NULL (normally only termcap options).
void check_options(void)
{
int opt_idx;
@@ -2259,9 +2246,7 @@ void check_options(void)
}
}
-/*
- * Check string options in a buffer for NULL value.
- */
+/// Check string options in a buffer for NULL value.
void check_buf_options(buf_T *buf)
{
check_string_option(&buf->b_p_bh);
@@ -2314,13 +2299,11 @@ void check_buf_options(buf_T *buf)
check_string_option(&buf->b_p_menc);
}
-/*
- * Free the string allocated for an option.
- * Checks for the string being empty_option. This may happen if we're out of
- * memory, vim_strsave() returned NULL, which was replaced by empty_option by
- * check_options().
- * Does NOT check for P_ALLOCED flag!
- */
+/// Free the string allocated for an option.
+/// Checks for the string being empty_option. This may happen if we're out of
+/// memory, vim_strsave() returned NULL, which was replaced by empty_option by
+/// check_options().
+/// Does NOT check for P_ALLOCED flag!
void free_string_option(char_u *p)
{
if (p != empty_option) {
@@ -2358,10 +2341,8 @@ int was_set_insecurely(char_u *opt, int opt_flags)
return -1;
}
-/*
- * Get a pointer to the flags used for the P_INSECURE flag of option
- * "opt_idx". For some local options a local flags field is used.
- */
+/// Get a pointer to the flags used for the P_INSECURE flag of option
+/// "opt_idx". For some local options a local flags field is used.
static uint32_t *insecure_flag(int opt_idx, int opt_flags)
{
if (opt_flags & OPT_LOCAL)
@@ -2379,9 +2360,7 @@ static uint32_t *insecure_flag(int opt_idx, int opt_flags)
}
-/*
- * Redraw the window title and/or tab page text later.
- */
+/// Redraw the window title and/or tab page text later.
static void redraw_titles(void)
{
need_maketitle = true;
@@ -2462,9 +2441,7 @@ set_string_option_direct(
}
}
-/*
- * Set global value for string option when it's a local option.
- */
+/// Set global value for string option when it's a local option.
static void
set_string_option_global(
int opt_idx, // option index
@@ -2565,7 +2542,7 @@ static bool valid_filetype(const char_u *val)
bool valid_spellang(const char_u *val)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return valid_name(val, ".-_,");
+ return valid_name(val, ".-_,@");
}
/// Return true if "val" is a valid 'spellfile' value.
@@ -3199,6 +3176,11 @@ ambw_end:
if (check_opt_strings(*varp, p_scl_values, false) != OK) {
errmsg = e_invarg;
}
+ } else if (varp == &curwin->w_p_fdc || varp == &curwin->w_allbuf_opt.wo_fdc) {
+ // 'foldcolumn'
+ if (check_opt_strings(*varp, p_fdc_values, false) != OK) {
+ errmsg = e_invarg;
+ }
} else if (varp == &p_pt) {
// 'pastetoggle': translate key codes like in a mapping
if (*p_pt) {
@@ -3652,7 +3634,7 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
}
// first round: check for valid value, second round: assign values
- for (round = 0; round <= set ? 1 : 0; round++) {
+ for (round = 0; round <= (set ? 1 : 0); round++) {
if (round > 0) {
// After checking that the value is valid: set defaults
for (i = 0; i < entries; i++) {
@@ -3726,10 +3708,8 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
return NULL; // no error
}
-/*
- * Check validity of options with the 'statusline' format.
- * Return error message or NULL.
- */
+/// Check validity of options with the 'statusline' format.
+/// Return error message or NULL.
char_u *check_stl_option(char_u *s)
{
int itemcnt = 0;
@@ -3822,16 +3802,15 @@ static char_u *did_set_spell_option(bool is_spellfile)
return errmsg;
}
-/*
- * Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'.
- * Return error message when failed, NULL when OK.
- */
+/// Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'.
+/// Return error message when failed, NULL when OK.
static char_u *compile_cap_prog(synblock_T *synblock)
+ FUNC_ATTR_NONNULL_ALL
{
regprog_T *rp = synblock->b_cap_prog;
char_u *re;
- if (*synblock->b_p_spc == NUL) {
+ if (synblock->b_p_spc == NULL || *synblock->b_p_spc == NUL) {
synblock->b_cap_prog = NULL;
} else {
// Prepend a ^ so that we only match at one column
@@ -4341,7 +4320,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
}
} else if (pp == &p_so) {
if (value < 0 && full_screen) {
- errmsg = e_scroll;
+ errmsg = e_positive;
}
} else if (pp == &p_siso) {
if (value < 0 && full_screen) {
@@ -4363,12 +4342,6 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (value < 0) {
errmsg = e_positive;
}
- } else if (pp == &curwin->w_p_fdc || pp == &curwin->w_allbuf_opt.wo_fdc) {
- if (value < 0) {
- errmsg = e_positive;
- } else if (value > 12) {
- errmsg = e_invarg;
- }
} else if (pp == &curwin->w_p_cole || pp == &curwin->w_allbuf_opt.wo_cole) {
if (value < 0) {
errmsg = e_positive;
@@ -4672,9 +4645,7 @@ static void trigger_optionsset_string(int opt_idx, int opt_flags,
}
}
-/*
- * Called after an option changed: check if something needs to be redrawn.
- */
+/// Called after an option changed: check if something needs to be redrawn.
static void check_redraw(uint32_t flags)
{
// Careful: P_RCLR and P_RALL are a combination of other P_ flags
@@ -5129,10 +5100,8 @@ static int find_key_option(const char_u *arg, bool has_lt)
return find_key_option_len(arg, STRLEN(arg), has_lt);
}
-/*
- * if 'all' == 0: show changed options
- * if 'all' == 1: show all normal options
- */
+/// if 'all' == 0: show changed options
+/// if 'all' == 1: show all normal options
static void
showoptions(
int all,
@@ -5281,10 +5250,8 @@ void ui_refresh_options(void)
}
}
-/*
- * showoneopt: show the value of one option
- * must not be called with a hidden option!
- */
+/// showoneopt: show the value of one option
+/// must not be called with a hidden option!
static void
showoneopt(
vimoption_T *p,
@@ -5320,28 +5287,26 @@ showoneopt(
info_message = false;
}
-/*
- * Write modified options as ":set" commands to a file.
- *
- * There are three values for "opt_flags":
- * OPT_GLOBAL: Write global option values and fresh values of
- * buffer-local options (used for start of a session
- * file).
- * OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
- * curwin (used for a vimrc file).
- * OPT_LOCAL: Write buffer-local option values for curbuf, fresh
- * and local values for window-local options of
- * curwin. Local values are also written when at the
- * default value, because a modeline or autocommand
- * may have set them when doing ":edit file" and the
- * user has set them back at the default or fresh
- * value.
- * When "local_only" is true, don't write fresh
- * values, only local values (for ":mkview").
- * (fresh value = value used for a new buffer or window for a local option).
- *
- * Return FAIL on error, OK otherwise.
- */
+/// Write modified options as ":set" commands to a file.
+///
+/// There are three values for "opt_flags":
+/// OPT_GLOBAL: Write global option values and fresh values of
+/// buffer-local options (used for start of a session
+/// file).
+/// OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
+/// curwin (used for a vimrc file).
+/// OPT_LOCAL: Write buffer-local option values for curbuf, fresh
+/// and local values for window-local options of
+/// curwin. Local values are also written when at the
+/// default value, because a modeline or autocommand
+/// may have set them when doing ":edit file" and the
+/// user has set them back at the default or fresh
+/// value.
+/// When "local_only" is true, don't write fresh
+/// values, only local values (for ":mkview").
+/// (fresh value = value used for a new buffer or window for a local option).
+///
+/// Return FAIL on error, OK otherwise.
int makeset(FILE *fd, int opt_flags, int local_only)
{
vimoption_T *p;
@@ -5452,10 +5417,8 @@ int makeset(FILE *fd, int opt_flags, int local_only)
return OK;
}
-/*
- * Generate set commands for the local fold options only. Used when
- * 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
- */
+/// Generate set commands for the local fold options only. Used when
+/// 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
int makefoldset(FILE *fd)
{
if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, false) == FAIL
@@ -5548,12 +5511,10 @@ static int put_setbool(FILE *fd, char *cmd, char *name, int value)
return OK;
}
-/*
- * Compute columns for ruler and shown command. 'sc_col' is also used to
- * decide what the maximum length of a message on the status line can be.
- * If there is a status line for the last window, 'sc_col' is independent
- * of 'ru_col'.
- */
+/// Compute columns for ruler and shown command. 'sc_col' is also used to
+/// decide what the maximum length of a message on the status line can be.
+/// If there is a status line for the last window, 'sc_col' is independent
+/// of 'ru_col'.
#define COL_RULER 17 // columns needed by standard ruler
@@ -5632,6 +5593,12 @@ void unset_global_local_option(char *name, void *from)
clear_string_option(&buf->b_p_tc);
buf->b_tc_flags = 0;
break;
+ case PV_SISO:
+ curwin->w_p_siso = -1;
+ break;
+ case PV_SO:
+ curwin->w_p_so = -1;
+ break;
case PV_DEF:
clear_string_option(&buf->b_p_def);
break;
@@ -5681,9 +5648,7 @@ void unset_global_local_option(char *name, void *from)
}
}
-/*
- * Get pointer to option variable, depending on local or global scope.
- */
+/// Get pointer to option variable, depending on local or global scope.
static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
{
if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
@@ -5704,6 +5669,8 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
case PV_AR: return (char_u *)&(curbuf->b_p_ar);
case PV_TAGS: return (char_u *)&(curbuf->b_p_tags);
case PV_TC: return (char_u *)&(curbuf->b_p_tc);
+ case PV_SISO: return (char_u *)&(curwin->w_p_siso);
+ case PV_SO: return (char_u *)&(curwin->w_p_so);
case PV_DEF: return (char_u *)&(curbuf->b_p_def);
case PV_INC: return (char_u *)&(curbuf->b_p_inc);
case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
@@ -5722,9 +5689,7 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
return get_varp(p);
}
-/*
- * Get pointer to option variable.
- */
+/// Get pointer to option variable.
static char_u *get_varp(vimoption_T *p)
{
// hidden option, always return NULL
@@ -5748,6 +5713,10 @@ static char_u *get_varp(vimoption_T *p)
? (char_u *)&(curbuf->b_p_tags) : p->var;
case PV_TC: return *curbuf->b_p_tc != NUL
? (char_u *)&(curbuf->b_p_tc) : p->var;
+ case PV_SISO: return curwin->w_p_siso >= 0
+ ? (char_u *)&(curwin->w_p_siso) : p->var;
+ case PV_SO: return curwin->w_p_so >= 0
+ ? (char_u *)&(curwin->w_p_so) : p->var;
case PV_BKC: return *curbuf->b_p_bkc != NUL
? (char_u *)&(curbuf->b_p_bkc) : p->var;
case PV_DEF: return *curbuf->b_p_def != NUL
@@ -5882,9 +5851,7 @@ static char_u *get_varp(vimoption_T *p)
return (char_u *)&(curbuf->b_p_wm);
}
-/*
- * Get the value of 'equalprg', either the buffer-local one or the global one.
- */
+/// Get the value of 'equalprg', either the buffer-local one or the global one.
char_u *get_equalprg(void)
{
if (*curbuf->b_p_ep == NUL) {
@@ -5893,22 +5860,18 @@ char_u *get_equalprg(void)
return curbuf->b_p_ep;
}
-/*
- * Copy options from one window to another.
- * Used when splitting a window.
- */
+/// Copy options from one window to another.
+/// Used when splitting a window.
void win_copy_options(win_T *wp_from, win_T *wp_to)
{
copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
}
-/*
- * Copy the options from one winopt_T to another.
- * Doesn't free the old option values in "to", use clear_winopt() for that.
- * The 'scroll' option is not copied, because it depends on the window height.
- * The 'previewwindow' option is reset, there can be only one preview window.
- */
+/// Copy the options from one winopt_T to another.
+/// Doesn't free the old option values in "to", use clear_winopt() for that.
+/// The 'scroll' option is not copied, because it depends on the window height.
+/// The 'previewwindow' option is reset, there can be only one preview window.
void copy_winopt(winopt_T *from, winopt_T *to)
{
to->wo_arab = from->wo_arab;
@@ -5936,8 +5899,9 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_diff_saved = from->wo_diff_saved;
to->wo_cocu = vim_strsave(from->wo_cocu);
to->wo_cole = from->wo_cole;
- to->wo_fdc = from->wo_fdc;
- to->wo_fdc_save = from->wo_fdc_save;
+ to->wo_fdc = vim_strsave(from->wo_fdc);
+ to->wo_fdc_save = from->wo_diff_saved
+ ? vim_strsave(from->wo_fdc_save) : empty_option;
to->wo_fen = from->wo_fen;
to->wo_fen_save = from->wo_fen_save;
to->wo_fdi = vim_strsave(from->wo_fdi);
@@ -5959,20 +5923,18 @@ void copy_winopt(winopt_T *from, winopt_T *to)
check_winopt(to); // don't want NULL pointers
}
-/*
- * Check string options in a window for a NULL value.
- */
+/// Check string options in a window for a NULL value.
void check_win_options(win_T *win)
{
check_winopt(&win->w_onebuf_opt);
check_winopt(&win->w_allbuf_opt);
}
-/*
- * Check for NULL pointers in a winopt_T and replace them with empty_option.
- */
+/// Check for NULL pointers in a winopt_T and replace them with empty_option.
static void check_winopt(winopt_T *wop)
{
+ check_string_option(&wop->wo_fdc);
+ check_string_option(&wop->wo_fdc_save);
check_string_option(&wop->wo_fdi);
check_string_option(&wop->wo_fdm);
check_string_option(&wop->wo_fdm_save);
@@ -5990,11 +5952,11 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_lcs);
}
-/*
- * Free the allocated memory inside a winopt_T.
- */
+/// Free the allocated memory inside a winopt_T.
void clear_winopt(winopt_T *wop)
{
+ clear_string_option(&wop->wo_fdc);
+ clear_string_option(&wop->wo_fdc_save);
clear_string_option(&wop->wo_fdi);
clear_string_option(&wop->wo_fdm);
clear_string_option(&wop->wo_fdm_save);
@@ -6023,15 +5985,13 @@ void didset_window_options(win_T *wp)
}
-/*
- * Copy global option values to local options for one buffer.
- * Used when creating a new buffer and sometimes when entering a buffer.
- * flags:
- * BCO_ENTER We will enter the buf buffer.
- * BCO_ALWAYS Always copy the options, but only set b_p_initialized when
- * appropriate.
- * BCO_NOHELP Don't copy the values to a help buffer.
- */
+/// Copy global option values to local options for one buffer.
+/// Used when creating a new buffer and sometimes when entering a buffer.
+/// flags:
+/// BCO_ENTER We will enter the buf buffer.
+/// BCO_ALWAYS Always copy the options, but only set b_p_initialized when
+/// appropriate.
+/// BCO_NOHELP Don't copy the values to a help buffer.
void buf_copy_options(buf_T *buf, int flags)
{
int should_copy = true;
@@ -6073,10 +6033,8 @@ void buf_copy_options(buf_T *buf, int flags)
save_p_isk = buf->b_p_isk;
buf->b_p_isk = NULL;
}
- /*
- * Always free the allocated strings.
- * If not already initialized, set 'readonly' and copy 'fileformat'.
- */
+ // Always free the allocated strings. If not already initialized,
+ // reset 'readonly' and copy 'fileformat'.
if (!buf->b_p_initialized) {
free_buf_options(buf, true);
buf->b_p_ro = false; // don't copy readonly
@@ -6228,9 +6186,7 @@ void buf_copy_options(buf_T *buf, int flags)
}
}
-/*
- * Reset the 'modifiable' option and its default value.
- */
+/// Reset the 'modifiable' option and its default value.
void reset_modifiable(void)
{
int opt_idx;
@@ -6243,17 +6199,13 @@ void reset_modifiable(void)
}
}
-/*
- * Set the global value for 'iminsert' to the local value.
- */
+/// Set the global value for 'iminsert' to the local value.
void set_iminsert_global(void)
{
p_iminsert = curbuf->b_p_iminsert;
}
-/*
- * Set the global value for 'imsearch' to the local value.
- */
+/// Set the global value for 'imsearch' to the local value.
void set_imsearch_global(void)
{
p_imsearch = curbuf->b_p_imsearch;
@@ -6555,10 +6507,8 @@ void ExpandOldSetting(int *num_file, char_u ***file)
*num_file = 1;
}
-/*
- * Get the value for the numeric or string option *opp in a nice format into
- * NameBuff[]. Must not be called with a hidden option!
- */
+/// Get the value for the numeric or string option///opp in a nice format into
+/// NameBuff[]. Must not be called with a hidden option!
static void
option_value2string(
vimoption_T *opp,
@@ -6611,21 +6561,18 @@ static int wc_use_keyname(char_u *varp, long *wcp)
return false;
}
-/*
- * Any character has an equivalent 'langmap' character. This is used for
- * keyboards that have a special language mode that sends characters above
- * 128 (although other characters can be translated too). The "to" field is a
- * Vim command character. This avoids having to switch the keyboard back to
- * ASCII mode when leaving Insert mode.
- *
- * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim
- * commands.
- * langmap_mapga.ga_data is a sorted table of langmap_entry_T.
- * This does the same as langmap_mapchar[] for characters >= 256.
- */
-/*
- * With multi-byte support use growarray for 'langmap' chars >= 256
- */
+/// Any character has an equivalent 'langmap' character. This is used for
+/// keyboards that have a special language mode that sends characters above
+/// 128 (although other characters can be translated too). The "to" field is a
+/// Vim command character. This avoids having to switch the keyboard back to
+/// ASCII mode when leaving Insert mode.
+///
+/// langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim
+/// commands.
+/// langmap_mapga.ga_data is a sorted table of langmap_entry_T.
+/// This does the same as langmap_mapchar[] for characters >= 256.
+///
+/// With multi-byte support use growarray for 'langmap' chars >= 256
typedef struct {
int from;
int to;
@@ -6633,10 +6580,8 @@ typedef struct {
static garray_T langmap_mapga = GA_EMPTY_INIT_VALUE;
-/*
- * Search for an entry in "langmap_mapga" for "from". If found set the "to"
- * field. If not found insert a new entry at the appropriate location.
- */
+/// Search for an entry in "langmap_mapga" for "from". If found set the "to"
+/// field. If not found insert a new entry at the appropriate location.
static void langmap_set_entry(int from, int to)
{
langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
@@ -6671,9 +6616,7 @@ static void langmap_set_entry(int from, int to)
entries[0].to = to;
}
-/*
- * Apply 'langmap' to multi-byte character "c" and return the result.
- */
+/// Apply 'langmap' to multi-byte character "c" and return the result.
int langmap_adjust_mb(int c)
{
langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
@@ -6704,10 +6647,8 @@ static void langmap_init(void)
ga_init(&langmap_mapga, sizeof(langmap_entry_T), 8);
}
-/*
- * Called when langmap option is set; the language map can be
- * changed at any time!
- */
+/// Called when langmap option is set; the language map can be
+/// changed at any time!
static void langmap_set(void)
{
char_u *p;
@@ -6810,9 +6751,7 @@ bool shortmess(int x)
&& vim_strchr((char_u *)SHM_ALL_ABBREVIATIONS, x) != NULL)));
}
-/*
- * paste_option_changed() - Called after p_paste was set or reset.
- */
+/// paste_option_changed() - Called after p_paste was set or reset.
static void paste_option_changed(void)
{
static int old_p_paste = false;
@@ -6959,9 +6898,7 @@ void reset_option_was_set(const char *name)
}
}
-/*
- * fill_breakat_flags() -- called when 'breakat' changes value.
- */
+/// fill_breakat_flags() -- called when 'breakat' changes value.
static void fill_breakat_flags(void)
{
char_u *p;
@@ -6978,12 +6915,10 @@ static void fill_breakat_flags(void)
}
}
-/*
- * Check an option that can be a range of string values.
- *
- * Return OK for correct value, FAIL otherwise.
- * Empty is always OK.
- */
+/// Check an option that can be a range of string values.
+///
+/// Return OK for correct value, FAIL otherwise.
+/// Empty is always OK.
static int check_opt_strings(
char_u *val,
char **values,
@@ -6993,13 +6928,11 @@ static int check_opt_strings(
return opt_strings_flags(val, values, NULL, list);
}
-/*
- * Handle an option that can be a range of string values.
- * Set a flag in "*flagp" for each string present.
- *
- * Return OK for correct value, FAIL otherwise.
- * Empty is always OK.
- */
+/// Handle an option that can be a range of string values.
+/// Set a flag in "*flagp" for each string present.
+///
+/// Return OK for correct value, FAIL otherwise.
+/// Empty is always OK.
static int opt_strings_flags(
char_u *val, // new value
char **values, // array of valid string values
@@ -7032,9 +6965,7 @@ static int opt_strings_flags(
return OK;
}
-/*
- * Read the 'wildmode' option, fill wim_flags[].
- */
+/// Read the 'wildmode' option, fill wim_flags[].
static int check_opt_wim(void)
{
char_u new_wim_flags[4];
@@ -7085,11 +7016,9 @@ static int check_opt_wim(void)
return OK;
}
-/*
- * Check if backspacing over something is allowed.
- * The parameter what is one of the following: whatBS_INDENT, BS_EOL
- * or BS_START
- */
+/// Check if backspacing over something is allowed.
+/// The parameter what is one of the following: whatBS_INDENT, BS_EOL
+/// or BS_START
bool can_bs(int what)
{
if (what == BS_START && bt_prompt(curbuf)) {
@@ -7103,10 +7032,8 @@ bool can_bs(int what)
return vim_strchr(p_bs, what) != NULL;
}
-/*
- * Save the current values of 'fileformat' and 'fileencoding', so that we know
- * the file must be considered changed when the value is different.
- */
+/// Save the current values of 'fileformat' and 'fileencoding', so that we know
+/// the file must be considered changed when the value is different.
void save_file_ff(buf_T *buf)
{
buf->b_start_ffc = *buf->b_p_ff;
@@ -7156,18 +7083,14 @@ bool file_ff_differs(buf_T *buf, bool ignore_empty)
return STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0;
}
-/*
- * return OK if "p" is a valid fileformat name, FAIL otherwise.
- */
+/// return OK if "p" is a valid fileformat name, FAIL otherwise.
int check_ff_value(char_u *p)
{
return check_opt_strings(p, p_ff_values, false);
}
-/*
- * Return the effective shiftwidth value for current buffer, using the
- * 'tabstop' value when 'shiftwidth' is zero.
- */
+/// Return the effective shiftwidth value for current buffer, using the
+/// 'tabstop' value when 'shiftwidth' is zero.
int get_sw_value(buf_T *buf)
{
long result = buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts;
@@ -7175,8 +7098,8 @@ int get_sw_value(buf_T *buf)
return (int)result;
}
-// Return the effective softtabstop value for the current buffer,
-// using the effective shiftwidth value when 'softtabstop' is negative.
+/// Return the effective softtabstop value for the current buffer,
+/// using the effective shiftwidth value when 'softtabstop' is negative.
int get_sts_value(void)
{
long result = curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
@@ -7184,12 +7107,10 @@ int get_sts_value(void)
return (int)result;
}
-/*
- * Check matchpairs option for "*initc".
- * If there is a match set "*initc" to the matching character and "*findc" to
- * the opposite character. Set "*backwards" to the direction.
- * When "switchit" is true swap the direction.
- */
+/// Check matchpairs option for "*initc".
+/// If there is a match set "*initc" to the matching character and "*findc" to
+/// the opposite character. Set "*backwards" to the direction.
+/// When "switchit" is true swap the direction.
void find_mps_values(int *initc, int *findc, int *backwards, int switchit)
{
char_u *ptr = curbuf->b_p_mps;
@@ -7294,12 +7215,13 @@ int get_fileformat(buf_T *buf)
/// argument.
///
/// @param eap can be NULL!
-int get_fileformat_force(buf_T *buf, exarg_T *eap)
+int get_fileformat_force(const buf_T *buf, const exarg_T *eap)
+ FUNC_ATTR_NONNULL_ARG(1)
{
int c;
if (eap != NULL && eap->force_ff != 0) {
- c = eap->cmd[eap->force_ff];
+ c = eap->force_ff;
} else {
if ((eap != NULL && eap->force_bin != 0)
? (eap->force_bin == FORCE_BIN) : buf->b_p_bin) {
@@ -7479,3 +7401,18 @@ dict_T *get_winbuf_options(const int bufopt)
return d;
}
+
+/// Return the effective 'scrolloff' value for the current window, using the
+/// global value when appropriate.
+long get_scrolloff_value(void)
+{
+ return curwin->w_p_so < 0 ? p_so : curwin->w_p_so;
+}
+
+/// Return the effective 'sidescrolloff' value for the current window, using the
+/// global value when appropriate.
+long get_sidescrolloff_value(void)
+{
+ return curwin->w_p_siso < 0 ? p_siso : curwin->w_p_siso;
+}
+
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index c5d8b134c4..192e57a642 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -835,6 +835,8 @@ enum {
, WV_RLC
, WV_SCBIND
, WV_SCROLL
+ , WV_SISO
+ , WV_SO
, WV_SPELL
, WV_CUC
, WV_CUL
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 7d080b8d56..e7c1a3fe88 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -831,10 +831,11 @@ return {
},
{
full_name='foldcolumn', abbreviation='fdc',
- type='number', scope={'window'},
+ type='string', scope={'window'},
vi_def=true,
+ alloced=true,
redraw={'current_window'},
- defaults={if_true={vi=false}}
+ defaults={if_true={vi="0"}}
},
{
full_name='foldenable', abbreviation='fen',
@@ -1989,7 +1990,7 @@ return {
},
{
full_name='scrolloff', abbreviation='so',
- type='number', scope={'global'},
+ type='number', scope={'global', 'window'},
vi_def=true,
vim=true,
redraw={'all_windows'},
@@ -2228,10 +2229,10 @@ return {
},
{
full_name='sidescrolloff', abbreviation='siso',
- type='number', scope={'global'},
+ type='number', scope={'global', 'window'},
vi_def=true,
vim=true,
- redraw={'current_buffer'},
+ redraw={'all_windows'},
varname='p_siso',
defaults={if_true={vi=0}}
},
@@ -2586,6 +2587,7 @@ return {
type='bool', scope={'global'},
vi_def=true,
vim=true,
+ redraw={'ui_option'},
varname='p_ttimeout',
defaults={if_true={vi=true}}
},
@@ -2593,6 +2595,7 @@ return {
full_name='ttimeoutlen', abbreviation='ttm',
type='number', scope={'global'},
vi_def=true,
+ redraw={'ui_option'},
varname='p_ttm',
defaults={if_true={vi=50}}
},
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index ae922e4040..873b611151 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -1147,6 +1147,30 @@ bool os_fileid_equal_fileinfo(const FileID *file_id,
&& file_id->device_id == file_info->stat.st_dev;
}
+/// Return the canonicalized absolute pathname.
+///
+/// @param[in] name Filename to be canonicalized.
+/// @param[out] buf Buffer to store the canonicalized values. A minimum length
+// of MAXPATHL+1 is required. If it is NULL, memory is
+// allocated. In that case, the caller should deallocate this
+// buffer.
+///
+/// @return pointer to the buf on success, or NULL.
+char *os_realpath(const char *name, char *buf)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ uv_fs_t request;
+ int result = uv_fs_realpath(&fs_loop, &request, name, NULL);
+ if (result == kLibuvSuccess) {
+ if (buf == NULL) {
+ buf = xmallocz(MAXPATHL);
+ }
+ xstrlcpy(buf, request.ptr, MAXPATHL + 1);
+ }
+ uv_fs_req_cleanup(&request);
+ return result == kLibuvSuccess ? buf : NULL;
+}
+
#ifdef WIN32
# include <shlobj.h>
@@ -1233,4 +1257,49 @@ shortcut_end:
return rfname;
}
+#define is_path_sep(c) ((c) == L'\\' || (c) == L'/')
+/// Returns true if the path contains a reparse point (junction or symbolic
+/// link). Otherwise false in returned.
+bool os_is_reparse_point_include(const char *path)
+{
+ wchar_t *p, *q, *utf16_path;
+ wchar_t buf[MAX_PATH];
+ DWORD attr;
+ bool result = false;
+
+ const int r = utf8_to_utf16(path, -1, &utf16_path);
+ if (r != 0) {
+ EMSG2("utf8_to_utf16 failed: %d", r);
+ return false;
+ }
+
+ p = utf16_path;
+ if (isalpha(p[0]) && p[1] == L':' && is_path_sep(p[2])) {
+ p += 3;
+ } else if (is_path_sep(p[0]) && is_path_sep(p[1])) {
+ p += 2;
+ }
+
+ while (*p != L'\0') {
+ q = wcspbrk(p, L"\\/");
+ if (q == NULL) {
+ p = q = utf16_path + wcslen(utf16_path);
+ } else {
+ p = q + 1;
+ }
+ if (q - utf16_path >= MAX_PATH) {
+ break;
+ }
+ wcsncpy(buf, utf16_path, (size_t)(q - utf16_path));
+ buf[q - utf16_path] = L'\0';
+ attr = GetFileAttributesW(buf);
+ if (attr != INVALID_FILE_ATTRIBUTES
+ && (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
+ result = true;
+ break;
+ }
+ }
+ xfree(utf16_path);
+ return result;
+}
#endif
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 3b8470182a..6294d5e4e2 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -448,7 +448,6 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file,
} else {
buffer[len] = NUL;
}
- i = 0;
for (p = buffer; p < buffer + len; p++) {
if (*p == NUL || (*p == ' ' && check_spaces)) { // count entry
i++;
diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c
index ba6226ef9d..112de9fed8 100644
--- a/src/nvim/os/signal.c
+++ b/src/nvim/os/signal.c
@@ -50,22 +50,13 @@ void signal_init(void)
signal_watcher_init(&main_loop, &shup, NULL);
signal_watcher_init(&main_loop, &squit, NULL);
signal_watcher_init(&main_loop, &sterm, NULL);
-#ifdef SIGPIPE
- signal_watcher_start(&spipe, on_signal, SIGPIPE);
-#endif
- signal_watcher_start(&shup, on_signal, SIGHUP);
-#ifdef SIGQUIT
- signal_watcher_start(&squit, on_signal, SIGQUIT);
-#endif
- signal_watcher_start(&sterm, on_signal, SIGTERM);
#ifdef SIGPWR
signal_watcher_init(&main_loop, &spwr, NULL);
- signal_watcher_start(&spwr, on_signal, SIGPWR);
#endif
#ifdef SIGUSR1
signal_watcher_init(&main_loop, &susr1, NULL);
- signal_watcher_start(&susr1, on_signal, SIGUSR1);
#endif
+ signal_start();
}
void signal_teardown(void)
@@ -83,11 +74,33 @@ void signal_teardown(void)
#endif
}
+void signal_start(void)
+{
+#ifdef SIGPIPE
+ signal_watcher_start(&spipe, on_signal, SIGPIPE);
+#endif
+ signal_watcher_start(&shup, on_signal, SIGHUP);
+#ifdef SIGQUIT
+ signal_watcher_start(&squit, on_signal, SIGQUIT);
+#endif
+ signal_watcher_start(&sterm, on_signal, SIGTERM);
+#ifdef SIGPWR
+ signal_watcher_start(&spwr, on_signal, SIGPWR);
+#endif
+#ifdef SIGUSR1
+ signal_watcher_start(&susr1, on_signal, SIGUSR1);
+#endif
+}
+
void signal_stop(void)
{
+#ifdef SIGPIPE
signal_watcher_stop(&spipe);
+#endif
signal_watcher_stop(&shup);
+#ifdef SIGQUIT
signal_watcher_stop(&squit);
+#endif
signal_watcher_stop(&sterm);
#ifdef SIGPWR
signal_watcher_stop(&spwr);
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 4dd0614fe2..346e40e02e 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -2,9 +2,6 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
#include <limits.h>
#include <uv.h>
@@ -13,7 +10,7 @@
#include "nvim/os/time.h"
#include "nvim/os/input.h"
#include "nvim/event/loop.h"
-#include "nvim/vim.h"
+#include "nvim/os/os.h"
#include "nvim/main.h"
static uv_mutex_t delay_mutex;
@@ -112,6 +109,10 @@ void os_microdelay(uint64_t us, bool ignoreinput)
uv_mutex_unlock(&delay_mutex);
}
+// Cache of the current timezone name as retrieved from TZ, or an empty string
+// where unset, up to 64 octets long including trailing null byte.
+static char tz_cache[64];
+
/// Portable version of POSIX localtime_r()
///
/// @return NULL in case of error
@@ -120,6 +121,19 @@ struct tm *os_localtime_r(const time_t *restrict clock,
{
#ifdef UNIX
// POSIX provides localtime_r() as a thread-safe version of localtime().
+ //
+ // Check to see if the environment variable TZ has changed since the last run.
+ // Call tzset(3) to update the global timezone variables if it has.
+ // POSIX standard doesn't require localtime_r() implementations to do that
+ // as it does with localtime(), and we don't want to call tzset() every time.
+ const char *tz = os_getenv("TZ");
+ if (tz == NULL) {
+ tz = "";
+ }
+ if (strncmp(tz_cache, tz, sizeof(tz_cache) - 1) != 0) {
+ tzset();
+ xstrlcpy(tz_cache, tz, sizeof(tz_cache));
+ }
return localtime_r(clock, result); // NOLINT(runtime/threadsafe_fn)
#else
// Windows version of localtime() is thread-safe.
@@ -144,6 +158,39 @@ struct tm *os_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL
return os_localtime_r(&rawtime, result);
}
+/// Portable version of POSIX ctime_r()
+///
+/// @param clock[in]
+/// @param result[out] Pointer to a 'char' where the result should be placed
+/// @param result_len length of result buffer
+/// @return human-readable string of current local time
+char *os_ctime_r(const time_t *restrict clock, char *restrict result,
+ size_t result_len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
+{
+ struct tm clock_local;
+ struct tm *clock_local_ptr = os_localtime_r(clock, &clock_local);
+ // MSVC returns NULL for an invalid value of seconds.
+ if (clock_local_ptr == NULL) {
+ snprintf(result, result_len, "%s\n", _("(Invalid)"));
+ } else {
+ strftime(result, result_len, "%a %b %d %H:%M:%S %Y\n", clock_local_ptr);
+ }
+ return result;
+}
+
+/// Gets the current Unix timestamp and adjusts it to local time.
+///
+/// @param result[out] Pointer to a 'char' where the result should be placed
+/// @param result_len length of result buffer
+/// @return human-readable string of current local time
+char *os_ctime(char *result, size_t result_len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
+{
+ time_t rawtime = time(NULL);
+ return os_ctime_r(&rawtime, result, result_len);
+}
+
/// Obtains the current Unix timestamp.
///
/// @return Seconds since epoch.
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index 4ba2a1032d..da34d85c00 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -38,7 +38,8 @@ static int pum_width; // width of displayed pum items
static int pum_base_width; // width of pum items base
static int pum_kind_width; // width of pum items kind column
static int pum_extra_width; // width of extra stuff
-static int pum_scrollbar; // TRUE when scrollbar present
+static int pum_scrollbar; // one when scrollbar present, else zero
+static bool pum_rl; // true when popupmenu is drawn 'rightleft'
static int pum_anchor_grid; // grid where position is defined
static int pum_row; // top row of pum
@@ -110,6 +111,8 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
|| (State == CMDLINE && ui_has(kUIWildmenu));
}
+ pum_rl = (curwin->w_p_rl && State != CMDLINE);
+
do {
// Mark the pum as visible already here,
// to avoid that must_redraw is set when 'cursorcolumn' is on.
@@ -127,7 +130,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
} else {
// anchor position: the start of the completed word
pum_win_row = curwin->w_wrow;
- if (curwin->w_p_rl) {
+ if (pum_rl) {
cursor_col = curwin->w_width - curwin->w_wcol - 1;
} else {
cursor_col = curwin->w_wcol;
@@ -270,16 +273,14 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
def_width = max_width;
}
- if ((((cursor_col < Columns - p_pw)
- || (cursor_col < Columns - max_width))
- && !curwin->w_p_rl)
- || (curwin->w_p_rl
- && ((cursor_col > p_pw) || (cursor_col > max_width)))) {
+ if ((((cursor_col < Columns - p_pw) || (cursor_col < Columns - max_width))
+ && !pum_rl)
+ || (pum_rl && ((cursor_col > p_pw) || (cursor_col > max_width)))) {
// align pum with "cursor_col"
pum_col = cursor_col;
// start with the maximum space available
- if (curwin->w_p_rl) {
+ if (pum_rl) {
pum_width = pum_col - pum_scrollbar + 1;
} else {
assert(Columns - pum_col - pum_scrollbar >= INT_MIN
@@ -297,19 +298,16 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
pum_width = (int)p_pw;
}
}
- } else if (((cursor_col > p_pw || cursor_col > max_width)
- && !curwin->w_p_rl)
- || (curwin->w_p_rl
- && (cursor_col < Columns - p_pw
- || cursor_col < Columns - max_width))) {
+ } else if (((cursor_col > p_pw || cursor_col > max_width) && !pum_rl)
+ || (pum_rl && (cursor_col < Columns - p_pw
+ || cursor_col < Columns - max_width))) {
// align pum edge with "cursor_col"
- if (curwin->w_p_rl
- && W_ENDCOL(curwin) < max_width + pum_scrollbar + 1) {
+ if (pum_rl && W_ENDCOL(curwin) < max_width + pum_scrollbar + 1) {
pum_col = cursor_col + max_width + pum_scrollbar + 1;
if (pum_col >= Columns) {
pum_col = Columns - 1;
}
- } else if (!curwin->w_p_rl) {
+ } else if (!pum_rl) {
if (curwin->w_wincol > Columns - max_width - pum_scrollbar
&& max_width <= p_pw) {
// use full width to end of the screen
@@ -320,7 +318,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
}
}
- if (curwin->w_p_rl) {
+ if (pum_rl) {
pum_width = pum_col - pum_scrollbar + 1;
} else {
pum_width = Columns - pum_col - pum_scrollbar;
@@ -328,7 +326,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
if (pum_width < p_pw) {
pum_width = (int)p_pw;
- if (curwin->w_p_rl) {
+ if (pum_rl) {
if (pum_width > pum_col) {
pum_width = pum_col;
}
@@ -346,7 +344,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
}
} else if (Columns < def_width) {
// not enough room, will use what we have
- if (curwin->w_p_rl) {
+ if (pum_rl) {
assert(Columns - 1 >= INT_MIN);
pum_col = (int)(Columns - 1);
} else {
@@ -360,7 +358,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed,
max_width = (int)p_pw;
}
- if (curwin->w_p_rl) {
+ if (pum_rl) {
pum_col = max_width - 1;
} else {
assert(Columns - max_width >= INT_MIN
@@ -399,7 +397,7 @@ void pum_redraw(void)
int grid_width = pum_width;
int col_off = 0;
bool extra_space = false;
- if (curwin->w_p_rl) {
+ if (pum_rl) {
col_off = pum_width;
if (pum_col < curwin->w_wincol + curwin->w_width - 1) {
grid_width += 1;
@@ -460,7 +458,7 @@ void pum_redraw(void)
// prepend a space if there is room
if (extra_space) {
- if (curwin->w_p_rl) {
+ if (pum_rl) {
grid_putchar(&pum_grid, ' ', row, col_off + 1, attr);
} else {
grid_putchar(&pum_grid, ' ', row, col_off - 1, attr);
@@ -507,7 +505,7 @@ void pum_redraw(void)
st = (char_u *)transstr((const char *)s);
*p = saved;
- if (curwin->w_p_rl) {
+ if (pum_rl) {
char_u *rt = reverse_text(st);
char_u *rt_start = rt;
int size = vim_strsize(rt);
@@ -542,7 +540,7 @@ void pum_redraw(void)
}
// Display two spaces for a Tab.
- if (curwin->w_p_rl) {
+ if (pum_rl) {
grid_puts_len(&pum_grid, (char_u *)" ", 2, row, col - 1,
attr);
col -= 2;
@@ -577,7 +575,7 @@ void pum_redraw(void)
break;
}
- if (curwin->w_p_rl) {
+ if (pum_rl) {
grid_fill(&pum_grid, row, row + 1, col_off - pum_base_width - n + 1,
col + 1, ' ', ' ', attr);
col = col_off - pum_base_width - n + 1;
@@ -589,7 +587,7 @@ void pum_redraw(void)
totwidth = pum_base_width + n;
}
- if (curwin->w_p_rl) {
+ if (pum_rl) {
grid_fill(&pum_grid, row, row + 1, col_off - pum_width + 1, col + 1,
' ', ' ', attr);
} else {
@@ -598,7 +596,7 @@ void pum_redraw(void)
}
if (pum_scrollbar > 0) {
- if (curwin->w_p_rl) {
+ if (pum_rl) {
grid_putchar(&pum_grid, ' ', row, col_off - pum_width,
i >= thumb_pos && i < thumb_pos + thumb_heigth
? attr_thumb : attr_scroll);
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 71c6f06ac0..484168e798 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -3845,7 +3845,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last)
*dirname = NUL;
// Add one line for each error
- if (old_last == NULL) {
+ if (old_last == NULL || old_last->qf_next == NULL) {
qfp = qfl->qf_start;
lnum = 0;
} else {
@@ -4775,10 +4775,10 @@ static void vgr_display_fname(char_u *fname)
static buf_T *vgr_load_dummy_buf(char_u *fname, char_u *dirname_start,
char_u *dirname_now)
{
- char_u *save_ei = NULL;
-
// Don't do Filetype autocommands to avoid loading syntax and
// indent scripts, a great speed improvement.
+ char_u *save_ei = au_event_disable(",Filetype");
+
long save_mls = p_mls;
p_mls = 0;
@@ -5134,6 +5134,7 @@ theend:
// Restore current working directory to "dirname_start" if they differ, taking
// into account whether it is set locally or globally.
static void restore_start_dir(char_u *dirname_start)
+ FUNC_ATTR_NONNULL_ALL
{
char_u *dirname_now = xmalloc(MAXPATHL);
@@ -5251,8 +5252,29 @@ load_dummy_buffer (
// directory to "dirname_start" prior to returning, if autocmds or the
// 'autochdir' option have changed it.
static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start)
+ FUNC_ATTR_NONNULL_ALL
{
- if (curbuf != buf) { // safety check
+ // If any autocommand opened a window on the dummy buffer, close that
+ // window. If we can't close them all then give up.
+ while (buf->b_nwindows > 0) {
+ bool did_one = false;
+
+ if (firstwin->w_next != NULL) {
+ for (win_T *wp = firstwin; wp != NULL; wp = wp->w_next) {
+ if (wp->w_buffer == buf) {
+ if (win_close(wp, false) == OK) {
+ did_one = true;
+ }
+ break;
+ }
+ }
+ }
+ if (!did_one) {
+ return;
+ }
+ }
+
+ if (curbuf != buf && buf->b_nwindows == 0) { // safety check
cleanup_T cs;
// Reset the error/interrupt/exception state here so that aborting()
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 42ea9a944d..34553fcec4 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -6492,20 +6492,24 @@ typedef struct {
static regsubmatch_T rsm; // can only be used when can_f_submatch is true
-/// Put the submatches in "argv[0]" which is a list passed into call_func() by
-/// vim_regsub_both().
-static int fill_submatch_list(int argc, typval_T *argv, int argcount)
+/// Put the submatches in "argv[argskip]" which is a list passed into
+/// call_func() by vim_regsub_both().
+static int fill_submatch_list(int argc FUNC_ATTR_UNUSED, typval_T *argv,
+ int argskip, int argcount)
+ FUNC_ATTR_NONNULL_ALL
{
- if (argcount == 0) {
- // called function doesn't take an argument
- return 0;
+ typval_T *listarg = argv + argskip;
+
+ if (argcount == argskip) {
+ // called function doesn't take a submatches argument
+ return argskip;
}
// Relies on sl_list to be the first item in staticList10_T.
- tv_list_init_static10((staticList10_T *)argv->vval.v_list);
+ tv_list_init_static10((staticList10_T *)listarg->vval.v_list);
// There are always 10 list items in staticList10_T.
- listitem_T *li = tv_list_first(argv->vval.v_list);
+ listitem_T *li = tv_list_first(listarg->vval.v_list);
for (int i = 0; i < 10; i++) {
char_u *s = rsm.sm_match->startp[i];
if (s == NULL || rsm.sm_match->endp[i] == NULL) {
@@ -6517,7 +6521,7 @@ static int fill_submatch_list(int argc, typval_T *argv, int argcount)
TV_LIST_ITEM_TV(li)->vval.v_string = s;
li = TV_LIST_ITEM_NEXT(argv->vval.v_list, li);
}
- return 1;
+ return argskip + 1;
}
static void clear_submatch_list(staticList10_T *sl)
@@ -6680,10 +6684,15 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
// fill_submatch_list() was called.
clear_submatch_list(&matchList);
}
- char buf[NUMBUFLEN];
- eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf);
- if (eval_result != NULL) {
- eval_result = vim_strsave(eval_result);
+ if (rettv.v_type == VAR_UNKNOWN) {
+ // something failed, no need to report another error
+ eval_result = NULL;
+ } else {
+ char buf[NUMBUFLEN];
+ eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf);
+ if (eval_result != NULL) {
+ eval_result = vim_strsave(eval_result);
+ }
}
tv_clear(&rettv);
} else {
diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h
index 5e5b19b63f..116bfee91e 100644
--- a/src/nvim/regexp_defs.h
+++ b/src/nvim/regexp_defs.h
@@ -91,7 +91,7 @@ typedef struct {
char_u *regmust;
int regmlen;
char_u reghasz;
- char_u program[1]; /* actually longer.. */
+ char_u program[1]; // actually longer..
} bt_regprog_T;
// Structure representing a NFA state.
@@ -102,7 +102,7 @@ struct nfa_state {
nfa_state_T *out;
nfa_state_T *out1;
int id;
- int lastlist[2]; /* 0: normal, 1: recursive */
+ int lastlist[2]; // 0: normal, 1: recursive
int val;
};
@@ -116,19 +116,19 @@ typedef struct {
unsigned re_engine;
unsigned re_flags; ///< Second argument for vim_regcomp().
- nfa_state_T *start; /* points into state[] */
+ nfa_state_T *start; // points into state[]
- int reganch; /* pattern starts with ^ */
- int regstart; /* char at start of pattern */
- char_u *match_text; /* plain text to match with */
+ int reganch; // pattern starts with ^
+ int regstart; // char at start of pattern
+ char_u *match_text; // plain text to match with
- int has_zend; /* pattern contains \ze */
- int has_backref; /* pattern contains \1 .. \9 */
+ int has_zend; // pattern contains \ze
+ int has_backref; // pattern contains \1 .. \9
int reghasz;
char_u *pattern;
- int nsubexp; /* number of () */
+ int nsubexp; // number of ()
int nstate;
- nfa_state_T state[1]; /* actually longer.. */
+ nfa_state_T state[1]; // actually longer..
} nfa_regprog_T;
/*
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 5df279c0a7..9c590efdbc 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -334,10 +334,10 @@ int update_screen(int type)
}
return FAIL;
}
+ updating_screen = 1;
- updating_screen = TRUE;
- ++display_tick; /* let syntax code know we're in a next round of
- * display updating */
+ display_tick++; // let syntax code know we're in a next round of
+ // display updating
// Tricky: vim code can reset msg_scrolled behind our back, so need
// separate bookkeeping for now.
@@ -417,7 +417,7 @@ int update_screen(int type)
need_wait_return = false;
}
- win_ui_flush_positions();
+ win_ui_flush();
msg_ext_check_clear();
/* reset cmdline_row now (may have been changed temporarily) */
@@ -565,7 +565,7 @@ int update_screen(int type)
wp->w_buffer->b_mod_set = false;
}
- updating_screen = FALSE;
+ updating_screen = 0;
/* Clear or redraw the command line. Done last, because scrolling may
* mess up the command line. */
@@ -1629,6 +1629,7 @@ static void win_update(win_T *wp)
* changes are relevant).
*/
wp->w_valid |= VALID_BOTLINE;
+ wp->w_viewport_invalid = true;
if (wp == curwin && wp->w_botline != old_botline && !recursive) {
recursive = TRUE;
curwin->w_valid &= ~VALID_TOPLINE;
@@ -1648,7 +1649,7 @@ static void win_update(win_T *wp)
/* restore got_int, unless CTRL-C was hit while redrawing */
if (!got_int)
got_int = save_got_int;
-}
+} // NOLINT(readability/fn_size)
/// Returns width of the signcolumn that should be used for the whole window
///
@@ -1744,7 +1745,7 @@ static int advance_color_col(int vcol, int **color_cols)
// space is available for window "wp", minus "col".
static int compute_foldcolumn(win_T *wp, int col)
{
- int fdc = wp->w_p_fdc;
+ int fdc = win_fdccol_count(wp);
int wmw = wp == curwin && p_wmw == 0 ? 1 : p_wmw;
int wwidth = wp->w_grid.Columns;
@@ -2215,10 +2216,10 @@ win_line (
int n_skip = 0; /* nr of chars to skip for 'nowrap' */
- int fromcol = 0, tocol = 0; // start/end of inverting
+ int fromcol = -10; // start of inverting
+ int tocol = MAXCOL; // end of inverting
int fromcol_prev = -2; // start of inverting after cursor
- int noinvcur = false; // don't invert the cursor
- pos_T *top, *bot;
+ bool noinvcur = false; // don't invert the cursor
int lnum_in_visual_area = false;
pos_T pos;
long v;
@@ -2416,27 +2417,28 @@ win_line (
capcol_lnum = 0;
}
- //
- // handle visual active in this window
- //
- fromcol = -10;
- tocol = MAXCOL;
+ // handle Visual active in this window
if (VIsual_active && wp->w_buffer == curwin->w_buffer) {
- // Visual is after curwin->w_cursor
+ pos_T *top, *bot;
+
if (ltoreq(curwin->w_cursor, VIsual)) {
+ // Visual is after curwin->w_cursor
top = &curwin->w_cursor;
bot = &VIsual;
- } else { // Visual is before curwin->w_cursor
+ } else {
+ // Visual is before curwin->w_cursor
top = &VIsual;
bot = &curwin->w_cursor;
}
lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum);
- if (VIsual_mode == Ctrl_V) { // block mode
+ if (VIsual_mode == Ctrl_V) {
+ // block mode
if (lnum_in_visual_area) {
fromcol = wp->w_old_cursor_fcol;
tocol = wp->w_old_cursor_lcol;
}
- } else { // non-block mode
+ } else {
+ // non-block mode
if (lnum > top->lnum && lnum <= bot->lnum) {
fromcol = 0;
} else if (lnum == top->lnum) {
@@ -3159,8 +3161,8 @@ win_line (
shl->endcol += (*mb_ptr2len)(line + shl->endcol);
}
- /* Loop to check if the match starts at the
- * current position */
+ // Loop to check if the match starts at the
+ // current position
continue;
}
}
@@ -3647,8 +3649,9 @@ win_line (
tab_len += n_extra - tab_len;
}
- /* if n_extra > 0, it gives the number of chars to use for
- * a tab, else we need to calculate the width for a tab */
+ // if n_extra > 0, it gives the number of chars
+ // to use for a tab, else we need to calculate the width
+ // for a tab
int len = (tab_len * mb_char2len(wp->w_p_lcs_chars.tab2));
if (n_extra > 0) {
len += n_extra - tab_len;
@@ -3660,10 +3663,16 @@ win_line (
xfree(p_extra_free);
p_extra_free = p;
for (i = 0; i < tab_len; i++) {
- utf_char2bytes(wp->w_p_lcs_chars.tab2, p);
- p += mb_char2len(wp->w_p_lcs_chars.tab2);
- n_extra += mb_char2len(wp->w_p_lcs_chars.tab2)
- - (saved_nextra > 0 ? 1: 0);
+ int lcs = wp->w_p_lcs_chars.tab2;
+
+ // if tab3 is given, need to change the char
+ // for tab
+ if (wp->w_p_lcs_chars.tab3 && i == tab_len - 1) {
+ lcs = wp->w_p_lcs_chars.tab3;
+ }
+ utf_char2bytes(lcs, p);
+ p += mb_char2len(lcs);
+ n_extra += mb_char2len(lcs) - (saved_nextra > 0 ? 1 : 0);
}
p_extra = p_extra_free;
@@ -5724,12 +5733,11 @@ static void end_search_hl(void)
* Init for calling prepare_search_hl().
*/
static void init_search_hl(win_T *wp)
+ FUNC_ATTR_NONNULL_ALL
{
- matchitem_T *cur;
-
- /* Setup for match and 'hlsearch' highlighting. Disable any previous
- * match */
- cur = wp->w_match_head;
+ // Setup for match and 'hlsearch' highlighting. Disable any previous
+ // match
+ matchitem_T *cur = wp->w_match_head;
while (cur != NULL) {
cur->hl.rm = cur->match;
if (cur->hlg_id == 0)
@@ -5739,7 +5747,7 @@ static void init_search_hl(win_T *wp)
cur->hl.buf = wp->w_buffer;
cur->hl.lnum = 0;
cur->hl.first_lnum = 0;
- /* Set the time limit to 'redrawtime'. */
+ // Set the time limit to 'redrawtime'.
cur->hl.tm = profile_setlimit(p_rdt);
cur = cur->next;
}
@@ -5755,18 +5763,16 @@ static void init_search_hl(win_T *wp)
* Advance to the match in window "wp" line "lnum" or past it.
*/
static void prepare_search_hl(win_T *wp, linenr_T lnum)
+ FUNC_ATTR_NONNULL_ALL
{
- matchitem_T *cur; /* points to the match list */
- match_T *shl; /* points to search_hl or a match */
- int shl_flag; /* flag to indicate whether search_hl
- has been processed or not */
- int n;
-
- /*
- * When using a multi-line pattern, start searching at the top
- * of the window or just after a closed fold.
- * Do this both for search_hl and the match list.
- */
+ matchitem_T *cur; // points to the match list
+ match_T *shl; // points to search_hl or a match
+ bool shl_flag; // flag to indicate whether search_hl
+ // has been processed or not
+
+ // When using a multi-line pattern, start searching at the top
+ // of the window or just after a closed fold.
+ // Do this both for search_hl and the match list.
cur = wp->w_match_head;
shl_flag = false;
while (cur != NULL || shl_flag == false) {
@@ -5793,7 +5799,7 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
}
bool pos_inprogress = true; // mark that a position match search is
// in progress
- n = 0;
+ int n = 0;
while (shl->first_lnum < lnum && (shl->rm.regprog != NULL
|| (cur != NULL && pos_inprogress))) {
next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n,
@@ -5831,6 +5837,7 @@ next_search_hl (
colnr_T mincol, /* minimal column for a match */
matchitem_T *cur /* to retrieve match positions if any */
)
+ FUNC_ATTR_NONNULL_ARG(2)
{
linenr_T l;
colnr_T matchcol;
@@ -5838,11 +5845,10 @@ next_search_hl (
int save_called_emsg = called_emsg;
if (shl->lnum != 0) {
- /* Check for three situations:
- * 1. If the "lnum" is below a previous match, start a new search.
- * 2. If the previous match includes "mincol", use it.
- * 3. Continue after the previous match.
- */
+ // Check for three situations:
+ // 1. If the "lnum" is below a previous match, start a new search.
+ // 2. If the previous match includes "mincol", use it.
+ // 3. Continue after the previous match.
l = shl->lnum + shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum;
if (lnum > l)
shl->lnum = 0;
@@ -5856,22 +5862,21 @@ next_search_hl (
*/
called_emsg = FALSE;
for (;; ) {
- /* Stop searching after passing the time limit. */
+ // Stop searching after passing the time limit.
if (profile_passed_limit(shl->tm)) {
shl->lnum = 0; /* no match found in time */
break;
}
- /* Three situations:
- * 1. No useful previous match: search from start of line.
- * 2. Not Vi compatible or empty match: continue at next character.
- * Break the loop if this is beyond the end of the line.
- * 3. Vi compatible searching: continue at end of previous match.
- */
- if (shl->lnum == 0)
+ // Three situations:
+ // 1. No useful previous match: search from start of line.
+ // 2. Not Vi compatible or empty match: continue at next character.
+ // Break the loop if this is beyond the end of the line.
+ // 3. Vi compatible searching: continue at end of previous match.
+ if (shl->lnum == 0) {
matchcol = 0;
- else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL
- || (shl->rm.endpos[0].lnum == 0
- && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) {
+ } else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL
+ || (shl->rm.endpos[0].lnum == 0
+ && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) {
char_u *ml;
matchcol = shl->rm.startpos[0].col;
@@ -5888,8 +5893,8 @@ next_search_hl (
shl->lnum = lnum;
if (shl->rm.regprog != NULL) {
- /* Remember whether shl->rm is using a copy of the regprog in
- * cur->match. */
+ // Remember whether shl->rm is using a copy of the regprog in
+ // cur->match.
bool regprog_is_copy = (shl != &search_hl
&& cur != NULL
&& shl == &cur->hl
@@ -5918,7 +5923,7 @@ next_search_hl (
nmatched = next_search_hl_pos(shl, lnum, &(cur->pos), matchcol);
}
if (nmatched == 0) {
- shl->lnum = 0; /* no match found */
+ shl->lnum = 0; // no match found
break;
}
if (shl->rm.startpos[0].lnum > 0
@@ -5926,7 +5931,7 @@ next_search_hl (
|| nmatched > 1
|| shl->rm.endpos[0].col > mincol) {
shl->lnum += shl->rm.startpos[0].lnum;
- break; /* useful match found */
+ break; // useful match found
}
// Restore called_emsg for assert_fails().
@@ -5943,6 +5948,7 @@ next_search_hl_pos(
posmatch_T *posmatch, // match positions
colnr_T mincol // minimal column for a match
)
+ FUNC_ATTR_NONNULL_ALL
{
int i;
int found = -1;
@@ -6097,9 +6103,10 @@ void check_for_delay(int check_msg_scroll)
&& emsg_silent == 0) {
ui_flush();
os_delay(1000L, true);
- emsg_on_display = FALSE;
- if (check_msg_scroll)
- msg_scroll = FALSE;
+ emsg_on_display = false;
+ if (check_msg_scroll) {
+ msg_scroll = false;
+ }
}
}
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 3ee9777805..23086c629b 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -1192,6 +1192,7 @@ int do_search(
len = STRLEN(p) + off_len + 3;
}
+ xfree(msgbuf);
msgbuf = xmalloc(len);
{
memset(msgbuf, ' ', len);
@@ -2227,6 +2228,8 @@ showmatch(
pos_T *lpos, save_cursor;
pos_T mpos;
colnr_T vcol;
+ long *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
+ long *siso = curwin->w_p_siso >= 0 ? &curwin->w_p_siso : &p_siso;
long save_so;
long save_siso;
int save_state;
@@ -2262,23 +2265,24 @@ showmatch(
&& vcol < curwin->w_leftcol + curwin->w_width_inner)) {
mpos = *lpos; // save the pos, update_screen() may change it
save_cursor = curwin->w_cursor;
- save_so = p_so;
- save_siso = p_siso;
- /* Handle "$" in 'cpo': If the ')' is typed on top of the "$",
- * stop displaying the "$". */
- if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol)
+ save_so = *so;
+ save_siso = *siso;
+ // Handle "$" in 'cpo': If the ')' is typed on top of the "$",
+ // stop displaying the "$".
+ if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol) {
dollar_vcol = -1;
- ++curwin->w_virtcol; /* do display ')' just before "$" */
- update_screen(VALID); /* show the new char first */
+ }
+ curwin->w_virtcol++; // do display ')' just before "$"
+ update_screen(VALID); // show the new char first
save_dollar_vcol = dollar_vcol;
save_state = State;
State = SHOWMATCH;
- ui_cursor_shape(); /* may show different cursor shape */
- curwin->w_cursor = mpos; /* move to matching char */
- p_so = 0; /* don't use 'scrolloff' here */
- p_siso = 0; /* don't use 'sidescrolloff' here */
- showruler(FALSE);
+ ui_cursor_shape(); // may show different cursor shape
+ curwin->w_cursor = mpos; // move to matching char
+ *so = 0; // don't use 'scrolloff' here
+ *siso = 0; // don't use 'sidescrolloff' here
+ showruler(false);
setcursor();
ui_flush();
/* Restore dollar_vcol(), because setcursor() may call curs_rows()
@@ -2294,11 +2298,11 @@ showmatch(
os_delay(p_mat * 100L, true);
else if (!char_avail())
os_delay(p_mat * 100L, false);
- curwin->w_cursor = save_cursor; /* restore cursor position */
- p_so = save_so;
- p_siso = save_siso;
+ curwin->w_cursor = save_cursor; // restore cursor position
+ *so = save_so;
+ *siso = save_siso;
State = save_state;
- ui_cursor_shape(); /* may show different cursor shape */
+ ui_cursor_shape(); // may show different cursor shape
}
}
}
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index 23dd447744..ab5d04d39b 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -198,7 +198,7 @@ static void insert_sign(
// column for signs.
if (buf->b_signlist == NULL) {
redraw_buf_later(buf, NOT_VALID);
- changed_cline_bef_curs();
+ changed_line_abv_curs();
}
// first sign in signlist
@@ -265,6 +265,81 @@ dict_T * sign_get_info(signlist_T *sign)
return d;
}
+// Sort the signs placed on the same line as "sign" by priority. Invoked after
+// changing the priority of an already placed sign. Assumes the signs in the
+// buffer are sorted by line number and priority.
+static void sign_sort_by_prio_on_line(buf_T *buf, signlist_T *sign)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // If there is only one sign in the buffer or only one sign on the line or
+ // the sign is already sorted by priority, then return.
+ if ((sign->prev == NULL
+ || sign->prev->lnum != sign->lnum
+ || sign->prev->priority > sign->priority)
+ && (sign->next == NULL
+ || sign->next->lnum != sign->lnum
+ || sign->next->priority < sign->priority)) {
+ return;
+ }
+
+ // One or more signs on the same line as 'sign'
+ // Find a sign after which 'sign' should be inserted
+
+ // First search backward for a sign with higher priority on the same line
+ signlist_T *p = sign;
+ while (p->prev != NULL
+ && p->prev->lnum == sign->lnum
+ && p->prev->priority <= sign->priority) {
+ p = p->prev;
+ }
+ if (p == sign) {
+ // Sign not found. Search forward for a sign with priority just before
+ // 'sign'.
+ p = sign->next;
+ while (p->next != NULL
+ && p->next->lnum == sign->lnum
+ && p->next->priority > sign->priority) {
+ p = p->next;
+ }
+ }
+
+ // Remove 'sign' from the list
+ if (buf->b_signlist == sign) {
+ buf->b_signlist = sign->next;
+ }
+ if (sign->prev != NULL) {
+ sign->prev->next = sign->next;
+ }
+ if (sign->next != NULL) {
+ sign->next->prev = sign->prev;
+ }
+ sign->prev = NULL;
+ sign->next = NULL;
+
+ // Re-insert 'sign' at the right place
+ if (p->priority <= sign->priority) {
+ // 'sign' has a higher priority and should be inserted before 'p'
+ sign->prev = p->prev;
+ sign->next = p;
+ p->prev = sign;
+ if (sign->prev != NULL) {
+ sign->prev->next = sign;
+ }
+ if (buf->b_signlist == p) {
+ buf->b_signlist = sign;
+ }
+ } else {
+ // 'sign' has a lower priority and should be inserted after 'p'
+ sign->prev = p;
+ sign->next = p->next;
+ p->next = sign;
+ if (sign->next != NULL) {
+ sign->next->prev = sign;
+ }
+ }
+}
+
+
/// Add the sign into the signlist. Find the right spot to do it though.
void buf_addsign(
buf_T *buf, // buffer to store sign in
@@ -284,6 +359,8 @@ void buf_addsign(
&& sign_in_group(sign, groupname)) {
// Update an existing sign
sign->typenr = typenr;
+ sign->priority = prio;
+ sign_sort_by_prio_on_line(buf, sign);
return;
} else if (lnum < sign->lnum) {
insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr);
@@ -418,11 +495,11 @@ linenr_T buf_delsign(
}
}
- // When deleted the last sign needs to redraw the windows to remove the
- // sign column.
+ // When deleting the last sign the cursor position may change, because the
+ // sign columns no longer shows. And the 'signcolumn' may be hidden.
if (buf->b_signlist == NULL) {
redraw_buf_later(buf, NOT_VALID);
- changed_cline_bef_curs();
+ changed_line_abv_curs();
}
return lnum;
@@ -495,7 +572,7 @@ void buf_delete_signs(buf_T *buf, char_u *group)
// When deleting the last sign need to redraw the windows to remove the
// sign column. Not when curwin is NULL (this means we're exiting).
if (buf->b_signlist != NULL && curwin != NULL) {
- changed_cline_bef_curs();
+ changed_line_abv_curs();
}
lastp = &buf->b_signlist;
@@ -754,6 +831,14 @@ int sign_define_by_name(
} else {
sp_prev->sn_next = sp;
}
+ } else {
+ // Signs may already exist, a redraw is needed in windows with a
+ // non-empty sign list.
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_buffer->b_signlist != NULL) {
+ redraw_buf_later(wp->w_buffer, NOT_VALID);
+ }
+ }
}
// set values for a defined sign.
@@ -1531,10 +1616,44 @@ static enum
EXP_SUBCMD, // expand :sign sub-commands
EXP_DEFINE, // expand :sign define {name} args
EXP_PLACE, // expand :sign place {id} args
+ EXP_LIST, // expand :sign place args
EXP_UNPLACE, // expand :sign unplace"
- EXP_SIGN_NAMES // expand with name of placed signs
+ EXP_SIGN_NAMES, // expand with name of placed signs
+ EXP_SIGN_GROUPS, // expand with name of placed sign groups
} expand_what;
+// Return the n'th sign name (used for command line completion)
+static char_u *get_nth_sign_name(int idx)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ // Complete with name of signs already defined
+ int current_idx = 0;
+ for (sign_T *sp = first_sign; sp != NULL; sp = sp->sn_next) {
+ if (current_idx++ == idx) {
+ return sp->sn_name;
+ }
+ }
+ return NULL;
+}
+
+// Return the n'th sign group name (used for command line completion)
+static char_u *get_nth_sign_group_name(int idx)
+{
+ // Complete with name of sign groups already defined
+ int current_idx = 0;
+ int todo = (int)sg_table.ht_used;
+ for (hashitem_T *hi = sg_table.ht_array; todo > 0; hi++) {
+ if (!HASHITEM_EMPTY(hi)) {
+ todo--;
+ if (current_idx++ == idx) {
+ signgroup_T *const group = HI2SG(hi);
+ return group->sg_name;
+ }
+ }
+ }
+ return NULL;
+}
+
/// Function given to ExpandGeneric() to obtain the sign command
/// expansion.
char_u * get_sign_name(expand_T *xp, int idx)
@@ -1552,20 +1671,18 @@ char_u * get_sign_name(expand_T *xp, int idx)
"buffer=", NULL };
return (char_u *)place_arg[idx];
}
+ case EXP_LIST: {
+ char *list_arg[] = { "group=", "file=", "buffer=", NULL };
+ return (char_u *)list_arg[idx];
+ }
case EXP_UNPLACE: {
char *unplace_arg[] = { "group=", "file=", "buffer=", NULL };
return (char_u *)unplace_arg[idx];
}
- case EXP_SIGN_NAMES: {
- // Complete with name of signs already defined
- int current_idx = 0;
- for (sign_T *sp = first_sign; sp != NULL; sp = sp->sn_next) {
- if (current_idx++ == idx) {
- return sp->sn_name;
- }
- }
- }
- return NULL;
+ case EXP_SIGN_NAMES:
+ return get_nth_sign_name(idx);
+ case EXP_SIGN_GROUPS:
+ return get_nth_sign_group_name(idx);
default:
return NULL;
}
@@ -1574,7 +1691,6 @@ char_u * get_sign_name(expand_T *xp, int idx)
/// Handle command line completion for :sign command.
void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
{
- char_u *p;
char_u *end_subcmd;
char_u *last;
int cmd_idx;
@@ -1598,26 +1714,6 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
// |
// begin_subcmd_args
begin_subcmd_args = skipwhite(end_subcmd);
- p = skiptowhite(begin_subcmd_args);
- if (*p == NUL) {
- //
- // Expand first argument of subcmd when possible.
- // For ":jump {id}" and ":unplace {id}", we could
- // possibly expand the ids of all signs already placed.
- //
- xp->xp_pattern = begin_subcmd_args;
- switch (cmd_idx) {
- case SIGNCMD_LIST:
- case SIGNCMD_UNDEFINE:
- // :sign list <CTRL-D>
- // :sign undefine <CTRL-D>
- expand_what = EXP_SIGN_NAMES;
- break;
- default:
- xp->xp_context = EXPAND_NOTHING;
- }
- return;
- }
// Expand last argument of subcmd.
//
@@ -1626,6 +1722,7 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
// p
// Loop until reaching last argument.
+ char_u *p = begin_subcmd_args;
do {
p = skipwhite(p);
last = p;
@@ -1645,7 +1742,20 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
expand_what = EXP_DEFINE;
break;
case SIGNCMD_PLACE:
- expand_what = EXP_PLACE;
+ // List placed signs
+ if (ascii_isdigit(*begin_subcmd_args)) {
+ // :sign place {id} {args}...
+ expand_what = EXP_PLACE;
+ } else {
+ // :sign place {args}...
+ expand_what = EXP_LIST;
+ }
+ break;
+ case SIGNCMD_LIST:
+ case SIGNCMD_UNDEFINE:
+ // :sign list <CTRL-D>
+ // :sign undefine <CTRL-D>
+ expand_what = EXP_SIGN_NAMES;
break;
case SIGNCMD_JUMP:
case SIGNCMD_UNPLACE:
@@ -1659,19 +1769,33 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
xp->xp_pattern = p + 1;
switch (cmd_idx) {
case SIGNCMD_DEFINE:
- if (STRNCMP(last, "texthl", p - last) == 0
- || STRNCMP(last, "linehl", p - last) == 0
- || STRNCMP(last, "numhl", p - last) == 0) {
+ if (STRNCMP(last, "texthl", 6) == 0
+ || STRNCMP(last, "linehl", 6) == 0
+ || STRNCMP(last, "numhl", 5) == 0) {
xp->xp_context = EXPAND_HIGHLIGHT;
- } else if (STRNCMP(last, "icon", p - last) == 0) {
+ } else if (STRNCMP(last, "icon", 4) == 0) {
xp->xp_context = EXPAND_FILES;
} else {
xp->xp_context = EXPAND_NOTHING;
}
break;
case SIGNCMD_PLACE:
- if (STRNCMP(last, "name", p - last) == 0) {
+ if (STRNCMP(last, "name", 4) == 0) {
expand_what = EXP_SIGN_NAMES;
+ } else if (STRNCMP(last, "group", 5) == 0) {
+ expand_what = EXP_SIGN_GROUPS;
+ } else if (STRNCMP(last, "file", 4) == 0) {
+ xp->xp_context = EXPAND_BUFFERS;
+ } else {
+ xp->xp_context = EXPAND_NOTHING;
+ }
+ break;
+ case SIGNCMD_UNPLACE:
+ case SIGNCMD_JUMP:
+ if (STRNCMP(last, "group", 5) == 0) {
+ expand_what = EXP_SIGN_GROUPS;
+ } else if (STRNCMP(last, "file", 4) == 0) {
+ xp->xp_context = EXPAND_BUFFERS;
} else {
xp->xp_context = EXPAND_NOTHING;
}
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 6cb8d01f51..180073ade1 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -2827,9 +2827,6 @@ void spell_suggest(int count)
smsg(_("Sorry, only %" PRId64 " suggestions"),
(int64_t)sug.su_ga.ga_len);
} else {
- XFREE_CLEAR(repl_from);
- XFREE_CLEAR(repl_to);
-
// When 'rightleft' is set the list is drawn right-left.
cmdmsg_rl = curwin->w_p_rl;
if (cmdmsg_rl)
@@ -2909,6 +2906,9 @@ void spell_suggest(int count)
if (selected > 0 && selected <= sug.su_ga.ga_len && u_save_cursor() == OK) {
// Save the from and to text for :spellrepall.
+ XFREE_CLEAR(repl_from);
+ XFREE_CLEAR(repl_to);
+
stp = &SUG(sug.su_ga, selected - 1);
if (sug.su_badlen > stp->st_orglen) {
// Replacing less than "su_badlen", append the remainder to
@@ -5761,19 +5761,22 @@ cleanup_suggestions (
int maxscore,
int keep // nr of suggestions to keep
)
+ FUNC_ATTR_NONNULL_ALL
{
suggest_T *stp = &SUG(*gap, 0);
- // Sort the list.
- qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T), sug_compare);
+ if (gap->ga_len > 0) {
+ // Sort the list.
+ qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T), sug_compare);
- // Truncate the list to the number of suggestions that will be displayed.
- if (gap->ga_len > keep) {
- for (int i = keep; i < gap->ga_len; ++i) {
- xfree(stp[i].st_word);
+ // Truncate the list to the number of suggestions that will be displayed.
+ if (gap->ga_len > keep) {
+ for (int i = keep; i < gap->ga_len; i++) {
+ xfree(stp[i].st_word);
+ }
+ gap->ga_len = keep;
+ return stp[keep - 1].st_score;
}
- gap->ga_len = keep;
- return stp[keep - 1].st_score;
}
return maxscore;
}
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index ddb9188371..ef4dfb3caa 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -6400,7 +6400,7 @@ static int color_numbers_88[28] = { 0, 4, 2, 6,
75, 11, 78, 15, -1 };
// for xterm with 256 colors...
static int color_numbers_256[28] = { 0, 4, 2, 6,
- 1, 5, 130, 130,
+ 1, 5, 130, 3,
248, 248, 7, 7,
242, 242,
12, 81, 10, 121,
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index 57bb43c846..ff07a00952 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -2540,7 +2540,9 @@ parse_match(
}
p += 2; // skip ";\""
if (*p++ == TAB) {
- while (ASCII_ISALPHA(*p)) {
+ // Accept ASCII alphabetic kind characters and any multi-byte
+ // character.
+ while (ASCII_ISALPHA(*p) || utfc_ptr2len(p) > 1) {
if (STRNCMP(p, "kind:", 5) == 0) {
tagp->tagkind = p + 5;
} else if (STRNCMP(p, "user_data:", 10) == 0) {
@@ -2559,19 +2561,22 @@ parse_match(
}
if (pt == NULL)
break;
- p = pt + 1;
+ p = pt;
+ MB_PTR_ADV(p);
}
}
}
if (tagp->tagkind != NULL) {
for (p = tagp->tagkind;
- *p && *p != '\t' && *p != '\r' && *p != '\n'; ++p)
- ;
+ *p && *p != '\t' && *p != '\r' && *p != '\n';
+ MB_PTR_ADV(p)) {
+ }
tagp->tagkind_end = p;
}
if (tagp->user_data != NULL) {
for (p = tagp->user_data;
- *p && *p != '\t' && *p != '\r' && *p != '\n'; p++) {
+ *p && *p != '\t' && *p != '\r' && *p != '\n';
+ MB_PTR_ADV(p)) {
}
tagp->user_data_end = p;
}
@@ -3181,7 +3186,8 @@ int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
if (tp.command_end != NULL) {
for (char_u *p = tp.command_end + 3;
- *p != NUL && *p != '\n' && *p != '\r'; p++) {
+ *p != NUL && *p != '\n' && *p != '\r';
+ MB_PTR_ADV(p)) {
if (p == tp.tagkind
|| (p + 5 == tp.tagkind && STRNCMP(p, "kind:", 5) == 0)) {
// skip "kind:<kind>" and "<kind>"
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index c5e756905a..a37cc60928 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -992,8 +992,9 @@ static void mouse_action(Terminal *term, int button, int row, int col,
static bool send_mouse_event(Terminal *term, int c)
{
int row = mouse_row, col = mouse_col, grid = mouse_grid;
+ int offset;
win_T *mouse_win = mouse_find_win(&grid, &row, &col);
- if (mouse_win == NULL) {
+ if (mouse_win == NULL || (offset = win_col_off(mouse_win)) > col) {
goto end;
}
@@ -1015,7 +1016,7 @@ static bool send_mouse_event(Terminal *term, int c)
default: return false;
}
- mouse_action(term, button, row, col, drag, 0);
+ mouse_action(term, button, row, col - offset, drag, 0);
size_t len = vterm_output_read(term->vt, term->textbuf,
sizeof(term->textbuf));
terminal_send(term, term->textbuf, (size_t)len);
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index c36458930f..e52fd888bd 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -86,7 +86,7 @@ nongui: nolog $(FIXFF) $(SCRIPTS) newtests report
@echo 'set $$_exitcode = -1\nrun\nif $$_exitcode != -1\n quit\nend' > .gdbinit
report:
- $(RUN_VIMTEST) $(NO_INITS) -u NONE -S summarize.vim messages
+ $(NVIM_PRG) -u NONE $(NO_INITS) -S summarize.vim messages
@echo
@echo 'Test results:'
@cat test_result.log
diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim
index fc79f57d2e..c86fdf25ab 100644
--- a/src/nvim/testdir/test49.vim
+++ b/src/nvim/testdir/test49.vim
@@ -1,6 +1,6 @@
" Vim script language tests
" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
-" Last Change: 2019 May 24
+" Last Change: 2019 Oct 08
"-------------------------------------------------------------------------------
" Test environment {{{1
@@ -456,7 +456,7 @@ function! ExtraVim(...)
" messing up the user's viminfo file.
let redirect = a:0 ?
\ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : ""
- exec "!echo '" . debug_quits . "q' | $NVIM_PRG -u NONE -N -es" . redirect .
+ exec "!echo '" . debug_quits . "q' | " .. v:progpath .. " -u NONE -N -es" . redirect .
\ " -c 'debuggreedy|set viminfo+=nviminfo'" .
\ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
\ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index e3547aea5b..954e5d875f 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -1072,6 +1072,40 @@ func Test_Cmd_Autocmds()
enew!
endfunc
+func s:ReadFile()
+ setl noswapfile nomodified
+ let filename = resolve(expand("<afile>:p"))
+ execute 'read' fnameescape(filename)
+ 1d_
+ exe 'file' fnameescape(filename)
+ setl buftype=acwrite
+endfunc
+
+func s:WriteFile()
+ let filename = resolve(expand("<afile>:p"))
+ setl buftype=
+ noautocmd execute 'write' fnameescape(filename)
+ setl buftype=acwrite
+ setl nomodified
+endfunc
+
+func Test_BufReadCmd()
+ autocmd BufReadCmd *.test call s:ReadFile()
+ autocmd BufWriteCmd *.test call s:WriteFile()
+
+ call writefile(['one', 'two', 'three'], 'Xcmd.test')
+ edit Xcmd.test
+ call assert_match('Xcmd.test" line 1 of 3', execute('file'))
+ normal! Gofour
+ write
+ call assert_equal(['one', 'two', 'three', 'four'], readfile('Xcmd.test'))
+
+ bwipe!
+ call delete('Xcmd.test')
+ au! BufReadCmd
+ au! BufWriteCmd
+endfunc
+
func SetChangeMarks(start, end)
exe a:start. 'mark ['
exe a:end. 'mark ]'
@@ -1786,3 +1820,46 @@ func Test_FileChangedShell_reload()
bwipe!
call delete('Xchanged')
endfunc
+
+" Test for FileReadCmd autocmd
+func Test_autocmd_FileReadCmd()
+ func ReadFileCmd()
+ call append(line('$'), "v:cmdarg = " .. v:cmdarg)
+ endfunc
+ augroup FileReadCmdTest
+ au!
+ au FileReadCmd Xtest call ReadFileCmd()
+ augroup END
+
+ new
+ read ++bin Xtest
+ read ++nobin Xtest
+ read ++edit Xtest
+ read ++bad=keep Xtest
+ read ++bad=drop Xtest
+ read ++bad=- Xtest
+ read ++ff=unix Xtest
+ read ++ff=dos Xtest
+ read ++ff=mac Xtest
+ read ++enc=utf-8 Xtest
+
+ call assert_equal(['',
+ \ 'v:cmdarg = ++bin',
+ \ 'v:cmdarg = ++nobin',
+ \ 'v:cmdarg = ++edit',
+ \ 'v:cmdarg = ++bad=keep',
+ \ 'v:cmdarg = ++bad=drop',
+ \ 'v:cmdarg = ++bad=-',
+ \ 'v:cmdarg = ++ff=unix',
+ \ 'v:cmdarg = ++ff=dos',
+ \ 'v:cmdarg = ++ff=mac',
+ \ 'v:cmdarg = ++enc=utf-8'], getline(1, '$'))
+
+ close!
+ augroup FileReadCmdTest
+ au!
+ augroup END
+ delfunc ReadFileCmd
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_compiler.vim b/src/nvim/testdir/test_compiler.vim
index 40d3cdbdae..6bb602717f 100644
--- a/src/nvim/testdir/test_compiler.vim
+++ b/src/nvim/testdir/test_compiler.vim
@@ -38,10 +38,11 @@ func Test_compiler()
endfunc
func Test_compiler_without_arg()
- let a=split(execute('compiler'))
- call assert_match('^.*runtime/compiler/ant.vim$', a[0])
- call assert_match('^.*runtime/compiler/bcc.vim$', a[1])
- call assert_match('^.*runtime/compiler/xmlwf.vim$', a[-1])
+ let runtime = substitute($VIMRUNTIME, '\\', '/', 'g')
+ let a = split(execute('compiler'))
+ call assert_match(runtime .. '/compiler/ant.vim$', a[0])
+ call assert_match(runtime .. '/compiler/bcc.vim$', a[1])
+ call assert_match(runtime .. '/compiler/xmlwf.vim$', a[-1])
endfunc
func Test_compiler_completion()
diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim
index 21e0271bda..fed642e34b 100644
--- a/src/nvim/testdir/test_diffmode.vim
+++ b/src/nvim/testdir/test_diffmode.vim
@@ -67,7 +67,7 @@ func Common_vert_split()
set foldmethod=marker foldcolumn=4
call assert_equal(0, &diff)
call assert_equal('marker', &foldmethod)
- call assert_equal(4, &foldcolumn)
+ call assert_equal('4', &foldcolumn)
call assert_equal(0, &scrollbind)
call assert_equal(0, &cursorbind)
call assert_equal(1, &wrap)
@@ -76,7 +76,7 @@ func Common_vert_split()
vert diffsplit Xtest2
call assert_equal(1, &diff)
call assert_equal('diff', &foldmethod)
- call assert_equal(2, &foldcolumn)
+ call assert_equal('2', &foldcolumn)
call assert_equal(1, &scrollbind)
call assert_equal(1, &cursorbind)
call assert_equal(0, &wrap)
@@ -142,7 +142,7 @@ func Common_vert_split()
1wincmd w
call assert_equal(0, &diff)
call assert_equal('marker', &foldmethod)
- call assert_equal(4, &foldcolumn)
+ call assert_equal('4', &foldcolumn)
call assert_equal(0, &scrollbind)
call assert_equal(0, &cursorbind)
call assert_equal(1, &wrap)
@@ -150,7 +150,7 @@ func Common_vert_split()
wincmd w
call assert_equal(0, &diff)
call assert_equal('marker', &foldmethod)
- call assert_equal(4, &foldcolumn)
+ call assert_equal('4', &foldcolumn)
call assert_equal(0, &scrollbind)
call assert_equal(0, &cursorbind)
call assert_equal(1, &wrap)
@@ -158,7 +158,7 @@ func Common_vert_split()
wincmd w
call assert_equal(0, &diff)
call assert_equal('marker', &foldmethod)
- call assert_equal(4, &foldcolumn)
+ call assert_equal('4', &foldcolumn)
call assert_equal(0, &scrollbind)
call assert_equal(0, &cursorbind)
call assert_equal(1, &wrap)
diff --git a/src/nvim/testdir/test_digraph.vim b/src/nvim/testdir/test_digraph.vim
index 5da05e85b5..1792dcc00b 100644
--- a/src/nvim/testdir/test_digraph.vim
+++ b/src/nvim/testdir/test_digraph.vim
@@ -433,6 +433,18 @@ func Test_digraphs_output()
call assert_equal('Z% Ж 1046', matchstr(out, '\C\<Z%\D*1046\>'))
call assert_equal('u- Å« 363', matchstr(out, '\C\<u-\D*363\>'))
call assert_equal('SH ^A 1', matchstr(out, '\C\<SH\D*1\>'))
+ call assert_notmatch('Latin supplement', out)
+
+ let out_bang_without_custom = execute(':digraph!')
+ digraph lt 60
+ let out_bang_with_custom = execute(':digraph!')
+ call assert_notmatch('lt', out_bang_without_custom)
+ call assert_match("^\n"
+ \ .. "NU ^@ 10 .*\n"
+ \ .. "Latin supplement\n"
+ \ .. "!I ¡ 161 .*\n"
+ \ .. ".*\n"
+ \ .. 'Custom\n.*\<lt < 60\>', out_bang_with_custom)
bw!
endfunc
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
index dd546dbf71..264d8b000f 100644
--- a/src/nvim/testdir/test_expr.vim
+++ b/src/nvim/testdir/test_expr.vim
@@ -475,6 +475,8 @@ func Test_funcref()
let OneByRef = funcref('One')
call assert_equal(2, OneByRef())
call assert_fails('echo funcref("{")', 'E475:')
+ let OneByRef = funcref("One", repeat(["foo"], 20))
+ call assert_fails('let OneByRef = funcref("One", repeat(["foo"], 21))', 'E118:')
endfunc
func Test_empty_concatenate()
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 7290cceb0b..c3ddce7914 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -79,6 +79,7 @@ let s:filename_checks = {
\ 'bib': ['file.bib'],
\ 'bindzone': ['named.root'],
\ 'blank': ['file.bl'],
+ \ 'bsdl': ['file.bsd', 'file.bsdl'],
\ 'bst': ['file.bst'],
\ 'bzr': ['bzr_log.any'],
\ 'c': ['enlightenment/file.cfg', 'file.qc', 'file.c'],
@@ -436,7 +437,7 @@ let s:filename_checks = {
\ 'swiftgyb': ['file.swift.gyb'],
\ 'sil': ['file.sil'],
\ 'sysctl': ['/etc/sysctl.conf', '/etc/sysctl.d/file.conf'],
- \ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.mount', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer', '/etc/systemd/system/some.d/file.conf', '/etc/systemd/system/some.d/.#file'],
+ \ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.mount', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer', '/etc/systemd/system/some.d/file.conf', '/etc/systemd/system/some.d/.#file', '/home/user/.config/systemd/user/some.d/mine.conf', '/home/user/.config/systemd/user/some.d/.#file'],
\ 'systemverilog': ['file.sv', 'file.svh'],
\ 'tags': ['tags'],
\ 'tak': ['file.tak'],
@@ -480,7 +481,7 @@ let s:filename_checks = {
\ 'verilog': ['file.v'],
\ 'verilogams': ['file.va', 'file.vams'],
\ 'vgrindefs': ['vgrindefs'],
- \ 'vhdl': ['file.hdl', 'file.vhd', 'file.vhdl', 'file.vbe', 'file.vst', 'file.vhdl_123'],
+ \ 'vhdl': ['file.hdl', 'file.vhd', 'file.vhdl', 'file.vbe', 'file.vst', 'file.vhdl_123', 'file.vho'],
\ 'vim': ['file.vim', 'file.vba', '.exrc', '_exrc'],
\ 'viminfo': ['.viminfo', '_viminfo'],
\ 'vmasm': ['file.mar'],
@@ -600,6 +601,7 @@ let s:script_checks = {
\ 'haskell': [['#!/path/haskell']],
\ 'cpp': [['// Standard iostream objects -*- C++ -*-'],
\ ['// -*- C++ -*-']],
+ \ 'yaml': [['%YAML 1.2']],
\ }
func Test_script_detection()
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 7822507f86..bd5cb6ad19 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -186,6 +186,32 @@ func Test_strftime()
call assert_fails('call strftime([])', 'E730:')
call assert_fails('call strftime("%Y", [])', 'E745:')
+
+ " Check that the time changes after we change the timezone
+ " Save previous timezone value, if any
+ if exists('$TZ')
+ let tz = $TZ
+ endif
+
+ " Force EST and then UTC, save the current hour (24-hour clock) for each
+ let $TZ = 'EST' | let est = strftime('%H')
+ let $TZ = 'UTC' | let utc = strftime('%H')
+
+ " Those hours should be two bytes long, and should not be the same; if they
+ " are, a tzset(3) call may have failed somewhere
+ call assert_equal(strlen(est), 2)
+ call assert_equal(strlen(utc), 2)
+ " TODO: this fails on MS-Windows
+ if has('unix')
+ call assert_notequal(est, utc)
+ endif
+
+ " If we cached a timezone value, put it back, otherwise clear it
+ if exists('tz')
+ let $TZ = tz
+ else
+ unlet $TZ
+ endif
endfunc
func Test_resolve()
@@ -640,6 +666,16 @@ func Test_getbufvar()
call assert_equal('iso-8859-2', getbufvar(bufnr('%'), '&fenc'))
close
+ " Get the b: dict.
+ let b:testvar = 'one'
+ new
+ let b:testvar = 'two'
+ let thebuf = bufnr()
+ wincmd w
+ call assert_equal('two', getbufvar(thebuf, 'testvar'))
+ call assert_equal('two', getbufvar(thebuf, '').testvar)
+ bwipe!
+
set fileformats&
endfunc
diff --git a/src/nvim/testdir/test_hardcopy.vim b/src/nvim/testdir/test_hardcopy.vim
index ced13b107c..6125f9b993 100644
--- a/src/nvim/testdir/test_hardcopy.vim
+++ b/src/nvim/testdir/test_hardcopy.vim
@@ -1,39 +1,137 @@
" Test :hardcopy
-func Test_printoptions_parsing()
- " Only test that this doesn't throw an error.
- set printoptions=left:5in,right:10pt,top:8mm,bottom:2pc
- set printoptions=left:2in,top:30pt,right:16mm,bottom:3pc
- set printoptions=header:3,syntax:y,number:7,wrap:n
- set printoptions=duplex:short,collate:n,jobsplit:y,portrait:n
- set printoptions=paper:10x14
- set printoptions=paper:A3
- set printoptions=paper:A4
- set printoptions=paper:A5
- set printoptions=paper:B4
- set printoptions=paper:B5
- set printoptions=paper:executive
- set printoptions=paper:folio
- set printoptions=paper:ledger
- set printoptions=paper:legal
- set printoptions=paper:letter
- set printoptions=paper:quarto
- set printoptions=paper:statement
- set printoptions=paper:tabloid
- set printoptions=formfeed:y
- set printoptions=
- set printoptions&
+func Test_printoptions()
+ edit test_hardcopy.vim
+ syn on
+
+ for opt in ['left:5in,right:10pt,top:8mm,bottom:2pc',
+ \ 'left:2in,top:30pt,right:16mm,bottom:3pc',
+ \ 'header:3,syntax:y,number:y,wrap:n',
+ \ 'header:3,syntax:n,number:y,wrap:y',
+ \ 'duplex:short,collate:n,jobsplit:y,portrait:n',
+ \ 'duplex:long,collate:y,jobsplit:n,portrait:y',
+ \ 'paper:10x14',
+ \ 'paper:A3',
+ \ 'paper:A4',
+ \ 'paper:A5',
+ \ 'paper:B4',
+ \ 'paper:B5',
+ \ 'paper:executive',
+ \ 'paper:folio',
+ \ 'paper:ledger',
+ \ 'paper:legal',
+ \ 'paper:letter',
+ \ 'paper:quarto',
+ \ 'paper:statement',
+ \ 'paper:tabloid',
+ \ 'formfeed:y',
+ \ '']
+ exe 'set printoptions=' .. opt
+ if has('postscript')
+ hardcopy > Xhardcopy_printoptions
+ let lines = readfile('Xhardcopy_printoptions')
+ call assert_true(len(lines) > 20, opt)
+ call assert_true(lines[0] =~ 'PS-Adobe', opt)
+ call delete('Xhardcopy_printoptions')
+ endif
+ endfor
call assert_fails('set printoptions=paper', 'E550:')
call assert_fails('set printoptions=shredder:on', 'E551:')
call assert_fails('set printoptions=left:no', 'E552:')
+ set printoptions&
+ bwipe
endfunc
-func Test_printmbfont_parsing()
- " Only test that this doesn't throw an error.
- set printmbfont=r:WadaMin-Regular,b:WadaMin-Bold,i:WadaMin-Italic,o:WadaMin-Bold-Italic,c:yes,a:no
- set printmbfont=
+func Test_printmbfont()
+ " Print a small help page which contains tabs to cover code that expands tabs to spaces.
+ help help
+ syn on
+
+ for opt in [':WadaMin-Regular,b:WadaMin-Bold,i:WadaMin-Italic,o:WadaMin-Bold-Italic,c:yes,a:no',
+ \ '']
+ exe 'set printmbfont=' .. opt
+ if has('postscript')
+ hardcopy > Xhardcopy_printmbfont
+ let lines = readfile('Xhardcopy_printmbfont')
+ call assert_true(len(lines) > 20, opt)
+ call assert_true(lines[0] =~ 'PS-Adobe', opt)
+ call delete('Xhardcopy_printmbfont')
+ endif
+ endfor
set printmbfont&
+ bwipe
+endfunc
+
+func Test_printexpr()
+ if !has('unix')
+ return
+ endif
+
+ " Not a very useful printexpr value, but enough to test
+ " hardcopy with 'printexpr'.
+ function PrintFile(fname)
+ call writefile(['Test printexpr: ' .. v:cmdarg],
+ \ 'Xhardcopy_printexpr')
+ call delete(a:fname)
+ return 0
+ endfunc
+ set printexpr=PrintFile(v:fname_in)
+
+ help help
+ hardcopy dummy args
+ call assert_equal(['Test printexpr: dummy args'],
+ \ readfile('Xhardcopy_printexpr'))
+ call delete('Xhardcopy_printexpr')
+
+ " Function return 1 to test print failure.
+ function PrintFails(fname)
+ call delete(a:fname)
+ return 1
+ endfunc
+ set printexpr=PrintFails(v:fname_in)
+ call assert_fails('hardcopy', 'E365:')
+
+ set printexpr&
+ bwipe
+endfunc
+
+func Test_errors()
+ " FIXME: Windows fails differently than Unix.
+ if has('unix')
+ edit test_hardcopy.vim
+ call assert_fails('hardcopy >', 'E324:')
+ bwipe
+ endif
+endfunc
+
+func Test_dark_background()
+ edit test_hardcopy.vim
+ syn on
+
+ for bg in ['dark', 'light']
+ exe 'set background=' .. bg
+
+ if has('postscript')
+ hardcopy > Xhardcopy_dark_background
+ let lines = readfile('Xhardcopy_dark_background')
+ call assert_true(len(lines) > 20)
+ call assert_true(lines[0] =~ 'PS-Adobe')
+ call delete('Xhardcopy_dark_background')
+ endif
+ endfor
+
+ set background&
+ bwipe
+endfun
+
+func Test_empty_buffer()
+ " FIXME: Unclear why this fails on Windows.
+ if has('unix')
+ new
+ call assert_equal("\nNo text to be printed", execute('hardcopy'))
+ bwipe
+ endif
endfunc
func Test_printheader_parsing()
@@ -46,22 +144,6 @@ func Test_printheader_parsing()
set printheader&
endfunc
-" Test that :hardcopy produces a non-empty file.
-" We don't check much of the contents.
-func Test_with_syntax()
- if has('postscript')
- edit test_hardcopy.vim
- set printoptions=syntax:y
- syn on
- hardcopy > Xhardcopy
- let lines = readfile('Xhardcopy')
- call assert_true(len(lines) > 20)
- call assert_true(lines[0] =~ 'PS-Adobe')
- call delete('Xhardcopy')
- set printoptions&
- endif
-endfunc
-
func Test_fname_with_spaces()
if !has('postscript')
return
@@ -86,4 +168,3 @@ func Test_illegal_byte()
bwipe!
call delete('Xpstest')
endfunc
-
diff --git a/src/nvim/testdir/test_listchars.vim b/src/nvim/testdir/test_listchars.vim
index 57cfaa298e..dcc588120c 100644
--- a/src/nvim/testdir/test_listchars.vim
+++ b/src/nvim/testdir/test_listchars.vim
@@ -58,6 +58,26 @@ func Test_listchars()
call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
endfor
+ " tab with 3rd character and linebreak set
+ set listchars-=tab:<=>
+ set listchars+=tab:<·>
+ set linebreak
+ let expected = [
+ \ '<······>aa<····>$',
+ \ '..bb<··>--$',
+ \ '...cccc>-$',
+ \ 'dd........ee--<>$',
+ \ '-$'
+ \ ]
+ redraw!
+ for i in range(1, 5)
+ call cursor(i, 1)
+ call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+ endfor
+ set nolinebreak
+ set listchars-=tab:<·>
+ set listchars+=tab:<=>
+
set listchars-=trail:-
let expected = [
\ '<======>aa<====>$',
diff --git a/src/nvim/testdir/test_maparg.vim b/src/nvim/testdir/test_maparg.vim
index 0b941d51ec..5f73bd80ad 100644
--- a/src/nvim/testdir/test_maparg.vim
+++ b/src/nvim/testdir/test_maparg.vim
@@ -41,6 +41,11 @@ function Test_maparg()
map abc y<S-char-114>y
call assert_equal("yRy", maparg('abc'))
+ omap { w
+ let d = maparg('{', 'o', 0, 1)
+ call assert_equal(['{', 'w', 'o'], [d.lhs, d.rhs, d.mode])
+ ounmap {
+
map abc <Nop>
call assert_equal("<Nop>", maparg('abc'))
unmap abc
@@ -62,3 +67,5 @@ function Test_range_map()
execute "normal a\uf040\<Esc>"
call assert_equal("abcd", getline(1))
endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim
index f14f292a92..82562339f6 100644
--- a/src/nvim/testdir/test_mapping.vim
+++ b/src/nvim/testdir/test_mapping.vim
@@ -390,3 +390,77 @@ func Test_motionforce_omap()
delfunc Select
delfunc GetCommand
endfunc
+
+" Test for mapping errors
+func Test_map_error()
+ call assert_fails('unmap', 'E474:')
+ call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:')
+ call assert_fails('unmap abc', 'E31:')
+ call assert_fails('unabbr abc', 'E24:')
+ call assert_equal('', maparg(''))
+ call assert_fails('echo maparg("abc", [])', 'E730:')
+
+ " unique map
+ map ,w /[#&!]<CR>
+ call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:')
+ " unique buffer-local map
+ call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:')
+ unmap ,w
+
+ " unique abbreviation
+ abbr SP special
+ call assert_fails("abbr <unique> SP special", 'E226:')
+ " unique buffer-local map
+ call assert_fails("abbr <buffer> <unique> SP special", 'E224:')
+ unabbr SP
+
+ call assert_fails('mapclear abc', 'E474:')
+ call assert_fails('abclear abc', 'E474:')
+endfunc
+
+" Test for <special> key mapping
+func Test_map_special()
+ throw 'skipped: Nvim does not support cpoptions flag "<"'
+ new
+ let old_cpo = &cpo
+ set cpo+=<
+ imap <F12> Blue
+ call feedkeys("i\<F12>", "x")
+ call assert_equal("<F12>", getline(1))
+ call feedkeys("ddi<F12>", "x")
+ call assert_equal("Blue", getline(1))
+ iunmap <F12>
+ imap <special> <F12> Green
+ call feedkeys("ddi\<F12>", "x")
+ call assert_equal("Green", getline(1))
+ call feedkeys("ddi<F12>", "x")
+ call assert_equal("<F12>", getline(1))
+ iunmap <special> <F12>
+ let &cpo = old_cpo
+ %bwipe!
+endfunc
+
+" Test for hasmapto()
+func Test_hasmapto()
+ call assert_equal(0, hasmapto('/^\k\+ ('))
+ call assert_equal(0, hasmapto('/^\k\+ (', 'n'))
+ nmap ,f /^\k\+ (<CR>
+ call assert_equal(1, hasmapto('/^\k\+ ('))
+ call assert_equal(1, hasmapto('/^\k\+ (', 'n'))
+ call assert_equal(0, hasmapto('/^\k\+ (', 'v'))
+
+ call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1))
+endfunc
+
+" Test for command-line completion of maps
+func Test_mapcomplete()
+ call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>',
+ \ '<silent>', '<special>', '<unique>'],
+ \ getcompletion('', 'mapping'))
+ call assert_equal([], getcompletion(',d', 'mapping'))
+
+ call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match("abbr! \x01", @:)
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_messages.vim b/src/nvim/testdir/test_messages.vim
index 265dee66ce..7fbf04311d 100644
--- a/src/nvim/testdir/test_messages.vim
+++ b/src/nvim/testdir/test_messages.vim
@@ -1,4 +1,4 @@
-" Tests for :messages
+" Tests for :messages, :echomsg, :echoerr
function Test_messages()
let oldmore = &more
@@ -6,6 +6,9 @@ function Test_messages()
set nomore
" Avoid the "message maintainer" line.
let $LANG = ''
+ let $LC_ALL = ''
+ let $LC_MESSAGES = ''
+ let $LC_COLLATE = ''
let arr = map(range(10), '"hello" . v:val')
for s in arr
@@ -65,6 +68,35 @@ func Test_message_completion()
call assert_equal('"message clear', @:)
endfunc
+func Test_echomsg()
+ call assert_equal("\nhello", execute(':echomsg "hello"'))
+ call assert_equal("\n", execute(':echomsg ""'))
+ call assert_equal("\n12345", execute(':echomsg 12345'))
+ call assert_equal("\n[]", execute(':echomsg []'))
+ call assert_equal("\n[1, 2, 3]", execute(':echomsg [1, 2, 3]'))
+ call assert_equal("\n{}", execute(':echomsg {}'))
+ call assert_equal("\n{'a': 1, 'b': 2}", execute(':echomsg {"a": 1, "b": 2}'))
+ if has('float')
+ call assert_equal("\n1.23", execute(':echomsg 1.23'))
+ endif
+ call assert_match("function('<lambda>\\d*')", execute(':echomsg {-> 1234}'))
+endfunc
+
+func Test_echoerr()
+ throw 'skipped: Nvim does not support test_ignore_error()'
+ call test_ignore_error('IgNoRe')
+ call assert_equal("\nIgNoRe hello", execute(':echoerr "IgNoRe hello"'))
+ call assert_equal("\n12345 IgNoRe", execute(':echoerr 12345 "IgNoRe"'))
+ call assert_equal("\n[1, 2, 'IgNoRe']", execute(':echoerr [1, 2, "IgNoRe"]'))
+ call assert_equal("\n{'IgNoRe': 2, 'a': 1}", execute(':echoerr {"a": 1, "IgNoRe": 2}'))
+ if has('float')
+ call assert_equal("\n1.23 IgNoRe", execute(':echoerr 1.23 "IgNoRe"'))
+ endif
+ call test_ignore_error('<lambda>')
+ call assert_match("function('<lambda>\\d*')", execute(':echoerr {-> 1234}'))
+ call test_ignore_error('RESET')
+endfunc
+
func Test_echospace()
set noruler noshowcmd laststatus=1
call assert_equal(&columns - 1, v:echospace)
diff --git a/src/nvim/testdir/test_number.vim b/src/nvim/testdir/test_number.vim
index 59debcea0d..3c9afc41d5 100644
--- a/src/nvim/testdir/test_number.vim
+++ b/src/nvim/testdir/test_number.vim
@@ -252,3 +252,14 @@ func Test_numberwidth_adjusted()
call s:compare_lines(expect, lines)
call s:close_windows()
endfunc
+
+" This was causing a memcheck error
+func Test_relativenumber_uninitialised()
+ new
+ set rnu
+ call setline(1, ["a", "b"])
+ redraw
+ call feedkeys("j", 'xt')
+ redraw
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 29d391c232..41f1710faf 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -511,3 +511,46 @@ func Test_shortmess_F2()
bwipe
bwipe
endfunc
+
+func Test_local_scrolloff()
+ set so=5
+ set siso=7
+ split
+ call assert_equal(5, &so)
+ setlocal so=3
+ call assert_equal(3, &so)
+ wincmd w
+ call assert_equal(5, &so)
+ wincmd w
+ setlocal so<
+ call assert_equal(5, &so)
+ setlocal so=0
+ call assert_equal(0, &so)
+ setlocal so=-1
+ call assert_equal(5, &so)
+
+ call assert_equal(7, &siso)
+ setlocal siso=3
+ call assert_equal(3, &siso)
+ wincmd w
+ call assert_equal(7, &siso)
+ wincmd w
+ setlocal siso<
+ call assert_equal(7, &siso)
+ setlocal siso=0
+ call assert_equal(0, &siso)
+ setlocal siso=-1
+ call assert_equal(7, &siso)
+
+ close
+ set so&
+ set siso&
+endfunc
+
+func Test_visualbell()
+ set belloff=
+ set visualbell
+ call assert_beeps('normal 0h')
+ set novisualbell
+ set belloff=all
+endfunc
diff --git a/src/nvim/testdir/test_plus_arg_edit.vim b/src/nvim/testdir/test_plus_arg_edit.vim
index f6d31e7626..e91a6e467a 100644
--- a/src/nvim/testdir/test_plus_arg_edit.vim
+++ b/src/nvim/testdir/test_plus_arg_edit.vim
@@ -8,3 +8,31 @@ function Test_edit()
call delete('Xfile1')
call delete('Xfile2')
endfunction
+
+func Test_edit_bad()
+ if !has('multi_byte')
+ finish
+ endif
+
+ " Test loading a utf8 file with bad utf8 sequences.
+ call writefile(["[\xff][\xc0][\xe2\x89\xf0][\xc2\xc2]"], "Xfile")
+ new
+
+ " Without ++bad=..., the default behavior is like ++bad=?
+ e! ++enc=utf8 Xfile
+ call assert_equal('[?][?][???][??]', getline(1))
+
+ e! ++enc=utf8 ++bad=_ Xfile
+ call assert_equal('[_][_][___][__]', getline(1))
+
+ e! ++enc=utf8 ++bad=drop Xfile
+ call assert_equal('[][][][]', getline(1))
+
+ e! ++enc=utf8 ++bad=keep Xfile
+ call assert_equal("[\xff][\xc0][\xe2\x89\xf0][\xc2\xc2]", getline(1))
+
+ call assert_fails('e! ++enc=utf8 ++bad=foo Xfile', 'E474:')
+
+ bw!
+ call delete('Xfile')
+endfunc
diff --git a/src/nvim/testdir/test_profile.vim b/src/nvim/testdir/test_profile.vim
index f3eb88abf0..4b0097617e 100644
--- a/src/nvim/testdir/test_profile.vim
+++ b/src/nvim/testdir/test_profile.vim
@@ -16,6 +16,7 @@ func Test_profile_func()
while l:count > 0
let l:count = l:count - 1
endwhile
+ sleep 1m
endfunc
func! Foo3()
endfunc
@@ -51,7 +52,7 @@ func Test_profile_func()
" - Unlike Foo3(), Foo2() should not be deleted since there is a check
" for v:profiling.
" - Bar() is not reported since it does not match "profile func Foo*".
- call assert_equal(30, len(lines))
+ call assert_equal(31, len(lines))
call assert_equal('FUNCTION Foo1()', lines[0])
call assert_match('Defined:.*Xprofile_func.vim:3', lines[1])
@@ -71,17 +72,18 @@ func Test_profile_func()
call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[16])
call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[17])
call assert_match('^\s*101\s\+.*\sendwhile$', lines[18])
- call assert_equal('', lines[19])
- call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[20])
- call assert_equal('count total (s) self (s) function', lines[21])
- call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[22])
- call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[23])
- call assert_equal('', lines[24])
- call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[25])
- call assert_equal('count total (s) self (s) function', lines[26])
- call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[27])
- call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[28])
- call assert_equal('', lines[29])
+ call assert_match('^\s*1\s\+.\+sleep 1m$', lines[19])
+ call assert_equal('', lines[20])
+ call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[21])
+ call assert_equal('count total (s) self (s) function', lines[22])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[23])
+ call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[24])
+ call assert_equal('', lines[25])
+ call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[26])
+ call assert_equal('count total (s) self (s) function', lines[27])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[28])
+ call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[29])
+ call assert_equal('', lines[30])
call delete('Xprofile_func.vim')
call delete('Xprofile_func.log')
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index d7b387c2c9..35555ca9d3 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -1510,6 +1510,13 @@ func Test_setqflist_invalid_nr()
call setqflist([], ' ', {'nr' : $XXX_DOES_NOT_EXIST})
endfunc
+func Test_setqflist_user_sets_buftype()
+ call setqflist([{'text': 'foo'}, {'text': 'bar'}])
+ set buftype=quickfix
+ call setqflist([], 'a')
+ enew
+endfunc
+
func Test_quickfix_set_list_with_act()
call XquickfixSetListWithAct('c')
call XquickfixSetListWithAct('l')
@@ -3311,6 +3318,14 @@ func Test_lvimgrep_crash()
enew | only
endfunc
+func Test_lvimgrep_crash2()
+ au BufNewFile x sfind
+ call assert_fails('lvimgrep x x', 'E480:')
+ call assert_fails('lvimgrep x x x', 'E480:')
+
+ au! BufNewFile
+endfunc
+
" Test for the position of the quickfix and location list window
func Test_qfwin_pos()
" Open two windows
diff --git a/src/nvim/testdir/test_quotestar.vim b/src/nvim/testdir/test_quotestar.vim
index ce5a9ee827..77a5153a81 100644
--- a/src/nvim/testdir/test_quotestar.vim
+++ b/src/nvim/testdir/test_quotestar.vim
@@ -108,7 +108,8 @@ func Do_test_quotestar_for_x11()
call remote_send(name, ":gui -f\<CR>")
endif
" Wait for the server in the GUI to be up and answering requests.
- call WaitForAssert({-> assert_match("1", remote_expr(name, "has('gui_running')", "", 1))})
+ " On some systems and with valgrind this can be very slow.
+ call WaitForAssert({-> assert_match("1", remote_expr(name, "has('gui_running')", "", 1))}, 10000)
call remote_send(name, ":let @* = 'maybe'\<CR>")
call WaitForAssert({-> assert_equal("maybe", remote_expr(name, "@*", "", 2))})
diff --git a/src/nvim/testdir/test_restricted.vim b/src/nvim/testdir/test_restricted.vim
new file mode 100644
index 0000000000..a29f7c33d3
--- /dev/null
+++ b/src/nvim/testdir/test_restricted.vim
@@ -0,0 +1,103 @@
+" Test for "rvim" or "vim -Z"
+
+source shared.vim
+
+"if has('win32') && has('gui')
+" " Win32 GUI shows a dialog instead of displaying the error in the last line.
+" finish
+"endif
+
+func Test_restricted()
+ call Run_restricted_test('!ls', 'E145:')
+endfunc
+
+func Run_restricted_test(ex_cmd, error)
+ let cmd = GetVimCommand('Xrestricted')
+ if cmd == ''
+ return
+ endif
+
+ " Use a VimEnter autocommand to avoid that the error message is displayed in
+ " a dialog with an OK button.
+ call writefile([
+ \ "func Init()",
+ \ " silent! " . a:ex_cmd,
+ \ " call writefile([v:errmsg], 'Xrestrout')",
+ \ " qa!",
+ \ "endfunc",
+ \ "au VimEnter * call Init()",
+ \ ], 'Xrestricted')
+ call system(cmd . ' -Z')
+ call assert_match(a:error, join(readfile('Xrestrout')))
+
+ call delete('Xrestricted')
+ call delete('Xrestrout')
+endfunc
+
+func Test_restricted_lua()
+ if !has('lua')
+ throw 'Skipped: Lua is not supported'
+ endif
+ call Run_restricted_test('lua print("Hello, Vim!")', 'E981:')
+ call Run_restricted_test('luado return "hello"', 'E981:')
+ call Run_restricted_test('luafile somefile', 'E981:')
+ call Run_restricted_test('call luaeval("expression")', 'E145:')
+endfunc
+
+func Test_restricted_mzscheme()
+ if !has('mzscheme')
+ throw 'Skipped: MzScheme is not supported'
+ endif
+ call Run_restricted_test('mzscheme statement', 'E981:')
+ call Run_restricted_test('mzfile somefile', 'E981:')
+ call Run_restricted_test('call mzeval("expression")', 'E145:')
+endfunc
+
+func Test_restricted_perl()
+ if !has('perl')
+ throw 'Skipped: Perl is not supported'
+ endif
+ " TODO: how to make Safe mode fail?
+ " call Run_restricted_test('perl system("ls")', 'E981:')
+ " call Run_restricted_test('perldo system("hello")', 'E981:')
+ " call Run_restricted_test('perlfile somefile', 'E981:')
+ " call Run_restricted_test('call perleval("system(\"ls\")")', 'E145:')
+endfunc
+
+func Test_restricted_python()
+ if !has('python')
+ throw 'Skipped: Python is not supported'
+ endif
+ call Run_restricted_test('python print "hello"', 'E981:')
+ call Run_restricted_test('pydo return "hello"', 'E981:')
+ call Run_restricted_test('pyfile somefile', 'E981:')
+ call Run_restricted_test('call pyeval("expression")', 'E145:')
+endfunc
+
+func Test_restricted_python3()
+ if !has('python3')
+ throw 'Skipped: Python3 is not supported'
+ endif
+ call Run_restricted_test('py3 print "hello"', 'E981:')
+ call Run_restricted_test('py3do return "hello"', 'E981:')
+ call Run_restricted_test('py3file somefile', 'E981:')
+ call Run_restricted_test('call py3eval("expression")', 'E145:')
+endfunc
+
+func Test_restricted_ruby()
+ if !has('ruby')
+ throw 'Skipped: Ruby is not supported'
+ endif
+ call Run_restricted_test('ruby print "Hello"', 'E981:')
+ call Run_restricted_test('rubydo print "Hello"', 'E981:')
+ call Run_restricted_test('rubyfile somefile', 'E981:')
+endfunc
+
+func Test_restricted_tcl()
+ if !has('tcl')
+ throw 'Skipped: Tcl is not supported'
+ endif
+ call Run_restricted_test('tcl puts "Hello"', 'E981:')
+ call Run_restricted_test('tcldo puts "Hello"', 'E981:')
+ call Run_restricted_test('tclfile somefile', 'E981:')
+endfunc
diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim
index 5d99027ca5..8036dea29f 100644
--- a/src/nvim/testdir/test_search.vim
+++ b/src/nvim/testdir/test_search.vim
@@ -698,3 +698,9 @@ func Test_search_display_pattern()
set norl
endif
endfunc
+
+func Test_search_special()
+ " this was causing illegal memory access and an endless loop
+ set t_PE=
+ exe "norm /\x80PS"
+endfunc
diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim
index ef4b227215..8b1927e4f0 100644
--- a/src/nvim/testdir/test_signs.vim
+++ b/src/nvim/testdir/test_signs.vim
@@ -4,6 +4,8 @@ if !has('signs')
finish
endif
+source screendump.vim
+
func Test_sign()
new
call setline(1, ['a', 'b', 'c', 'd'])
@@ -210,13 +212,16 @@ func Test_sign_completion()
call assert_equal('"sign define Sign linehl=SpellBad SpellCap ' .
\ 'SpellLocal SpellRare', @:)
- call writefile(['foo'], 'XsignOne')
- call writefile(['bar'], 'XsignTwo')
+ call feedkeys(":sign define Sign texthl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign define Sign texthl=SpellBad SpellCap ' .
+ \ 'SpellLocal SpellRare', @:)
+
+ call writefile(repeat(["Sun is shining"], 30), "XsignOne")
+ call writefile(repeat(["Sky is blue"], 30), "XsignTwo")
call feedkeys(":sign define Sign icon=Xsig\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign define Sign icon=XsignOne XsignTwo', @:)
- call delete('XsignOne')
- call delete('XsignTwo')
+ " Test for completion of arguments to ':sign undefine'
call feedkeys(":sign undefine \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign undefine Sign1 Sign2', @:)
@@ -227,17 +232,70 @@ func Test_sign_completion()
call feedkeys(":sign place 1 name=\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign place 1 name=Sign1 Sign2', @:)
+ edit XsignOne
+ sign place 1 name=Sign1 line=5
+ sign place 1 name=Sign1 group=g1 line=10
+ edit XsignTwo
+ sign place 1 name=Sign2 group=g2 line=15
+
+ " Test for completion of group= and file= arguments to ':sign place'
+ call feedkeys(":sign place 1 name=Sign1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign place 1 name=Sign1 file=XsignOne XsignTwo', @:)
+ call feedkeys(":sign place 1 name=Sign1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign place 1 name=Sign1 group=g1 g2', @:)
+
+ " Test for completion of arguments to 'sign place' without sign identifier
+ call feedkeys(":sign place \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign place buffer= file= group=', @:)
+ call feedkeys(":sign place file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign place file=XsignOne XsignTwo', @:)
+ call feedkeys(":sign place group=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign place group=g1 g2', @:)
+ call feedkeys(":sign place group=g1 file=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign place group=g1 file=XsignOne XsignTwo', @:)
+
+ " Test for completion of arguments to ':sign unplace'
call feedkeys(":sign unplace 1 \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign unplace 1 buffer= file= group=', @:)
-
+ call feedkeys(":sign unplace 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign unplace 1 file=XsignOne XsignTwo', @:)
+ call feedkeys(":sign unplace 1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign unplace 1 group=g1 g2', @:)
+ call feedkeys(":sign unplace 1 group=g2 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign unplace 1 group=g2 file=XsignOne XsignTwo', @:)
+
+ " Test for completion of arguments to ':sign list'
call feedkeys(":sign list \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign list Sign1 Sign2', @:)
+ " Test for completion of arguments to ':sign jump'
call feedkeys(":sign jump 1 \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign jump 1 buffer= file= group=', @:)
+ call feedkeys(":sign jump 1 file=Xsign\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign jump 1 file=XsignOne XsignTwo', @:)
+ call feedkeys(":sign jump 1 group=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign jump 1 group=g1 g2', @:)
+
+ " Error cases
+ call feedkeys(":sign here\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign here', @:)
+ call feedkeys(":sign define Sign here=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal("\"sign define Sign here=\<C-A>", @:)
+ call feedkeys(":sign place 1 here=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal("\"sign place 1 here=\<C-A>", @:)
+ call feedkeys(":sign jump 1 here=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal("\"sign jump 1 here=\<C-A>", @:)
+ call feedkeys(":sign here there\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal("\"sign here there\<C-A>", @:)
+ call feedkeys(":sign here there=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal("\"sign here there=\<C-A>", @:)
+ sign unplace * group=*
sign undefine Sign1
sign undefine Sign2
+ enew
+ call delete('XsignOne')
+ call delete('XsignTwo')
endfunc
func Test_sign_invalid_commands()
@@ -1127,6 +1185,319 @@ func Test_sign_priority()
\ 'priority' : 10}],
\ s[0].signs)
+ call sign_unplace('*')
+
+ " Three signs on different lines with changing priorities
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 11, 'priority' : 50})
+ call sign_place(2, '', 'sign2', 'Xsign',
+ \ {'lnum' : 12, 'priority' : 60})
+ call sign_place(3, '', 'sign3', 'Xsign',
+ \ {'lnum' : 13, 'priority' : 70})
+ call sign_place(2, '', 'sign2', 'Xsign',
+ \ {'lnum' : 12, 'priority' : 40})
+ call sign_place(3, '', 'sign3', 'Xsign',
+ \ {'lnum' : 13, 'priority' : 30})
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 11, 'priority' : 50})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, 'group' : '',
+ \ 'priority' : 50},
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 12, 'group' : '',
+ \ 'priority' : 40},
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 13, 'group' : '',
+ \ 'priority' : 30}],
+ \ s[0].signs)
+
+ call sign_unplace('*')
+
+ " Two signs on the same line with changing priorities
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ call sign_place(2, '', 'sign2', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 30})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 30},
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20}],
+ \ s[0].signs)
+ " Change the priority of the last sign to highest
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 40})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 40},
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 30}],
+ \ s[0].signs)
+ " Change the priority of the first sign to lowest
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 25})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 30},
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 25}],
+ \ s[0].signs)
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 45})
+ call sign_place(2, '', 'sign2', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 55})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 55},
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 45}],
+ \ s[0].signs)
+
+ call sign_unplace('*')
+
+ " Three signs on the same line with changing priorities
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 40})
+ call sign_place(2, '', 'sign2', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 30})
+ call sign_place(3, '', 'sign3', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 40},
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 30},
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20}],
+ \ s[0].signs)
+
+ " Change the priority of the middle sign to the highest
+ call sign_place(2, '', 'sign2', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 50})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 50},
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 40},
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20}],
+ \ s[0].signs)
+
+ " Change the priority of the middle sign to the lowest
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 15})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 50},
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 15}],
+ \ s[0].signs)
+
+ " Change the priority of the last sign to the highest
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 55})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 55},
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 50},
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20}],
+ \ s[0].signs)
+
+ " Change the priority of the first sign to the lowest
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 15})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 50},
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 15}],
+ \ s[0].signs)
+
+ call sign_unplace('*')
+
+ " Three signs on the same line with changing priorities along with other
+ " signs
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 2, 'priority' : 10})
+ call sign_place(2, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 30})
+ call sign_place(3, '', 'sign2', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ call sign_place(4, '', 'sign3', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 25})
+ call sign_place(5, '', 'sign2', 'Xsign',
+ \ {'lnum' : 6, 'priority' : 80})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 30},
+ \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 25},
+ \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+ \ 'priority' : 80}],
+ \ s[0].signs)
+
+ " Change the priority of the first sign to lowest
+ call sign_place(2, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 15})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 25},
+ \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 15},
+ \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+ \ 'priority' : 80}],
+ \ s[0].signs)
+
+ " Change the priority of the last sign to highest
+ call sign_place(2, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 30})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 30},
+ \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 25},
+ \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+ \ 'priority' : 80}],
+ \ s[0].signs)
+
+ " Change the priority of the middle sign to lowest
+ call sign_place(4, '', 'sign3', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 15})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 30},
+ \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 15},
+ \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+ \ 'priority' : 80}],
+ \ s[0].signs)
+
+ " Change the priority of the middle sign to highest
+ call sign_place(3, '', 'sign2', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 35})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 35},
+ \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 30},
+ \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 15},
+ \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+ \ 'priority' : 80}],
+ \ s[0].signs)
+
+ call sign_unplace('*')
+
+ " Multiple signs with the same priority on the same line
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ call sign_place(2, '', 'sign2', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ call sign_place(3, '', 'sign3', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20}],
+ \ s[0].signs)
+ " Place the last sign again with the same priority
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20}],
+ \ s[0].signs)
+ " Place the first sign again with the same priority
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20}],
+ \ s[0].signs)
+ " Place the middle sign again with the same priority
+ call sign_place(3, '', 'sign3', 'Xsign',
+ \ {'lnum' : 4, 'priority' : 20})
+ let s = sign_getplaced('Xsign', {'group' : '*'})
+ call assert_equal([
+ \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20},
+ \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+ \ 'priority' : 20}],
+ \ s[0].signs)
+
+ call sign_unplace('*')
+
+ " Place multiple signs with same id on a line with different priority
+ call sign_place(1, '', 'sign1', 'Xsign',
+ \ {'lnum' : 5, 'priority' : 20})
+ call sign_place(1, '', 'sign2', 'Xsign',
+ \ {'lnum' : 5, 'priority' : 10})
+ let s = sign_getplaced('Xsign', {'lnum' : 5})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign2', 'lnum' : 5, 'group' : '',
+ \ 'priority' : 10}],
+ \ s[0].signs)
+ call sign_place(1, '', 'sign2', 'Xsign',
+ \ {'lnum' : 5, 'priority' : 5})
+ let s = sign_getplaced('Xsign', {'lnum' : 5})
+ call assert_equal([
+ \ {'id' : 1, 'name' : 'sign2', 'lnum' : 5, 'group' : '',
+ \ 'priority' : 5}],
+ \ s[0].signs)
+
" Error case
call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign',
\ [])", 'E715:')
@@ -1339,3 +1710,35 @@ func Test_sign_jump_func()
sign undefine sign1
enew! | only!
endfunc
+
+" Test for correct cursor position after the sign column appears or disappears.
+func Test_sign_cursor_position()
+ if !CanRunVimInTerminal()
+ throw 'Skipped: cannot make screendumps'
+ endif
+
+ let lines =<< trim END
+ call setline(1, [repeat('x', 75), 'mmmm', 'yyyy'])
+ call cursor(2,1)
+ sign define s1 texthl=Search text==>
+ redraw
+ sign place 10 line=2 name=s1
+ END
+ call writefile(lines, 'XtestSigncolumn')
+ let buf = RunVimInTerminal('-S XtestSigncolumn', {'rows': 6})
+ call VerifyScreenDump(buf, 'Test_sign_cursor_1', {})
+
+ " Change the sign text
+ call term_sendkeys(buf, ":sign define s1 text=-)\<CR>")
+ call VerifyScreenDump(buf, 'Test_sign_cursor_2', {})
+
+ " update cursor position calculation
+ call term_sendkeys(buf, "lh")
+ call term_sendkeys(buf, ":sign unplace 10\<CR>")
+ call VerifyScreenDump(buf, 'Test_sign_cursor_3', {})
+
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('XtestSigncolumn')
+endfunc
diff --git a/src/nvim/testdir/test_spell.vim b/src/nvim/testdir/test_spell.vim
index 94789d6ea3..e5eaa01e92 100644
--- a/src/nvim/testdir/test_spell.vim
+++ b/src/nvim/testdir/test_spell.vim
@@ -130,20 +130,21 @@ endfunc
func Test_spellinfo()
throw 'skipped: Nvim does not support enc=latin1'
new
+ let runtime = substitute($VIMRUNTIME, '\\', '/', 'g')
set enc=latin1 spell spelllang=en
- call assert_match("^\nfile: .*/runtime/spell/en.latin1.spl\n$", execute('spellinfo'))
+ call assert_match("^\nfile: " .. runtime .. "/spell/en.latin1.spl\n$", execute('spellinfo'))
set enc=cp1250 spell spelllang=en
- call assert_match("^\nfile: .*/runtime/spell/en.ascii.spl\n$", execute('spellinfo'))
+ call assert_match("^\nfile: " .. runtime .. "/spell/en.ascii.spl\n$", execute('spellinfo'))
set enc=utf-8 spell spelllang=en
- call assert_match("^\nfile: .*/runtime/spell/en.utf-8.spl\n$", execute('spellinfo'))
+ call assert_match("^\nfile: " .. runtime .. "/spell/en.utf-8.spl\n$", execute('spellinfo'))
set enc=latin1 spell spelllang=en_us,en_nz
call assert_match("^\n" .
- \ "file: .*/runtime/spell/en.latin1.spl\n" .
- \ "file: .*/runtime/spell/en.latin1.spl\n$", execute('spellinfo'))
+ \ "file: " .. runtime .. "/spell/en.latin1.spl\n" .
+ \ "file: " .. runtime .. "/spell/en.latin1.spl\n$", execute('spellinfo'))
set spell spelllang=
call assert_fails('spellinfo', 'E756:')
diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim
index e94bd22cea..ff07d8eceb 100644
--- a/src/nvim/testdir/test_substitute.vim
+++ b/src/nvim/testdir/test_substitute.vim
@@ -613,6 +613,25 @@ func Test_sub_replace_10()
call assert_equal('1aaa', substitute('123', '1\zs\|[23]', 'a', 'g'))
endfunc
+func SubReplacer(text, submatches)
+ return a:text .. a:submatches[0] .. a:text
+endfunc
+func SubReplacer20(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, submatches)
+ return a:t3 .. a:submatches[0] .. a:t11
+endfunc
+
+func Test_substitute_partial()
+ call assert_equal('1foo2foo3', substitute('123', '2', function('SubReplacer', ['foo']), 'g'))
+
+ " 19 arguments plus one is just OK
+ let Replacer = function('SubReplacer20', repeat(['foo'], 19))
+ call assert_equal('1foo2foo3', substitute('123', '2', Replacer, 'g'))
+
+ " 20 arguments plus one is too many
+ let Replacer = function('SubReplacer20', repeat(['foo'], 20))
+ call assert_fails("call substitute('123', '2', Replacer, 'g')", 'E118')
+endfunc
+
func Test_sub_cmd_9()
new
let input = ['1 aaa', '2 aaa', '3 aaa']
diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim
index cb54ace695..d4ff42fd68 100644
--- a/src/nvim/testdir/test_taglist.vim
+++ b/src/nvim/testdir/test_taglist.vim
@@ -7,6 +7,7 @@ func Test_taglist()
\ "BFoo\tXbar\t1",
\ "BBar\tXbar\t2",
\ "Kindly\tXbar\t3;\"\tv\tfile:",
+ \ "Lambda\tXbar\t3;\"\tλ\tfile:",
\ "Command\tXbar\tcall cursor(3, 4)|;\"\td",
\ ], 'Xtags')
set tags=Xtags
@@ -17,12 +18,16 @@ func Test_taglist()
call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name}))
call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name}))
- let kind = taglist("Kindly")
- call assert_equal(1, len(kind))
- call assert_equal('v', kind[0]['kind'])
- call assert_equal('3', kind[0]['cmd'])
- call assert_equal(1, kind[0]['static'])
- call assert_equal('Xbar', kind[0]['filename'])
+ let kindly = taglist("Kindly")
+ call assert_equal(1, len(kindly))
+ call assert_equal('v', kindly[0]['kind'])
+ call assert_equal('3', kindly[0]['cmd'])
+ call assert_equal(1, kindly[0]['static'])
+ call assert_equal('Xbar', kindly[0]['filename'])
+
+ let lambda = taglist("Lambda")
+ call assert_equal(1, len(lambda))
+ call assert_equal('λ', lambda[0]['kind'])
let cmd = taglist("Command")
call assert_equal(1, len(cmd))
diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim
index 3043103270..40376a877e 100644
--- a/src/nvim/testdir/test_timers.vim
+++ b/src/nvim/testdir/test_timers.vim
@@ -339,4 +339,8 @@ func Test_nocatch_garbage_collect()
delfunc FeedChar
endfunc
+func Test_timer_invalid_callback()
+ call assert_fails('call timer_start(0, "0")', 'E921')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_user_func.vim b/src/nvim/testdir/test_user_func.vim
index e7a3701386..67701ee3ca 100644
--- a/src/nvim/testdir/test_user_func.vim
+++ b/src/nvim/testdir/test_user_func.vim
@@ -94,3 +94,7 @@ func Test_user_func()
unlet g:retval g:counter
enew!
endfunc
+
+func Test_failed_call_in_try()
+ try | call UnknownFunc() | catch | endtry
+endfunc
diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim
index b1f33f56dd..1b4ce4c4af 100644
--- a/src/nvim/testdir/test_utf8.vim
+++ b/src/nvim/testdir/test_utf8.vim
@@ -60,3 +60,46 @@ func Test_getvcol()
call assert_equal(2, virtcol("'["))
call assert_equal(2, virtcol("']"))
endfunc
+
+func Test_list2str_str2list_utf8()
+ " One Unicode codepoint
+ let s = "\u3042\u3044"
+ let l = [0x3042, 0x3044]
+ call assert_equal(l, str2list(s, 1))
+ call assert_equal(s, list2str(l, 1))
+ if &enc ==# 'utf-8'
+ call assert_equal(str2list(s), str2list(s, 1))
+ call assert_equal(list2str(l), list2str(l, 1))
+ endif
+
+ " With composing characters
+ let s = "\u304b\u3099\u3044"
+ let l = [0x304b, 0x3099, 0x3044]
+ call assert_equal(l, str2list(s, 1))
+ call assert_equal(s, list2str(l, 1))
+ if &enc ==# 'utf-8'
+ call assert_equal(str2list(s), str2list(s, 1))
+ call assert_equal(list2str(l), list2str(l, 1))
+ endif
+
+ " Null list is the same as an empty list
+ call assert_equal('', list2str([]))
+ " call assert_equal('', list2str(test_null_list()))
+endfunc
+
+func Test_list2str_str2list_latin1()
+ " When 'encoding' is not multi-byte can still get utf-8 string.
+ " But we need to create the utf-8 string while 'encoding' is utf-8.
+ let s = "\u3042\u3044"
+ let l = [0x3042, 0x3044]
+
+ let save_encoding = &encoding
+ " set encoding=latin1
+
+ let lres = str2list(s, 1)
+ let sres = list2str(l, 1)
+
+ let &encoding = save_encoding
+ call assert_equal(l, lres)
+ call assert_equal(s, sres)
+endfunc
diff --git a/src/nvim/testdir/test_writefile.vim b/src/nvim/testdir/test_writefile.vim
index 6066d61af4..56031662a3 100644
--- a/src/nvim/testdir/test_writefile.vim
+++ b/src/nvim/testdir/test_writefile.vim
@@ -1,4 +1,4 @@
-" Tests for the writefile() function.
+" Tests for the writefile() function and some :write commands.
func Test_writefile()
let f = tempname()
@@ -16,6 +16,11 @@ func Test_writefile()
call delete(f)
endfunc
+func Test_writefile_ignore_regexp_error()
+ write Xt[z-a]est.txt
+ call delete('Xt[z-a]est.txt')
+endfunc
+
func Test_writefile_fails_gently()
call assert_fails('call writefile(["test"], "Xfile", [])', 'E730:')
call assert_false(filereadable("Xfile"))
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 951cb50c3c..bbee7e4712 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -31,6 +31,10 @@ void tinput_init(TermInput *input, Loop *loop)
input->paste = 0;
input->in_fd = STDIN_FILENO;
input->waiting_for_bg_response = 0;
+ // The main thread is waiting for the UI thread to call CONTINUE, so it can
+ // safely access global variables.
+ input->ttimeout = (bool)p_ttimeout;
+ input->ttimeoutlen = p_ttm;
input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE);
uv_mutex_init(&input->key_buffer_mutex);
uv_cond_init(&input->key_buffer_cond);
@@ -285,21 +289,6 @@ static TermKeyResult tk_getkey(TermKey *tk, TermKeyKey *key, bool force)
static void tinput_timer_cb(TimeWatcher *watcher, void *data);
-static int get_key_code_timeout(void)
-{
- Integer ms = -1;
- // Check 'ttimeout' to determine if we should send ESC after 'ttimeoutlen'.
- Error err = ERROR_INIT;
- if (nvim_get_option(cstr_as_string("ttimeout"), &err).data.boolean) {
- Object rv = nvim_get_option(cstr_as_string("ttimeoutlen"), &err);
- if (!ERROR_SET(&err)) {
- ms = rv.data.integer;
- }
- }
- api_clear_error(&err);
- return (int)ms;
-}
-
static void tk_getkeys(TermInput *input, bool force)
{
TermKeyKey key;
@@ -324,12 +313,11 @@ static void tk_getkeys(TermInput *input, bool force)
// yet contain all the bytes required. `key` structure indicates what
// termkey_getkey_force() would return.
- int ms = get_key_code_timeout();
-
- if (ms > 0) {
+ if (input->ttimeout && input->ttimeoutlen >= 0) {
// Stop the current timer if already running
time_watcher_stop(&input->timer_handle);
- time_watcher_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0);
+ time_watcher_start(&input->timer_handle, tinput_timer_cb,
+ (uint64_t)input->ttimeoutlen, 0);
} else {
tk_getkeys(input, true);
}
diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h
index 77bd6fa132..b30546c815 100644
--- a/src/nvim/tui/input.h
+++ b/src/nvim/tui/input.h
@@ -12,7 +12,9 @@ typedef struct term_input {
// Phases: -1=all 0=disabled 1=first-chunk 2=continue 3=last-chunk
int8_t paste;
bool waiting;
+ bool ttimeout;
int8_t waiting_for_bg_response;
+ long ttimeoutlen;
TermKey *tk;
#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
TermKey_Terminfo_Getstr_Hook *tk_ti_hook_fn; ///< libtermkey terminfo hook
diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c
index 03173afe07..ff2a357752 100644
--- a/src/nvim/tui/terminfo.c
+++ b/src/nvim/tui/terminfo.c
@@ -31,7 +31,10 @@ bool terminfo_is_term_family(const char *term, const char *family)
return tlen >= flen
&& 0 == memcmp(term, family, flen)
// Per commentary in terminfo, minus is the only valid suffix separator.
- && ('\0' == term[flen] || '-' == term[flen]);
+ // The screen terminfo may have a terminal name like screen.xterm. By making
+ // the dot(.) a valid separator, such terminal names will also be the
+ // terminal family of the screen.
+ && ('\0' == term[flen] || '-' == term[flen] || '.' == term[flen]);
}
bool terminfo_is_bsd_console(const char *term)
@@ -187,7 +190,7 @@ void terminfo_info_msg(const unibi_term *const ut)
msg_printf_attr(0, " %-25s %-10s = ", unibi_name_str(i),
unibi_short_name_str(i));
// Most of these strings will contain escape sequences.
- msg_outtrans_special((char_u *)s, false);
+ msg_outtrans_special((char_u *)s, false, 0);
msg_putchar('\n');
}
}
@@ -214,7 +217,7 @@ void terminfo_info_msg(const unibi_term *const ut)
msg_puts("Extended string capabilities:\n");
for (size_t i = 0; i < unibi_count_ext_str(ut); i++) {
msg_printf_attr(0, " %-25s = ", unibi_get_ext_str_name(ut, i));
- msg_outtrans_special((char_u *)unibi_get_ext_str(ut, i), false);
+ msg_outtrans_special((char_u *)unibi_get_ext_str(ut, i), false, 0);
msg_putchar('\n');
}
}
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index e9276db484..228545a844 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -31,6 +31,7 @@
#include "nvim/event/signal.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
+#include "nvim/os/signal.h"
#include "nvim/os/tty.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
@@ -48,10 +49,15 @@
#define OUTBUF_SIZE 0xffff
#define TOO_MANY_EVENTS 1000000
-#define STARTS_WITH(str, prefix) (strlen(str) >= (sizeof(prefix) - 1) \
- && 0 == memcmp((str), (prefix), sizeof(prefix) - 1))
-#define TMUX_WRAP(is_tmux, seq) ((is_tmux) \
- ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
+#define STARTS_WITH(str, prefix) \
+ (strlen(str) >= (sizeof(prefix) - 1) && 0 == memcmp((str), (prefix), \
+ sizeof(prefix) - 1))
+#define SCREEN_WRAP(is_screen, seq) ((is_screen) \
+ ? DCS_STR seq STERM_STR : seq)
+#define SCREEN_TMUX_WRAP(is_screen, is_tmux, seq) \
+ ((is_screen) \
+ ? DCS_STR seq STERM_STR : (is_tmux) \
+ ? DCS_STR "tmux;\x1b" seq STERM_STR : seq)
#define LINUXSET0C "\x1b[?0c"
#define LINUXSET1C "\x1b[?1c"
@@ -1099,6 +1105,7 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow,
set_scroll_region(ui, top, bot, left, right);
}
cursor_goto(ui, top, left);
+ update_attrs(ui, 0);
if (rows > 0) {
if (rows == 1) {
@@ -1238,7 +1245,9 @@ static void suspend_event(void **argv)
tui_terminal_stop(ui);
data->cont_received = false;
stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
+ signal_stop();
kill(0, SIGTSTP);
+ signal_start();
while (!data->cont_received) {
// poll the event loop until SIGCONT is received
loop_poll_events(data->loop, -1);
@@ -1291,6 +1300,12 @@ static void tui_option_set(UI *ui, String name, Object value)
data->print_attr_id = -1;
invalidate(ui, 0, data->grid.height, 0, data->grid.width);
}
+ if (strequal(name.data, "ttimeout")) {
+ data->input.ttimeout = value.data.boolean;
+ }
+ if (strequal(name.data, "ttimeoutlen")) {
+ data->input.ttimeoutlen = (long)value.data.integer;
+ }
}
static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol,
@@ -1528,7 +1543,10 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
bool rxvt = terminfo_is_term_family(term, "rxvt");
bool teraterm = terminfo_is_term_family(term, "teraterm");
bool putty = terminfo_is_term_family(term, "putty");
- bool screen = terminfo_is_term_family(term, "screen");
+ bool screen = terminfo_is_term_family(term, "screen") && !os_getenv("TMUX");
+ bool screen_host_linuxvt =
+ terminfo_is_term_family(screen && term[6] == '.'
+ ? term + 7 : NULL, "linux");
bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX");
bool st = terminfo_is_term_family(term, "st");
bool gnome = terminfo_is_term_family(term, "gnome")
@@ -1630,6 +1648,11 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
// per the screen manual; 2017-04 terminfo.src lacks these.
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
+ // Fix an issue where smglr is inherited by TERM=screen.xterm.
+ if (unibi_get_str(ut, unibi_set_lr_margin)) {
+ ILOG("Disabling smglr with TERM=screen.xterm for screen.");
+ unibi_set_str(ut, unibi_set_lr_margin, NULL);
+ }
} else if (tmux) {
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
@@ -1682,8 +1705,9 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
#define XTERM_SETAB_16 \
"\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e39%;m"
- data->unibi_ext.get_bg = (int)unibi_add_ext_str(ut, "ext.get_bg",
- "\x1b]11;?\x07");
+ data->unibi_ext.get_bg =
+ (int)unibi_add_ext_str(ut, "ext.get_bg",
+ SCREEN_TMUX_WRAP(screen, tmux, "\x1b]11;?\x07"));
// Terminals with 256-colour SGR support despite what terminfo says.
if (unibi_get_num(ut, unibi_max_colors) < 256) {
@@ -1718,6 +1742,32 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
data->unibi_ext.set_cursor_style = unibi_find_ext_str(ut, "Ss");
}
+ // GNU Screen does not have Ss/Se. When terminfo has Ss/Se, it is wrapped with
+ // DCS because it is inherited from the host terminal.
+ if (screen) {
+ size_t len;
+ size_t dcs_st_len = strlen(DCS_STR) + strlen(STERM_STR);
+ if (-1 != data->unibi_ext.set_cursor_style) {
+ const char *orig_ss =
+ unibi_get_ext_str(data->ut, (size_t)data->unibi_ext.reset_cursor_style);
+ len = STRLEN(orig_ss) + dcs_st_len + 1;
+ char *ss = xmalloc(len);
+ snprintf(ss, len, "%s%s%s", DCS_STR, orig_ss, STERM_STR);
+ unibi_set_ext_str(data->ut, (size_t)data->unibi_ext.set_cursor_style, ss);
+ xfree(ss);
+ }
+ if (-1 != data->unibi_ext.reset_cursor_style) {
+ const char *orig_se =
+ unibi_get_ext_str(data->ut, (size_t)data->unibi_ext.reset_cursor_style);
+ len = strlen(orig_se) + dcs_st_len + 1;
+ char *se = xmalloc(len);
+ snprintf(se, len, "%s%s%s", DCS_STR, orig_se, STERM_STR);
+ unibi_set_ext_str(data->ut,
+ (size_t)data->unibi_ext.reset_cursor_style, se);
+ xfree(se);
+ }
+ }
+
// Dickey ncurses terminfo includes Ss/Se capabilities since 2011-07-14. So
// adding them to terminal types, that have such control sequences but lack
// the correct terminfo entries, is a fixup, not an augmentation.
@@ -1733,7 +1783,12 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
|| (konsolev >= 180770) // #9364
|| tmux // per tmux manual page
// https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html
- || screen
+ || (screen
+ && (!screen_host_linuxvt
+ || (screen_host_linuxvt
+ && (xterm_version || (vte_version > 0) || colorterm))))
+ // Since GNU Screen does not support DECSCUSR, DECSCUSR is wrapped
+ // in DCS and output to the host terminal.
|| st // #7641
|| rxvt // per command.C
// per analysis of VT100Terminal.m
@@ -1746,34 +1801,43 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
|| (linuxvt
&& (xterm_version || (vte_version > 0) || colorterm)))) {
data->unibi_ext.set_cursor_style =
- (int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q");
+ (int)unibi_add_ext_str(ut, "Ss", SCREEN_WRAP(screen, "\x1b[%p1%d q"));
if (-1 == data->unibi_ext.reset_cursor_style) {
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
"");
}
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
- "\x1b[ q");
- } else if (linuxvt) {
+ SCREEN_WRAP(screen, "\x1b[ q"));
+ } else if (linuxvt || screen_host_linuxvt) {
// Linux uses an idiosyncratic escape code to set the cursor shape and
// does not support DECSCUSR.
// See http://linuxgazette.net/137/anonymous.html for more info
- data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
- "\x1b[?"
- "%?"
- // The parameter passed to Ss is the DECSCUSR parameter, so the
- // terminal capability has to translate into the Linux idiosyncratic
- // parameter.
- //
- // linuxvt only supports block and underline. It is also only
- // possible to have a steady block (no steady underline)
- "%p1%{2}%<" "%t%{8}" // blink block
- "%e%p1%{2}%=" "%t%{112}" // steady block
- "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block)
- "%e%p1%{4}%=" "%t%{4}" // steady underline
- "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
- "%e%p1%{6}%=" "%t%{2}" // steady bar
- "%e%{0}" // anything else
- "%;" "%dc");
+ //
+ // Since gnu Screen does not have Ss/Se, if the host terminal is a linux
+ // console that does not support xterm extensions, it will wraps the
+ // linux-specific sequence in DCS and outputs it.
+ data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(
+ ut, "Ss",
+ SCREEN_WRAP(screen,
+ "\x1b[?"
+ "%?"
+ // The parameter passed to Ss is the DECSCUSR parameter,
+ // so the
+ // terminal capability has to translate into the Linux
+ // idiosyncratic parameter.
+ //
+ // linuxvt only supports block and underline. It is also
+ // only possible to have a steady block (no steady
+ // underline)
+ "%p1%{2}%<" "%t%{8}" // blink block
+ "%e%p1%{2}%=" "%t%{112}" // steady block
+ "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half
+ // block)
+ "%e%p1%{4}%=" "%t%{4}" // steady underline
+ "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
+ "%e%p1%{6}%=" "%t%{2}" // steady bar
+ "%e%{0}" // anything else
+ "%;" "%dc"));
if (-1 == data->unibi_ext.reset_cursor_style) {
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
"");
@@ -1783,21 +1847,25 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,
} else if (konsolev > 0 && konsolev < 180770) {
// Konsole before version 18.07.70: set up a nonce profile. This has
// side-effects on temporary font resizing. #6798
- data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
- TMUX_WRAP(tmux, "\x1b]50;CursorShape=%?"
- "%p1%{3}%<" "%t%{0}" // block
- "%e%p1%{5}%<" "%t%{2}" // underline
- "%e%{1}" // everything else is bar
- "%;%d;BlinkingCursorEnabled=%?"
- "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special,
- "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag.
- "%;%d\x07"));
+ data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(
+ ut, "Ss",
+ SCREEN_TMUX_WRAP(screen, tmux,
+ "\x1b]50;CursorShape=%?"
+ "%p1%{3}%<" "%t%{0}" // block
+ "%e%p1%{5}%<" "%t%{2}" // underline
+ "%e%{1}" // everything else is bar
+ "%;%d;BlinkingCursorEnabled=%?"
+ "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude
+ // zero as special,
+ "%e%p1%{1}%&" // in all other c2ses we can treat bit
+ // #0 as a flag.
+ "%;%d\x07"));
if (-1 == data->unibi_ext.reset_cursor_style) {
data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
"");
}
unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
- "\x1b]50;\x07");
+ SCREEN_TMUX_WRAP(screen, tmux, "\x1b]50;\x07"));
}
}
}
@@ -1826,6 +1894,8 @@ static void augment_terminfo(TUIData *data, const char *term,
bool alacritty = terminfo_is_term_family(term, "alacritty");
// None of the following work over SSH; see :help TERM .
bool iterm_pretending_xterm = xterm && iterm_env;
+ bool screen_host_rxvt =
+ terminfo_is_term_family(screen && term[6] == '.' ? term + 7 : NULL, "rxvt");
const char *xterm_version = os_getenv("XTERM_VERSION");
bool true_xterm = xterm && !!xterm_version && !bsdvt;
@@ -1895,8 +1965,8 @@ static void augment_terminfo(TUIData *data, const char *term,
// all panes, which is not particularly desirable. A better approach
// would use a tmux control sequence and an extra if(screen) test.
data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
- ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\"));
- } else if ((xterm || rxvt || alacritty)
+ ut, NULL, SCREEN_TMUX_WRAP(screen, tmux, "\033]Pl%p1%06x\033\\"));
+ } else if ((xterm || rxvt || tmux || alacritty)
&& (vte_version == 0 || vte_version >= 3900)) {
// Supported in urxvt, newer VTE.
data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
@@ -1915,21 +1985,27 @@ static void augment_terminfo(TUIData *data, const char *term,
/// Terminals usually ignore unrecognized private modes, and there is no
/// known ambiguity with these. So we just set them unconditionally.
+ /// If the DECSET is not supported by GNU Screen, it is wrapped with DCS and
+ /// sent to the host terminal.
data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(
ut, "ext.enable_lr_margin", "\x1b[?69h");
data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(
ut, "ext.disable_lr_margin", "\x1b[?69l");
data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(
- ut, "ext.enable_bpaste", "\x1b[?2004h");
+ ut, "ext.enable_bpaste", SCREEN_WRAP(screen, "\x1b[?2004h"));
data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(
- ut, "ext.disable_bpaste", "\x1b[?2004l");
+ ut, "ext.disable_bpaste", SCREEN_WRAP(screen, "\x1b[?2004l"));
// For urxvt send BOTH xterm and old urxvt sequences. #8695
data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(
ut, "ext.enable_focus",
- rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h");
+ (rxvt || screen_host_rxvt)
+ ? SCREEN_WRAP(screen, "\x1b[?1004h\x1b]777;focus;on\x7")
+ : SCREEN_WRAP(screen, "\x1b[?1004h"));
data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(
ut, "ext.disable_focus",
- rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l");
+ (rxvt || screen_host_rxvt)
+ ? SCREEN_WRAP(screen, "\x1b[?1004l\x1b]777;focus;off\x7")
+ : SCREEN_WRAP(screen, "\x1b[?1004l"));
data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(
ut, "ext.enable_mouse", "\x1b[?1002h\x1b[?1006h");
data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(
@@ -1961,7 +2037,23 @@ static void flush_buf(UI *ui)
uv_buf_t *bufp = &bufs[0];
TUIData *data = ui->data;
- if (data->bufpos <= 0 && data->busy == data->is_invisible) {
+ // The content of the output for each condition is shown in the following
+ // table. Therefore, if data->bufpos == 0 and N/A or invis + norm, there is
+ // no need to output it.
+ //
+ // | is_invisible | !is_invisible
+ // ------+-----------------+--------------+---------------
+ // busy | want_invisible | N/A | invis
+ // | !want_invisible | N/A | invis
+ // ------+-----------------+--------------+---------------
+ // !busy | want_invisible | N/A | invis
+ // | !want_invisible | norm | invis + norm
+ // ------+-----------------+--------------+---------------
+ //
+ if (data->bufpos <= 0
+ && ((data->is_invisible && data->busy)
+ || (data->is_invisible && !data->busy && data->want_invisible)
+ || (!data->is_invisible && !data->busy && !data->want_invisible))) {
return;
}
@@ -1988,8 +2080,8 @@ static void flush_buf(UI *ui)
bufp->base = data->norm;
bufp->len = UV_BUF_LEN(data->normlen);
bufp++;
+ data->is_invisible = false;
}
- data->is_invisible = false;
}
uv_write(&req, STRUCT_CAST(uv_stream_t, &data->output_handle),
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 0f841760d6..3a5aa95ad3 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -424,7 +424,7 @@ int ui_current_col(void)
void ui_flush(void)
{
cmdline_ui_flush();
- win_ui_flush_positions();
+ win_ui_flush();
msg_ext_ui_flush();
msg_scroll_flush();
diff --git a/src/nvim/version.c b/src/nvim/version.c
index c67fd9175f..15a9713c7c 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -129,13 +129,13 @@ static const int included_patches[] = {
1792,
1791,
1790,
- // 1789,
+ 1789,
1788,
1787,
1786,
1785,
1784,
- // 1783,
+ 1783,
1782,
1781,
1780,
@@ -258,7 +258,7 @@ static const int included_patches[] = {
1663,
1662,
1661,
- // 1660,
+ 1660,
1659,
1658,
1657,
@@ -331,7 +331,7 @@ static const int included_patches[] = {
1590,
// 1589,
// 1588,
- // 1587,
+ 1587,
1586,
1585,
1584,
@@ -398,7 +398,7 @@ static const int included_patches[] = {
1523,
1522,
1521,
- // 1520,
+ 1520,
1519,
1518,
1517,
@@ -496,7 +496,7 @@ static const int included_patches[] = {
1425,
1424,
1423,
- // 1422,
+ 1422,
1421,
1420,
1419,
@@ -530,7 +530,7 @@ static const int included_patches[] = {
1391,
1390,
1389,
- // 1388,
+ 1388,
1387,
1386,
1385,
@@ -547,7 +547,7 @@ static const int included_patches[] = {
1374,
1373,
1372,
- // 1371,
+ 1371,
1370,
1369,
1368,
@@ -560,11 +560,11 @@ static const int included_patches[] = {
1361,
1360,
1359,
- // 1358,
+ 1358,
1357,
1356,
- // 1355,
- // 1354,
+ 1355,
+ 1354,
1353,
1352,
1351,
@@ -573,7 +573,7 @@ static const int included_patches[] = {
1348,
1347,
1346,
- // 1345,
+ 1345,
1344,
1343,
1342,
@@ -631,7 +631,7 @@ static const int included_patches[] = {
1290,
1289,
1288,
- // 1287,
+ 1287,
1286,
1285,
1284,
@@ -789,7 +789,7 @@ static const int included_patches[] = {
1132,
1131,
1130,
- // 1129,
+ 1129,
1128,
1127,
1126,
diff --git a/src/nvim/viml/parser/expressions.h b/src/nvim/viml/parser/expressions.h
index 23e172da75..838a742271 100644
--- a/src/nvim/viml/parser/expressions.h
+++ b/src/nvim/viml/parser/expressions.h
@@ -326,7 +326,7 @@ struct expr_ast_node {
} data;
};
-enum {
+enum ExprParserFlags {
/// Allow multiple expressions in a row: e.g. for :echo
///
/// Parser will still parse only one of them though.
@@ -345,7 +345,7 @@ enum {
// viml_expressions_parser.c, nvim_parse_expression() flags parsing
// alongside with its documentation and flag sets in check_parsing()
// function in expressions parser functional and unit tests.
-} ExprParserFlags;
+};
/// AST error definition
typedef struct {
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 8181883426..a89715ff79 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -618,7 +618,6 @@ void win_set_minimal_style(win_T *wp)
wp->w_p_cuc = false;
wp->w_p_spell = false;
wp->w_p_list = false;
- wp->w_p_fdc = 0;
// Hide EOB region: use " " fillchar and cleared highlighting
if (wp->w_p_fcs_chars.eob != ' ') {
@@ -642,6 +641,12 @@ void win_set_minimal_style(win_T *wp)
wp->w_p_scl = (char_u *)xstrdup("auto");
}
+ // foldcolumn: use 'auto'
+ if (wp->w_p_fdc[0] != '0') {
+ xfree(wp->w_p_fdc);
+ wp->w_p_fdc = (char_u *)xstrdup("0");
+ }
+
// colorcolumn: cleared
if (wp->w_p_cc != NULL && *wp->w_p_cc != NUL) {
xfree(wp->w_p_cc);
@@ -689,6 +694,21 @@ void win_check_anchored_floats(win_T *win)
}
}
+/// Return the number of fold columns to display
+int win_fdccol_count(win_T *wp)
+{
+ const char *fdc = (const char *)wp->w_p_fdc;
+
+ // auto:<NUM>
+ if (strncmp(fdc, "auto:", 5) == 0) {
+ int needed_fdccols = getDeepestNesting(wp);
+ return MIN(fdc[5] - '0', needed_fdccols);
+ } else {
+ return fdc[0] - '0';
+ }
+}
+
+
static void ui_ext_win_position(win_T *wp)
{
if (!wp->w_floating) {
@@ -753,6 +773,21 @@ static void ui_ext_win_position(win_T *wp)
}
+void ui_ext_win_viewport(win_T *wp)
+{
+ if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid) {
+ int botline = wp->w_botline;
+ if (botline == wp->w_buffer->b_ml.ml_line_count+1
+ && wp->w_empty_rows == 0) {
+ // TODO(bfredl): The might be more cases to consider, like how does this
+ // interact with incomplete final line? Diff filler lines?
+ botline = wp->w_buffer->b_ml.ml_line_count;
+ }
+ ui_call_win_viewport(wp->w_grid.handle, wp->handle, wp->w_topline-1,
+ botline, wp->w_cursor.lnum-1, wp->w_cursor.col);
+ wp->w_viewport_invalid = false;
+ }
+}
static bool parse_float_anchor(String anchor, FloatAnchor *out)
{
@@ -4668,6 +4703,11 @@ static win_T *win_alloc(win_T *after, int hidden)
new_wp->w_scbind_pos = 1;
new_wp->w_floating = 0;
new_wp->w_float_config = FLOAT_CONFIG_INIT;
+ new_wp->w_viewport_invalid = true;
+
+ // use global option for global-local options
+ new_wp->w_p_so = -1;
+ new_wp->w_p_siso = -1;
/* We won't calculate w_fraction until resizing the window */
new_wp->w_fraction = 0;
@@ -5779,9 +5819,10 @@ void scroll_to_fraction(win_T *wp, int prev_height)
}
if (wp == curwin) {
- if (p_so)
+ if (get_scrolloff_value()) {
update_topline();
- curs_columns(FALSE); /* validate w_wrow */
+ }
+ curs_columns(false); // validate w_wrow
}
if (prev_height > 0) {
wp->w_prev_fraction_row = wp->w_wrow;
@@ -6503,10 +6544,12 @@ void restore_buffer(bufref_T *save_curbuf)
/// @param[in] id a desired ID 'id' can be specified
/// (greater than or equal to 1). -1 must be specified if no
/// particular ID is desired
+/// @param[in] conceal_char pointer to conceal replacement char
/// @return ID of added match, -1 on failure.
int match_add(win_T *wp, const char *const grp, const char *const pat,
int prio, int id, list_T *pos_list,
const char *const conceal_char)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
{
matchitem_T *cur;
matchitem_T *prev;
@@ -6543,7 +6586,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
return -1;
}
- /* Find available match ID. */
+ // Find available match ID.
while (id == -1) {
cur = wp->w_match_head;
while (cur != NULL && cur->id != wp->w_next_match_id)
@@ -6553,7 +6596,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
wp->w_next_match_id++;
}
- /* Build new match. */
+ // Build new match.
m = xcalloc(1, sizeof(matchitem_T));
m->id = id;
m->priority = prio;
@@ -6661,9 +6704,9 @@ int match_add(win_T *wp, const char *const grp, const char *const pat,
rtype = VALID;
}
}
-
- /* Insert new match. The match list is in ascending order with regard to
- * the match priorities. */
+
+ // Insert new match. The match list is in ascending order with regard to
+ // the match priorities.
cur = wp->w_match_head;
prev = cur;
while (cur != NULL && prio >= cur->priority) {
@@ -6967,7 +7010,7 @@ void get_framelayout(const frame_T *fr, list_T *l, bool outer)
}
}
-void win_ui_flush_positions(void)
+void win_ui_flush(void)
{
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_pos_changed && wp->w_grid.chars != NULL) {
@@ -6978,6 +7021,9 @@ void win_ui_flush_positions(void)
}
wp->w_pos_changed = false;
}
+ if (tp == curtab) {
+ ui_ext_win_viewport(wp);
+ }
}
}
diff --git a/src/nvim/xdiff/xdiff.h b/src/nvim/xdiff/xdiff.h
index bc26fb64fd..8ff4a05bfb 100644
--- a/src/nvim/xdiff/xdiff.h
+++ b/src/nvim/xdiff/xdiff.h
@@ -25,9 +25,9 @@
#ifdef __cplusplus
extern "C" {
-#endif /* #ifdef __cplusplus */
+#endif // #ifdef __cplusplus
-/* xpparm_t.flags */
+// xpparm_t.flags
#define XDF_NEED_MINIMAL (1 << 0)
#define XDF_IGNORE_WHITESPACE (1 << 1)
@@ -48,22 +48,22 @@ extern "C" {
#define XDF_INDENT_HEURISTIC (1 << 23)
-/* xdemitconf_t.flags */
+// xdemitconf_t.flags
#define XDL_EMIT_FUNCNAMES (1 << 0)
#define XDL_EMIT_FUNCCONTEXT (1 << 2)
-/* merge simplification levels */
+// merge simplification levels
#define XDL_MERGE_MINIMAL 0
#define XDL_MERGE_EAGER 1
#define XDL_MERGE_ZEALOUS 2
#define XDL_MERGE_ZEALOUS_ALNUM 3
-/* merge favor modes */
+// merge favor modes
#define XDL_MERGE_FAVOR_OURS 1
#define XDL_MERGE_FAVOR_THEIRS 2
#define XDL_MERGE_FAVOR_UNION 3
-/* merge output styles */
+// merge output styles
#define XDL_MERGE_DIFF3 1
typedef struct s_mmfile {
@@ -79,7 +79,7 @@ typedef struct s_mmbuffer {
typedef struct s_xpparam {
unsigned long flags;
- /* See Documentation/diff-options.txt. */
+ // See Documentation/diff-options.txt.
char **anchors;
size_t anchors_nr;
} xpparam_t;
@@ -126,9 +126,9 @@ typedef struct s_xmparam {
int level;
int favor;
int style;
- const char *ancestor; /* label for orig */
- const char *file1; /* label for mf1 */
- const char *file2; /* label for mf2 */
+ const char *ancestor; // label for orig
+ const char *file1; // label for mf1
+ const char *file2; // label for mf2
} xmparam_t;
#define DEFAULT_CONFLICT_MARKER_SIZE 7
@@ -138,6 +138,6 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
#ifdef __cplusplus
}
-#endif /* #ifdef __cplusplus */
+#endif // #ifdef __cplusplus
-#endif /* #if !defined(XDIFF_H) */
+#endif // #if !defined(XDIFF_H)
diff --git a/src/nvim/xdiff/xdiffi.c b/src/nvim/xdiff/xdiffi.c
index 96d5277027..3806903986 100644
--- a/src/nvim/xdiff/xdiffi.c
+++ b/src/nvim/xdiff/xdiffi.c
@@ -418,24 +418,24 @@ static int xget_indent(xrecord_t *rec)
ret += 1;
else if (c == '\t')
ret += 8 - ret % 8;
- /* ignore other whitespace characters */
+ // ignore other whitespace characters
if (ret >= MAX_INDENT)
return MAX_INDENT;
}
- /* The line contains only whitespace. */
+ // The line contains only whitespace.
return -1;
}
/*
- * If more than this number of consecutive blank rows are found, just return this
- * value. This avoids requiring O(N^2) work for pathological cases, and also
- * ensures that the output of score_split fits in an int.
+ * If more than this number of consecutive blank rows are found, just return
+ * this value. This avoids requiring O(N^2) work for pathological cases, and
+ * also ensures that the output of score_split fits in an int.
*/
#define MAX_BLANKS 20
-/* Characteristics measured about a hypothetical split position. */
+// Characteristics measured about a hypothetical split position.
struct split_measurement {
/*
* Is the split at the end of the file (aside from any blank lines)?
@@ -472,10 +472,10 @@ struct split_measurement {
};
struct split_score {
- /* The effective indent of this split (smaller is preferred). */
+ // The effective indent of this split (smaller is preferred).
int effective_indent;
- /* Penalty for this split (smaller is preferred). */
+ // Penalty for this split (smaller is preferred).
int penalty;
};
@@ -534,16 +534,16 @@ static void measure_split(const xdfile_t *xdf, long split,
* integer math.
*/
-/* Penalty if there are no non-blank lines before the split */
+// Penalty if there are no non-blank lines before the split
#define START_OF_FILE_PENALTY 1
-/* Penalty if there are no non-blank lines after the split */
+// Penalty if there are no non-blank lines after the split
#define END_OF_FILE_PENALTY 21
-/* Multiplier for the number of blank lines around the split */
+// Multiplier for the number of blank lines around the split
#define TOTAL_BLANK_WEIGHT (-30)
-/* Multiplier for the number of blank lines after the split */
+// Multiplier for the number of blank lines after the split
#define POST_BLANK_WEIGHT 6
/*
@@ -610,7 +610,7 @@ static void score_add_split(const struct split_measurement *m, struct split_scor
post_blank = (m->indent == -1) ? 1 + m->post_blank : 0;
total_blank = m->pre_blank + post_blank;
- /* Penalties based on nearby blank lines: */
+ // Penalties based on nearby blank lines:
s->penalty += TOTAL_BLANK_WEIGHT * total_blank;
s->penalty += POST_BLANK_WEIGHT * post_blank;
@@ -621,13 +621,13 @@ static void score_add_split(const struct split_measurement *m, struct split_scor
any_blanks = (total_blank != 0);
- /* Note that the effective indent is -1 at the end of the file: */
+ // Note that the effective indent is -1 at the end of the file:
s->effective_indent += indent;
if (indent == -1) {
- /* No additional adjustments needed. */
+ // No additional adjustments needed.
} else if (m->pre_indent == -1) {
- /* No additional adjustments needed. */
+ // No additional adjustments needed.
} else if (indent > m->pre_indent) {
/*
* The line is indented more than its predecessor.
@@ -669,7 +669,7 @@ static void score_add_split(const struct split_measurement *m, struct split_scor
static int score_cmp(struct split_score *s1, struct split_score *s2)
{
- /* -1 if s1.effective_indent < s2->effective_indent, etc. */
+ // -1 if s1.effective_indent < s2->effective_indent, etc.
int cmp_indents = ((s1->effective_indent > s2->effective_indent) -
(s1->effective_indent < s2->effective_indent));
@@ -809,7 +809,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
group_init(xdfo, &go);
while (1) {
- /* If the group is empty in the to-be-compacted file, skip it: */
+ // If the group is empty in the to-be-compacted file, skip it:
if (g.end == g.start)
goto next;
@@ -828,7 +828,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
*/
end_matching_other = -1;
- /* Shift the group backward as much as possible: */
+ // Shift the group backward as much as possible:
while (!group_slide_up(xdf, &g, flags))
if (group_previous(xdfo, &go))
xdl_bug("group sync broken sliding up");
@@ -842,7 +842,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
if (go.end > go.start)
end_matching_other = g.end;
- /* Now shift the group forward as far as possible: */
+ // Now shift the group forward as far as possible:
while (1) {
if (group_slide_down(xdf, &g, flags))
break;
@@ -863,7 +863,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
*/
if (g.end == earliest_end) {
- /* no shifting was possible */
+ // no shifting was possible
} else if (end_matching_other != -1) {
/*
* Move the possibly merged group of changes back to line
@@ -921,7 +921,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
}
next:
- /* Move past the just-processed group: */
+ // Move past the just-processed group:
if (group_next(xdf, &g))
break;
if (group_next(xdfo, &go))
diff --git a/src/nvim/xdiff/xdiffi.h b/src/nvim/xdiff/xdiffi.h
index 8f1c7c8b04..467a1e85cd 100644
--- a/src/nvim/xdiff/xdiffi.h
+++ b/src/nvim/xdiff/xdiffi.h
@@ -61,4 +61,4 @@ int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdfenv_t *env);
-#endif /* #if !defined(XDIFFI_H) */
+#endif // #if !defined(XDIFFI_H)
diff --git a/src/nvim/xdiff/xemit.c b/src/nvim/xdiff/xemit.c
index d8a6f1ed38..f1a45139cc 100644
--- a/src/nvim/xdiff/xemit.c
+++ b/src/nvim/xdiff/xemit.c
@@ -54,9 +54,9 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
xdchange_t *xch, *xchp, *lxch;
long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;
long max_ignorable = xecfg->ctxlen;
- unsigned long ignored = 0; /* number of ignored blank lines */
+ unsigned long ignored = 0; // number of ignored blank lines
- /* remove ignorable changes that are too far before other changes */
+ // remove ignorable changes that are too far before other changes
for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
xch = xchp->next;
@@ -99,9 +99,9 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
static long def_ff(const char *rec, long len, char *buf, long sz, void *priv UNUSED)
{
if (len > 0 &&
- (isalpha((unsigned char)*rec) || /* identifier? */
- *rec == '_' || /* also identifier? */
- *rec == '$')) { /* identifiers from VMS and other esoterico */
+ (isalpha((unsigned char)*rec) || // identifier?
+ *rec == '_' || // also identifier?
+ *rec == '$')) { // identifiers from VMS and other esoterico
if (len > sz)
len = sz;
while (0 < len && isspace((unsigned char)rec[len - 1]))
@@ -197,7 +197,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
long fs1, i1 = xch->i1;
- /* Appended chunk? */
+ // Appended chunk?
if (i1 >= xe->xdf1.nrec) {
long i2 = xch->i2;
diff --git a/src/nvim/xdiff/xemit.h b/src/nvim/xdiff/xemit.h
index 1b9887e670..3ce7e3dd50 100644
--- a/src/nvim/xdiff/xemit.h
+++ b/src/nvim/xdiff/xemit.h
@@ -33,4 +33,4 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
-#endif /* #if !defined(XEMIT_H) */
+#endif // #if !defined(XEMIT_H)
diff --git a/src/nvim/xdiff/xhistogram.c b/src/nvim/xdiff/xhistogram.c
index 3fb8974dd4..28cf8258e5 100644
--- a/src/nvim/xdiff/xhistogram.c
+++ b/src/nvim/xdiff/xhistogram.c
@@ -55,8 +55,8 @@ struct histindex {
struct record {
unsigned int ptr, cnt;
struct record *next;
- } **records, /* an occurrence */
- **line_map; /* map of line to record chain */
+ } **records, // an occurrence
+ **line_map; // map of line to record chain
chastore_t rcha;
unsigned int *next_ptrs;
unsigned int table_bits,
@@ -128,7 +128,7 @@ static int scanA(struct histindex *index, int line1, int count1)
*/
NEXT_PTR(index, ptr) = rec->ptr;
rec->ptr = ptr;
- /* cap rec->cnt at MAX_CNT */
+ // cap rec->cnt at MAX_CNT
rec->cnt = XDL_MIN(MAX_CNT, rec->cnt + 1);
LINE_MAP(index, ptr) = rec;
goto continue_scan;
@@ -154,7 +154,7 @@ static int scanA(struct histindex *index, int line1, int count1)
LINE_MAP(index, ptr) = rec;
continue_scan:
- ; /* no op */
+ ; // no op
}
return 0;
@@ -266,7 +266,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
index.records = NULL;
index.line_map = NULL;
- /* in case of early xdl_cha_free() */
+ // in case of early xdl_cha_free()
index.rcha.head = NULL;
index.table_bits = xdl_hashbits(count1);
@@ -288,7 +288,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
goto cleanup;
memset(index.next_ptrs, 0, sz);
- /* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
+ // lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx()
if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
goto cleanup;
diff --git a/src/nvim/xdiff/xinclude.h b/src/nvim/xdiff/xinclude.h
index 46b8608314..5a359d1431 100644
--- a/src/nvim/xdiff/xinclude.h
+++ b/src/nvim/xdiff/xinclude.h
@@ -20,13 +20,13 @@
*
*/
-/* defines HAVE_ATTRIBUTE_UNUSED */
+// defines HAVE_ATTRIBUTE_UNUSED
#ifdef HAVE_CONFIG_H
# include "../auto/config.h"
#endif
-/* Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter
- * can be used to check for mistakes. */
+// Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter
+// can be used to check for mistakes.
#ifdef HAVE_ATTRIBUTE_UNUSED
# define UNUSED __attribute__((unused))
#else
@@ -58,4 +58,4 @@
#include "xemit.h"
-#endif /* #if !defined(XINCLUDE_H) */
+#endif // #if !defined(XINCLUDE_H)
diff --git a/src/nvim/xdiff/xmacros.h b/src/nvim/xdiff/xmacros.h
index 2809a28ca9..1167ebbb05 100644
--- a/src/nvim/xdiff/xmacros.h
+++ b/src/nvim/xdiff/xmacros.h
@@ -51,4 +51,4 @@ do { \
} while (0)
-#endif /* #if !defined(XMACROS_H) */
+#endif // #if !defined(XMACROS_H)
diff --git a/src/nvim/xdiff/xpatience.c b/src/nvim/xdiff/xpatience.c
index 2c65aac386..f6c84c67d8 100644
--- a/src/nvim/xdiff/xpatience.c
+++ b/src/nvim/xdiff/xpatience.c
@@ -69,7 +69,7 @@ struct hashmap {
*/
unsigned anchor : 1;
} *entries, *first, *last;
- /* were common records found? */
+ // were common records found?
unsigned long has_matches;
mmfile_t *file1, *file2;
xdfenv_t *env;
@@ -86,7 +86,7 @@ static int is_anchor(xpparam_t const *xpp, const char *line)
return 0;
}
-/* The argument "pass" is 1 for the first file, 2 for the second. */
+// The argument "pass" is 1 for the first file, 2 for the second.
static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
int pass)
{
@@ -155,7 +155,7 @@ static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
result->xpp = xpp;
result->env = env;
- /* We know exactly how large we want the hash map */
+ // We know exactly how large we want the hash map
result->alloc = count1 * 2;
result->entries = (struct entry *)
xdl_malloc(result->alloc * sizeof(struct entry));
@@ -163,11 +163,11 @@ static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
return -1;
memset(result->entries, 0, result->alloc * sizeof(struct entry));
- /* First, fill with entries from the first file */
+ // First, fill with entries from the first file
while (count1--)
insert_record(xpp, line1++, result, 1);
- /* Then search for matches in the second file */
+ // Then search for matches in the second file
while (count2--)
insert_record(xpp, line2++, result, 2);
@@ -185,13 +185,13 @@ static int binary_search(struct entry **sequence, int longest,
while (left + 1 < right) {
int middle = left + (right - left) / 2;
- /* by construction, no two entries can be equal */
+ // by construction, no two entries can be equal
if (sequence[middle]->line2 > entry->line2)
right = middle;
else
left = middle;
}
- /* return the index in "sequence", _not_ the sequence length */
+ // return the index in "sequence", _not_ the sequence length
return left;
}
@@ -216,7 +216,7 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
*/
int anchor_i = -1;
- /* Added to silence Coverity. */
+ // Added to silence Coverity.
if (sequence == NULL)
return map->first;
@@ -237,13 +237,13 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
}
}
- /* No common unique lines were found */
+ // No common unique lines were found
if (!longest) {
xdl_free(sequence);
return NULL;
}
- /* Iterate starting at the last element, adjusting the "next" members */
+ // Iterate starting at the last element, adjusting the "next" members
entry = sequence[longest - 1];
entry->next = NULL;
while (entry->previous) {
@@ -273,7 +273,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,
int next1, next2;
for (;;) {
- /* Try to grow the line ranges of common lines */
+ // Try to grow the line ranges of common lines
if (first) {
next1 = first->line1;
next2 = first->line2;
@@ -292,7 +292,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,
line2++;
}
- /* Recurse */
+ // Recurse
if (next1 > line1 || next2 > line2) {
struct hashmap submap;
@@ -343,7 +343,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
struct entry *first;
int result = 0;
- /* trivial case: one side is empty */
+ // trivial case: one side is empty
if (!count1) {
while(count2--)
env->xdf2.rchg[line2++ - 1] = 1;
@@ -359,7 +359,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
line1, count1, line2, count2))
return -1;
- /* are there any matching lines at all? */
+ // are there any matching lines at all?
if (!map.has_matches) {
while(count1--)
env->xdf1.rchg[line1++ - 1] = 1;
@@ -387,7 +387,7 @@ int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
return -1;
- /* environment is cleaned up in xdl_diff() */
+ // environment is cleaned up in xdl_diff()
return patience_diff(file1, file2, xpp, env,
1, env->xdf1.nrec, 1, env->xdf2.nrec);
}
diff --git a/src/nvim/xdiff/xprepare.h b/src/nvim/xdiff/xprepare.h
index 947d9fc1bb..b67b3b25ab 100644
--- a/src/nvim/xdiff/xprepare.h
+++ b/src/nvim/xdiff/xprepare.h
@@ -31,4 +31,4 @@ void xdl_free_env(xdfenv_t *xe);
-#endif /* #if !defined(XPREPARE_H) */
+#endif // #if !defined(XPREPARE_H)
diff --git a/src/nvim/xdiff/xtypes.h b/src/nvim/xdiff/xtypes.h
index 8442bd436e..026999c1bf 100644
--- a/src/nvim/xdiff/xtypes.h
+++ b/src/nvim/xdiff/xtypes.h
@@ -64,4 +64,4 @@ typedef struct s_xdfenv {
-#endif /* #if !defined(XTYPES_H) */
+#endif // #if !defined(XTYPES_H)
diff --git a/src/nvim/xdiff/xutils.c b/src/nvim/xdiff/xutils.c
index 25a090fb73..e8c7d2f884 100644
--- a/src/nvim/xdiff/xutils.c
+++ b/src/nvim/xdiff/xutils.c
@@ -168,7 +168,7 @@ static int ends_with_optional_cr(const char *l, long s, long i)
s--;
if (s == i)
return 1;
- /* do not ignore CR at the end of an incomplete line */
+ // do not ignore CR at the end of an incomplete line
if (complete && s == i + 1 && l[i] == '\r')
return 1;
return 0;
@@ -208,7 +208,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
} else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
while (i1 < s1 && i2 < s2) {
if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {
- /* Skip matching spaces and try again */
+ // Skip matching spaces and try again
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
i1++;
while (i2 < s2 && XDL_ISSPACE(l2[i2]))
@@ -224,7 +224,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
i2++;
}
} else if (flags & XDF_IGNORE_CR_AT_EOL) {
- /* Find the first difference and see how the line ends */
+ // Find the first difference and see how the line ends
while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) {
i1++;
i2++;
@@ -261,7 +261,7 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
for (; ptr < top && *ptr != '\n'; ptr++) {
if (cr_at_eol_only) {
- /* do not ignore CR at the end of an incomplete line */
+ // do not ignore CR at the end of an incomplete line
if (*ptr == '\r' &&
(ptr + 1 < top && ptr[1] == '\n'))
continue;
@@ -274,7 +274,7 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data,
ptr++;
at_eol = (top <= ptr + 1 || ptr[1] == '\n');
if (flags & XDF_IGNORE_WHITESPACE)
- ; /* already handled */
+ ; // already handled
else if (flags & XDF_IGNORE_WHITESPACE_CHANGE
&& !at_eol) {
ha += (ha << 5);
diff --git a/src/nvim/xdiff/xutils.h b/src/nvim/xdiff/xutils.h
index fba7bae03c..0bebd93022 100644
--- a/src/nvim/xdiff/xutils.h
+++ b/src/nvim/xdiff/xutils.h
@@ -44,4 +44,4 @@ int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
-#endif /* #if !defined(XUTILS_H) */
+#endif // #if !defined(XUTILS_H)
diff --git a/src/tree_sitter/api.h b/src/tree_sitter/api.h
index 40187e3db0..9d832e6ec4 100644
--- a/src/tree_sitter/api.h
+++ b/src/tree_sitter/api.h
@@ -174,8 +174,19 @@ const TSLanguage *ts_parser_language(const TSParser *self);
* The second and third parameters specify the location and length of an array
* of ranges. The parser does *not* take ownership of these ranges; it copies
* the data, so it doesn't matter how these ranges are allocated.
+ *
+ * If `length` is zero, then the entire document will be parsed. Otherwise,
+ * the given ranges must be ordered from earliest to latest in the document,
+ * and they must not overlap. That is, the following must hold for all
+ * `i` < `length - 1`:
+ *
+ * ranges[i].end_byte <= ranges[i + 1].start_byte
+ *
+ * If this requirement is not satisfied, the operation will fail, the ranges
+ * will not be assigned, and this function will return `false`. On success,
+ * this function returns `true`
*/
-void ts_parser_set_included_ranges(
+bool ts_parser_set_included_ranges(
TSParser *self,
const TSRange *ranges,
uint32_t length
@@ -325,14 +336,6 @@ TSLogger ts_parser_logger(const TSParser *self);
*/
void ts_parser_print_dot_graphs(TSParser *self, int file);
-/**
- * Set whether or not the parser should halt immediately upon detecting an
- * error. This will generally result in a syntax tree with an error at the
- * root, and one or more partial syntax trees within the error. This behavior
- * may not be supported long-term.
- */
-void ts_parser_halt_on_error(TSParser *self, bool halt);
-
/******************/
/* Section - Tree */
/******************/
@@ -732,13 +735,23 @@ const char *ts_query_string_value_for_id(
);
/**
- * Disable a certain capture within a query. This prevents the capture
- * from being returned in matches, and also avoids any resource usage
- * associated with recording the capture.
+ * Disable a certain capture within a query.
+ *
+ * This prevents the capture from being returned in matches, and also avoids
+ * any resource usage associated with recording the capture. Currently, there
+ * is no way to undo this.
*/
void ts_query_disable_capture(TSQuery *, const char *, uint32_t);
/**
+ * Disable a certain pattern within a query.
+ *
+ * This prevents the pattern from matching and removes most of the overhead
+ * associated with the pattern. Currently, there is no way to undo this.
+ */
+void ts_query_disable_pattern(TSQuery *, uint32_t);
+
+/**
* Create a new cursor for executing a given query.
*
* The cursor stores the state that is needed to iteratively search
diff --git a/src/tree_sitter/array.h b/src/tree_sitter/array.h
index bc77e687bf..26cb8448f1 100644
--- a/src/tree_sitter/array.h
+++ b/src/tree_sitter/array.h
@@ -126,12 +126,28 @@ static inline void array__splice(VoidArray *self, size_t element_size,
array__reserve(self, element_size, new_size);
char *contents = (char *)self->contents;
- if (self->size > old_end)
- memmove(contents + new_end * element_size, contents + old_end * element_size,
- (self->size - old_end) * element_size);
- if (new_count > 0)
- memcpy((contents + index * element_size), elements,
- new_count * element_size);
+ if (self->size > old_end) {
+ memmove(
+ contents + new_end * element_size,
+ contents + old_end * element_size,
+ (self->size - old_end) * element_size
+ );
+ }
+ if (new_count > 0) {
+ if (elements) {
+ memcpy(
+ (contents + index * element_size),
+ elements,
+ new_count * element_size
+ );
+ } else {
+ memset(
+ (contents + index * element_size),
+ 0,
+ new_count * element_size
+ );
+ }
+ }
self->size += new_count - old_count;
}
diff --git a/src/tree_sitter/atomic.h b/src/tree_sitter/atomic.h
index 301ee36700..7bd0e850a9 100644
--- a/src/tree_sitter/atomic.h
+++ b/src/tree_sitter/atomic.h
@@ -12,11 +12,11 @@ static inline size_t atomic_load(const volatile size_t *p) {
}
static inline uint32_t atomic_inc(volatile uint32_t *p) {
- return InterlockedIncrement(p);
+ return InterlockedIncrement((long volatile *)p);
}
static inline uint32_t atomic_dec(volatile uint32_t *p) {
- return InterlockedDecrement(p);
+ return InterlockedDecrement((long volatile *)p);
}
#else
diff --git a/src/tree_sitter/bits.h b/src/tree_sitter/bits.h
index 3bec455dd1..ce7a715567 100644
--- a/src/tree_sitter/bits.h
+++ b/src/tree_sitter/bits.h
@@ -7,7 +7,7 @@ static inline uint32_t bitmask_for_index(uint16_t id) {
return (1u << (31 - id));
}
-#ifdef _WIN32
+#if defined _WIN32 && !defined __GNUC__
#include <intrin.h>
diff --git a/src/tree_sitter/language.c b/src/tree_sitter/language.c
index e240ef2a53..a396b4b0b6 100644
--- a/src/tree_sitter/language.c
+++ b/src/tree_sitter/language.c
@@ -72,8 +72,10 @@ const char *ts_language_symbol_name(
return "ERROR";
} else if (symbol == ts_builtin_sym_error_repeat) {
return "_ERROR";
- } else {
+ } else if (symbol < ts_language_symbol_count(self)) {
return self->symbol_names[symbol];
+ } else {
+ return NULL;
}
}
@@ -119,7 +121,7 @@ const char *ts_language_field_name_for_id(
TSFieldId id
) {
uint32_t count = ts_language_field_count(self);
- if (count) {
+ if (count && id <= count) {
return self->field_names[id];
} else {
return NULL;
diff --git a/src/tree_sitter/language.h b/src/tree_sitter/language.h
index d7e17c3d70..f908b4593a 100644
--- a/src/tree_sitter/language.h
+++ b/src/tree_sitter/language.h
@@ -29,10 +29,12 @@ static inline bool ts_language_is_symbol_external(const TSLanguage *self, TSSymb
return 0 < symbol && symbol < self->external_token_count + 1;
}
-static inline const TSParseAction *ts_language_actions(const TSLanguage *self,
- TSStateId state,
- TSSymbol symbol,
- uint32_t *count) {
+static inline const TSParseAction *ts_language_actions(
+ const TSLanguage *self,
+ TSStateId state,
+ TSSymbol symbol,
+ uint32_t *count
+) {
TableEntry entry;
ts_language_table_entry(self, state, symbol, &entry);
*count = entry.action_count;
@@ -90,8 +92,8 @@ static inline TSStateId ts_language_next_state(const TSLanguage *self,
const TSParseAction *actions = ts_language_actions(self, state, symbol, &count);
if (count > 0) {
TSParseAction action = actions[count - 1];
- if (action.type == TSParseActionTypeShift || action.type == TSParseActionTypeRecover) {
- return action.params.state;
+ if (action.type == TSParseActionTypeShift) {
+ return action.params.extra ? state : action.params.state;
}
}
return 0;
diff --git a/src/tree_sitter/lexer.c b/src/tree_sitter/lexer.c
index e2ca851973..3f8a4c0ae8 100644
--- a/src/tree_sitter/lexer.c
+++ b/src/tree_sitter/lexer.c
@@ -355,7 +355,7 @@ void ts_lexer_mark_end(Lexer *self) {
ts_lexer__mark_end(&self->data);
}
-void ts_lexer_set_included_ranges(
+bool ts_lexer_set_included_ranges(
Lexer *self,
const TSRange *ranges,
uint32_t count
@@ -363,6 +363,16 @@ void ts_lexer_set_included_ranges(
if (count == 0 || !ranges) {
ranges = &DEFAULT_RANGE;
count = 1;
+ } else {
+ uint32_t previous_byte = 0;
+ for (unsigned i = 0; i < count; i++) {
+ const TSRange *range = &ranges[i];
+ if (
+ range->start_byte < previous_byte ||
+ range->end_byte < range->start_byte
+ ) return false;
+ previous_byte = range->end_byte;
+ }
}
size_t size = count * sizeof(TSRange);
@@ -370,6 +380,7 @@ void ts_lexer_set_included_ranges(
memcpy(self->included_ranges, ranges, size);
self->included_range_count = count;
ts_lexer_goto(self, self->current_position);
+ return true;
}
TSRange *ts_lexer_included_ranges(const Lexer *self, uint32_t *count) {
diff --git a/src/tree_sitter/lexer.h b/src/tree_sitter/lexer.h
index 8cd9c26706..5e39294529 100644
--- a/src/tree_sitter/lexer.h
+++ b/src/tree_sitter/lexer.h
@@ -38,7 +38,7 @@ void ts_lexer_start(Lexer *);
void ts_lexer_finish(Lexer *, uint32_t *);
void ts_lexer_advance_to_end(Lexer *);
void ts_lexer_mark_end(Lexer *);
-void ts_lexer_set_included_ranges(Lexer *self, const TSRange *ranges, uint32_t count);
+bool ts_lexer_set_included_ranges(Lexer *self, const TSRange *ranges, uint32_t count);
TSRange *ts_lexer_included_ranges(const Lexer *self, uint32_t *count);
#ifdef __cplusplus
diff --git a/src/tree_sitter/node.c b/src/tree_sitter/node.c
index b03e2fc979..576f3ef38e 100644
--- a/src/tree_sitter/node.c
+++ b/src/tree_sitter/node.c
@@ -150,7 +150,9 @@ static inline TSNode ts_node__child(
while (ts_node_child_iterator_next(&iterator, &child)) {
if (ts_node__is_relevant(child, include_anonymous)) {
if (index == child_index) {
- ts_tree_set_cached_parent(self.tree, &child, &self);
+ if (ts_node__is_relevant(self, true)) {
+ ts_tree_set_cached_parent(self.tree, &child, &self);
+ }
return child;
}
index++;
diff --git a/src/tree_sitter/parser.c b/src/tree_sitter/parser.c
index f381afccab..d4b227308b 100644
--- a/src/tree_sitter/parser.c
+++ b/src/tree_sitter/parser.c
@@ -71,7 +71,6 @@ struct TSParser {
unsigned accept_count;
unsigned operation_count;
const volatile size_t *cancellation_flag;
- bool halt_on_error;
Subtree old_tree;
TSRangeArray included_range_differences;
unsigned included_range_difference_index;
@@ -325,6 +324,12 @@ static bool ts_parser__can_reuse_first_leaf(
TSStateId leaf_state = ts_subtree_leaf_parse_state(tree);
TSLexMode leaf_lex_mode = self->language->lex_modes[leaf_state];
+ // At the end of a non-terminal extra node, the lexer normally returns
+ // NULL, which indicates that the parser should look for a reduce action
+ // at symbol `0`. Avoid reusing tokens in this situation to ensure that
+ // the same thing happens when incrementally reparsing.
+ if (current_lex_mode.lex_state == (uint16_t)(-1)) return false;
+
// If the token was created in a state with the same set of lookaheads, it is reusable.
if (
table_entry->action_count > 0 &&
@@ -594,6 +599,10 @@ static Subtree ts_parser__reuse_node(
uint32_t byte_offset = reusable_node_byte_offset(&self->reusable_node);
uint32_t end_byte_offset = byte_offset + ts_subtree_total_bytes(result);
+ // Do not reuse an EOF node if the included ranges array has changes
+ // later on in the file.
+ if (ts_subtree_is_eof(result)) end_byte_offset = UINT32_MAX;
+
if (byte_offset > position) {
LOG("before_reusable_node symbol:%s", TREE_NAME(result));
break;
@@ -1014,7 +1023,9 @@ static void ts_parser__handle_error(
TSStateId state_after_missing_symbol = ts_language_next_state(
self->language, state, missing_symbol
);
- if (state_after_missing_symbol == 0) continue;
+ if (state_after_missing_symbol == 0 || state_after_missing_symbol == state) {
+ continue;
+ }
if (ts_language_has_reduce_action(
self->language,
@@ -1067,46 +1078,6 @@ static void ts_parser__handle_error(
LOG_STACK();
}
-static void ts_parser__halt_parse(TSParser *self) {
- LOG("halting_parse");
- LOG_STACK();
-
- ts_lexer_advance_to_end(&self->lexer);
- Length remaining_length = length_sub(
- self->lexer.current_position,
- ts_stack_position(self->stack, 0)
- );
-
- Subtree filler_node = ts_subtree_new_error(
- &self->tree_pool,
- 0,
- length_zero(),
- remaining_length,
- remaining_length.bytes,
- 0,
- self->language
- );
- ts_subtree_to_mut_unsafe(filler_node).ptr->visible = false;
- ts_stack_push(self->stack, 0, filler_node, false, 0);
-
- SubtreeArray children = array_new();
- Subtree root_error = ts_subtree_new_error_node(&self->tree_pool, &children, false, self->language);
- ts_stack_push(self->stack, 0, root_error, false, 0);
-
- Subtree eof = ts_subtree_new_leaf(
- &self->tree_pool,
- ts_builtin_sym_end,
- length_zero(),
- length_zero(),
- 0,
- 0,
- false,
- false,
- self->language
- );
- ts_parser__accept(self, 0, eof);
-}
-
static bool ts_parser__recover_to_state(
TSParser *self,
StackVersion version,
@@ -1644,8 +1615,8 @@ static unsigned ts_parser__condense_stack(TSParser *self) {
static bool ts_parser_has_outstanding_parse(TSParser *self) {
return (
- self->lexer.current_position.bytes > 0 ||
- ts_stack_state(self->stack, 0) != 1
+ ts_stack_state(self->stack, 0) != 1 ||
+ ts_stack_node_count_since_error(self->stack, 0) != 0
);
}
@@ -1661,7 +1632,6 @@ TSParser *ts_parser_new(void) {
self->finished_tree = NULL_SUBTREE;
self->reusable_node = reusable_node_new();
self->dot_graph_file = NULL;
- self->halt_on_error = false;
self->cancellation_flag = NULL;
self->timeout_duration = 0;
self->end_clock = clock_null();
@@ -1741,10 +1711,6 @@ void ts_parser_print_dot_graphs(TSParser *self, int fd) {
}
}
-void ts_parser_halt_on_error(TSParser *self, bool should_halt_on_error) {
- self->halt_on_error = should_halt_on_error;
-}
-
const size_t *ts_parser_cancellation_flag(const TSParser *self) {
return (const size_t *)self->cancellation_flag;
}
@@ -1761,8 +1727,12 @@ void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros) {
self->timeout_duration = duration_from_micros(timeout_micros);
}
-void ts_parser_set_included_ranges(TSParser *self, const TSRange *ranges, uint32_t count) {
- ts_lexer_set_included_ranges(&self->lexer, ranges, count);
+bool ts_parser_set_included_ranges(
+ TSParser *self,
+ const TSRange *ranges,
+ uint32_t count
+) {
+ return ts_lexer_set_included_ranges(&self->lexer, ranges, count);
}
const TSRange *ts_parser_included_ranges(const TSParser *self, uint32_t *count) {
@@ -1858,9 +1828,6 @@ TSTree *ts_parser_parse(
unsigned min_error_cost = ts_parser__condense_stack(self);
if (self->finished_tree.ptr && ts_subtree_error_cost(self->finished_tree) < min_error_cost) {
break;
- } else if (self->halt_on_error && min_error_cost > 0) {
- ts_parser__halt_parse(self);
- break;
}
while (self->included_range_difference_index < self->included_range_differences.size) {
diff --git a/src/tree_sitter/query.c b/src/tree_sitter/query.c
index 2563325248..92a8006179 100644
--- a/src/tree_sitter/query.c
+++ b/src/tree_sitter/query.c
@@ -19,6 +19,8 @@ typedef struct {
uint8_t next_size;
} Stream;
+#define MAX_STEP_CAPTURE_COUNT 4
+
/*
* QueryStep - A step in the process of matching a query. Each node within
* a query S-expression maps to one of these steps. An entire pattern is
@@ -33,13 +35,21 @@ typedef struct {
* captured in this pattern.
* - `depth` - The depth where this node occurs in the pattern. The root node
* of the pattern has depth zero.
+ * - `repeat_step_index` - If this step is part of a repetition, the index of
+ * the beginning of the repetition. A `NONE` value means this step is not
+ * part of a repetition.
*/
typedef struct {
TSSymbol symbol;
TSFieldId field;
- uint16_t capture_id;
- uint16_t depth: 15;
+ uint16_t capture_ids[MAX_STEP_CAPTURE_COUNT];
+ uint16_t repeat_step_index;
+ uint16_t depth: 11;
bool contains_captures: 1;
+ bool is_pattern_start: 1;
+ bool is_immediate: 1;
+ bool is_last: 1;
+ bool is_repeated: 1;
} QueryStep;
/*
@@ -62,10 +72,12 @@ typedef struct {
} SymbolTable;
/*
- * PatternEntry - The set of steps needed to match a particular pattern,
- * represented as a slice of a shared array. These entries are stored in a
- * 'pattern map' - a sorted array that makes it possible to efficiently lookup
- * patterns based on the symbol for their first step.
+ * PatternEntry - Information about the starting point for matching a
+ * particular pattern, consisting of the index of the pattern within the query,
+ * and the index of the patter's first step in the shared `steps` array. These
+ * entries are stored in a 'pattern map' - a sorted array that makes it
+ * possible to efficiently lookup patterns based on the symbol for their first
+ * step.
*/
typedef struct {
uint16_t step_index;
@@ -79,23 +91,27 @@ typedef struct {
* represented as one of these states.
*/
typedef struct {
+ uint32_t id;
uint16_t start_depth;
uint16_t pattern_index;
uint16_t step_index;
- uint16_t capture_count;
- uint16_t capture_list_id;
uint16_t consumed_capture_count;
- uint32_t id;
+ uint16_t repeat_match_count;
+ uint16_t step_index_on_failure;
+ uint8_t capture_list_id;
+ bool seeking_non_match;
} QueryState;
+typedef Array(TSQueryCapture) CaptureList;
+
/*
* CaptureListPool - A collection of *lists* of captures. Each QueryState
- * needs to maintain its own list of captures. They are all represented as
- * slices of one shared array. The CaptureListPool keeps track of which
- * parts of the shared array are currently in use by a QueryState.
+ * needs to maintain its own list of captures. To avoid repeated allocations,
+ * the reuses a fixed set of capture lists, and keeps track of which ones
+ * are currently in use.
*/
typedef struct {
- Array(TSQueryCapture) list;
+ CaptureList list[32];
uint32_t usage_map;
} CaptureListPool;
@@ -113,7 +129,6 @@ struct TSQuery {
Array(Slice) predicates_by_pattern;
Array(uint32_t) start_bytes_by_pattern;
const TSLanguage *language;
- uint16_t max_capture_count;
uint16_t wildcard_root_pattern_count;
TSSymbol *symbol_map;
};
@@ -140,6 +155,7 @@ static const TSQueryError PARENT_DONE = -1;
static const uint8_t PATTERN_DONE_MARKER = UINT8_MAX;
static const uint16_t NONE = UINT16_MAX;
static const TSSymbol WILDCARD_SYMBOL = 0;
+static const TSSymbol NAMED_WILDCARD_SYMBOL = UINT16_MAX - 1;
static const uint16_t MAX_STATE_COUNT = 32;
// #define LOG(...) fprintf(stderr, __VA_ARGS__)
@@ -226,24 +242,25 @@ static void stream_scan_identifier(Stream *stream) {
static CaptureListPool capture_list_pool_new(void) {
return (CaptureListPool) {
- .list = array_new(),
.usage_map = UINT32_MAX,
};
}
-static void capture_list_pool_reset(CaptureListPool *self, uint16_t list_size) {
+static void capture_list_pool_reset(CaptureListPool *self) {
self->usage_map = UINT32_MAX;
- uint32_t total_size = MAX_STATE_COUNT * list_size;
- array_reserve(&self->list, total_size);
- self->list.size = total_size;
+ for (unsigned i = 0; i < 32; i++) {
+ array_clear(&self->list[i]);
+ }
}
static void capture_list_pool_delete(CaptureListPool *self) {
- array_delete(&self->list);
+ for (unsigned i = 0; i < 32; i++) {
+ array_delete(&self->list[i]);
+ }
}
-static TSQueryCapture *capture_list_pool_get(CaptureListPool *self, uint16_t id) {
- return &self->list.contents[id * (self->list.size / MAX_STATE_COUNT)];
+static CaptureList *capture_list_pool_get(CaptureListPool *self, uint16_t id) {
+ return &self->list[id];
}
static bool capture_list_pool_is_empty(const CaptureListPool *self) {
@@ -262,6 +279,7 @@ static uint16_t capture_list_pool_acquire(CaptureListPool *self) {
}
static void capture_list_pool_release(CaptureListPool *self, uint16_t id) {
+ array_clear(&self->list[id]);
self->usage_map |= bitmask_for_index(id);
}
@@ -324,6 +342,114 @@ static uint16_t symbol_table_insert_name(
return self->slices.size - 1;
}
+static uint16_t symbol_table_insert_name_with_escapes(
+ SymbolTable *self,
+ const char *escaped_name,
+ uint32_t escaped_length
+) {
+ Slice slice = {
+ .offset = self->characters.size,
+ .length = 0,
+ };
+ array_grow_by(&self->characters, escaped_length + 1);
+
+ // Copy the contents of the literal into the characters buffer, processing escape
+ // sequences like \n and \". This needs to be done before checking if the literal
+ // is already present, in order to do the string comparison.
+ bool is_escaped = false;
+ for (unsigned i = 0; i < escaped_length; i++) {
+ const char *src = &escaped_name[i];
+ char *dest = &self->characters.contents[slice.offset + slice.length];
+ if (is_escaped) {
+ switch (*src) {
+ case 'n':
+ *dest = '\n';
+ break;
+ case 'r':
+ *dest = '\r';
+ break;
+ case 't':
+ *dest = '\t';
+ break;
+ case '0':
+ *dest = '\0';
+ break;
+ default:
+ *dest = *src;
+ break;
+ }
+ is_escaped = false;
+ slice.length++;
+ } else {
+ if (*src == '\\') {
+ is_escaped = true;
+ } else {
+ *dest = *src;
+ slice.length++;
+ }
+ }
+ }
+
+ // If the string is already present, remove the redundant content from the characters
+ // buffer and return the existing id.
+ int id = symbol_table_id_for_name(self, &self->characters.contents[slice.offset], slice.length);
+ if (id >= 0) {
+ self->characters.size -= (escaped_length + 1);
+ return id;
+ }
+
+ self->characters.contents[slice.offset + slice.length] = 0;
+ array_push(&self->slices, slice);
+ return self->slices.size - 1;
+}
+
+/************
+ * QueryStep
+ ************/
+
+static QueryStep query_step__new(
+ TSSymbol symbol,
+ uint16_t depth,
+ bool is_immediate
+) {
+ return (QueryStep) {
+ .symbol = symbol,
+ .depth = depth,
+ .field = 0,
+ .capture_ids = {NONE, NONE, NONE, NONE},
+ .contains_captures = false,
+ .is_repeated = false,
+ .is_last = false,
+ .is_pattern_start = false,
+ .is_immediate = is_immediate,
+ .repeat_step_index = NONE,
+ };
+}
+
+static void query_step__add_capture(QueryStep *self, uint16_t capture_id) {
+ for (unsigned i = 0; i < MAX_STEP_CAPTURE_COUNT; i++) {
+ if (self->capture_ids[i] == NONE) {
+ self->capture_ids[i] = capture_id;
+ break;
+ }
+ }
+}
+
+static void query_step__remove_capture(QueryStep *self, uint16_t capture_id) {
+ for (unsigned i = 0; i < MAX_STEP_CAPTURE_COUNT; i++) {
+ if (self->capture_ids[i] == capture_id) {
+ self->capture_ids[i] = NONE;
+ while (i + 1 < MAX_STEP_CAPTURE_COUNT) {
+ if (self->capture_ids[i + 1] == NONE) break;
+ self->capture_ids[i] = self->capture_ids[i + 1];
+ self->capture_ids[i + 1] = NONE;
+ i++;
+ }
+ break;
+ }
+ }
+}
+
/*********
* Query
*********/
@@ -333,7 +459,7 @@ static uint16_t symbol_table_insert_name(
// to quickly find the starting steps of all of the patterns whose root matches
// that node. Each entry has two fields: a `pattern_index`, which identifies one
// of the patterns in the query, and a `step_index`, which indicates the start
-// offset of that pattern's steps pattern within the `steps` array.
+// offset of that pattern's steps within the `steps` array.
//
// The entries are sorted by the patterns' root symbols, and lookups use a
// binary search. This ensures that the cost of this initial lookup step
@@ -399,14 +525,14 @@ static void ts_query__finalize_steps(TSQuery *self) {
for (unsigned i = 0; i < self->steps.size; i++) {
QueryStep *step = &self->steps.contents[i];
uint32_t depth = step->depth;
- if (step->capture_id != NONE) {
+ if (step->capture_ids[0] != NONE) {
step->contains_captures = true;
} else {
step->contains_captures = false;
for (unsigned j = i + 1; j < self->steps.size; j++) {
QueryStep *s = &self->steps.contents[j];
if (s->depth == PATTERN_DONE_MARKER || s->depth <= depth) break;
- if (s->capture_id != NONE) step->contains_captures = true;
+ if (s->capture_ids[0] != NONE) step->contains_captures = true;
}
}
}
@@ -473,9 +599,22 @@ static TSQueryError ts_query__parse_predicate(
stream_advance(stream);
// Parse the string content
+ bool is_escaped = false;
const char *string_content = stream->input;
- while (stream->next != '"') {
- if (stream->next == '\n' || !stream_advance(stream)) {
+ for (;;) {
+ if (is_escaped) {
+ is_escaped = false;
+ } else {
+ if (stream->next == '\\') {
+ is_escaped = true;
+ } else if (stream->next == '"') {
+ break;
+ } else if (stream->next == '\n') {
+ stream_reset(stream, string_content - 1);
+ return TSQueryErrorSyntax;
+ }
+ }
+ if (!stream_advance(stream)) {
stream_reset(stream, string_content - 1);
return TSQueryErrorSyntax;
}
@@ -483,7 +622,7 @@ static TSQueryError ts_query__parse_predicate(
uint32_t length = stream->input - string_content;
// Add a step for the node
- uint16_t id = symbol_table_insert_name(
+ uint16_t id = symbol_table_insert_name_with_escapes(
&self->predicate_values,
string_content,
length
@@ -533,7 +672,8 @@ static TSQueryError ts_query__parse_pattern(
TSQuery *self,
Stream *stream,
uint32_t depth,
- uint32_t *capture_count
+ uint32_t *capture_count,
+ bool is_immediate
) {
uint16_t starting_step_index = self->steps.size;
@@ -552,7 +692,7 @@ static TSQueryError ts_query__parse_pattern(
// Parse a nested list, which represents a pattern followed by
// zero-or-more predicates.
if (stream->next == '(' && depth == 0) {
- TSQueryError e = ts_query__parse_pattern(self, stream, 0, capture_count);
+ TSQueryError e = ts_query__parse_pattern(self, stream, 0, capture_count, is_immediate);
if (e) return e;
// Parse the predicates.
@@ -573,7 +713,7 @@ static TSQueryError ts_query__parse_pattern(
// Parse the wildcard symbol
if (stream->next == '*') {
- symbol = WILDCARD_SYMBOL;
+ symbol = depth > 0 ? NAMED_WILDCARD_SYMBOL : WILDCARD_SYMBOL;
stream_advance(stream);
}
@@ -597,24 +737,37 @@ static TSQueryError ts_query__parse_pattern(
}
// Add a step for the node.
- array_push(&self->steps, ((QueryStep) {
- .depth = depth,
- .symbol = symbol,
- .field = 0,
- .capture_id = NONE,
- .contains_captures = false,
- }));
+ array_push(&self->steps, query_step__new(symbol, depth, is_immediate));
// Parse the child patterns
stream_skip_whitespace(stream);
+ bool child_is_immediate = false;
+ uint16_t child_start_step_index = self->steps.size;
for (;;) {
- TSQueryError e = ts_query__parse_pattern(self, stream, depth + 1, capture_count);
+ if (stream->next == '.') {
+ child_is_immediate = true;
+ stream_advance(stream);
+ stream_skip_whitespace(stream);
+ }
+
+ TSQueryError e = ts_query__parse_pattern(
+ self,
+ stream,
+ depth + 1,
+ capture_count,
+ child_is_immediate
+ );
if (e == PARENT_DONE) {
+ if (child_is_immediate) {
+ self->steps.contents[child_start_step_index].is_last = true;
+ }
stream_advance(stream);
break;
} else if (e) {
return e;
}
+
+ child_is_immediate = false;
}
}
@@ -643,13 +796,7 @@ static TSQueryError ts_query__parse_pattern(
stream_reset(stream, string_content);
return TSQueryErrorNodeType;
}
- array_push(&self->steps, ((QueryStep) {
- .depth = depth,
- .symbol = symbol,
- .field = 0,
- .capture_id = NONE,
- .contains_captures = false,
- }));
+ array_push(&self->steps, query_step__new(symbol, depth, is_immediate));
if (stream->next != '"') return TSQueryErrorSyntax;
stream_advance(stream);
@@ -672,7 +819,13 @@ static TSQueryError ts_query__parse_pattern(
// Parse the pattern
uint32_t step_index = self->steps.size;
- TSQueryError e = ts_query__parse_pattern(self, stream, depth, capture_count);
+ TSQueryError e = ts_query__parse_pattern(
+ self,
+ stream,
+ depth,
+ capture_count,
+ is_immediate
+ );
if (e == PARENT_DONE) return TSQueryErrorSyntax;
if (e) return e;
@@ -695,12 +848,7 @@ static TSQueryError ts_query__parse_pattern(
stream_skip_whitespace(stream);
// Add a step that matches any kind of node
- array_push(&self->steps, ((QueryStep) {
- .depth = depth,
- .symbol = WILDCARD_SYMBOL,
- .field = 0,
- .contains_captures = false,
- }));
+ array_push(&self->steps, query_step__new(WILDCARD_SYMBOL, depth, is_immediate));
}
else {
@@ -709,26 +857,43 @@ static TSQueryError ts_query__parse_pattern(
stream_skip_whitespace(stream);
- // Parse an '@'-prefixed capture pattern
- if (stream->next == '@') {
- stream_advance(stream);
+ // Parse suffixes modifiers for this pattern
+ for (;;) {
+ QueryStep *step = &self->steps.contents[starting_step_index];
- // Parse the capture name
- if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax;
- const char *capture_name = stream->input;
- stream_scan_identifier(stream);
- uint32_t length = stream->input - capture_name;
+ if (stream->next == '+') {
+ stream_advance(stream);
+ step->is_repeated = true;
+ array_back(&self->steps)->repeat_step_index = starting_step_index;
+ stream_skip_whitespace(stream);
+ }
- // Add the capture id to the first step of the pattern
- uint16_t capture_id = symbol_table_insert_name(
- &self->captures,
- capture_name,
- length
- );
- self->steps.contents[starting_step_index].capture_id = capture_id;
- (*capture_count)++;
+ // Parse an '@'-prefixed capture pattern
+ else if (stream->next == '@') {
+ stream_advance(stream);
- stream_skip_whitespace(stream);
+ // Parse the capture name
+ if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax;
+ const char *capture_name = stream->input;
+ stream_scan_identifier(stream);
+ uint32_t length = stream->input - capture_name;
+
+ // Add the capture id to the first step of the pattern
+ uint16_t capture_id = symbol_table_insert_name(
+ &self->captures,
+ capture_name,
+ length
+ );
+ query_step__add_capture(step, capture_id);
+ (*capture_count)++;
+
+ stream_skip_whitespace(stream);
+ }
+
+ // No more suffix modifiers
+ else {
+ break;
+ }
}
return 0;
@@ -778,24 +943,22 @@ TSQuery *ts_query_new(
.predicates_by_pattern = array_new(),
.symbol_map = symbol_map,
.wildcard_root_pattern_count = 0,
- .max_capture_count = 0,
.language = language,
};
// Parse all of the S-expressions in the given string.
Stream stream = stream_new(source, source_len);
stream_skip_whitespace(&stream);
- uint32_t start_step_index;
while (stream.input < stream.end) {
- start_step_index = self->steps.size;
+ uint32_t start_step_index = self->steps.size;
uint32_t capture_count = 0;
array_push(&self->start_bytes_by_pattern, stream.input - source);
array_push(&self->predicates_by_pattern, ((Slice) {
.offset = self->predicate_steps.size,
.length = 0,
}));
- *error_type = ts_query__parse_pattern(self, &stream, 0, &capture_count);
- array_push(&self->steps, ((QueryStep) { .depth = PATTERN_DONE_MARKER }));
+ *error_type = ts_query__parse_pattern(self, &stream, 0, &capture_count, false);
+ array_push(&self->steps, query_step__new(0, PATTERN_DONE_MARKER, false));
// If any pattern could not be parsed, then report the error information
// and terminate.
@@ -805,7 +968,19 @@ TSQuery *ts_query_new(
return NULL;
}
+ // If a pattern has a wildcard at its root, optimize the matching process
+ // by skipping matching the wildcard.
+ if (
+ self->steps.contents[start_step_index].symbol == WILDCARD_SYMBOL
+ ) {
+ QueryStep *second_step = &self->steps.contents[start_step_index + 1];
+ if (second_step->symbol != WILDCARD_SYMBOL && second_step->depth != PATTERN_DONE_MARKER) {
+ start_step_index += 1;
+ }
+ }
+
// Maintain a map that can look up patterns for a given root symbol.
+ self->steps.contents[start_step_index].is_pattern_start = true;
ts_query__pattern_map_insert(
self,
self->steps.contents[start_step_index].symbol,
@@ -814,13 +989,6 @@ TSQuery *ts_query_new(
if (self->steps.contents[start_step_index].symbol == WILDCARD_SYMBOL) {
self->wildcard_root_pattern_count++;
}
-
- // Keep track of the maximum number of captures in pattern, because
- // that numer determines how much space is needed to store each capture
- // list.
- if (capture_count > self->max_capture_count) {
- self->max_capture_count = capture_count;
- }
}
ts_query__finalize_steps(self);
@@ -891,16 +1059,31 @@ void ts_query_disable_capture(
const char *name,
uint32_t length
) {
+ // Remove capture information for any pattern step that previously
+ // captured with the given name.
int id = symbol_table_id_for_name(&self->captures, name, length);
if (id != -1) {
for (unsigned i = 0; i < self->steps.size; i++) {
QueryStep *step = &self->steps.contents[i];
- if (step->capture_id == id) {
- step->capture_id = NONE;
- }
+ query_step__remove_capture(step, id);
+ }
+ ts_query__finalize_steps(self);
+ }
+}
+
+void ts_query_disable_pattern(
+ TSQuery *self,
+ uint32_t pattern_index
+) {
+ // Remove the given pattern from the pattern map. Its steps will still
+ // be in the `steps` array, but they will never be read.
+ for (unsigned i = 0; i < self->pattern_map.size; i++) {
+ PatternEntry *pattern = &self->pattern_map.contents[i];
+ if (pattern->pattern_index == pattern_index) {
+ array_erase(&self->pattern_map, i);
+ i--;
}
}
- ts_query__finalize_steps(self);
}
/***************
@@ -940,7 +1123,7 @@ void ts_query_cursor_exec(
array_clear(&self->states);
array_clear(&self->finished_states);
ts_tree_cursor_reset(&self->cursor, node);
- capture_list_pool_reset(&self->capture_list_pool, query->max_capture_count);
+ capture_list_pool_reset(&self->capture_list_pool);
self->next_state_id = 0;
self->depth = 0;
self->ascending = false;
@@ -984,12 +1167,12 @@ static bool ts_query_cursor__first_in_progress_capture(
bool result = false;
for (unsigned i = 0; i < self->states.size; i++) {
const QueryState *state = &self->states.contents[i];
- if (state->capture_count > 0) {
- const TSQueryCapture *captures = capture_list_pool_get(
- &self->capture_list_pool,
- state->capture_list_id
- );
- uint32_t capture_byte = ts_node_start_byte(captures[0].node);
+ const CaptureList *captures = capture_list_pool_get(
+ &self->capture_list_pool,
+ state->capture_list_id
+ );
+ if (captures->size > 0) {
+ uint32_t capture_byte = ts_node_start_byte(captures->contents[0].node);
if (
!result ||
capture_byte < *byte_offset ||
@@ -1010,8 +1193,21 @@ static bool ts_query_cursor__first_in_progress_capture(
static bool ts_query__cursor_add_state(
TSQueryCursor *self,
- const PatternEntry *slice
+ const PatternEntry *pattern
) {
+ QueryStep *step = &self->query->steps.contents[pattern->step_index];
+
+ // If this pattern begins with a repetition, then avoid creating
+ // new states after already matching the repetition one or more times.
+ // The query should only one match for the repetition - the one that
+ // started the earliest.
+ if (step->is_repeated) {
+ for (unsigned i = 0; i < self->states.size; i++) {
+ QueryState *state = &self->states.contents[i];
+ if (state->step_index == pattern->step_index) return true;
+ }
+ }
+
uint32_t list_id = capture_list_pool_acquire(&self->capture_list_pool);
// If there are no capture lists left in the pool, then terminate whichever
@@ -1037,14 +1233,20 @@ static bool ts_query__cursor_add_state(
}
}
- LOG(" start state. pattern:%u\n", slice->pattern_index);
+ LOG(
+ " start state. pattern:%u, step:%u\n",
+ pattern->pattern_index,
+ pattern->step_index
+ );
array_push(&self->states, ((QueryState) {
.capture_list_id = list_id,
- .step_index = slice->step_index,
- .pattern_index = slice->pattern_index,
- .start_depth = self->depth,
- .capture_count = 0,
+ .step_index = pattern->step_index,
+ .pattern_index = pattern->pattern_index,
+ .start_depth = self->depth - step->depth,
.consumed_capture_count = 0,
+ .repeat_match_count = 0,
+ .step_index_on_failure = NONE,
+ .seeking_non_match = false,
}));
return true;
}
@@ -1058,15 +1260,15 @@ static QueryState *ts_query__cursor_copy_state(
array_push(&self->states, *state);
QueryState *new_state = array_back(&self->states);
new_state->capture_list_id = new_list_id;
- TSQueryCapture *old_captures = capture_list_pool_get(
+ CaptureList *old_captures = capture_list_pool_get(
&self->capture_list_pool,
state->capture_list_id
);
- TSQueryCapture *new_captures = capture_list_pool_get(
+ CaptureList *new_captures = capture_list_pool_get(
&self->capture_list_pool,
new_list_id
);
- memcpy(new_captures, old_captures, state->capture_count * sizeof(TSQueryCapture));
+ array_push_all(new_captures, old_captures);
return new_state;
}
@@ -1113,15 +1315,16 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) {
return self->finished_states.size > 0;
}
} else {
- bool can_have_later_siblings;
+ bool has_later_siblings;
bool can_have_later_siblings_with_this_field;
TSFieldId field_id = ts_tree_cursor_current_status(
&self->cursor,
- &can_have_later_siblings,
+ &has_later_siblings,
&can_have_later_siblings_with_this_field
);
TSNode node = ts_tree_cursor_current_node(&self->cursor);
TSSymbol symbol = ts_node_symbol(node);
+ bool is_named = ts_node_is_named(node);
if (symbol != ts_builtin_sym_error && self->query->symbol_map) {
symbol = self->query->symbol_map[symbol];
}
@@ -1145,43 +1348,46 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) {
) return false;
LOG(
- "enter node. type:%s, field:%s, row:%u state_count:%u, finished_state_count:%u, can_have_later_siblings:%d, can_have_later_siblings_with_this_field:%d\n",
+ "enter node. "
+ "type:%s, field:%s, row:%u state_count:%u, "
+ "finished_state_count:%u, has_later_siblings:%d, "
+ "can_have_later_siblings_with_this_field:%d\n",
ts_node_type(node),
ts_language_field_name_for_id(self->query->language, field_id),
ts_node_start_point(node).row,
self->states.size,
self->finished_states.size,
- can_have_later_siblings,
+ has_later_siblings,
can_have_later_siblings_with_this_field
);
// Add new states for any patterns whose root node is a wildcard.
for (unsigned i = 0; i < self->query->wildcard_root_pattern_count; i++) {
- PatternEntry *slice = &self->query->pattern_map.contents[i];
- QueryStep *step = &self->query->steps.contents[slice->step_index];
+ PatternEntry *pattern = &self->query->pattern_map.contents[i];
+ QueryStep *step = &self->query->steps.contents[pattern->step_index];
// If this node matches the first step of the pattern, then add a new
// state at the start of this pattern.
if (step->field && field_id != step->field) continue;
- if (!ts_query__cursor_add_state(self, slice)) break;
+ if (!ts_query__cursor_add_state(self, pattern)) break;
}
// Add new states for any patterns whose root node matches this node.
unsigned i;
if (ts_query__pattern_map_search(self->query, symbol, &i)) {
- PatternEntry *slice = &self->query->pattern_map.contents[i];
- QueryStep *step = &self->query->steps.contents[slice->step_index];
+ PatternEntry *pattern = &self->query->pattern_map.contents[i];
+ QueryStep *step = &self->query->steps.contents[pattern->step_index];
do {
// If this node matches the first step of the pattern, then add a new
// state at the start of this pattern.
if (step->field && field_id != step->field) continue;
- if (!ts_query__cursor_add_state(self, slice)) break;
+ if (!ts_query__cursor_add_state(self, pattern)) break;
// Advance to the next pattern whose root node matches this node.
i++;
if (i == self->query->pattern_map.size) break;
- slice = &self->query->pattern_map.contents[i];
- step = &self->query->steps.contents[slice->step_index];
+ pattern = &self->query->pattern_map.contents[i];
+ step = &self->query->steps.contents[pattern->step_index];
} while (step->symbol == symbol);
}
@@ -1191,14 +1397,23 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) {
QueryStep *step = &self->query->steps.contents[state->step_index];
// Check that the node matches all of the criteria for the next
- // step of the pattern.if (
+ // step of the pattern.
if ((uint32_t)state->start_depth + (uint32_t)step->depth != self->depth) continue;
// Determine if this node matches this step of the pattern, and also
// if this node can have later siblings that match this step of the
// pattern.
- bool node_does_match = !step->symbol || step->symbol == symbol;
- bool later_sibling_can_match = can_have_later_siblings;
+ bool node_does_match =
+ step->symbol == symbol ||
+ step->symbol == WILDCARD_SYMBOL ||
+ (step->symbol == NAMED_WILDCARD_SYMBOL && is_named);
+ bool later_sibling_can_match = has_later_siblings;
+ if (step->is_immediate && is_named) {
+ later_sibling_can_match = false;
+ }
+ if (step->is_last && has_later_siblings) {
+ node_does_match = false;
+ }
if (step->field) {
if (step->field == field_id) {
if (!can_have_later_siblings_with_this_field) {
@@ -1210,6 +1425,24 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) {
}
if (!node_does_match) {
+ // If this QueryState has processed a repeating sequence, and that repeating
+ // sequence has ended, move on to the *next* step of this state's pattern.
+ if (
+ state->step_index_on_failure != NONE &&
+ (!later_sibling_can_match || step->is_repeated)
+ ) {
+ LOG(
+ " finish repetition state. pattern:%u, step:%u\n",
+ state->pattern_index,
+ state->step_index
+ );
+ state->step_index = state->step_index_on_failure;
+ state->step_index_on_failure = NONE;
+ state->repeat_match_count = 0;
+ i--;
+ continue;
+ }
+
if (!later_sibling_can_match) {
LOG(
" discard state. pattern:%u, step:%u\n",
@@ -1224,9 +1457,17 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) {
i--;
n--;
}
+
+ state->seeking_non_match = false;
continue;
}
+ // The `seeking_non_match` flag indicates that a previous QueryState
+ // has already begun processing this repeating sequence, so that *this*
+ // QueryState should not begin matching until a separate repeating sequence
+ // is found.
+ if (state->seeking_non_match) continue;
+
// Some patterns can match their root node in multiple ways,
// capturing different children. If this pattern step could match
// later children within the same parent, then this query state
@@ -1236,11 +1477,20 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) {
// siblings.
QueryState *next_state = state;
if (
- step->depth > 0 &&
+ !step->is_pattern_start &&
step->contains_captures &&
- later_sibling_can_match
+ later_sibling_can_match &&
+ state->repeat_match_count == 0
) {
QueryState *copy = ts_query__cursor_copy_state(self, state);
+
+ // The QueryState that matched this node has begun matching a repeating
+ // sequence. The QueryState that *skipped* this node should not start
+ // matching later elements of the same repeating sequence.
+ if (step->is_repeated) {
+ state->seeking_non_match = true;
+ }
+
if (copy) {
LOG(
" split state. pattern:%u, step:%u\n",
@@ -1249,53 +1499,71 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) {
);
next_state = copy;
} else {
- LOG(" canot split state.\n");
+ LOG(" cannot split state.\n");
}
}
- LOG(
- " advance state. pattern:%u, step:%u\n",
- next_state->pattern_index,
- next_state->step_index
- );
-
// If the current node is captured in this pattern, add it to the
// capture list.
- if (step->capture_id != NONE) {
- LOG(
- " capture node. pattern:%u, capture_id:%u\n",
- next_state->pattern_index,
- step->capture_id
- );
- TSQueryCapture *capture_list = capture_list_pool_get(
+ for (unsigned j = 0; j < MAX_STEP_CAPTURE_COUNT; j++) {
+ uint16_t capture_id = step->capture_ids[j];
+ if (step->capture_ids[j] == NONE) break;
+ CaptureList *capture_list = capture_list_pool_get(
&self->capture_list_pool,
next_state->capture_list_id
);
- capture_list[next_state->capture_count++] = (TSQueryCapture) {
+ array_push(capture_list, ((TSQueryCapture) {
node,
- step->capture_id
- };
+ capture_id
+ }));
+ LOG(
+ " capture node. pattern:%u, capture_id:%u, capture_count:%u\n",
+ next_state->pattern_index,
+ capture_id,
+ capture_list->size
+ );
}
- // If the pattern is now done, then remove it from the list of
- // in-progress states, and add it to the list of finished states.
- next_state->step_index++;
- QueryStep *next_step = step + 1;
- if (next_step->depth == PATTERN_DONE_MARKER) {
- LOG(" finish pattern %u\n", next_state->pattern_index);
+ // If this is the end of a repetition, then jump back to the beginning
+ // of that repetition.
+ if (step->repeat_step_index != NONE) {
+ next_state->step_index_on_failure = next_state->step_index + 1;
+ next_state->step_index = step->repeat_step_index;
+ next_state->repeat_match_count++;
+ LOG(
+ " continue repeat. pattern:%u, match_count:%u\n",
+ next_state->pattern_index,
+ next_state->repeat_match_count
+ );
+ } else {
+ next_state->step_index++;
+ LOG(
+ " advance state. pattern:%u, step:%u\n",
+ next_state->pattern_index,
+ next_state->step_index
+ );
- next_state->id = self->next_state_id++;
- array_push(&self->finished_states, *next_state);
- if (next_state == state) {
- array_erase(&self->states, i);
- i--;
- n--;
- } else {
- self->states.size--;
+ QueryStep *next_step = step + 1;
+
+ // If the pattern is now done, then remove it from the list of
+ // in-progress states, and add it to the list of finished states.
+ if (next_step->depth == PATTERN_DONE_MARKER) {
+ LOG(" finish pattern %u\n", next_state->pattern_index);
+
+ next_state->id = self->next_state_id++;
+ array_push(&self->finished_states, *next_state);
+ if (next_state == state) {
+ array_erase(&self->states, i);
+ i--;
+ n--;
+ } else {
+ self->states.size--;
+ }
}
}
}
+
// Continue descending if possible.
if (ts_tree_cursor_goto_first_child(&self->cursor)) {
self->depth++;
@@ -1321,11 +1589,12 @@ bool ts_query_cursor_next_match(
QueryState *state = &self->finished_states.contents[0];
match->id = state->id;
match->pattern_index = state->pattern_index;
- match->capture_count = state->capture_count;
- match->captures = capture_list_pool_get(
+ CaptureList *captures = capture_list_pool_get(
&self->capture_list_pool,
state->capture_list_id
);
+ match->captures = captures->contents;
+ match->capture_count = captures->size;
capture_list_pool_release(&self->capture_list_pool, state->capture_list_id);
array_erase(&self->finished_states, 0);
return true;
@@ -1378,13 +1647,13 @@ bool ts_query_cursor_next_capture(
uint32_t first_finished_pattern_index = first_unfinished_pattern_index;
for (unsigned i = 0; i < self->finished_states.size; i++) {
const QueryState *state = &self->finished_states.contents[i];
- if (state->capture_count > state->consumed_capture_count) {
- const TSQueryCapture *captures = capture_list_pool_get(
- &self->capture_list_pool,
- state->capture_list_id
- );
+ CaptureList *captures = capture_list_pool_get(
+ &self->capture_list_pool,
+ state->capture_list_id
+ );
+ if (captures->size > state->consumed_capture_count) {
uint32_t capture_byte = ts_node_start_byte(
- captures[state->consumed_capture_count].node
+ captures->contents[state->consumed_capture_count].node
);
if (
capture_byte < first_finished_capture_byte ||
@@ -1416,11 +1685,12 @@ bool ts_query_cursor_next_capture(
];
match->id = state->id;
match->pattern_index = state->pattern_index;
- match->capture_count = state->capture_count;
- match->captures = capture_list_pool_get(
+ CaptureList *captures = capture_list_pool_get(
&self->capture_list_pool,
state->capture_list_id
);
+ match->captures = captures->contents;
+ match->capture_count = captures->size;
*capture_index = state->consumed_capture_count;
state->consumed_capture_count++;
return true;
diff --git a/src/tree_sitter/stack.c b/src/tree_sitter/stack.c
index 3e842c99c3..ade1577566 100644
--- a/src/tree_sitter/stack.c
+++ b/src/tree_sitter/stack.c
@@ -11,7 +11,7 @@
#define MAX_NODE_POOL_SIZE 50
#define MAX_ITERATOR_COUNT 64
-#ifdef _WIN32
+#if defined _WIN32 && !defined __GNUC__
#define inline __forceinline
#else
#define inline static inline __attribute__((always_inline))
diff --git a/src/tree_sitter/subtree.c b/src/tree_sitter/subtree.c
index 30144fa175..b98f172339 100644
--- a/src/tree_sitter/subtree.c
+++ b/src/tree_sitter/subtree.c
@@ -322,12 +322,9 @@ void ts_subtree_balance(Subtree self, SubtreePool *pool, const TSLanguage *langu
if (tree.ptr->repeat_depth > 0) {
Subtree child1 = tree.ptr->children[0];
Subtree child2 = tree.ptr->children[tree.ptr->child_count - 1];
- if (
- ts_subtree_child_count(child1) > 0 &&
- ts_subtree_child_count(child2) > 0 &&
- child1.ptr->repeat_depth > child2.ptr->repeat_depth
- ) {
- unsigned n = child1.ptr->repeat_depth - child2.ptr->repeat_depth;
+ long repeat_delta = (long)ts_subtree_repeat_depth(child1) - (long)ts_subtree_repeat_depth(child2);
+ if (repeat_delta > 0) {
+ unsigned n = repeat_delta;
for (unsigned i = n / 2; i > 0; i /= 2) {
ts_subtree__compress(tree, i, language, &pool->tree_stack);
n -= i;
@@ -344,10 +341,6 @@ void ts_subtree_balance(Subtree self, SubtreePool *pool, const TSLanguage *langu
}
}
-static inline uint32_t ts_subtree_repeat_depth(Subtree self) {
- return ts_subtree_child_count(self) ? self.ptr->repeat_depth : 0;
-}
-
void ts_subtree_set_children(
MutableSubtree self, Subtree *children, uint32_t child_count, const TSLanguage *language
) {
diff --git a/src/tree_sitter/subtree.h b/src/tree_sitter/subtree.h
index 79ccd92390..18c48dcbd0 100644
--- a/src/tree_sitter/subtree.h
+++ b/src/tree_sitter/subtree.h
@@ -206,6 +206,10 @@ static inline uint32_t ts_subtree_child_count(Subtree self) {
return self.data.is_inline ? 0 : self.ptr->child_count;
}
+static inline uint32_t ts_subtree_repeat_depth(Subtree self) {
+ return self.data.is_inline ? 0 : self.ptr->repeat_depth;
+}
+
static inline uint32_t ts_subtree_node_count(Subtree self) {
return (self.data.is_inline || self.ptr->child_count == 0) ? 1 : self.ptr->node_count;
}
diff --git a/src/tree_sitter/utf16.c b/src/tree_sitter/utf16.c
deleted file mode 100644
index 3956c01cb9..0000000000
--- a/src/tree_sitter/utf16.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "./utf16.h"
-
-utf8proc_ssize_t utf16_iterate(
- const utf8proc_uint8_t *string,
- utf8proc_ssize_t length,
- utf8proc_int32_t *code_point
-) {
- if (length < 2) {
- *code_point = -1;
- return 0;
- }
-
- uint16_t *units = (uint16_t *)string;
- uint16_t unit = units[0];
-
- if (unit < 0xd800 || unit >= 0xe000) {
- *code_point = unit;
- return 2;
- }
-
- if (unit < 0xdc00) {
- if (length >= 4) {
- uint16_t next_unit = units[1];
- if (next_unit >= 0xdc00 && next_unit < 0xe000) {
- *code_point = 0x10000 + ((unit - 0xd800) << 10) + (next_unit - 0xdc00);
- return 4;
- }
- }
- }
-
- *code_point = -1;
- return 2;
-}
diff --git a/src/tree_sitter/utf16.h b/src/tree_sitter/utf16.h
deleted file mode 100644
index 32fd05e6db..0000000000
--- a/src/tree_sitter/utf16.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef TREE_SITTER_UTF16_H_
-#define TREE_SITTER_UTF16_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <stdlib.h>
-#include "utf8proc.h"
-
-// Analogous to utf8proc's utf8proc_iterate function. Reads one code point from
-// the given UTF16 string and stores it in the location pointed to by `code_point`.
-// Returns the number of bytes in `string` that were read.
-utf8proc_ssize_t utf16_iterate(const utf8proc_uint8_t *, utf8proc_ssize_t, utf8proc_int32_t *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // TREE_SITTER_UTF16_H_