aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/api.txt2
-rw-r--r--runtime/doc/news.txt2
-rw-r--r--src/nvim/api/autocmd.c16
-rw-r--r--src/nvim/api/buffer.c2
-rw-r--r--src/nvim/api/command.c4
-rw-r--r--src/nvim/api/extmark.c16
-rw-r--r--src/nvim/api/options.c2
-rw-r--r--src/nvim/api/private/helpers.c10
-rw-r--r--src/nvim/api/private/helpers.h4
-rw-r--r--src/nvim/api/ui.c2
-rw-r--r--src/nvim/api/vim.c8
-rw-r--r--src/nvim/api/vimscript.c10
-rw-r--r--src/nvim/api/win_config.c8
-rw-r--r--src/nvim/buffer_defs.h1
-rw-r--r--src/nvim/channel.c8
-rw-r--r--src/nvim/charset.c15
-rw-r--r--src/nvim/cursor_shape.c4
-rw-r--r--src/nvim/decoration.c7
-rw-r--r--src/nvim/decoration.h4
-rw-r--r--src/nvim/drawline.c226
-rw-r--r--src/nvim/edit.c4
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/ex_cmds.c27
-rw-r--r--src/nvim/ex_getln.c4
-rw-r--r--src/nvim/extmark.c3
-rw-r--r--src/nvim/fileio.c3
-rw-r--r--src/nvim/generators/gen_ex_cmds.lua1
-rw-r--r--src/nvim/grid.c3
-rw-r--r--src/nvim/highlight.c14
-rw-r--r--src/nvim/highlight_group.c17
-rw-r--r--src/nvim/lua/executor.c91
-rw-r--r--src/nvim/lua/secure.c118
-rw-r--r--src/nvim/lua/secure.h12
-rw-r--r--src/nvim/main.c1
-rw-r--r--src/nvim/mapping.c10
-rw-r--r--src/nvim/mbyte.c18
-rw-r--r--src/nvim/message.c4
-rw-r--r--src/nvim/msgpack_rpc/channel.c4
-rw-r--r--src/nvim/normal.c2
-rw-r--r--src/nvim/option.c4
-rw-r--r--src/nvim/os/process.c2
-rw-r--r--src/nvim/plines.c85
-rw-r--r--src/nvim/plines.h6
-rw-r--r--src/nvim/popupmenu.c8
-rw-r--r--src/nvim/runtime.c4
-rw-r--r--src/nvim/shada.c6
-rw-r--r--src/nvim/statusline.c2
-rw-r--r--src/nvim/tui/input.c4
-rw-r--r--src/nvim/tui/tui.c10
-rw-r--r--src/nvim/ui.c4
-rw-r--r--src/nvim/ui_client.c4
-rw-r--r--src/nvim/usercmd.c22
-rw-r--r--test/README.md2
-rw-r--r--test/busted/outputHandlers/nvim.lua8
-rw-r--r--test/functional/api/buffer_spec.lua14
-rw-r--r--test/functional/api/extmark_spec.lua4
-rw-r--r--test/functional/api/highlight_spec.lua5
-rw-r--r--test/functional/api/vim_spec.lua4
-rw-r--r--test/functional/api/window_spec.lua6
-rw-r--r--test/functional/ex_cmds/append_spec.lua2
-rw-r--r--test/functional/ex_cmds/mksession_spec.lua6
-rw-r--r--test/functional/legacy/012_directory_spec.lua4
-rw-r--r--test/functional/lua/buffer_updates_spec.lua8
-rw-r--r--test/functional/lua/filetype_spec.lua2
-rw-r--r--test/functional/lua/luaeval_spec.lua2
-rw-r--r--test/functional/lua/runtime_spec.lua32
-rw-r--r--test/functional/lua/secure_spec.lua2
-rw-r--r--test/functional/lua/vim_spec.lua6
-rw-r--r--test/functional/plugin/lsp/incremental_sync_spec.lua2
-rw-r--r--test/functional/plugin/shada_spec.lua30
-rw-r--r--test/functional/provider/perl_spec.lua2
-rw-r--r--test/functional/provider/ruby_spec.lua2
-rw-r--r--test/functional/shada/buffers_spec.lua4
-rw-r--r--test/functional/terminal/scrollback_spec.lua38
-rw-r--r--test/functional/terminal/tui_spec.lua4
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua2
-rw-r--r--test/functional/ui/decorations_spec.lua887
-rw-r--r--test/functional/ui/spell_spec.lua15
-rw-r--r--test/functional/vimscript/buf_functions_spec.lua2
79 files changed, 1555 insertions, 390 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index e7cda59906..f399f1ed25 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -2608,6 +2608,8 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {*opts})
• "overlay": display over the specified column, without
shifting the underlying text.
• "right_align": display right aligned in the window.
+ • "inline": display at the specified column, and shift the
+ buffer text to the right as needed
• virt_text_win_col : position the virtual text at a fixed
window column (starting from the first text column)
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 9f6ab2ddd0..5690dbf3bc 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -56,6 +56,8 @@ The following new APIs or features were added.
• |Query:iter_matches()| now has the ability to set the maximum start depth
for matches.
+• Added inline virtual text support to |nvim_buf_set_extmark()|.
+
==============================================================================
CHANGED FEATURES *news-changed*
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c
index 6ecbff2606..14937cfd8f 100644
--- a/src/nvim/api/autocmd.c
+++ b/src/nvim/api/autocmd.c
@@ -293,17 +293,17 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err)
break;
case kCallbackFuncref:
case kCallbackPartial:
- PUT(autocmd_info, "callback", STRING_OBJ(cstr_as_string(callback_to_string(cb))));
+ PUT(autocmd_info, "callback", CSTR_AS_OBJ(callback_to_string(cb)));
break;
default:
abort();
}
} else {
- PUT(autocmd_info, "command", STRING_OBJ(cstr_as_string(xstrdup(ac->exec.callable.cmd))));
+ PUT(autocmd_info, "command", CSTR_TO_OBJ(ac->exec.callable.cmd));
}
- PUT(autocmd_info, "pattern", STRING_OBJ(cstr_to_string(ap->pat)));
- PUT(autocmd_info, "event", STRING_OBJ(cstr_to_string(event_nr2name(event))));
+ PUT(autocmd_info, "pattern", CSTR_TO_OBJ(ap->pat));
+ PUT(autocmd_info, "event", CSTR_TO_OBJ(event_nr2name(event)));
PUT(autocmd_info, "once", BOOLEAN_OBJ(ac->once));
if (ap->buflocal_nr) {
@@ -475,7 +475,7 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc
}
if (patterns.size == 0) {
- ADD(patterns, STRING_OBJ(STATIC_CSTR_TO_STRING("*")));
+ ADD(patterns, STATIC_CSTR_TO_OBJ("*"));
}
VALIDATE_R((event_array.size > 0), "event", {
@@ -587,7 +587,7 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err)
// When we create the autocmds, we want to say that they are all matched, so that's *
// but when we clear them, we want to say that we didn't pass a pattern, so that's NUL
if (patterns.size == 0) {
- ADD(patterns, STRING_OBJ(STATIC_CSTR_TO_STRING("")));
+ ADD(patterns, STATIC_CSTR_TO_OBJ(""));
}
// If we didn't pass any events, that means clear all events.
@@ -763,7 +763,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err)
}
if (patterns.size == 0) {
- ADD(patterns, STRING_OBJ(STATIC_CSTR_TO_STRING("")));
+ ADD(patterns, STATIC_CSTR_TO_OBJ(""));
}
if (HAS_KEY(opts->data)) {
@@ -894,7 +894,7 @@ static bool get_patterns_from_pattern_or_buf(Array *patterns, Object pattern, Ob
}
snprintf((char *)pattern_buflocal, BUFLOCAL_PAT_LEN, "<buffer=%d>", (int)buf->handle);
- ADD(*patterns, STRING_OBJ(cstr_to_string(pattern_buflocal)));
+ ADD(*patterns, CSTR_TO_OBJ(pattern_buflocal));
}
return true;
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 10c684941c..82a62c3192 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -518,7 +518,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In
{
MAXSIZE_TEMP_ARRAY(scratch, 1);
if (replacement.size == 0) {
- ADD_C(scratch, STRING_OBJ(STATIC_CSTR_AS_STRING("")));
+ ADD_C(scratch, STATIC_CSTR_AS_OBJ(""));
replacement = scratch;
}
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c
index b1603c5d6e..6d715bcf46 100644
--- a/src/nvim/api/command.c
+++ b/src/nvim/api/command.c
@@ -245,7 +245,7 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err)
Dictionary filter = ARRAY_DICT_INIT;
PUT(filter, "pattern", cmdinfo.cmdmod.cmod_filter_pat
? CSTR_TO_OBJ(cmdinfo.cmdmod.cmod_filter_pat)
- : STRING_OBJ(STATIC_CSTR_TO_STRING("")));
+ : STATIC_CSTR_TO_OBJ(""));
PUT(filter, "force", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_filter_force));
PUT(mods, "filter", DICTIONARY_OBJ(filter));
@@ -438,7 +438,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
break;
}
- ADD(args, STRING_OBJ(cstr_as_string(data_str)));
+ ADD(args, CSTR_AS_OBJ(data_str));
}
bool argc_valid;
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index d6f0288f94..299413e510 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -106,7 +106,7 @@ bool ns_initialized(uint32_t ns)
static Object hl_group_name(int hl_id, bool hl_name)
{
if (hl_name) {
- return STRING_OBJ(cstr_to_string(syn_id2name(hl_id)));
+ return CSTR_TO_OBJ(syn_id2name(hl_id));
} else {
return INTEGER_OBJ(hl_id);
}
@@ -140,7 +140,7 @@ static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict
PUT(dict, "hl_eol", BOOLEAN_OBJ(decor->hl_eol));
}
if (decor->hl_mode) {
- PUT(dict, "hl_mode", STRING_OBJ(cstr_to_string(hl_mode_str[decor->hl_mode])));
+ PUT(dict, "hl_mode", CSTR_TO_OBJ(hl_mode_str[decor->hl_mode]));
}
if (kv_size(decor->virt_text)) {
@@ -148,7 +148,7 @@ static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict
for (size_t i = 0; i < decor->virt_text.size; i++) {
Array chunk = ARRAY_DICT_INIT;
VirtTextChunk *vtc = &decor->virt_text.items[i];
- ADD(chunk, STRING_OBJ(cstr_to_string(vtc->text)));
+ ADD(chunk, CSTR_TO_OBJ(vtc->text));
if (vtc->hl_id > 0) {
ADD(chunk, hl_group_name(vtc->hl_id, hl_name));
}
@@ -160,7 +160,7 @@ static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict
PUT(dict, "virt_text_win_col", INTEGER_OBJ(decor->col));
}
PUT(dict, "virt_text_pos",
- STRING_OBJ(cstr_to_string(virt_text_pos_str[decor->virt_text_pos])));
+ CSTR_TO_OBJ(virt_text_pos_str[decor->virt_text_pos]));
}
if (decor->ui_watched) {
@@ -177,7 +177,7 @@ static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict
for (size_t j = 0; j < vt->size; j++) {
Array chunk = ARRAY_DICT_INIT;
VirtTextChunk *vtc = &vt->items[j];
- ADD(chunk, STRING_OBJ(cstr_to_string(vtc->text)));
+ ADD(chunk, CSTR_TO_OBJ(vtc->text));
if (vtc->hl_id > 0) {
ADD(chunk, hl_group_name(vtc->hl_id, hl_name));
}
@@ -191,7 +191,7 @@ static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict
}
if (decor->sign_text) {
- PUT(dict, "sign_text", STRING_OBJ(cstr_to_string(decor->sign_text)));
+ PUT(dict, "sign_text", CSTR_TO_OBJ(decor->sign_text));
}
// uncrustify:off
@@ -477,6 +477,8 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// - "overlay": display over the specified column, without
/// shifting the underlying text.
/// - "right_align": display right aligned in the window.
+/// - "inline": display at the specified column, and
+/// shift the buffer text to the right as needed
/// - virt_text_win_col : position the virtual text at a fixed
/// window column (starting from the first
/// text column)
@@ -695,6 +697,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
decor.virt_text_pos = kVTOverlay;
} else if (strequal("right_align", str.data)) {
decor.virt_text_pos = kVTRightAlign;
+ } else if (strequal("inline", str.data)) {
+ decor.virt_text_pos = kVTInline;
} else {
VALIDATE_S(false, "virt_text_pos", "", {
goto error;
diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c
index 6193a5c75b..e18312a6dc 100644
--- a/src/nvim/api/options.c
+++ b/src/nvim/api/options.c
@@ -188,7 +188,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
switch (result) {
case gov_string:
- rv = STRING_OBJ(cstr_as_string(stringval));
+ rv = CSTR_AS_OBJ(stringval);
break;
case gov_number:
rv = INTEGER_OBJ(numval);
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 02060a8950..2544809553 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -660,10 +660,10 @@ static void init_ui_event_metadata(Dictionary *metadata)
msgpack_unpacked_destroy(&unpacked);
PUT(*metadata, "ui_events", ui_events);
Array ui_options = ARRAY_DICT_INIT;
- ADD(ui_options, STRING_OBJ(cstr_to_string("rgb")));
+ ADD(ui_options, CSTR_TO_OBJ("rgb"));
for (UIExtension i = 0; i < kUIExtCount; i++) {
if (ui_ext_names[i][0] != '_') {
- ADD(ui_options, STRING_OBJ(cstr_to_string(ui_ext_names[i])));
+ ADD(ui_options, CSTR_TO_OBJ(ui_ext_names[i]));
}
}
PUT(*metadata, "ui_options", ARRAY_OBJ(ui_options));
@@ -692,17 +692,17 @@ static void init_type_metadata(Dictionary *metadata)
Dictionary buffer_metadata = ARRAY_DICT_INIT;
PUT(buffer_metadata, "id",
INTEGER_OBJ(kObjectTypeBuffer - EXT_OBJECT_TYPE_SHIFT));
- PUT(buffer_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_buf_")));
+ PUT(buffer_metadata, "prefix", CSTR_TO_OBJ("nvim_buf_"));
Dictionary window_metadata = ARRAY_DICT_INIT;
PUT(window_metadata, "id",
INTEGER_OBJ(kObjectTypeWindow - EXT_OBJECT_TYPE_SHIFT));
- PUT(window_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_win_")));
+ PUT(window_metadata, "prefix", CSTR_TO_OBJ("nvim_win_"));
Dictionary tabpage_metadata = ARRAY_DICT_INIT;
PUT(tabpage_metadata, "id",
INTEGER_OBJ(kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT));
- PUT(tabpage_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_tabpage_")));
+ PUT(tabpage_metadata, "prefix", CSTR_TO_OBJ("nvim_tabpage_"));
PUT(types, "Buffer", DICTIONARY_OBJ(buffer_metadata));
PUT(types, "Window", DICTIONARY_OBJ(window_metadata));
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index bac501ed62..a9cfaeae22 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -34,6 +34,7 @@
.type = kObjectTypeString, \
.data.string = s })
+#define CSTR_AS_OBJ(s) STRING_OBJ(cstr_as_string(s))
#define CSTR_TO_OBJ(s) STRING_OBJ(cstr_to_string(s))
#define BUFFER_OBJ(s) ((Object) { \
@@ -103,6 +104,9 @@
.data = xmemdupz(s, sizeof(s) - 1), \
.size = sizeof(s) - 1 })
+#define STATIC_CSTR_AS_OBJ(s) STRING_OBJ(STATIC_CSTR_AS_STRING(s))
+#define STATIC_CSTR_TO_OBJ(s) STRING_OBJ(STATIC_CSTR_TO_STRING(s))
+
// Helpers used by the generated msgpack-rpc api wrappers
#define api_init_boolean
#define api_init_integer
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 532c3054ab..e98c589189 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -795,7 +795,7 @@ void remote_ui_put(UI *ui, const char *cell)
UIData *data = ui->data;
data->client_col++;
Array args = data->call_buf;
- ADD_C(args, STRING_OBJ(cstr_as_string((char *)cell)));
+ ADD_C(args, CSTR_AS_OBJ((char *)cell));
push_call(ui, "put", args);
}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index d47f47e638..36163859eb 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -531,7 +531,7 @@ static void find_runtime_cb(char *fname, void *cookie)
{
Array *rv = (Array *)cookie;
if (fname != NULL) {
- ADD(*rv, STRING_OBJ(cstr_to_string(fname)));
+ ADD(*rv, CSTR_TO_OBJ(fname));
}
}
@@ -1383,7 +1383,7 @@ Dictionary nvim_get_mode(void)
get_mode(modestr);
bool blocked = input_blocking();
- PUT(rv, "mode", STRING_OBJ(cstr_to_string(modestr)));
+ PUT(rv, "mode", CSTR_TO_OBJ(modestr));
PUT(rv, "blocking", BOOLEAN_OBJ(blocked));
return rv;
@@ -1926,7 +1926,7 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E
}
ret = arena_array(arena, 3);
size_t off = g->line_offset[(size_t)row] + (size_t)col;
- ADD_C(ret, STRING_OBJ(cstr_as_string((char *)g->chars[off])));
+ ADD_C(ret, CSTR_AS_OBJ((char *)g->chars[off]));
int attr = g->attrs[off];
ADD_C(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, arena, err)));
// will not work first time
@@ -2035,7 +2035,7 @@ Array nvim_get_mark(String name, Dictionary opts, Error *err)
ADD(rv, INTEGER_OBJ(row));
ADD(rv, INTEGER_OBJ(col));
ADD(rv, INTEGER_OBJ(bufnr));
- ADD(rv, STRING_OBJ(cstr_to_string(filename)));
+ ADD(rv, CSTR_TO_OBJ(filename));
if (allocated) {
xfree(filename);
diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c
index 208aa165c9..1a67be8860 100644
--- a/src/nvim/api/vimscript.c
+++ b/src/nvim/api/vimscript.c
@@ -502,7 +502,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, E
};
err_dict.items[0] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("message"),
- .value = STRING_OBJ(cstr_to_string(east.err.msg)),
+ .value = CSTR_TO_OBJ(east.err.msg),
};
if (east.err.arg == NULL) {
err_dict.items[1] = (KeyValuePair) {
@@ -539,7 +539,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, E
chunk_arr.items[0] = INTEGER_OBJ((Integer)chunk.start.line);
chunk_arr.items[1] = INTEGER_OBJ((Integer)chunk.start.col);
chunk_arr.items[2] = INTEGER_OBJ((Integer)chunk.end_col);
- chunk_arr.items[3] = STRING_OBJ(cstr_to_string(chunk.group));
+ chunk_arr.items[3] = CSTR_TO_OBJ(chunk.group);
hl.items[i] = ARRAY_OBJ(chunk_arr);
}
ret.items[ret.size++] = (KeyValuePair) {
@@ -616,7 +616,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, E
kv_drop(ast_conv_stack, 1);
ret_node->items[ret_node->size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("type"),
- .value = STRING_OBJ(cstr_to_string(east_node_type_tab[node->type])),
+ .value = CSTR_TO_OBJ(east_node_type_tab[node->type]),
};
Array start_array = {
.items = xmalloc(2 * sizeof(start_array.items[0])),
@@ -701,11 +701,11 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, E
case kExprNodeComparison:
ret_node->items[ret_node->size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("cmp_type"),
- .value = STRING_OBJ(cstr_to_string(eltkn_cmp_type_tab[node->data.cmp.type])),
+ .value = CSTR_TO_OBJ(eltkn_cmp_type_tab[node->data.cmp.type]),
};
ret_node->items[ret_node->size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("ccs_strategy"),
- .value = STRING_OBJ(cstr_to_string(ccs_tab[node->data.cmp.ccs])),
+ .value = CSTR_TO_OBJ(ccs_tab[node->data.cmp.ccs]),
};
ret_node->items[ret_node->size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("invert"),
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index c267fee39a..8e4fbb6779 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -267,7 +267,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
PUT(rv, "bufpos", ARRAY_OBJ(pos));
}
}
- PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor])));
+ PUT(rv, "anchor", CSTR_TO_OBJ(float_anchor_str[config->anchor]));
PUT(rv, "row", FLOAT_OBJ(config->row));
PUT(rv, "col", FLOAT_OBJ(config->col));
PUT(rv, "zindex", INTEGER_OBJ(config->zindex));
@@ -283,7 +283,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
char *hi_name = syn_id2name(hi_id);
if (hi_name[0]) {
ADD(tuple, STRING_OBJ(s));
- ADD(tuple, STRING_OBJ(cstr_to_string(hi_name)));
+ ADD(tuple, CSTR_TO_OBJ(hi_name));
ADD(border, ARRAY_OBJ(tuple));
} else {
ADD(border, STRING_OBJ(s));
@@ -297,7 +297,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
Array tuple = ARRAY_DICT_INIT;
ADD(tuple, CSTR_TO_OBJ(title_datas.items[i].text));
if (title_datas.items[i].hl_id > 0) {
- ADD(tuple, STRING_OBJ(cstr_to_string(syn_id2name(title_datas.items[i].hl_id))));
+ ADD(tuple, CSTR_TO_OBJ(syn_id2name(title_datas.items[i].hl_id)));
}
ADD(titles, ARRAY_OBJ(tuple));
}
@@ -317,7 +317,7 @@ Dictionary nvim_win_get_config(Window window, Error *err)
const char *rel = (wp->w_floating && !config->external
? float_relative_str[config->relative] : "");
- PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel)));
+ PUT(rv, "relative", CSTR_TO_OBJ(rel));
return rv;
}
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index f8b26d9d16..f3f98bbd17 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -808,6 +808,7 @@ struct file_buffer {
MarkTree b_marktree[1];
Map(uint32_t, uint32_t) b_extmark_ns[1]; // extmark namespaces
+ size_t b_virt_text_inline; // number of inline virtual texts
size_t b_virt_line_blocks; // number of virt_line blocks
size_t b_signs; // number of sign extmarks
size_t b_signs_with_text; // number of sign extmarks with text
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 154b8206b8..569d3f5887 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -884,14 +884,14 @@ Dictionary channel_info(uint64_t id)
stream_desc = "job";
if (chan->stream.proc.type == kProcessTypePty) {
const char *name = pty_process_tty_name(&chan->stream.pty);
- PUT(info, "pty", STRING_OBJ(cstr_to_string(name)));
+ PUT(info, "pty", CSTR_TO_OBJ(name));
}
char **p = chan->stream.proc.argv;
Array argv = ARRAY_DICT_INIT;
if (p != NULL) {
while (*p != NULL) {
- ADD(argv, STRING_OBJ(cstr_to_string(*p)));
+ ADD(argv, CSTR_TO_OBJ(*p));
p++;
}
}
@@ -918,7 +918,7 @@ Dictionary channel_info(uint64_t id)
default:
abort();
}
- PUT(info, "stream", STRING_OBJ(cstr_to_string(stream_desc)));
+ PUT(info, "stream", CSTR_TO_OBJ(stream_desc));
if (chan->is_rpc) {
mode_desc = "rpc";
@@ -929,7 +929,7 @@ Dictionary channel_info(uint64_t id)
} else {
mode_desc = "bytes";
}
- PUT(info, "mode", STRING_OBJ(cstr_to_string(mode_desc)));
+ PUT(info, "mode", CSTR_TO_OBJ(mode_desc));
return info;
}
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 8cae831881..49890a460a 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -989,6 +989,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
}
chartabsize_T cts;
+ bool on_NUL = false;
init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line);
// This function is used very often, do some speed optimizations.
@@ -1052,8 +1053,9 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
// make sure we don't go past the end of the line
if (*cts.cts_ptr == NUL) {
- // NUL at end of line only takes one column
- incr = 1;
+ // NUL at end of line only takes one column, unless there is virtual text
+ incr = MAX(1, cts.cts_cur_text_width_left + cts.cts_cur_text_width_right);
+ on_NUL = true;
break;
}
@@ -1079,8 +1081,6 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
}
if (cursor != NULL) {
- // cursor is after inserted text
- vcol += cts.cts_cur_text_width;
if ((*ptr == TAB)
&& (State & MODE_NORMAL)
&& !wp->w_p_list
@@ -1089,6 +1089,13 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
// cursor at end
*cursor = vcol + incr - 1;
} else {
+ if (!on_NUL) {
+ // cursor is after inserted text, unless on the NUL
+ vcol += cts.cts_cur_text_width_left;
+ if ((State & MODE_INSERT) == 0) {
+ vcol += cts.cts_cur_text_width_right;
+ }
+ }
// cursor at start
*cursor = vcol + head;
}
diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c
index 428f9f28e4..4e5886406a 100644
--- a/src/nvim/cursor_shape.c
+++ b/src/nvim/cursor_shape.c
@@ -62,8 +62,8 @@ Array mode_style_array(Arena *arena)
for (int i = 0; i < SHAPE_IDX_COUNT; i++) {
cursorentry_T *cur = &shape_table[i];
Dictionary dic = arena_dict(arena, 3 + ((cur->used_for & SHAPE_CURSOR) ? 9 : 0));
- PUT_C(dic, "name", STRING_OBJ(cstr_as_string(cur->full_name)));
- PUT_C(dic, "short_name", STRING_OBJ(cstr_as_string(cur->name)));
+ PUT_C(dic, "name", CSTR_AS_OBJ(cur->full_name));
+ PUT_C(dic, "short_name", CSTR_AS_OBJ(cur->name));
if (cur->used_for & SHAPE_MOUSE) {
PUT_C(dic, "mouse_shape", INTEGER_OBJ(cur->mshape));
}
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 87e4441f32..ce1af290c1 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -83,6 +83,9 @@ void decor_redraw(buf_T *buf, int row1, int row2, Decoration *decor)
if (decor && decor_virt_pos(*decor)) {
redraw_buf_line_later(buf, row1 + 1, false);
+ if (decor->virt_text_pos == kVTInline) {
+ changed_line_display_buf(buf);
+ }
}
if (decor && kv_size(decor->virt_lines)) {
@@ -95,6 +98,10 @@ void decor_remove(buf_T *buf, int row, int row2, Decoration *decor)
{
decor_redraw(buf, row, row2, decor);
if (decor) {
+ if (kv_size(decor->virt_text) && decor->virt_text_pos == kVTInline) {
+ assert(buf->b_virt_text_inline > 0);
+ buf->b_virt_text_inline--;
+ }
if (kv_size(decor->virt_lines)) {
assert(buf->b_virt_line_blocks > 0);
buf->b_virt_line_blocks--;
diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h
index 92001d496d..95c9655742 100644
--- a/src/nvim/decoration.h
+++ b/src/nvim/decoration.h
@@ -23,9 +23,11 @@ typedef enum {
kVTOverlay,
kVTWinCol,
kVTRightAlign,
+ kVTInline,
} VirtTextPos;
-EXTERN const char *const virt_text_pos_str[] INIT(= { "eol", "overlay", "win_col", "right_align" });
+EXTERN const char *const virt_text_pos_str[] INIT(= { "eol", "overlay", "win_col", "right_align",
+ "inline" });
typedef enum {
kHlModeUnknown,
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index dc90be36be..510731a438 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -98,6 +98,7 @@ typedef struct {
int char_attr; ///< attributes for next character
int n_extra; ///< number of extra bytes
+ int n_attr; ///< chars with special attr
char *p_extra; ///< string of extra chars, plus NUL, only used
///< when c_extra and c_final are NUL
char *p_extra_free; ///< p_extra buffer that needs to be freed
@@ -105,9 +106,12 @@ typedef struct {
int c_extra; ///< extra chars, all the same
int c_final; ///< final char, mandatory if set
+ bool extra_for_extmark;
+
// saved "extra" items for when draw_state becomes WL_LINE (again)
int saved_n_extra;
char *saved_p_extra;
+ bool saved_extra_for_extmark;
int saved_c_extra;
int saved_c_final;
int saved_char_attr;
@@ -120,6 +124,14 @@ typedef struct {
int filler_lines; ///< nr of filler lines to be drawn
int filler_todo; ///< nr of filler lines still to do + 1
SignTextAttrs sattrs[SIGN_SHOW_MAX]; ///< sign attributes for the sign column
+
+ VirtText virt_inline;
+ size_t virt_inline_i;
+
+ bool reset_extra_attr;
+
+ int skip_cells; // nr of cells to skip for virtual text
+ int skipped_cells; // nr of skipped virtual text cells
} winlinevars_T;
/// for line_putchar. Contains the state that needs to be remembered from
@@ -342,12 +354,20 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode,
schar_T dummy[2];
int cells = line_putchar(buf, &s, through ? dummy : &linebuf_char[col],
max_col - col, false, vcol);
- // if we failed to emit a char, we still need to advance
- cells = MAX(cells, 1);
-
+ // If we failed to emit a char, we still need to put a space and advance.
+ if (cells < 1) {
+ schar_from_ascii(linebuf_char[col], ' ');
+ cells = 1;
+ }
for (int c = 0; c < cells; c++) {
linebuf_attr[col++] = attr;
}
+ if (col < max_col && linebuf_char[col][0] == 0) {
+ // If the left half of a double-width char is overwritten,
+ // change the right half to a space so that grid redraws properly,
+ // but don't advance the current column.
+ schar_from_ascii(linebuf_char[col], ' ');
+ }
vcol += cells;
}
return col;
@@ -843,6 +863,73 @@ static void apply_cursorline_highlight(win_T *wp, winlinevars_T *wlv)
}
}
+static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t v, bool *do_save)
+{
+ while (true) {
+ // we could already be inside an existing inline text with multiple chunks
+ if (!(wlv->virt_inline_i < kv_size(wlv->virt_inline))) {
+ DecorState *state = &decor_state;
+ for (size_t i = 0; i < kv_size(state->active); i++) {
+ DecorRange *item = &kv_A(state->active, i);
+ if (item->start_row != state->row
+ || !kv_size(item->decor.virt_text)
+ || item->decor.virt_text_pos != kVTInline) {
+ continue;
+ }
+ if (item->win_col >= -1 && item->start_col == v) {
+ wlv->virt_inline = item->decor.virt_text;
+ wlv->virt_inline_i = 0;
+ item->win_col = -2;
+ break;
+ }
+ }
+ }
+
+ if (wlv->n_extra == 0 || !wlv->extra_for_extmark) {
+ wlv->reset_extra_attr = false;
+ }
+
+ if (wlv->n_extra <= 0 && wlv->virt_inline_i < kv_size(wlv->virt_inline)) {
+ VirtTextChunk vtc = kv_A(wlv->virt_inline, wlv->virt_inline_i);
+ wlv->p_extra = vtc.text;
+ wlv->n_extra = (int)strlen(wlv->p_extra);
+ wlv->extra_for_extmark = true;
+ wlv->c_extra = NUL;
+ wlv->c_final = NUL;
+ wlv->extra_attr = vtc.hl_id ? syn_id2attr(vtc.hl_id) : 0;
+ wlv->n_attr = mb_charlen(vtc.text);
+ wlv->virt_inline_i++;
+ *do_save = true;
+ // If the text didn't reach until the first window
+ // column we need to skip cells.
+ if (wlv->skip_cells > 0) {
+ int virt_text_len = wlv->n_attr;
+ if (virt_text_len > wlv->skip_cells) {
+ int len = mb_charlen2bytelen(wlv->p_extra, wlv->skip_cells);
+ wlv->n_extra -= len;
+ wlv->p_extra += len;
+ wlv->n_attr -= wlv->skip_cells;
+ // Skipped cells needed to be accounted for in vcol.
+ wlv->skipped_cells += wlv->skip_cells;
+ wlv->skip_cells = 0;
+ } else {
+ // the whole text is left of the window, drop
+ // it and advance to the next one
+ wlv->skip_cells -= virt_text_len;
+ // Skipped cells needed to be accounted for in vcol.
+ wlv->skipped_cells += virt_text_len;
+ wlv->n_attr = 0;
+ wlv->n_extra = 0;
+
+ // go to the start so the next virtual text chunk can be selected.
+ continue;
+ }
+ }
+ }
+ break;
+ }
+}
+
static bool check_mb_utf8(int *c, int *u8cc)
{
if (utf_char2len(*c) > 1) {
@@ -909,6 +996,7 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra)
wlv->draw_state = WL_START;
wlv->saved_n_extra = wlv->n_extra;
wlv->saved_p_extra = wlv->p_extra;
+ wlv->saved_extra_for_extmark = wlv->extra_for_extmark;
wlv->saved_c_extra = wlv->c_extra;
wlv->saved_c_final = wlv->c_final;
wlv->saved_char_attr = wlv->char_attr;
@@ -923,6 +1011,8 @@ static void win_line_continue(winlinevars_T *wlv)
if (wlv->saved_n_extra > 0) {
// Continue item from end of wrapped line.
wlv->n_extra = wlv->saved_n_extra;
+ wlv->saved_n_extra = 0;
+ wlv->extra_for_extmark = wlv->saved_extra_for_extmark;
wlv->c_extra = wlv->saved_c_extra;
wlv->c_final = wlv->saved_c_final;
wlv->p_extra = wlv->saved_p_extra;
@@ -961,12 +1051,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// at end-of-line
bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
- int n_attr = 0; // chars with special attr
int saved_attr2 = 0; // char_attr saved for n_attr
int n_attr3 = 0; // chars with overruling special attr
int saved_attr3 = 0; // char_attr saved for n_attr3
- int n_skip = 0; // nr of chars to skip for 'nowrap'
+ int n_skip = 0; // nr of chars to skip for 'nowrap' or
+ // concealing
int fromcol_prev = -2; // start of inverting after cursor
bool noinvcur = false; // don't invert the cursor
@@ -978,7 +1068,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
bool area_highlighting = false; // Visual or incsearch highlighting in this line
int vi_attr = 0; // attributes for Visual and incsearch highlighting
int area_attr = 0; // attributes desired by highlighting
+ int saved_area_attr = 0; // idem for area_attr
int search_attr = 0; // attributes desired by 'hlsearch'
+ int saved_search_attr = 0; // search_attr to be used when n_extra
+ // goes to zero
int vcol_save_attr = 0; // saved attr for 'cursorcolumn'
int syntax_attr = 0; // attributes desired by syntax
bool has_syntax = false; // this buffer has syntax highl.
@@ -1016,6 +1109,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
int prev_c1 = 0; // first composing char for prev_c
bool search_attr_from_match = false; // if search_attr is from :match
+ bool saved_search_attr_from_match = false; // if search_attr is from :match
bool has_decor = false; // this buffer has decoration
int win_col_offset = 0; // offset for window columns
@@ -1428,6 +1522,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
}
}
+ // If there the text doesn't reach to the desired column, need to skip
+ // "skip_cells" cells when virtual text follows.
+ if (!wp->w_p_wrap && v > wlv.vcol) {
+ wlv.skip_cells = (int)(v - wlv.vcol);
+ }
+
// Adjust for when the inverted text is before the screen,
// and when the start of the inverted text is before the screen.
if (wlv.tocol <= wlv.vcol) {
@@ -1706,7 +1806,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.n_extra = 0;
}
- if (wlv.draw_state == WL_LINE && (area_highlighting || has_spell)) {
+ int extmark_attr = 0;
+ if (wlv.draw_state == WL_LINE
+ && (area_highlighting || has_spell || (extra_check && !has_fold))) {
// handle Visual or match highlighting in this line
if (wlv.vcol == wlv.fromcol
|| (wlv.vcol + 1 == wlv.fromcol && wlv.n_extra == 0
@@ -1724,7 +1826,29 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
area_active = false;
}
- if (!wlv.n_extra) {
+ if (has_decor && v >= 0) {
+ bool selected = (area_active || (area_highlighting && noinvcur
+ && wlv.vcol == wp->w_virtcol));
+ extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off,
+ selected, &decor_state);
+
+ bool do_save = false;
+ handle_inline_virtual_text(wp, &wlv, v, &do_save);
+ if (do_save) {
+ // restore search_attr and area_attr when n_extra is down to zero
+ // TODO(bfredl): this is ugly as fuck. look if we can do this some other way.
+ saved_search_attr = search_attr;
+ saved_area_attr = area_attr;
+ saved_search_attr_from_match = search_attr_from_match;
+ search_attr_from_match = false;
+ search_attr = 0;
+ area_attr = 0;
+ extmark_attr = 0;
+ n_skip = 0;
+ }
+ }
+
+ if (wlv.n_extra == 0) {
// Check for start/end of 'hlsearch' and other matches.
// After end, check for start/end of next match.
// When another match, have to check for start again.
@@ -1742,12 +1866,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
}
if (wlv.diff_hlf != (hlf_T)0) {
+ // When there is extra text (eg: virtual text) it gets the
+ // diff highlighting for the line, but not for changed text.
if (wlv.diff_hlf == HLF_CHD && ptr - line >= change_start
&& wlv.n_extra == 0) {
wlv.diff_hlf = HLF_TXD; // changed text
}
- if (wlv.diff_hlf == HLF_TXD && ptr - line > change_end
- && wlv.n_extra == 0) {
+ if (wlv.diff_hlf == HLF_TXD && ((ptr - line > change_end && wlv.n_extra == 0)
+ || (wlv.n_extra > 0 && wlv.extra_for_extmark))) {
wlv.diff_hlf = HLF_CHD; // changed line
}
wlv.line_attr = win_hl_attr(wp, (int)wlv.diff_hlf);
@@ -1848,6 +1974,26 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.p_extra++;
}
wlv.n_extra--;
+
+ // Only restore search_attr and area_attr after "n_extra" in
+ // the next screen line is also done.
+ if (wlv.n_extra <= 0) {
+ if (wlv.saved_n_extra <= 0) {
+ if (search_attr == 0) {
+ search_attr = saved_search_attr;
+ }
+ if (area_attr == 0 && *ptr != NUL) {
+ area_attr = saved_area_attr;
+ }
+
+ if (wlv.extra_for_extmark) {
+ // wlv.extra_attr should be used at this position but not
+ // any further.
+ wlv.reset_extra_attr = true;
+ }
+ }
+ wlv.extra_for_extmark = false;
+ }
} else if (foldinfo.fi_lines > 0) {
// skip writing the buffer line itself
c = NUL;
@@ -1899,7 +2045,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.c_extra = NUL;
wlv.c_final = NUL;
if (area_attr == 0 && search_attr == 0) {
- n_attr = wlv.n_extra + 1;
+ wlv.n_attr = wlv.n_extra + 1;
wlv.extra_attr = win_hl_attr(wp, HLF_8);
saved_attr2 = wlv.char_attr; // save current attr
}
@@ -1954,7 +2100,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.c_final = NUL;
c = ' ';
if (area_attr == 0 && search_attr == 0) {
- n_attr = wlv.n_extra + 1;
+ wlv.n_attr = wlv.n_extra + 1;
wlv.extra_attr = win_hl_attr(wp, HLF_AT);
saved_attr2 = wlv.char_attr; // save current attr
}
@@ -2019,10 +2165,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
}
if (has_decor && v > 0) {
- bool selected = (area_active || (area_highlighting && noinvcur
- && wlv.vcol == wp->w_virtcol));
- int extmark_attr = decor_redraw_col(wp, (colnr_T)v - 1, wlv.off,
- selected, &decor_state);
if (extmark_attr != 0) {
if (!attr_pri) {
wlv.char_attr = hl_combine_attr(wlv.char_attr, extmark_attr);
@@ -2046,9 +2188,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
v = (ptr - line);
if (has_spell && v >= word_end && v > cur_checked_col) {
spell_attr = 0;
- if (!attr_pri) {
- wlv.char_attr = hl_combine_attr(wlv.char_attr, syntax_attr);
- }
if (c != 0 && ((!has_syntax && !no_plain_buffer) || can_spell)) {
char *prev_ptr;
char *p;
@@ -2130,7 +2269,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
chartabsize_T cts;
init_chartabsize_arg(&cts, wp, lnum, wlv.vcol, line, p);
+ // do not want virtual text to be counted here
+ cts.cts_has_virt_text = false;
wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1;
+ clear_chartabsize_arg(&cts);
// We have just drawn the showbreak value, no need to add
// space for it again.
@@ -2162,7 +2304,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
c = ' ';
}
}
- clear_chartabsize_arg(&cts);
}
in_multispace = c == ' ' && ((ptr > line + 1 && ptr[-2] == ' ') || *ptr == ' ');
@@ -2193,7 +2334,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
} else {
c = (c == ' ') ? wp->w_p_lcs_chars.space : wp->w_p_lcs_chars.nbsp;
}
- n_attr = 1;
+ wlv.n_attr = 1;
wlv.extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = wlv.char_attr; // save current attr
mb_c = c;
@@ -2216,7 +2357,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
c = wp->w_p_lcs_chars.space;
}
- n_attr = 1;
+ wlv.n_attr = 1;
wlv.extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = wlv.char_attr; // save current attr
mb_c = c;
@@ -2332,7 +2473,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.c_extra = wp->w_p_lcs_chars.tab2;
}
wlv.c_final = wp->w_p_lcs_chars.tab3;
- n_attr = tab_len + 1;
+ wlv.n_attr = tab_len + 1;
wlv.extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = wlv.char_attr; // save current attr
mb_c = c;
@@ -2359,15 +2500,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
&& wlv.line_attr == 0
&& wlv.line_attr_lowprio == 0) {
// In virtualedit, visual selections may extend beyond end of line
- if (area_highlighting && virtual_active()
- && wlv.tocol != MAXCOL && wlv.vcol < wlv.tocol) {
- wlv.n_extra = 0;
- } else {
+ if (!(area_highlighting && virtual_active()
+ && wlv.tocol != MAXCOL && wlv.vcol < wlv.tocol)) {
wlv.p_extra = at_end_str;
- wlv.n_extra = 1;
- wlv.c_extra = NUL;
- wlv.c_final = NUL;
}
+ wlv.n_extra = 0;
}
if (wp->w_p_list && wp->w_p_lcs_chars.eol > 0) {
c = wp->w_p_lcs_chars.eol;
@@ -2377,7 +2514,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
lcs_eol_one = -1;
ptr--; // put it back at the NUL
wlv.extra_attr = win_hl_attr(wp, HLF_AT);
- n_attr = 1;
+ wlv.n_attr = 1;
mb_c = c;
mb_utf8 = check_mb_utf8(&c, u8cc);
} else if (c != NUL) {
@@ -2406,7 +2543,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.n_extra = byte2cells(c) - 1;
c = (uint8_t)(*wlv.p_extra++);
}
- n_attr = wlv.n_extra + 1;
+ wlv.n_attr = wlv.n_extra + 1;
wlv.extra_attr = win_hl_attr(wp, HLF_8);
saved_attr2 = wlv.char_attr; // save current attr
mb_utf8 = false; // don't draw as UTF-8
@@ -2466,7 +2603,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
}
}
wlv.n_extra = 0;
- n_attr = 0;
+ wlv.n_attr = 0;
} else if (n_skip == 0) {
is_concealing = true;
n_skip = 1;
@@ -2501,8 +2638,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
}
// Don't override visual selection highlighting.
- if (n_attr > 0 && wlv.draw_state == WL_LINE && !search_attr_from_match) {
+ if (wlv.n_attr > 0 && wlv.draw_state == WL_LINE && !search_attr_from_match) {
wlv.char_attr = hl_combine_attr(wlv.char_attr, wlv.extra_attr);
+ if (wlv.reset_extra_attr) {
+ wlv.reset_extra_attr = false;
+ wlv.extra_attr = 0;
+ // search_attr_from_match can be restored now that the extra_attr has been applied
+ search_attr_from_match = saved_search_attr_from_match;
+ }
}
// Handle the case where we are in column 0 but not on the first
@@ -2522,7 +2665,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.c_extra = MB_FILLER_CHAR;
wlv.c_final = NUL;
wlv.n_extra = 1;
- n_attr = 2;
+ wlv.n_attr = 2;
wlv.extra_attr = win_hl_attr(wp, HLF_AT);
}
mb_c = c;
@@ -2738,7 +2881,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
&& !has_fold
&& (*ptr != NUL
|| lcs_eol_one > 0
- || (wlv.n_extra && (wlv.c_extra != NUL || *wlv.p_extra != NUL)))) {
+ || (wlv.n_extra > 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL)))) {
c = wp->w_p_lcs_chars.ext;
wlv.char_attr = win_hl_attr(wp, HLF_AT);
mb_c = c;
@@ -2809,6 +2952,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.col++;
// UTF-8: Put a 0 in the second screen char.
linebuf_char[wlv.off][0] = 0;
+ linebuf_attr[wlv.off] = linebuf_attr[wlv.off - 1];
if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) {
wlv.vcol++;
}
@@ -2858,7 +3002,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.boguscols += wlv.n_extra;
}
wlv.n_extra = 0;
- n_attr = 0;
+ wlv.n_attr = 0;
}
if (utf_char2cells(mb_c) > 1) {
@@ -2883,13 +3027,19 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
if (wlv.n_extra > 0) {
wlv.vcol += wlv.n_extra;
wlv.n_extra = 0;
- n_attr = 0;
+ wlv.n_attr = 0;
}
}
} else {
n_skip--;
}
+ // The skipped cells need to be accounted for in vcol.
+ if (wlv.draw_state > WL_STC && wlv.skipped_cells > 0) {
+ wlv.vcol += wlv.skipped_cells;
+ wlv.skipped_cells = 0;
+ }
+
// Only advance the "wlv.vcol" when after the 'number' or
// 'relativenumber' column.
if (wlv.draw_state > WL_STC
@@ -2907,7 +3057,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
}
// restore attributes after last 'listchars' or 'number' char
- if (n_attr > 0 && wlv.draw_state == WL_LINE && --n_attr == 0) {
+ if (wlv.n_attr > 0 && wlv.draw_state == WL_LINE && --wlv.n_attr == 0) {
wlv.char_attr = saved_attr2;
}
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index e3321a8b99..a25387f5a6 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -232,7 +232,7 @@ static void insert_enter(InsertState *s)
stop_insert_mode = false;
// need to position cursor again when on a TAB
- if (gchar_cursor() == TAB) {
+ if (gchar_cursor() == TAB || curbuf->b_virt_text_inline > 0) {
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
}
@@ -3471,7 +3471,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
State = MODE_NORMAL;
may_trigger_modechanged();
// need to position cursor again when on a TAB
- if (gchar_cursor() == TAB) {
+ if (gchar_cursor() == TAB || curbuf->b_virt_text_inline > 0) {
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 1b21f107a8..52924bf9a5 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8712,7 +8712,7 @@ void ex_checkhealth(exarg_T *eap)
{
Error err = ERROR_INIT;
MAXSIZE_TEMP_ARRAY(args, 1);
- ADD_C(args, STRING_OBJ(cstr_as_string(eap->arg)));
+ ADD_C(args, CSTR_AS_OBJ(eap->arg));
NLUA_EXEC_STATIC("return vim.health._check(...)", args, &err);
if (!ERROR_SET(&err)) {
return;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 9a8dc9899c..1d8c3c0cf4 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -54,7 +54,6 @@
#include "nvim/highlight_group.h"
#include "nvim/indent.h"
#include "nvim/input.h"
-#include "nvim/lua/executor.h"
#include "nvim/macros.h"
#include "nvim/main.h"
#include "nvim/mark.h"
@@ -4804,29 +4803,3 @@ void ex_oldfiles(exarg_T *eap)
}
}
}
-
-void ex_trust(exarg_T *eap)
-{
- const char *const p = skiptowhite(eap->arg);
- char *arg1 = xmemdupz(eap->arg, (size_t)(p - eap->arg));
- const char *action = "allow";
- const char *path = skipwhite(p);
-
- if (strcmp(arg1, "++deny") == 0) {
- action = "deny";
- } else if (strcmp(arg1, "++remove") == 0) {
- action = "remove";
- } else if (*arg1 != '\0') {
- semsg(e_invarg2, arg1);
- goto theend;
- }
-
- if (path[0] == '\0') {
- path = NULL;
- }
-
- nlua_trust(action, path);
-
-theend:
- xfree(arg1);
-}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index a4c1863576..dd23f6ece9 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -3387,7 +3387,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line)
} else {
Array item = arena_array(&arena, 2);
ADD_C(item, INTEGER_OBJ(0));
- ADD_C(item, STRING_OBJ(cstr_as_string(line->cmdbuff)));
+ ADD_C(item, CSTR_AS_OBJ(line->cmdbuff));
content = arena_array(&arena, 1);
ADD_C(content, ARRAY_OBJ(item));
}
@@ -3414,7 +3414,7 @@ void ui_ext_cmdline_block_append(size_t indent, const char *line)
Array item = ARRAY_DICT_INIT;
ADD(item, INTEGER_OBJ(0));
- ADD(item, STRING_OBJ(cstr_as_string(buf)));
+ ADD(item, CSTR_AS_OBJ(buf));
Array content = ARRAY_DICT_INIT;
ADD(content, ARRAY_OBJ(item));
ADD(cmdline_block, ARRAY_OBJ(content));
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index acdc36f9c7..f4a6a02682 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -148,6 +148,9 @@ revised:
}
if (decor) {
+ if (kv_size(decor->virt_text) && decor->virt_text_pos == kVTInline) {
+ buf->b_virt_text_inline++;
+ }
if (kv_size(decor->virt_lines)) {
buf->b_virt_line_blocks++;
}
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 57aa063504..e60007bf88 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -3481,8 +3481,7 @@ void vim_deltempdir(void)
char *vim_gettempdir(void)
{
static int notfound = 0;
- bool exists = false;
- if (vim_tempdir == NULL || !(exists = os_isdir(vim_tempdir))) {
+ if (vim_tempdir == NULL || !os_isdir(vim_tempdir)) {
if (vim_tempdir != NULL) {
notfound++;
if (notfound == 1) {
diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua
index 76b372eac2..b9fae7d0fe 100644
--- a/src/nvim/generators/gen_ex_cmds.lua
+++ b/src/nvim/generators/gen_ex_cmds.lua
@@ -55,6 +55,7 @@ defsfile:write(string.format([[
#include "nvim/help.h"
#include "nvim/indent.h"
#include "nvim/lua/executor.h"
+#include "nvim/lua/secure.h"
#include "nvim/mapping.h"
#include "nvim/mark.h"
#include "nvim/match.h"
diff --git a/src/nvim/grid.c b/src/nvim/grid.c
index 037606c38f..76dd2a073a 100644
--- a/src/nvim/grid.c
+++ b/src/nvim/grid.c
@@ -316,8 +316,7 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int
// When at the start of the text and overwriting the right half of a
// two-cell character in the same grid, truncate that into a '>'.
if (ptr == text && col > 0 && grid->chars[off][0] == 0) {
- grid->chars[off - 1][0] = '>';
- grid->chars[off - 1][1] = 0;
+ schar_from_ascii(grid->chars[off - 1], '>');
}
schar_copy(grid->chars[off], buf);
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index a53da95fba..fad113adc5 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -207,7 +207,7 @@ int ns_get_hl(NS *ns_hl, int hl_id, bool link, bool nodefault)
if (!valid_item && p->hl_def != LUA_NOREF && !recursive) {
MAXSIZE_TEMP_ARRAY(args, 3);
ADD_C(args, INTEGER_OBJ((Integer)ns_id));
- ADD_C(args, STRING_OBJ(cstr_to_string(syn_id2name(hl_id))));
+ ADD_C(args, CSTR_TO_OBJ(syn_id2name(hl_id)));
ADD_C(args, BOOLEAN_OBJ(link));
// TODO(bfredl): preload the "global" attr dict?
@@ -1141,21 +1141,21 @@ static void hl_inspect_impl(Array *arr, int attr)
HlEntry e = kv_A(attr_entries, attr);
switch (e.kind) {
case kHlSyntax:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax")));
+ PUT(item, "kind", CSTR_TO_OBJ("syntax"));
PUT(item, "hi_name",
- STRING_OBJ(cstr_to_string(syn_id2name(e.id1))));
+ CSTR_TO_OBJ(syn_id2name(e.id1)));
break;
case kHlUI:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("ui")));
+ PUT(item, "kind", CSTR_TO_OBJ("ui"));
const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1];
- PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name)));
+ PUT(item, "ui_name", CSTR_TO_OBJ(ui_name));
PUT(item, "hi_name",
- STRING_OBJ(cstr_to_string(syn_id2name(e.id2))));
+ CSTR_TO_OBJ(syn_id2name(e.id2)));
break;
case kHlTerminal:
- PUT(item, "kind", STRING_OBJ(cstr_to_string("term")));
+ PUT(item, "kind", CSTR_TO_OBJ("term"));
break;
case kHlCombine:
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index 41e7bdb7ac..09e7d04e02 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -697,10 +697,18 @@ int load_colors(char *name)
char *buf = xmalloc(buflen);
apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf);
snprintf(buf, buflen, "colors/%s.vim", name);
- int retval = source_runtime(buf, DIP_START + DIP_OPT);
+ int retval = source_runtime(buf, 0);
if (retval == FAIL) {
snprintf(buf, buflen, "colors/%s.lua", name);
- retval = source_runtime(buf, DIP_START + DIP_OPT);
+ retval = source_runtime(buf, 0);
+ }
+ if (retval == FAIL) {
+ snprintf(buf, buflen, "colors/%s.vim", name);
+ retval = source_runtime(buf, DIP_NORTP + DIP_START + DIP_OPT);
+ }
+ if (retval == FAIL) {
+ snprintf(buf, buflen, "colors/%s.lua", name);
+ retval = source_runtime(buf, DIP_NORTP + DIP_START + DIP_OPT);
}
xfree(buf);
if (retval == OK) {
@@ -1548,8 +1556,11 @@ static bool hlgroup2dict(Dictionary *hl, NS ns_id, int hl_id, Arena *arena)
HlAttrs attr =
syn_attr2entry(ns_id == 0 ? sgp->sg_attr : ns_get_hl(&ns_id, hl_id, false, sgp->sg_set));
*hl = arena_dict(arena, HLATTRS_DICT_SIZE + 1);
+ if (attr.rgb_ae_attr & HL_DEFAULT) {
+ PUT_C(*hl, "default", BOOLEAN_OBJ(true));
+ }
if (link > 0) {
- PUT_C(*hl, "link", STRING_OBJ(cstr_as_string(hl_table[link - 1].sg_name)));
+ PUT_C(*hl, "link", CSTR_AS_OBJ(hl_table[link - 1].sg_name));
}
Dictionary hl_cterm = arena_dict(arena, HLATTRS_DICT_SIZE);
hlattrs2dict(hl, NULL, attr, true, true);
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 1d11379956..8c1d8addcd 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -109,11 +109,16 @@ typedef enum luv_err_type {
kThreadCallback,
} luv_err_t;
+lua_State *get_global_lstate(void)
+{
+ return global_lstate;
+}
+
/// Convert lua error into a Vim error message
///
/// @param lstate Lua interpreter state.
/// @param[in] msg Message base, must contain one `%s`.
-static void nlua_error(lua_State *const lstate, const char *const msg)
+void nlua_error(lua_State *const lstate, const char *const msg)
FUNC_ATTR_NONNULL_ALL
{
size_t len;
@@ -150,7 +155,7 @@ static void nlua_error(lua_State *const lstate, const char *const msg)
/// @param lstate Lua interpreter state
/// @param[in] nargs Number of arguments expected by the function being called.
/// @param[in] nresults Number of results the function returns.
-static int nlua_pcall(lua_State *lstate, int nargs, int nresults)
+int nlua_pcall(lua_State *lstate, int nargs, int nresults)
{
lua_getglobal(lstate, "debug");
lua_getfield(lstate, -1, "traceback");
@@ -336,7 +341,7 @@ static int nlua_init_argv(lua_State *const L, char **argv, int argc, int lua_arg
lua_pushstring(L, argv[lua_arg0 - 1]);
lua_rawseti(L, -2, 0); // _G.arg[0] = "foo.lua"
- for (; lua_arg0 >= 0 && i + lua_arg0 < argc; i++) {
+ for (; i + lua_arg0 < argc; i++) {
lua_pushstring(L, argv[i + lua_arg0]);
lua_rawseti(L, -2, i + 1); // _G.arg[i+1] = "--foo"
}
@@ -836,7 +841,7 @@ void nlua_run_script(char **argv, int argc, int lua_arg0)
exit(lua_ok ? 0 : 1);
}
-lua_State *nlua_init_state(bool thread)
+static lua_State *nlua_init_state(bool thread)
{
// If it is called from the main thread, it will attempt to rebuild the cache.
const uv_thread_t self = uv_thread_self();
@@ -916,6 +921,7 @@ static void nlua_common_free_all_mem(lua_State *lstate)
lua_close(lstate);
}
+
static void nlua_print_event(void **argv)
{
char *str = argv[0];
@@ -2275,80 +2281,3 @@ plain:
kv_printf(str, "<Lua %d>", ref);
return str.items;
}
-
-char *nlua_read_secure(const char *path)
-{
- lua_State *const lstate = global_lstate;
- const int top = lua_gettop(lstate);
-
- lua_getglobal(lstate, "vim");
- lua_getfield(lstate, -1, "secure");
- lua_getfield(lstate, -1, "read");
- lua_pushstring(lstate, path);
- if (nlua_pcall(lstate, 1, 1)) {
- nlua_error(lstate, _("Error executing vim.secure.read: %.*s"));
- lua_settop(lstate, top);
- return NULL;
- }
-
- size_t len = 0;
- const char *contents = lua_tolstring(lstate, -1, &len);
- char *buf = NULL;
- if (contents != NULL) {
- // Add one to include trailing null byte
- buf = xcalloc(len + 1, sizeof(char));
- memcpy(buf, contents, len + 1);
- }
-
- lua_settop(lstate, top);
- return buf;
-}
-
-bool nlua_trust(const char *action, const char *path)
-{
- lua_State *const lstate = global_lstate;
- const int top = lua_gettop(lstate);
-
- lua_getglobal(lstate, "vim");
- lua_getfield(lstate, -1, "secure");
- lua_getfield(lstate, -1, "trust");
-
- lua_newtable(lstate);
- lua_pushstring(lstate, "action");
- lua_pushstring(lstate, action);
- lua_settable(lstate, -3);
- if (path == NULL) {
- lua_pushstring(lstate, "bufnr");
- lua_pushnumber(lstate, 0);
- lua_settable(lstate, -3);
- } else {
- lua_pushstring(lstate, "path");
- lua_pushstring(lstate, path);
- lua_settable(lstate, -3);
- }
-
- if (nlua_pcall(lstate, 1, 2)) {
- nlua_error(lstate, _("Error executing vim.secure.trust: %.*s"));
- lua_settop(lstate, top);
- return false;
- }
-
- bool success = lua_toboolean(lstate, -2);
- const char *msg = lua_tostring(lstate, -1);
- if (msg != NULL) {
- if (success) {
- if (strcmp(action, "allow") == 0) {
- smsg("Allowed \"%s\" in trust database.", msg);
- } else if (strcmp(action, "deny") == 0) {
- smsg("Denied \"%s\" in trust database.", msg);
- } else if (strcmp(action, "remove") == 0) {
- smsg("Removed \"%s\" from trust database.", msg);
- }
- } else {
- semsg(e_trustfile, msg);
- }
- }
-
- lua_settop(lstate, top);
- return success;
-}
diff --git a/src/nvim/lua/secure.c b/src/nvim/lua/secure.c
new file mode 100644
index 0000000000..30d5a95fc0
--- /dev/null
+++ b/src/nvim/lua/secure.c
@@ -0,0 +1,118 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include <lauxlib.h>
+#include <lua.h>
+#include <lualib.h>
+
+#include "nvim/charset.h"
+#include "nvim/lua/executor.h"
+#include "nvim/lua/secure.h"
+#include "nvim/message.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/secure.c.generated.h"
+#endif
+
+char *nlua_read_secure(const char *path)
+{
+ lua_State *const lstate = get_global_lstate();
+ const int top = lua_gettop(lstate);
+
+ lua_getglobal(lstate, "vim");
+ lua_getfield(lstate, -1, "secure");
+ lua_getfield(lstate, -1, "read");
+ lua_pushstring(lstate, path);
+ if (nlua_pcall(lstate, 1, 1)) {
+ nlua_error(lstate, _("Error executing vim.secure.read: %.*s"));
+ lua_settop(lstate, top);
+ return NULL;
+ }
+
+ size_t len = 0;
+ const char *contents = lua_tolstring(lstate, -1, &len);
+ char *buf = NULL;
+ if (contents != NULL) {
+ // Add one to include trailing null byte
+ buf = xcalloc(len + 1, sizeof(char));
+ memcpy(buf, contents, len + 1);
+ }
+
+ lua_settop(lstate, top);
+ return buf;
+}
+
+static bool nlua_trust(const char *action, const char *path)
+{
+ lua_State *const lstate = get_global_lstate();
+ const int top = lua_gettop(lstate);
+
+ lua_getglobal(lstate, "vim");
+ lua_getfield(lstate, -1, "secure");
+ lua_getfield(lstate, -1, "trust");
+
+ lua_newtable(lstate);
+ lua_pushstring(lstate, "action");
+ lua_pushstring(lstate, action);
+ lua_settable(lstate, -3);
+ if (path == NULL) {
+ lua_pushstring(lstate, "bufnr");
+ lua_pushnumber(lstate, 0);
+ lua_settable(lstate, -3);
+ } else {
+ lua_pushstring(lstate, "path");
+ lua_pushstring(lstate, path);
+ lua_settable(lstate, -3);
+ }
+
+ if (nlua_pcall(lstate, 1, 2)) {
+ nlua_error(lstate, _("Error executing vim.secure.trust: %.*s"));
+ lua_settop(lstate, top);
+ return false;
+ }
+
+ bool success = lua_toboolean(lstate, -2);
+ const char *msg = lua_tostring(lstate, -1);
+ if (msg != NULL) {
+ if (success) {
+ if (strcmp(action, "allow") == 0) {
+ smsg("Allowed \"%s\" in trust database.", msg);
+ } else if (strcmp(action, "deny") == 0) {
+ smsg("Denied \"%s\" in trust database.", msg);
+ } else if (strcmp(action, "remove") == 0) {
+ smsg("Removed \"%s\" from trust database.", msg);
+ }
+ } else {
+ semsg(e_trustfile, msg);
+ }
+ }
+
+ lua_settop(lstate, top);
+ return success;
+}
+
+void ex_trust(exarg_T *eap)
+{
+ const char *const p = skiptowhite(eap->arg);
+ char *arg1 = xmemdupz(eap->arg, (size_t)(p - eap->arg));
+ const char *action = "allow";
+ const char *path = skipwhite(p);
+
+ if (strcmp(arg1, "++deny") == 0) {
+ action = "deny";
+ } else if (strcmp(arg1, "++remove") == 0) {
+ action = "remove";
+ } else if (*arg1 != '\0') {
+ semsg(e_invarg2, arg1);
+ goto theend;
+ }
+
+ if (path[0] == '\0') {
+ path = NULL;
+ }
+
+ nlua_trust(action, path);
+
+theend:
+ xfree(arg1);
+}
diff --git a/src/nvim/lua/secure.h b/src/nvim/lua/secure.h
new file mode 100644
index 0000000000..87c468538e
--- /dev/null
+++ b/src/nvim/lua/secure.h
@@ -0,0 +1,12 @@
+#ifndef NVIM_LUA_SECURE_H
+#define NVIM_LUA_SECURE_H
+
+#include <lua.h>
+
+#include "nvim/ex_cmds_defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/secure.h.generated.h"
+#endif
+
+#endif // NVIM_LUA_SECURE_H
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 4999d9dd2a..6015bbd06e 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -49,6 +49,7 @@
#include "nvim/keycodes.h"
#include "nvim/log.h"
#include "nvim/lua/executor.h"
+#include "nvim/lua/secure.h"
#include "nvim/macros.h"
#include "nvim/main.h"
#include "nvim/mark.h"
diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c
index c5449bd66e..e40e67cead 100644
--- a/src/nvim/mapping.c
+++ b/src/nvim/mapping.c
@@ -2096,13 +2096,13 @@ static Dictionary mapblock_fill_dict(const mapblock_T *const mp, const char *lhs
: cstr_as_string(str2special_save(mp->m_str, false, true))));
}
if (mp->m_desc != NULL) {
- PUT(dict, "desc", STRING_OBJ(cstr_to_string(mp->m_desc)));
+ PUT(dict, "desc", CSTR_TO_OBJ(mp->m_desc));
}
- PUT(dict, "lhs", STRING_OBJ(cstr_as_string(lhs)));
- PUT(dict, "lhsraw", STRING_OBJ(cstr_to_string(mp->m_keys)));
+ PUT(dict, "lhs", CSTR_AS_OBJ(lhs));
+ PUT(dict, "lhsraw", CSTR_TO_OBJ(mp->m_keys));
if (lhsrawalt != NULL) {
// Also add the value for the simplified entry.
- PUT(dict, "lhsrawalt", STRING_OBJ(cstr_to_string(lhsrawalt)));
+ PUT(dict, "lhsrawalt", CSTR_TO_OBJ(lhsrawalt));
}
PUT(dict, "noremap", INTEGER_OBJ(noremap_value));
PUT(dict, "script", INTEGER_OBJ(mp->m_noremap == REMAP_SCRIPT ? 1 : 0));
@@ -2115,7 +2115,7 @@ static Dictionary mapblock_fill_dict(const mapblock_T *const mp, const char *lhs
if (mp->m_replace_keycodes) {
PUT(dict, "replace_keycodes", INTEGER_OBJ(1));
}
- PUT(dict, "mode", STRING_OBJ(cstr_as_string(mapmode)));
+ PUT(dict, "mode", CSTR_AS_OBJ(mapmode));
return dict;
}
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 7d61b918d2..66c26275f1 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -2024,6 +2024,24 @@ int mb_charlen(const char *str)
return count;
}
+int mb_charlen2bytelen(const char *str, int charlen)
+{
+ const char *p = str;
+ int count = 0;
+
+ if (p == NULL) {
+ return 0;
+ }
+
+ for (int i = 0; *p != NUL && i < charlen; i++) {
+ int b = utfc_ptr2len(p);
+ p += b;
+ count += b;
+ }
+
+ return count;
+}
+
/// Like mb_charlen() but for a string with specified length.
int mb_charlen_len(const char *str, int len)
{
diff --git a/src/nvim/message.c b/src/nvim/message.c
index aa97ea15e5..1cb4a3cbf4 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1069,7 +1069,7 @@ void ex_messages(void *const eap_p)
for (; p != NULL; p = p->next) {
if (kv_size(p->multiattr) || (p->msg && p->msg[0])) {
Array entry = ARRAY_DICT_INIT;
- ADD(entry, STRING_OBJ(cstr_to_string(p->kind)));
+ ADD(entry, CSTR_TO_OBJ(p->kind));
Array content = ARRAY_DICT_INIT;
if (kv_size(p->multiattr)) {
for (uint32_t i = 0; i < kv_size(p->multiattr); i++) {
@@ -1082,7 +1082,7 @@ void ex_messages(void *const eap_p)
} else if (p->msg && p->msg[0]) {
Array content_entry = ARRAY_DICT_INIT;
ADD(content_entry, INTEGER_OBJ(p->attr));
- ADD(content_entry, STRING_OBJ(cstr_to_string(p->msg)));
+ ADD(content_entry, CSTR_TO_OBJ(p->msg));
ADD(content, ARRAY_OBJ(content_entry));
}
ADD(entry, ARRAY_OBJ(content));
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index cd5daee915..1772b0497b 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -628,7 +628,7 @@ static void chan_close_with_error(Channel *channel, char *msg, int loglevel)
ChannelCallFrame *frame = kv_A(channel->rpc.call_stack, i);
frame->returned = true;
frame->errored = true;
- frame->result = STRING_OBJ(cstr_to_string(msg));
+ frame->result = CSTR_TO_OBJ(msg);
}
channel_close(channel->id, kChannelPartRpc, NULL);
@@ -665,7 +665,7 @@ static WBuffer *serialize_response(uint64_t channel_id, MsgpackRpcRequestHandler
} else {
Array args = ARRAY_DICT_INIT;
ADD(args, INTEGER_OBJ(err->type));
- ADD(args, STRING_OBJ(cstr_to_string(err->msg)));
+ ADD(args, CSTR_TO_OBJ(err->msg));
msgpack_rpc_serialize_request(0, cstr_as_string("nvim_error_event"),
args, &pac);
api_free_array(args);
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index c3fdb304a3..60fff45323 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2031,7 +2031,7 @@ static void display_showcmd(void)
if (len > 0) {
// placeholder for future highlight support
ADD_C(chunk, INTEGER_OBJ(0));
- ADD_C(chunk, STRING_OBJ(cstr_as_string(showcmd_buf)));
+ ADD_C(chunk, CSTR_AS_OBJ(showcmd_buf));
ADD_C(content, ARRAY_OBJ(chunk));
}
ui_call_msg_showcmd(content);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 327c5fc089..722afa64d8 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1252,7 +1252,7 @@ static void do_set_option_string(int opt_idx, int opt_flags, char **argp, int ne
}
if (options[opt_idx].flags & P_UI_OPTION) {
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
- STRING_OBJ(cstr_as_string(saved_newval)));
+ CSTR_AS_OBJ(saved_newval));
}
}
xfree(saved_origval);
@@ -3803,7 +3803,7 @@ void ui_refresh_options(void)
value = INTEGER_OBJ(*(long *)varp);
} else if (flags & P_STRING) {
// cstr_as_string handles NULL string
- value = STRING_OBJ(cstr_as_string(*(char **)varp));
+ value = CSTR_AS_OBJ(*(char **)varp);
}
ui_call_option_set(name, value);
}
diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c
index 2a248a1e32..98ae251e2b 100644
--- a/src/nvim/os/process.c
+++ b/src/nvim/os/process.c
@@ -254,7 +254,7 @@ Dictionary os_proc_info(int pid)
if (pe.th32ProcessID == (DWORD)pid) {
PUT(pinfo, "pid", INTEGER_OBJ(pid));
PUT(pinfo, "ppid", INTEGER_OBJ((int)pe.th32ParentProcessID));
- PUT(pinfo, "name", STRING_OBJ(cstr_to_string(pe.szExeFile)));
+ PUT(pinfo, "name", CSTR_TO_OBJ(pe.szExeFile));
}
return pinfo;
diff --git a/src/nvim/plines.c b/src/nvim/plines.c
index 3e69e547cb..25c745ae97 100644
--- a/src/nvim/plines.c
+++ b/src/nvim/plines.c
@@ -102,12 +102,16 @@ int plines_win_nofold(win_T *wp, linenr_T lnum)
char *s;
unsigned col;
int width;
+ chartabsize_T cts;
s = ml_get_buf(wp->w_buffer, lnum, false);
- if (*s == NUL) { // empty line
- return 1;
+ init_chartabsize_arg(&cts, wp, lnum, 0, s, s);
+ if (*s == NUL && !cts.cts_has_virt_text) {
+ return 1; // be quick for an empty line
}
- col = win_linetabsize(wp, lnum, s, MAXCOL);
+ win_linetabsize_cts(&cts, (colnr_T)MAXCOL);
+ clear_chartabsize_arg(&cts);
+ col = (unsigned)cts.cts_vcol;
// If list mode is on, then the '$' at the end of the line may take up one
// extra column.
@@ -262,6 +266,11 @@ int linetabsize_col(int startcol, char *s)
while (*cts.cts_ptr != NUL) {
cts.cts_vcol += lbr_chartabsize_adv(&cts);
}
+ if (cts.cts_has_virt_text && cts.cts_ptr == cts.cts_line) {
+ // check for virtual text in an empty line
+ (void)lbr_chartabsize_adv(&cts);
+ cts.cts_vcol += cts.cts_cur_text_width_left + cts.cts_cur_text_width_right;
+ }
clear_chartabsize_arg(&cts);
return cts.cts_vcol;
}
@@ -277,10 +286,7 @@ unsigned win_linetabsize(win_T *wp, linenr_T lnum, char *line, colnr_T len)
{
chartabsize_T cts;
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
- for (; *cts.cts_ptr != NUL && (len == MAXCOL || cts.cts_ptr < line + len);
- MB_PTR_ADV(cts.cts_ptr)) {
- cts.cts_vcol += win_lbr_chartabsize(&cts, NULL);
- }
+ win_linetabsize_cts(&cts, len);
clear_chartabsize_arg(&cts);
return (unsigned)cts.cts_vcol;
}
@@ -292,20 +298,43 @@ unsigned linetabsize(win_T *wp, linenr_T lnum)
return win_linetabsize(wp, lnum, ml_get_buf(wp->w_buffer, lnum, false), (colnr_T)MAXCOL);
}
+void win_linetabsize_cts(chartabsize_T *cts, colnr_T len)
+{
+ for (; *cts->cts_ptr != NUL && (len == MAXCOL || cts->cts_ptr < cts->cts_line + len);
+ MB_PTR_ADV(cts->cts_ptr)) {
+ cts->cts_vcol += win_lbr_chartabsize(cts, NULL);
+ }
+ // check for a virtual text on an empty line
+ if (cts->cts_has_virt_text && *cts->cts_ptr == NUL
+ && cts->cts_ptr == cts->cts_line) {
+ (void)win_lbr_chartabsize(cts, NULL);
+ cts->cts_vcol += cts->cts_cur_text_width_left + cts->cts_cur_text_width_right;
+ }
+}
+
/// Prepare the structure passed to chartabsize functions.
///
/// "line" is the start of the line, "ptr" is the first relevant character.
-/// When "lnum" is zero do not use text properties that insert text.
-void init_chartabsize_arg(chartabsize_T *cts, win_T *wp, linenr_T lnum FUNC_ATTR_UNUSED,
- colnr_T col, char *line, char *ptr)
+/// When "lnum" is zero do not use inline virtual text.
+void init_chartabsize_arg(chartabsize_T *cts, win_T *wp, linenr_T lnum, colnr_T col, char *line,
+ char *ptr)
{
cts->cts_win = wp;
cts->cts_vcol = col;
cts->cts_line = line;
cts->cts_ptr = ptr;
- cts->cts_cur_text_width = 0;
- // TODO(bfredl): actually lookup inline virtual text here
+ cts->cts_cur_text_width_left = 0;
+ cts->cts_cur_text_width_right = 0;
cts->cts_has_virt_text = false;
+ cts->cts_row = lnum - 1;
+
+ if (cts->cts_row >= 0) {
+ marktree_itr_get(wp->w_buffer->b_marktree, cts->cts_row, 0, cts->cts_iter);
+ mtkey_t mark = marktree_itr_current(cts->cts_iter);
+ if (mark.pos.row == cts->cts_row) {
+ cts->cts_has_virt_text = true;
+ }
+ }
}
/// Free any allocated item in "cts".
@@ -369,7 +398,8 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp)
int mb_added = 0;
int numberextra;
- cts->cts_cur_text_width = 0;
+ cts->cts_cur_text_width_left = 0;
+ cts->cts_cur_text_width_right = 0;
// No 'linebreak', 'showbreak' and 'breakindent': return quickly.
if (!wp->w_p_lbr && !wp->w_p_bri && *get_showbreak_value(wp) == NUL
@@ -383,7 +413,34 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp)
// First get normal size, without 'linebreak' or virtual text
int size = win_chartabsize(wp, s, vcol);
if (cts->cts_has_virt_text) {
- // TODO(bfredl): inline virtual text
+ int tab_size = size;
+ int charlen = *s == NUL ? 1 : utf_ptr2len(s);
+ int col = (int)(s - line);
+ while (true) {
+ mtkey_t mark = marktree_itr_current(cts->cts_iter);
+ if (mark.pos.row != cts->cts_row || mark.pos.col > col) {
+ break;
+ } else if (mark.pos.col >= col && mark.pos.col < col + charlen) {
+ if (!mt_end(mark)) {
+ Decoration decor = get_decor(mark);
+ if (decor.virt_text_pos == kVTInline) {
+ if (mt_right(mark)) {
+ cts->cts_cur_text_width_right += decor.virt_text_width;
+ } else {
+ cts->cts_cur_text_width_left += decor.virt_text_width;
+ }
+ size += decor.virt_text_width;
+ if (*s == TAB) {
+ // tab size changes because of the inserted text
+ size -= tab_size;
+ tab_size = win_chartabsize(wp, s, vcol + size);
+ size += tab_size;
+ }
+ }
+ }
+ }
+ marktree_itr_next(wp->w_buffer->b_marktree, cts->cts_iter);
+ }
}
int c = (uint8_t)(*s);
diff --git a/src/nvim/plines.h b/src/nvim/plines.h
index 808f6d284e..2ce7133705 100644
--- a/src/nvim/plines.h
+++ b/src/nvim/plines.h
@@ -11,10 +11,12 @@ typedef struct {
win_T *cts_win;
char *cts_line; // start of the line
char *cts_ptr; // current position in line
+ int cts_row;
bool cts_has_virt_text; // true if if a property inserts text
- int cts_cur_text_width; // width of current inserted text
- // TODO(bfredl): iterator in to the marktree for scanning virt text
+ int cts_cur_text_width_left; // width of virtual text left of cursor
+ int cts_cur_text_width_right; // width of virtual text right of cursor
+ MarkTreeIter cts_iter[1];
int cts_vcol; // virtual column at current position
} chartabsize_T;
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index 6d5d063a75..15d0372c6f 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -164,10 +164,10 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
Array arr = arena_array(&arena, (size_t)size);
for (int i = 0; i < size; i++) {
Array item = arena_array(&arena, 4);
- ADD_C(item, STRING_OBJ(cstr_as_string(array[i].pum_text)));
- ADD_C(item, STRING_OBJ(cstr_as_string(array[i].pum_kind)));
- ADD_C(item, STRING_OBJ(cstr_as_string(array[i].pum_extra)));
- ADD_C(item, STRING_OBJ(cstr_as_string(array[i].pum_info)));
+ ADD_C(item, CSTR_AS_OBJ(array[i].pum_text));
+ ADD_C(item, CSTR_AS_OBJ(array[i].pum_kind));
+ ADD_C(item, CSTR_AS_OBJ(array[i].pum_extra));
+ ADD_C(item, CSTR_AS_OBJ(array[i].pum_info));
ADD_C(arr, ARRAY_OBJ(item));
}
ui_call_popupmenu_show(arr, selected, pum_win_row, cursor_col,
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index a9068fabc8..4b27067fb8 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -512,7 +512,7 @@ Array runtime_inspect(void)
for (size_t i = 0; i < kv_size(path); i++) {
SearchPathItem *item = &kv_A(path, i);
Array entry = ARRAY_DICT_INIT;
- ADD(entry, STRING_OBJ(cstr_to_string(item->path)));
+ ADD(entry, CSTR_TO_OBJ(item->path));
ADD(entry, BOOLEAN_OBJ(item->after));
if (item->has_lua != kNone) {
ADD(entry, BOOLEAN_OBJ(item->has_lua == kTrue));
@@ -568,7 +568,7 @@ ArrayOf(String) runtime_get_named_common(bool lua, Array pat, bool all,
item->path, pat_item.data.string.data);
if (size < buf_len) {
if (os_file_is_readable(buf)) {
- ADD(rv, STRING_OBJ(cstr_to_string(buf)));
+ ADD(rv, CSTR_TO_OBJ(buf));
if (!all) {
goto done;
}
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index d3a0b12e5e..db911f4bfd 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -2529,15 +2529,15 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef
.capacity = 5,
.items = ((KeyValuePair[]) {
{ STATIC_CSTR_AS_STRING("generator"),
- STRING_OBJ(STATIC_CSTR_AS_STRING("nvim")) },
+ STATIC_CSTR_AS_OBJ("nvim") },
{ STATIC_CSTR_AS_STRING("version"),
- STRING_OBJ(cstr_as_string(longVersion)) },
+ CSTR_AS_OBJ(longVersion) },
{ STATIC_CSTR_AS_STRING("max_kbyte"),
INTEGER_OBJ((Integer)max_kbyte) },
{ STATIC_CSTR_AS_STRING("pid"),
INTEGER_OBJ((Integer)os_get_pid()) },
{ STATIC_CSTR_AS_STRING("encoding"),
- STRING_OBJ(cstr_as_string(p_enc)) },
+ CSTR_AS_OBJ(p_enc) },
}),
}
}
diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c
index 5a14d57538..015c578396 100644
--- a/src/nvim/statusline.c
+++ b/src/nvim/statusline.c
@@ -596,7 +596,7 @@ void win_redr_ruler(win_T *wp)
MAXSIZE_TEMP_ARRAY(content, 1);
MAXSIZE_TEMP_ARRAY(chunk, 2);
ADD_C(chunk, INTEGER_OBJ(attr));
- ADD_C(chunk, STRING_OBJ(cstr_as_string(buffer)));
+ ADD_C(chunk, CSTR_AS_OBJ(buffer));
ADD_C(content, ARRAY_OBJ(chunk));
ui_call_msg_ruler(content);
did_show_ext_ruler = true;
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 81a68d5b07..30a1af68ad 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -547,8 +547,8 @@ static void set_bg(char *bgvalue)
{
if (ui_client_attached) {
MAXSIZE_TEMP_ARRAY(args, 2);
- ADD_C(args, STRING_OBJ(cstr_as_string("term_background")));
- ADD_C(args, STRING_OBJ(cstr_as_string(bgvalue)));
+ ADD_C(args, CSTR_AS_OBJ("term_background"));
+ ADD_C(args, CSTR_AS_OBJ(bgvalue));
rpc_send_event(ui_client_channel_id, "nvim_ui_set_option", args);
}
}
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 6a9769e351..c9d9b08b79 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1302,16 +1302,16 @@ static void show_verbose_terminfo(TUIData *tui)
Array chunks = ARRAY_DICT_INIT;
Array title = ARRAY_DICT_INIT;
- ADD(title, STRING_OBJ(cstr_to_string("\n\n--- Terminal info --- {{{\n")));
- ADD(title, STRING_OBJ(cstr_to_string("Title")));
+ ADD(title, CSTR_TO_OBJ("\n\n--- Terminal info --- {{{\n"));
+ ADD(title, CSTR_TO_OBJ("Title"));
ADD(chunks, ARRAY_OBJ(title));
Array info = ARRAY_DICT_INIT;
String str = terminfo_info_msg(ut, tui->term);
ADD(info, STRING_OBJ(str));
ADD(chunks, ARRAY_OBJ(info));
Array end_fold = ARRAY_DICT_INIT;
- ADD(end_fold, STRING_OBJ(cstr_to_string("}}}\n")));
- ADD(end_fold, STRING_OBJ(cstr_to_string("Title")));
+ ADD(end_fold, CSTR_TO_OBJ("}}}\n"));
+ ADD(end_fold, CSTR_TO_OBJ("Title"));
ADD(chunks, ARRAY_OBJ(end_fold));
Array args = ARRAY_DICT_INIT;
@@ -1425,7 +1425,7 @@ void tui_option_set(TUIData *tui, String name, Object value)
if (ui_client_channel_id) {
MAXSIZE_TEMP_ARRAY(args, 2);
- ADD_C(args, STRING_OBJ(cstr_as_string("rgb")));
+ ADD_C(args, CSTR_AS_OBJ("rgb"));
ADD_C(args, BOOLEAN_OBJ(value.data.boolean));
rpc_send_event(ui_client_channel_id, "nvim_ui_set_option", args);
}
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 24f20af2f3..8c31032492 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -613,8 +613,8 @@ Array ui_array(void)
PUT(info, "override", BOOLEAN_OBJ(ui->override));
// TUI fields. (`stdin_fd` is intentionally omitted.)
- PUT(info, "term_name", STRING_OBJ(cstr_to_string(ui->term_name)));
- PUT(info, "term_background", STRING_OBJ(cstr_to_string(ui->term_background)));
+ PUT(info, "term_name", CSTR_TO_OBJ(ui->term_name));
+ PUT(info, "term_background", CSTR_TO_OBJ(ui->term_background));
PUT(info, "term_colors", INTEGER_OBJ(ui->term_colors));
PUT(info, "stdin_tty", BOOLEAN_OBJ(ui->stdin_tty));
PUT(info, "stdout_tty", BOOLEAN_OBJ(ui->stdout_tty));
diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c
index b93b31f7dc..1918b0b800 100644
--- a/src/nvim/ui_client.c
+++ b/src/nvim/ui_client.c
@@ -83,11 +83,11 @@ void ui_client_attach(int width, int height, char *term)
PUT_C(opts, "ext_linegrid", BOOLEAN_OBJ(true));
PUT_C(opts, "ext_termcolors", BOOLEAN_OBJ(true));
if (term) {
- PUT_C(opts, "term_name", STRING_OBJ(cstr_as_string(term)));
+ PUT_C(opts, "term_name", CSTR_AS_OBJ(term));
}
if (ui_client_bg_response != kNone) {
bool is_dark = (ui_client_bg_response == kTrue);
- PUT_C(opts, "term_background", STRING_OBJ(cstr_as_string(is_dark ? "dark" : "light")));
+ PUT_C(opts, "term_background", CSTR_AS_OBJ(is_dark ? "dark" : "light"));
}
PUT_C(opts, "term_colors", INTEGER_OBJ(t_colors));
if (!ui_client_is_remote) {
diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c
index 11f2620aaa..c56b241988 100644
--- a/src/nvim/usercmd.c
+++ b/src/nvim/usercmd.c
@@ -1754,8 +1754,8 @@ Dictionary commands_array(buf_T *buf)
Dictionary d = ARRAY_DICT_INIT;
ucmd_T *cmd = USER_CMD_GA(gap, i);
- PUT(d, "name", STRING_OBJ(cstr_to_string(cmd->uc_name)));
- PUT(d, "definition", STRING_OBJ(cstr_to_string(cmd->uc_rep)));
+ PUT(d, "name", CSTR_TO_OBJ(cmd->uc_name));
+ PUT(d, "definition", CSTR_TO_OBJ(cmd->uc_rep));
PUT(d, "script_id", INTEGER_OBJ(cmd->uc_script_ctx.sc_sid));
PUT(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_BANG)));
PUT(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_TRLBAR)));
@@ -1775,21 +1775,21 @@ Dictionary commands_array(buf_T *buf)
case (EX_EXTRA | EX_NOSPC | EX_NEEDARG):
arg[0] = '1'; break;
}
- PUT(d, "nargs", STRING_OBJ(cstr_to_string(arg)));
+ PUT(d, "nargs", CSTR_TO_OBJ(arg));
char *cmd_compl = get_command_complete(cmd->uc_compl);
PUT(d, "complete", (cmd_compl == NULL
- ? NIL : STRING_OBJ(cstr_to_string(cmd_compl))));
+ ? NIL : CSTR_TO_OBJ(cmd_compl)));
PUT(d, "complete_arg", cmd->uc_compl_arg == NULL
- ? NIL : STRING_OBJ(cstr_to_string(cmd->uc_compl_arg)));
+ ? NIL : CSTR_TO_OBJ(cmd->uc_compl_arg));
Object obj = NIL;
if (cmd->uc_argt & EX_COUNT) {
if (cmd->uc_def >= 0) {
snprintf(str, sizeof(str), "%" PRId64, cmd->uc_def);
- obj = STRING_OBJ(cstr_to_string(str)); // -count=N
+ obj = CSTR_TO_OBJ(str); // -count=N
} else {
- obj = STRING_OBJ(cstr_to_string("0")); // -count
+ obj = CSTR_TO_OBJ("0"); // -count
}
}
PUT(d, "count", obj);
@@ -1797,12 +1797,12 @@ Dictionary commands_array(buf_T *buf)
obj = NIL;
if (cmd->uc_argt & EX_RANGE) {
if (cmd->uc_argt & EX_DFLALL) {
- obj = STRING_OBJ(cstr_to_string("%")); // -range=%
+ obj = CSTR_TO_OBJ("%"); // -range=%
} else if (cmd->uc_def >= 0) {
snprintf(str, sizeof(str), "%" PRId64, cmd->uc_def);
- obj = STRING_OBJ(cstr_to_string(str)); // -range=N
+ obj = CSTR_TO_OBJ(str); // -range=N
} else {
- obj = STRING_OBJ(cstr_to_string(".")); // -range
+ obj = CSTR_TO_OBJ("."); // -range
}
}
PUT(d, "range", obj);
@@ -1811,7 +1811,7 @@ Dictionary commands_array(buf_T *buf)
for (int j = 0; addr_type_complete[j].expand != ADDR_NONE; j++) {
if (addr_type_complete[j].expand != ADDR_LINES
&& addr_type_complete[j].expand == cmd->uc_addr_type) {
- obj = STRING_OBJ(cstr_to_string(addr_type_complete[j].name));
+ obj = CSTR_TO_OBJ(addr_type_complete[j].name);
break;
}
}
diff --git a/test/README.md b/test/README.md
index 65a5ae7912..42d0ec0323 100644
--- a/test/README.md
+++ b/test/README.md
@@ -285,7 +285,7 @@ Number; !must be defined to function properly):
- `VALGRIND_LOG` (F) (S): overrides valgrind log file name used for `VALGRIND`.
-- `TEST_COLORS` (F) (U) (D): enable pretty colors in test runner.
+- `TEST_COLORS` (F) (U) (D): enable pretty colors in test runner. Set to true by default.
- `TEST_SKIP_FRAGILE` (F) (D): makes test suite skip some fragile tests.
diff --git a/test/busted/outputHandlers/nvim.lua b/test/busted/outputHandlers/nvim.lua
index e17536e0f8..4bfa21fe49 100644
--- a/test/busted/outputHandlers/nvim.lua
+++ b/test/busted/outputHandlers/nvim.lua
@@ -1,9 +1,15 @@
local pretty = require 'pl.pretty'
local global_helpers = require('test.helpers')
--- Colors are disabled by default. #15610
local colors = setmetatable({}, {__index = function() return function(s) return s == nil and '' or tostring(s) end end})
+
+local enable_colors = true
if os.getenv "TEST_COLORS" then
+ local test_colors = os.getenv("TEST_COLORS"):lower()
+ local disable_colors = test_colors == 'false' or test_colors == '0' or test_colors == 'no' or test_colors == 'off'
+ enable_colors = not disable_colors
+end
+if enable_colors then
colors = require 'term.colors'
end
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua
index df9092fa14..bf9e952319 100644
--- a/test/functional/api/buffer_spec.lua
+++ b/test/functional/api/buffer_spec.lua
@@ -630,19 +630,19 @@ describe('api/buf', function()
eq('Index out of bounds', pcall_err(get_offset, 6))
eq('Index out of bounds', pcall_err(get_offset, -1))
- meths.set_option_value('eol', false, {buf=0})
- meths.set_option_value('fixeol', false, {buf=0})
+ meths.set_option_value('eol', false, {})
+ meths.set_option_value('fixeol', false, {})
eq(28, get_offset(5))
-- fileformat is ignored
- meths.set_option_value('fileformat', 'dos', {buf=0})
+ meths.set_option_value('fileformat', 'dos', {})
eq(0, get_offset(0))
eq(6, get_offset(1))
eq(15, get_offset(2))
eq(16, get_offset(3))
eq(24, get_offset(4))
eq(28, get_offset(5))
- meths.set_option_value('eol', true, {buf=0})
+ meths.set_option_value('eol', true, {})
eq(29, get_offset(5))
command("set hidden")
@@ -699,9 +699,9 @@ describe('api/buf', function()
describe('nvim_get_option_value, nvim_set_option_value', function()
it('works', function()
- eq(8, nvim('get_option_value', 'shiftwidth', {buf = 0}))
- nvim('set_option_value', 'shiftwidth', 4, {buf=0})
- eq(4, nvim('get_option_value', 'shiftwidth', {buf = 0}))
+ eq(8, nvim('get_option_value', 'shiftwidth', {}))
+ nvim('set_option_value', 'shiftwidth', 4, {})
+ eq(4, nvim('get_option_value', 'shiftwidth', {}))
-- global-local option
nvim('set_option_value', 'define', 'test', {buf = 0})
eq('test', nvim('get_option_value', 'define', {buf = 0}))
diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua
index 0960e910f1..675c8332de 100644
--- a/test/functional/api/extmark_spec.lua
+++ b/test/functional/api/extmark_spec.lua
@@ -1401,7 +1401,7 @@ describe('API/extmarks', function()
it('in read-only buffer', function()
command("view! runtime/doc/help.txt")
- eq(true, meths.get_option_value('ro', {buf=0}))
+ eq(true, meths.get_option_value('ro', {}))
local id = set_extmark(ns, 0, 0, 2)
eq({{id, 0, 2}}, get_extmarks(ns,0, -1))
end)
@@ -1474,7 +1474,7 @@ describe('API/extmarks', function()
it('in prompt buffer', function()
feed('dd')
local id = set_extmark(ns, marks[1], 0, 0, {})
- meths.set_option_value('buftype', 'prompt', {buf = 0})
+ meths.set_option_value('buftype', 'prompt', {})
feed('i<esc>')
eq({{id, 0, 2}}, get_extmarks(ns, 0, -1))
end)
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index 1601184e1b..d3a79327ae 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -596,4 +596,9 @@ describe('API: get highlight', function()
eq({}, data["@foobar.hubbabubba"])
eq(nil, data["@foobar"])
end)
+
+ it('should return default flag', function()
+ meths.set_hl(0, 'Tried', { fg = "#00ff00", default = true })
+ eq({ fg = tonumber('00ff00', 16), default = true }, meths.get_hl(0, { name = 'Tried' }))
+ end)
end)
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 5b8b52a559..040c26e058 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1397,7 +1397,7 @@ describe('API', function()
it('works to set global value of local options', function()
nvim('set_option_value', 'lisp', true, {scope='global'})
eq(true, nvim('get_option_value', 'lisp', {scope='global'}))
- eq(false, nvim('get_option_value', 'lisp', {buf=0}))
+ eq(false, nvim('get_option_value', 'lisp', {}))
eq(nil, nvim('command_output', 'setglobal lisp?'):match('nolisp'))
eq('nolisp', nvim('command_output', 'setlocal lisp?'):match('nolisp'))
nvim('set_option_value', 'shiftwidth', 20, {scope='global'})
@@ -1493,7 +1493,7 @@ describe('API', function()
end)
it('set window options', function()
- nvim('set_option_value', 'colorcolumn', '4,3', {win=0})
+ nvim('set_option_value', 'colorcolumn', '4,3', {})
eq('4,3', nvim('get_option_value', 'colorcolumn', {scope = 'local'}))
command("set modified hidden")
command("enew") -- edit new buffer, window option is preserved
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
index 660fa4731e..a6d1807961 100644
--- a/test/functional/api/window_spec.lua
+++ b/test/functional/api/window_spec.lua
@@ -365,11 +365,11 @@ describe('API/win', function()
describe('nvim_get_option_value, nvim_set_option_value', function()
it('works', function()
- nvim('set_option_value', 'colorcolumn', '4,3', {win=0})
- eq('4,3', nvim('get_option_value', 'colorcolumn', {win = 0}))
+ nvim('set_option_value', 'colorcolumn', '4,3', {})
+ eq('4,3', nvim('get_option_value', 'colorcolumn', {}))
command("set modified hidden")
command("enew") -- edit new buffer, window option is preserved
- eq('4,3', nvim('get_option_value', 'colorcolumn', {win = 0}))
+ eq('4,3', nvim('get_option_value', 'colorcolumn', {}))
-- global-local option
nvim('set_option_value', 'statusline', 'window-status', {win=0})
diff --git a/test/functional/ex_cmds/append_spec.lua b/test/functional/ex_cmds/append_spec.lua
index e3a39384a6..4134eed87e 100644
--- a/test/functional/ex_cmds/append_spec.lua
+++ b/test/functional/ex_cmds/append_spec.lua
@@ -43,7 +43,7 @@ local cmdtest = function(cmd, prep, ret1)
eq(hisline, funcs.histget(':', -2))
eq(cmd, funcs.histget(':'))
-- Test that command-line window was launched
- eq('nofile', meths.get_option_value('buftype', {buf=0}))
+ eq('nofile', meths.get_option_value('buftype', {}))
eq('n', funcs.mode(1))
feed('<CR>')
eq('c', funcs.mode(1))
diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua
index f51e7c62cb..7522d4a99c 100644
--- a/test/functional/ex_cmds/mksession_spec.lua
+++ b/test/functional/ex_cmds/mksession_spec.lua
@@ -81,7 +81,7 @@ describe(':mksession', function()
local buf_count = #meths.list_bufs()
eq(2, buf_count)
- eq('terminal', meths.get_option_value('buftype', { buf = 0 }))
+ eq('terminal', meths.get_option_value('buftype', {}))
test_terminal_session_disabled(2)
@@ -112,7 +112,7 @@ describe(':mksession', function()
it('do not restore :terminal if not set in sessionoptions, only buffer #13078', function()
command('terminal')
- eq('terminal', meths.get_option_value('buftype', { buf = 0 }))
+ eq('terminal', meths.get_option_value('buftype', {}))
local buf_count = #meths.list_bufs()
eq(1, buf_count)
@@ -120,7 +120,7 @@ describe(':mksession', function()
test_terminal_session_disabled(1)
-- no terminal should be set
- eq('', meths.get_option_value('buftype', { buf = 0 }))
+ eq('', meths.get_option_value('buftype', {}))
end)
it('restores tab-local working directories', function()
diff --git a/test/functional/legacy/012_directory_spec.lua b/test/functional/legacy/012_directory_spec.lua
index f44ba10f7f..25d0dcb81e 100644
--- a/test/functional/legacy/012_directory_spec.lua
+++ b/test/functional/legacy/012_directory_spec.lua
@@ -58,7 +58,7 @@ describe("'directory' option", function()
end of testfile]])
meths.set_option_value('swapfile', true, {})
- meths.set_option_value('swapfile', true, {buf=0})
+ meths.set_option_value('swapfile', true, {})
meths.set_option_value('directory', '.', {})
-- sanity check: files should not exist yet.
@@ -83,7 +83,7 @@ describe("'directory' option", function()
meths.set_option_value('directory', 'Xtest.je', {})
command('bdelete')
command('edit Xtest2/Xtest3')
- eq(true, meths.get_option_value('swapfile', {buf=0}))
+ eq(true, meths.get_option_value('swapfile', {}))
poke_eventloop()
eq({ "Xtest3" }, ls_dir_sorted("Xtest2"))
diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua
index 64cb524e99..d415b708be 100644
--- a/test/functional/lua/buffer_updates_spec.lua
+++ b/test/functional/lua/buffer_updates_spec.lua
@@ -415,7 +415,7 @@ describe('lua: nvim_buf_attach on_bytes', function()
it('opening lines', function()
local check_events = setup_eventcheck(verify, origlines)
- -- meths.set_option_value('autoindent', true, { buf = 0 })
+ -- meths.set_option_value('autoindent', true, {})
feed 'Go'
check_events {
{ "test1", "bytes", 1, 4, 7, 0, 114, 0, 0, 0, 1, 0, 1 };
@@ -428,7 +428,7 @@ describe('lua: nvim_buf_attach on_bytes', function()
it('opening lines with autoindent', function()
local check_events = setup_eventcheck(verify, origlines)
- meths.set_option_value('autoindent', true, { buf = 0 })
+ meths.set_option_value('autoindent', true, {})
feed 'Go'
check_events {
{ "test1", "bytes", 1, 4, 7, 0, 114, 0, 0, 0, 1, 0, 5 };
@@ -462,8 +462,8 @@ describe('lua: nvim_buf_attach on_bytes', function()
it('continuing comments with fo=or', function()
local check_events = setup_eventcheck(verify, {'// Comment'})
- meths.set_option_value('formatoptions', 'ro', { buf = 0 })
- meths.set_option_value('filetype', 'c', { buf = 0 })
+ meths.set_option_value('formatoptions', 'ro', {})
+ meths.set_option_value('filetype', 'c', {})
feed 'A<CR>'
check_events {
{ "test1", "bytes", 1, 4, 0, 10, 10, 0, 0, 0, 1, 3, 4 };
diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua
index 4ea94796bc..b3d95e1c7f 100644
--- a/test/functional/lua/filetype_spec.lua
+++ b/test/functional/lua/filetype_spec.lua
@@ -134,6 +134,6 @@ end)
describe('filetype.lua', function()
it('does not override user autocommands that set filetype #20333', function()
clear({args={'--clean', '--cmd', 'autocmd BufRead *.md set filetype=notmarkdown', 'README.md'}})
- eq('notmarkdown', meths.get_option_value('filetype', { buf = 0 }))
+ eq('notmarkdown', meths.get_option_value('filetype', {}))
end)
end)
diff --git a/test/functional/lua/luaeval_spec.lua b/test/functional/lua/luaeval_spec.lua
index 31da5db1df..dfbd2fb18b 100644
--- a/test/functional/lua/luaeval_spec.lua
+++ b/test/functional/lua/luaeval_spec.lua
@@ -514,7 +514,7 @@ describe('v:lua', function()
[5] = {bold = true, foreground = Screen.colors.SeaGreen4},
})
screen:attach()
- meths.set_option_value('omnifunc', 'v:lua.mymod.omni', { buf = 0 })
+ meths.set_option_value('omnifunc', 'v:lua.mymod.omni', {})
feed('isome st<c-x><c-o>')
screen:expect{grid=[[
some stuff^ |
diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua
index 72c99ac1f3..cd19ea4e49 100644
--- a/test/functional/lua/runtime_spec.lua
+++ b/test/functional/lua/runtime_spec.lua
@@ -61,6 +61,38 @@ describe('runtime:', function()
eq('vim', eval('g:colorscheme'))
end)
+
+ it("loads lua colorscheme in 'rtp' if vim version only exists in 'pp' #23724", function()
+ local pack_dir = 'Test_Pack'
+ mkdir_p(pack_dir)
+ finally(function()
+ rmdir(pack_dir)
+ end)
+ exec('set pp+=' .. pack_dir)
+
+ local pack_opt_dir = pack_dir .. sep .. 'pack' .. sep .. 'some_name' .. sep .. 'opt'
+ local colors_opt_dir = pack_opt_dir .. sep .. 'some_pack' .. sep .. 'colors'
+ mkdir_p(colors_opt_dir)
+
+ local rtp_colorscheme_file = colorscheme_folder .. sep .. 'new_colorscheme'
+ local pp_opt_colorscheme_file = colors_opt_dir .. sep .. 'new_colorscheme'
+
+ write_file(pp_opt_colorscheme_file .. '.lua', [[vim.g.colorscheme = 'lua_pp']])
+ exec('colorscheme new_colorscheme')
+ eq('lua_pp', eval('g:colorscheme'))
+
+ write_file(pp_opt_colorscheme_file .. '.vim', [[let g:colorscheme = 'vim_pp']])
+ exec('colorscheme new_colorscheme')
+ eq('vim_pp', eval('g:colorscheme'))
+
+ write_file(rtp_colorscheme_file .. '.lua', [[vim.g.colorscheme = 'lua_rtp']])
+ exec('colorscheme new_colorscheme')
+ eq('lua_rtp', eval('g:colorscheme'))
+
+ write_file(rtp_colorscheme_file .. '.vim', [[let g:colorscheme = 'vim_rtp']])
+ exec('colorscheme new_colorscheme')
+ eq('vim_rtp', eval('g:colorscheme'))
+ end)
end)
describe('compiler', function()
diff --git a/test/functional/lua/secure_spec.lua b/test/functional/lua/secure_spec.lua
index 9a6292a6c6..fc20a06390 100644
--- a/test/functional/lua/secure_spec.lua
+++ b/test/functional/lua/secure_spec.lua
@@ -160,7 +160,7 @@ describe('vim.secure', function()
-- Cannot write file
pcall_err(command, 'write')
- eq(true, meths.get_option_value('readonly', {buf=0}))
+ eq(true, meths.get_option_value('readonly', {}))
end)
end)
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 9a7654d610..978a4fe0b6 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -1496,7 +1496,7 @@ describe('lua stdlib', function()
it('vim.bo', function()
eq('', funcs.luaeval "vim.bo.filetype")
exec_lua [[
- vim.api.nvim_set_option_value("filetype", "markdown", {buf = 0})
+ vim.api.nvim_set_option_value("filetype", "markdown", {})
BUF = vim.api.nvim_create_buf(false, true)
vim.api.nvim_set_option_value("modifiable", false, {buf = BUF})
]]
@@ -1519,9 +1519,9 @@ describe('lua stdlib', function()
it('vim.wo', function()
exec_lua [[
- vim.api.nvim_set_option_value("cole", 2, {win=0})
+ vim.api.nvim_set_option_value("cole", 2, {})
vim.cmd "split"
- vim.api.nvim_set_option_value("cole", 2, {win=0})
+ vim.api.nvim_set_option_value("cole", 2, {})
]]
eq(2, funcs.luaeval "vim.wo.cole")
exec_lua [[
diff --git a/test/functional/plugin/lsp/incremental_sync_spec.lua b/test/functional/plugin/lsp/incremental_sync_spec.lua
index 1dca464d74..724b3efb97 100644
--- a/test/functional/plugin/lsp/incremental_sync_spec.lua
+++ b/test/functional/plugin/lsp/incremental_sync_spec.lua
@@ -21,7 +21,7 @@ before_each(function ()
-- ["mac"] = '\r',
-- }
- -- local line_ending = format_line_ending[vim.api.nvim_get_option_value('fileformat', {buf=0})]
+ -- local line_ending = format_line_ending[vim.api.nvim_get_option_value('fileformat', {})]
function test_register(bufnr, id, offset_encoding, line_ending)
diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua
index 43222f1904..8d37100607 100644
--- a/test/functional/plugin/shada_spec.lua
+++ b/test/functional/plugin/shada_spec.lua
@@ -2181,8 +2181,8 @@ describe('plugin/shada.vim', function()
' - contents "ab"',
' - "a"',
}, nvim_eval('getline(1, "$")'))
- eq(false, nvim('get_option_value', 'modified', {buf=0}))
- eq('shada', nvim('get_option_value', 'filetype', {buf=0}))
+ eq(false, nvim('get_option_value', 'modified', {}))
+ eq('shada', nvim('get_option_value', 'filetype', {}))
nvim_command('edit ' .. fname_tmp)
eq({
'History entry with timestamp ' .. epoch .. ':',
@@ -2191,8 +2191,8 @@ describe('plugin/shada.vim', function()
' - contents "ab"',
' - "b"',
}, nvim_eval('getline(1, "$")'))
- eq(false, nvim('get_option_value', 'modified', {buf=0}))
- eq('shada', nvim('get_option_value', 'filetype', {buf=0}))
+ eq(false, nvim('get_option_value', 'modified', {}))
+ eq('shada', nvim('get_option_value', 'filetype', {}))
eq('++opt not supported', exc_exec('edit ++enc=latin1 ' .. fname))
neq({
'History entry with timestamp ' .. epoch .. ':',
@@ -2201,7 +2201,7 @@ describe('plugin/shada.vim', function()
' - contents "ab"',
' - "a"',
}, nvim_eval('getline(1, "$")'))
- neq(true, nvim('get_option_value', 'modified', {buf=0}))
+ neq(true, nvim('get_option_value', 'modified', {}))
end)
it('event FileReadCmd', function()
@@ -2217,8 +2217,8 @@ describe('plugin/shada.vim', function()
' - contents "ab"',
' - "a"',
}, nvim_eval('getline(1, "$")'))
- eq(true, nvim('get_option_value', 'modified', {buf=0}))
- neq('shada', nvim('get_option_value', 'filetype', {buf=0}))
+ eq(true, nvim('get_option_value', 'modified', {}))
+ neq('shada', nvim('get_option_value', 'filetype', {}))
nvim_command('1,$read ' .. fname_tmp)
eq({
'',
@@ -2233,9 +2233,9 @@ describe('plugin/shada.vim', function()
' - contents "ab"',
' - "b"',
}, nvim_eval('getline(1, "$")'))
- eq(true, nvim('get_option_value', 'modified', {buf=0}))
- neq('shada', nvim('get_option_value', 'filetype', {buf=0}))
- nvim('set_option_value', 'modified', false, {buf=0})
+ eq(true, nvim('get_option_value', 'modified', {}))
+ neq('shada', nvim('get_option_value', 'filetype', {}))
+ nvim('set_option_value', 'modified', false, {})
eq('++opt not supported', exc_exec('$read ++enc=latin1 ' .. fname))
eq({
'',
@@ -2250,7 +2250,7 @@ describe('plugin/shada.vim', function()
' - contents "ab"',
' - "b"',
}, nvim_eval('getline(1, "$")'))
- neq(true, nvim('get_option_value', 'modified', {buf=0}))
+ neq(true, nvim('get_option_value', 'modified', {}))
end)
it('event BufWriteCmd', function()
@@ -2517,10 +2517,10 @@ describe('ftplugin/shada.vim', function()
it('sets options correctly', function()
nvim_command('filetype plugin indent on')
nvim_command('setlocal filetype=shada')
- eq(true, nvim('get_option_value', 'expandtab', {buf=0}))
- eq(2, nvim('get_option_value', 'tabstop', {buf=0}))
- eq(2, nvim('get_option_value', 'softtabstop', {buf=0}))
- eq(2, nvim('get_option_value', 'shiftwidth', {buf=0}))
+ eq(true, nvim('get_option_value', 'expandtab', {}))
+ eq(2, nvim('get_option_value', 'tabstop', {}))
+ eq(2, nvim('get_option_value', 'softtabstop', {}))
+ eq(2, nvim('get_option_value', 'shiftwidth', {}))
end)
it('sets indentkeys correctly', function()
diff --git a/test/functional/provider/perl_spec.lua b/test/functional/provider/perl_spec.lua
index bc7261895d..8049f0f3e2 100644
--- a/test/functional/provider/perl_spec.lua
+++ b/test/functional/provider/perl_spec.lua
@@ -45,7 +45,7 @@ describe('legacy perl provider', function()
-- :perldo 1; doesn't change $_,
-- the buffer should not be changed
command('normal :perldo 1;')
- eq(false, meths.get_option_value('modified', {buf=0}))
+ eq(false, meths.get_option_value('modified', {}))
-- insert some text
insert('abc\ndef\nghi')
expect([[
diff --git a/test/functional/provider/ruby_spec.lua b/test/functional/provider/ruby_spec.lua
index 40ace28c4e..d3b967dfbe 100644
--- a/test/functional/provider/ruby_spec.lua
+++ b/test/functional/provider/ruby_spec.lua
@@ -97,7 +97,7 @@ describe(':rubydo command', function()
it('does not modify the buffer if no changes are made', function()
command('normal :rubydo 42')
- eq(false, meths.get_option_value('modified', {buf=0}))
+ eq(false, meths.get_option_value('modified', {}))
end)
end)
diff --git a/test/functional/shada/buffers_spec.lua b/test/functional/shada/buffers_spec.lua
index 2740eeeca6..b1c4ded541 100644
--- a/test/functional/shada/buffers_spec.lua
+++ b/test/functional/shada/buffers_spec.lua
@@ -48,7 +48,7 @@ describe('shada support code', function()
reset('set shada+=%')
nvim_command('edit ' .. testfilename)
nvim_command('edit ' .. testfilename_2)
- meths.set_option_value('buflisted', false, {buf=0})
+ meths.set_option_value('buflisted', false, {})
expect_exit(nvim_command, 'qall')
reset('set shada+=%')
eq(2, funcs.bufnr('$'))
@@ -60,7 +60,7 @@ describe('shada support code', function()
reset('set shada+=%')
nvim_command('edit ' .. testfilename)
nvim_command('edit ' .. testfilename_2)
- meths.set_option_value('buftype', 'quickfix', {buf=0})
+ meths.set_option_value('buftype', 'quickfix', {})
expect_exit(nvim_command, 'qall')
reset('set shada+=%')
eq(2, funcs.bufnr('$'))
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 48a9fa7171..5d3e55d898 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -401,7 +401,7 @@ describe("'scrollback' option", function()
screen = thelpers.screen_setup(nil, "['sh']", 30)
end
- meths.set_option_value('scrollback', 0, {buf = 0})
+ meths.set_option_value('scrollback', 0, {})
feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n'))
screen:expect{any='30: line '}
retry(nil, nil, function() expect_lines(7) end)
@@ -417,7 +417,7 @@ describe("'scrollback' option", function()
screen = thelpers.screen_setup(nil, "['sh']", 30)
end
- meths.set_option_value('scrollback', 200, {buf=0})
+ meths.set_option_value('scrollback', 200, {})
-- Wait for prompt.
screen:expect{any='%$'}
@@ -426,10 +426,10 @@ describe("'scrollback' option", function()
screen:expect{any='30: line '}
retry(nil, nil, function() expect_lines(33, 2) end)
- meths.set_option_value('scrollback', 10, {buf=0})
+ meths.set_option_value('scrollback', 10, {})
poke_eventloop()
retry(nil, nil, function() expect_lines(16) end)
- meths.set_option_value('scrollback', 10000, {buf=0})
+ meths.set_option_value('scrollback', 10000, {})
retry(nil, nil, function() expect_lines(16) end)
-- Terminal job data is received asynchronously, may happen before the
-- 'scrollback' option is synchronized with the internal sb_buffer.
@@ -484,18 +484,18 @@ describe("'scrollback' option", function()
]])
local term_height = 6 -- Actual terminal screen height, not the scrollback
-- Initial
- local scrollback = meths.get_option_value('scrollback', {buf=0})
+ local scrollback = meths.get_option_value('scrollback', {})
eq(scrollback + term_height, eval('line("$")'))
-- Reduction
scrollback = scrollback - 2
- meths.set_option_value('scrollback', scrollback, {buf=0})
+ meths.set_option_value('scrollback', scrollback, {})
eq(scrollback + term_height, eval('line("$")'))
end)
it('defaults to 10000 in :terminal buffers', function()
set_fake_shell()
command('terminal')
- eq(10000, meths.get_option_value('scrollback', {buf=0}))
+ eq(10000, meths.get_option_value('scrollback', {}))
end)
it('error if set to invalid value', function()
@@ -507,7 +507,7 @@ describe("'scrollback' option", function()
it('defaults to -1 on normal buffers', function()
command('new')
- eq(-1, meths.get_option_value('scrollback', {buf=0}))
+ eq(-1, meths.get_option_value('scrollback', {}))
end)
it(':setlocal in a :terminal buffer', function()
@@ -516,45 +516,45 @@ describe("'scrollback' option", function()
-- _Global_ scrollback=-1 defaults :terminal to 10_000.
command('setglobal scrollback=-1')
command('terminal')
- eq(10000, meths.get_option_value('scrollback', {buf=0}))
+ eq(10000, meths.get_option_value('scrollback', {}))
-- _Local_ scrollback=-1 in :terminal forces the _maximum_.
command('setlocal scrollback=-1')
retry(nil, nil, function() -- Fixup happens on refresh, not immediately.
- eq(100000, meths.get_option_value('scrollback', {buf=0}))
+ eq(100000, meths.get_option_value('scrollback', {}))
end)
-- _Local_ scrollback=-1 during TermOpen forces the maximum. #9605
command('setglobal scrollback=-1')
command('autocmd TermOpen * setlocal scrollback=-1')
command('terminal')
- eq(100000, meths.get_option_value('scrollback', {buf=0}))
+ eq(100000, meths.get_option_value('scrollback', {}))
end)
it(':setlocal in a normal buffer', function()
command('new')
-- :setlocal to -1.
command('setlocal scrollback=-1')
- eq(-1, meths.get_option_value('scrollback', {buf=0}))
+ eq(-1, meths.get_option_value('scrollback', {}))
-- :setlocal to anything except -1. Currently, this just has no effect.
command('setlocal scrollback=42')
- eq(42, meths.get_option_value('scrollback', {buf=0}))
+ eq(42, meths.get_option_value('scrollback', {}))
end)
it(':set updates local value and global default', function()
set_fake_shell()
command('set scrollback=42') -- set global value
- eq(42, meths.get_option_value('scrollback', {buf=0}))
+ eq(42, meths.get_option_value('scrollback', {}))
command('terminal')
- eq(42, meths.get_option_value('scrollback', {buf=0})) -- inherits global default
+ eq(42, meths.get_option_value('scrollback', {})) -- inherits global default
command('setlocal scrollback=99')
- eq(99, meths.get_option_value('scrollback', {buf=0}))
+ eq(99, meths.get_option_value('scrollback', {}))
command('set scrollback<') -- reset to global default
- eq(42, meths.get_option_value('scrollback', {buf=0}))
+ eq(42, meths.get_option_value('scrollback', {}))
command('setglobal scrollback=734') -- new global default
- eq(42, meths.get_option_value('scrollback', {buf=0})) -- local value did not change
+ eq(42, meths.get_option_value('scrollback', {})) -- local value did not change
command('terminal')
- eq(734, meths.get_option_value('scrollback', {buf=0}))
+ eq(734, meths.get_option_value('scrollback', {}))
end)
end)
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 3cfd222336..1b65c1cddc 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -1458,8 +1458,8 @@ describe('TUI', function()
it('allows grid to assume wider ambiguous-width characters than host terminal #19686', function()
child_session:request('nvim_buf_set_lines', 0, 0, -1, true, { ('℃'):rep(60), ('℃'):rep(60) })
- child_session:request('nvim_set_option_value', 'cursorline', true, {win=0})
- child_session:request('nvim_set_option_value', 'list', true, {win=0})
+ child_session:request('nvim_set_option_value', 'cursorline', true, {})
+ child_session:request('nvim_set_option_value', 'list', true, {})
child_session:request('nvim_set_option_value', 'listchars', 'eol:$', {win=0})
feed_data('gg')
local singlewidth_screen = [[
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index 3e1520e5fd..da14531fa2 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -71,7 +71,7 @@ describe(':terminal', function()
end)
it('does not change size if updated when not visible in any window #19665', function()
- local channel = meths.get_option_value('channel', { buf = 0 })
+ local channel = meths.get_option_value('channel', {})
command('enew')
sleep(100)
meths.chan_send(channel, 'foo')
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index 324362a865..e430865df6 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -611,6 +611,20 @@ describe('decorations providers', function()
end)
end)
+local example_text = [[
+for _,item in ipairs(items) do
+ local text, hl_id_cell, count = unpack(item)
+ if hl_id_cell ~= nil then
+ hl_id = hl_id_cell
+ end
+ for _ = 1, (count or 1) do
+ local cell = line[colpos]
+ cell.text = text
+ cell.hl_id = hl_id
+ colpos = colpos+1
+ end
+end]]
+
describe('extmark decorations', function()
local screen, ns
before_each( function()
@@ -650,20 +664,6 @@ describe('extmark decorations', function()
ns = meths.create_namespace 'test'
end)
- local example_text = [[
-for _,item in ipairs(items) do
- local text, hl_id_cell, count = unpack(item)
- if hl_id_cell ~= nil then
- hl_id = hl_id_cell
- end
- for _ = 1, (count or 1) do
- local cell = line[colpos]
- cell.text = text
- cell.hl_id = hl_id
- colpos = colpos+1
- end
-end]]
-
it('empty virtual text at eol should not break colorcolumn #17860', function()
insert(example_text)
feed('gg')
@@ -704,14 +704,14 @@ end]]
-- can "float" beyond end of line
meths.buf_set_extmark(0, ns, 5, 28, { virt_text={{'loopy', 'ErrorMsg'}}, virt_text_pos='overlay'})
-- bound check: right edge of window
- meths.buf_set_extmark(0, ns, 2, 26, { virt_text={{'bork bork bork '}, {'bork bork bork', 'ErrorMsg'}}, virt_text_pos='overlay'})
+ meths.buf_set_extmark(0, ns, 2, 26, { virt_text={{'bork bork bork'}, {(' bork'):rep(10), 'ErrorMsg'}}, virt_text_pos='overlay'})
-- empty virt_text should not change anything
meths.buf_set_extmark(0, ns, 6, 16, { virt_text={{''}}, virt_text_pos='overlay'})
screen:expect{grid=[[
^for _,item in ipairs(items) do |
{2:|} local text, hl_id_cell, count = unpack(item) |
- {2:|} if hl_id_cell ~= nil tbork bork bork {4:bork bork}|
+ {2:|} if hl_id_cell ~= nil tbork bork bork{4: bork bork}|
{2:|} {1:|} hl_id = hl_id_cell |
{2:|} end |
{2:|} for _ = 1, (count or 1) {4:loopy} |
@@ -726,7 +726,6 @@ end]]
|
]]}
-
-- handles broken lines
screen:try_resize(22, 25)
screen:expect{grid=[[
@@ -736,7 +735,7 @@ end]]
cell, count = unpack(i|
tem) |
{2:|} if hl_id_cell ~= n|
- il tbork bork bork {4:bor}|
+ il tbork bork bork{4: bor}|
{2:|} {1:|} hl_id = hl_id_|
cell |
{2:|} end |
@@ -756,6 +755,75 @@ end]]
{1:~ }|
|
]]}
+
+ -- truncating in the middle of a char leaves a space
+ meths.buf_set_lines(0, 0, 1, true, {'for _,item in ipairs(items) do -- 古古古'})
+ meths.buf_set_lines(0, 10, 12, true, {' end -- ??????????', 'end -- ?古古古古?古古'})
+ meths.buf_set_extmark(0, ns, 0, 35, { virt_text={{'A', 'ErrorMsg'}, {'AA'}}, virt_text_pos='overlay'})
+ meths.buf_set_extmark(0, ns, 10, 19, { virt_text={{'口口口', 'ErrorMsg'}}, virt_text_pos='overlay'})
+ meths.buf_set_extmark(0, ns, 11, 21, { virt_text={{'口口口', 'ErrorMsg'}}, virt_text_pos='overlay'})
+ meths.buf_set_extmark(0, ns, 11, 8, { virt_text={{'口口', 'ErrorMsg'}}, virt_text_pos='overlay'})
+ screen:expect{grid=[[
+ ^for _,item in ipairs(i|
+ tems) do -- {4:A}AA 古 |
+ {2:|} local text, hl_id_|
+ cell, count = unpack(i|
+ tem) |
+ {2:|} if hl_id_cell ~= n|
+ il tbork bork bork{4: bor}|
+ {2:|} {1:|} hl_id = hl_id_|
+ cell |
+ {2:|} end |
+ {2:|} for _ = 1, (count |
+ or 1) {4:loopy} |
+ {2:|} {1:|} local cell = l|
+ ine[colpos] |
+ {2:|} {1:|} cell.text = te|
+ xt |
+ {2:|} {1:|} cell.hl_id = h|
+ l_id |
+ {2:|} {1:|} cofoo{3:bar}{4:!!}olpo|
+ s+1 |
+ end -- ???????{4:口 }|
+ end -- {4:口口} 古古{4:口口 }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ screen:try_resize(82, 13)
+ screen:expect{grid=[[
+ ^for _,item in ipairs(items) do -- {4:A}AA 古 |
+ {2:|} local text, hl_id_cell, count = unpack(item) |
+ {2:|} if hl_id_cell ~= nil tbork bork bork{4: bork bork bork bork bork bork bork bork b}|
+ {2:|} {1:|} hl_id = hl_id_cell |
+ {2:|} end |
+ {2:|} for _ = 1, (count or 1) {4:loopy} |
+ {2:|} {1:|} local cell = line[colpos] |
+ {2:|} {1:|} cell.text = text |
+ {2:|} {1:|} cell.hl_id = hl_id |
+ {2:|} {1:|} cofoo{3:bar}{4:!!}olpos+1 |
+ end -- ???????{4:口口口} |
+ end -- {4:口口} 古古{4:口口口} |
+ |
+ ]]}
+
+ meths.buf_clear_namespace(0, ns, 0, -1)
+ screen:expect{grid=[[
+ ^for _,item in ipairs(items) do -- 古古古 |
+ local text, hl_id_cell, count = unpack(item) |
+ if hl_id_cell ~= nil then |
+ hl_id = hl_id_cell |
+ end |
+ for _ = 1, (count or 1) do |
+ local cell = line[colpos] |
+ cell.text = text |
+ cell.hl_id = hl_id |
+ colpos = colpos+1 |
+ end -- ?????????? |
+ end -- ?古古古古?古古 |
+ |
+ ]]}
end)
it('can have virtual text of overlay position and styling', function()
@@ -1165,7 +1233,744 @@ end]]
meths.buf_set_extmark(0, ns, 0, 3, { end_col = 6, hl_group = 'TestBold', priority = 20 })
screen:expect_unchanged(true)
end)
+end)
+
+describe('decorations: inline virtual text', function()
+ local screen, ns
+ before_each( function()
+ clear()
+ screen = Screen.new(50, 10)
+ screen:attach()
+ screen:set_default_attr_ids {
+ [1] = {bold=true, foreground=Screen.colors.Blue};
+ [2] = {foreground = Screen.colors.Brown};
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen};
+ [4] = {background = Screen.colors.Red1, foreground = Screen.colors.Gray100};
+ [5] = {background = Screen.colors.Red1, bold = true};
+ [6] = {foreground = Screen.colors.DarkCyan};
+ [7] = {background = Screen.colors.LightGrey};
+ [8] = {bold = true};
+ [9] = {background = Screen.colors.Plum1};
+ [10] = {foreground = Screen.colors.SlateBlue};
+ [11] = {blend = 30, background = Screen.colors.Red1};
+ [12] = {background = Screen.colors.Yellow1};
+ [13] = {reverse = true};
+ [14] = {foreground = Screen.colors.SlateBlue, background = Screen.colors.LightMagenta};
+ [15] = {bold = true, reverse = true};
+ }
+
+ ns = meths.create_namespace 'test'
+ end)
+
+
+ it('works', function()
+ insert(example_text)
+ feed 'gg'
+ screen:expect{grid=[[
+ ^for _,item in ipairs(items) do |
+ local text, hl_id_cell, count = unpack(item) |
+ if hl_id_cell ~= nil then |
+ hl_id = hl_id_cell |
+ end |
+ for _ = 1, (count or 1) do |
+ local cell = line[colpos] |
+ cell.text = text |
+ cell.hl_id = hl_id |
+ |
+ ]]}
+
+ meths.buf_set_extmark(0, ns, 1, 14, {virt_text={{': ', 'Special'}, {'string', 'Type'}}, virt_text_pos='inline'})
+ screen:expect{grid=[[
+ ^for _,item in ipairs(items) do |
+ local text{10:: }{3:string}, hl_id_cell, count = unpack|
+ (item) |
+ if hl_id_cell ~= nil then |
+ hl_id = hl_id_cell |
+ end |
+ for _ = 1, (count or 1) do |
+ local cell = line[colpos] |
+ cell.text = text |
+ |
+ ]]}
+
+ screen:try_resize(55, 10)
+ screen:expect{grid=[[
+ ^for _,item in ipairs(items) do |
+ local text{10:: }{3:string}, hl_id_cell, count = unpack(item|
+ ) |
+ if hl_id_cell ~= nil then |
+ hl_id = hl_id_cell |
+ end |
+ for _ = 1, (count or 1) do |
+ local cell = line[colpos] |
+ cell.text = text |
+ |
+ ]]}
+
+ screen:try_resize(56, 10)
+ screen:expect{grid=[[
+ ^for _,item in ipairs(items) do |
+ local text{10:: }{3:string}, hl_id_cell, count = unpack(item)|
+ if hl_id_cell ~= nil then |
+ hl_id = hl_id_cell |
+ end |
+ for _ = 1, (count or 1) do |
+ local cell = line[colpos] |
+ cell.text = text |
+ cell.hl_id = hl_id |
+ |
+ ]]}
+ end)
+
+ it('cursor positions are correct with multiple inline virtual text', function()
+ insert('12345678')
+ meths.buf_set_extmark(0, ns, 0, 4,
+ { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' })
+ meths.buf_set_extmark(0, ns, 0, 4,
+ { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' })
+ feed '^'
+ feed '4l'
+ screen:expect { grid = [[
+ 1234{10: virtual text virtual text }^5678 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('adjusts cursor location correctly when inserting around inline virtual text', function()
+ insert('12345678')
+ feed '$'
+ meths.buf_set_extmark(0, ns, 0, 4,
+ { virt_text = { { ' virtual text ', 'Special' } }, virt_text_pos = 'inline' })
+
+ screen:expect { grid = [[
+ 1234{10: virtual text }567^8 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('has correct highlighting with multi-byte characters', function()
+ insert('12345678')
+ meths.buf_set_extmark(0, ns, 0, 4,
+ { virt_text = { { 'múlti-byté chñröcters 修补', 'Special' } }, virt_text_pos = 'inline' })
+
+ screen:expect { grid = [[
+ 1234{10:múlti-byté chñröcters 修补}567^8 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('has correct cursor position when inserting around virtual text', function()
+ insert('12345678')
+ meths.buf_set_extmark(0, ns, 0, 4,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ feed '^'
+ feed '3l'
+ feed 'a'
+ screen:expect { grid = [[
+ 1234{10:^virtual text}5678 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {8:-- INSERT --} |
+ ]]}
+ feed '<ESC>'
+ screen:expect{grid=[[
+ 123^4{10:virtual text}5678 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ feed '^'
+ feed '4l'
+ feed 'i'
+ screen:expect { grid = [[
+ 1234{10:^virtual text}5678 |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {8:-- INSERT --} |
+ ]]}
+ end)
+
+ it('has correct cursor position with virtual text on an empty line', function()
+ meths.buf_set_extmark(0, ns, 0, 0,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ screen:expect { grid = [[
+ {10:^virtual text} |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('text is drawn correctly when inserting a wrapping virtual text on an empty line', function()
+ feed('o<esc>')
+ insert([[aaaaaaa
+
+bbbbbbb]])
+ meths.buf_set_extmark(0, ns, 0, 0,
+ { virt_text = { { string.rep('X', 51), 'Special' } }, virt_text_pos = 'inline' })
+ meths.buf_set_extmark(0, ns, 2, 0,
+ { virt_text = { { string.rep('X', 50), 'Special' } }, virt_text_pos = 'inline' })
+ feed('gg0')
+ screen:expect { grid = [[
+ {10:^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ {10:X} |
+ aaaaaaa |
+ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ bbbbbbb |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('j')
+ screen:expect { grid = [[
+ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ {10:X} |
+ ^aaaaaaa |
+ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ bbbbbbb |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('j')
+ screen:expect { grid = [[
+ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ {10:X} |
+ aaaaaaa |
+ {10:^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ bbbbbbb |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('j')
+ screen:expect { grid = [[
+ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ {10:X} |
+ aaaaaaa |
+ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ ^bbbbbbb |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('cursor position is correct with virtual text attached to hard tabs', function()
+ command('set noexpandtab')
+ feed('i')
+ feed('<TAB>')
+ feed('<TAB>')
+ feed('test')
+ feed('<ESC>')
+ meths.buf_set_extmark(0, ns, 0, 1,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ feed('0')
+ screen:expect { grid = [[
+ ^ {10:virtual text} test |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('l')
+ screen:expect { grid = [[
+ {10:virtual text} ^ test |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('l')
+ screen:expect { grid = [[
+ {10:virtual text} ^test |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('l')
+ screen:expect { grid = [[
+ {10:virtual text} t^est |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('l')
+ screen:expect { grid = [[
+ {10:virtual text} te^st |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('cursor position is correct with virtual text on an empty line', function()
+ command('set linebreak')
+ insert('one twoword')
+ feed('0')
+ meths.buf_set_extmark(0, ns, 0, 3,
+ { virt_text = { { ': virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ screen:expect { grid = [[
+ ^one{10:: virtual text} twoword |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('search highlight is correct', function()
+ insert('foo foo foo foo')
+ feed('0')
+ meths.buf_set_extmark(0, ns, 0, 8,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ screen:expect { grid = [[
+ ^foo foo {10:virtual text}foo foo |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('/foo')
+ screen:expect { grid = [[
+ {12:foo} {13:foo} {10:virtual text}{12:foo} {12:foo} |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ /foo^ |
+ ]]}
+ end)
+
+ it('visual select highlight is correct', function()
+ insert('foo foo foo foo')
+ feed('0')
+ meths.buf_set_extmark(0, ns, 0, 8,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ feed('8l')
+ screen:expect { grid = [[
+ foo foo {10:virtual text}^foo foo |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('v')
+ feed('2h')
+ screen:expect { grid = [[
+ foo fo^o{7: }{10:virtual text}{7:f}oo foo |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {8:-- VISUAL --} |
+ ]]}
+ end)
+
+ it('cursor position is correct when inserting around a virtual text with right gravity set to false', function()
+ insert('foo foo foo foo')
+ meths.buf_set_extmark(0, ns, 0, 8,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline', right_gravity = false })
+ feed('0')
+ feed('8l')
+ screen:expect { grid = [[
+ foo foo {10:virtual text}^foo foo |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('i')
+ screen:expect { grid = [[
+ foo foo {10:virtual text}^foo foo |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {8:-- INSERT --} |
+ ]]}
+ end)
+
+ it('cursor position is correct when inserting around virtual texts with both left and right gravity ', function()
+ insert('foo foo foo foo')
+ meths.buf_set_extmark(0, ns, 0, 8, { virt_text = {{ '>>', 'Special' }}, virt_text_pos = 'inline', right_gravity = false })
+ meths.buf_set_extmark(0, ns, 0, 8, { virt_text = {{ '<<', 'Special' }}, virt_text_pos = 'inline', right_gravity = true })
+ feed('08l')
+ screen:expect{ grid = [[
+ foo foo {10:>><<}^foo foo |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ feed('i')
+ screen:expect { grid = [[
+ foo foo {10:>>^<<}foo foo |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {8:-- INSERT --} |
+ ]]}
+ end)
+
+ it('draws correctly with no wrap multiple virtual text, where one is hidden', function()
+ insert('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz')
+ command("set nowrap")
+ meths.buf_set_extmark(0, ns, 0, 50,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ meths.buf_set_extmark(0, ns, 0, 2,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ feed('$')
+ screen:expect { grid = [[
+ opqrstuvwxyzabcdefghijklmnopqrstuvwx{10:virtual text}y^z|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('draws correctly with no wrap and a long virtual text', function()
+ insert('abcdefghi')
+ command("set nowrap")
+ meths.buf_set_extmark(0, ns, 0, 2,
+ { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline' })
+ feed('$')
+ screen:expect { grid = [[
+ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}cdefgh^i|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('tabs are the correct length with no wrap following virtual text', function()
+ command('set nowrap')
+ feed('itest<TAB>a<ESC>')
+ meths.buf_set_extmark(0, ns, 0, 0,
+ { virt_text = { { string.rep('a', 55), 'Special' } }, virt_text_pos = 'inline' })
+ feed('gg$')
+ screen:expect { grid = [[
+ {10:aaaaaaaaaaaaaaaaaaaaaaaaa}test ^a |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('highlighting does not extend when no wrap is enabled with a long virtual text', function()
+ insert('abcdef')
+ command("set nowrap")
+ meths.buf_set_extmark(0, ns, 0, 3,
+ { virt_text = { { string.rep('X', 50), 'Special' } }, virt_text_pos = 'inline' })
+ feed('$')
+ screen:expect { grid = [[
+ {10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}de^f|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('highlighting is correct when virtual text wraps with number', function()
+ insert([[
+ test
+ test]])
+ command('set number')
+ meths.buf_set_extmark(0, ns, 0, 1,
+ { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline' })
+ feed('gg0')
+ screen:expect { grid = [[
+ {2: 1 }^t{10:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}|
+ {2: }{10:XXXXXXXXXX}est |
+ {2: 2 }test |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('highlighting is correct when virtual text is proceeded with a match', function()
+ insert([[test]])
+ meths.buf_set_extmark(0, ns, 0, 2,
+ { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline' })
+ feed('gg0')
+ command('match ErrorMsg /e/')
+ screen:expect { grid = [[
+ ^t{4:e}{10:virtual text}st |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ command('match ErrorMsg /s/')
+ screen:expect { grid = [[
+ ^te{10:virtual text}{4:s}t |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('in diff mode is highlighted correct', function()
+ insert([[
+ 9000
+ 0009
+ 0009
+ 9000
+ 0009
+ ]])
+ command("set diff")
+ meths.buf_set_extmark(0, ns, 0, 1,
+ { virt_text = { { 'test', 'Special' } }, virt_text_pos = 'inline', right_gravity = false })
+ command("vnew")
+ insert([[
+ 000
+ 000
+ 000
+ 000
+ 000
+ ]])
+ command("set diff")
+ feed('gg0')
+ screen:expect { grid = [[
+ {9:^000 }│{5:9}{14:test}{9:000 }|
+ {9:000 }│{9:000}{5:9}{9: }|
+ {9:000 }│{9:000}{5:9}{9: }|
+ {9:000 }│{5:9}{9:000 }|
+ {9:000 }│{9:000}{5:9}{9: }|
+ │ |
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {15:[No Name] [+] }{13:[No Name] [+] }|
+ |
+ ]]}
+ end)
+
+ it('correctly draws when there are multiple overlapping virtual texts on the same line with nowrap', function()
+ command('set nowrap')
+ insert('a')
+ meths.buf_set_extmark(0, ns, 0, 0,
+ { virt_text = { { string.rep('a', 55), 'Special' } }, virt_text_pos = 'inline' })
+ meths.buf_set_extmark(0, ns, 0, 0,
+ { virt_text = { { string.rep('b', 55), 'Special' } }, virt_text_pos = 'inline' })
+ feed('$')
+ screen:expect { grid = [[
+ {10:bbbbbbbbbbbbbbbbbbbbbbbbb}^a |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ end)
+
+ it('correctly draws when overflowing virtual text is followed by tab with no wrap', function()
+ command('set nowrap')
+ feed('i<TAB>test<ESC>')
+ meths.buf_set_extmark(
+ 0,
+ ns,
+ 0,
+ 0,
+ { virt_text = { { string.rep('a', 60), 'Special' } }, virt_text_pos = 'inline' }
+ )
+ feed('0')
+ screen:expect({
+ grid = [[
+ {10:aaaaaaaaaaaaaaaaaaaaaa} ^ test |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]],
+ })
+ end)
end)
describe('decorations: virtual lines', function()
@@ -1189,7 +1994,7 @@ describe('decorations: virtual lines', function()
ns = meths.create_namespace 'test'
end)
- local example_text = [[
+ local example_text2 = [[
if (h->n_buckets < new_n_buckets) { // expand
khkey_t *new_keys = (khkey_t *)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t));
h->keys = new_keys;
@@ -1200,7 +2005,7 @@ if (h->n_buckets < new_n_buckets) { // expand
}]]
it('works with one line', function()
- insert(example_text)
+ insert(example_text2)
feed 'gg'
meths.buf_set_extmark(0, ns, 1, 33, {
virt_lines={ {{">> ", "NonText"}, {"krealloc", "Identifier"}, {": change the size of an allocation"}}};
@@ -1309,7 +2114,7 @@ if (h->n_buckets < new_n_buckets) { // expand
end)
it('works with text at the beginning of the buffer', function()
- insert(example_text)
+ insert(example_text2)
feed 'gg'
screen:expect{grid=[[
@@ -1370,7 +2175,7 @@ if (h->n_buckets < new_n_buckets) { // expand
end)
it('works with text at the end of the buffer', function()
- insert(example_text)
+ insert(example_text2)
feed 'G'
screen:expect{grid=[[
@@ -1489,7 +2294,7 @@ if (h->n_buckets < new_n_buckets) { // expand
end)
it('works beyond end of the buffer with virt_lines_above', function()
- insert(example_text)
+ insert(example_text2)
feed 'G'
screen:expect{grid=[[
@@ -1760,7 +2565,7 @@ if (h->n_buckets < new_n_buckets) { // expand
end)
it('works with sign and numbercolumns', function()
- insert(example_text)
+ insert(example_text2)
feed 'gg'
command 'set number signcolumn=yes'
screen:expect{grid=[[
@@ -1826,7 +2631,7 @@ if (h->n_buckets < new_n_buckets) { // expand
it('works with hard tabs', function()
- insert(example_text)
+ insert(example_text2)
feed 'gg'
meths.buf_set_extmark(0, ns, 1, 0, {
virt_lines={ {{">>", "NonText"}, {"\tvery\ttabby", "Identifier"}, {"text\twith\ttabs"}}};
@@ -1910,10 +2715,10 @@ describe('decorations: signs', function()
}
ns = meths.create_namespace 'test'
- meths.set_option_value('signcolumn', 'auto:9', {win = 0})
+ meths.set_option_value('signcolumn', 'auto:9', {})
end)
- local example_text = [[
+ local example_test3 = [[
l1
l2
l3
@@ -1922,7 +2727,7 @@ l5
]]
it('can add a single sign (no end row)', function()
- insert(example_text)
+ insert(example_test3)
feed 'gg'
meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S'})
@@ -1943,7 +2748,7 @@ l5
end)
it('can add a single sign (with end row)', function()
- insert(example_text)
+ insert(example_test3)
feed 'gg'
meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S', end_row=1})
@@ -1965,7 +2770,7 @@ l5
it('can add multiple signs (single extmark)', function()
pending('TODO(lewis6991): Support ranged signs')
- insert(example_text)
+ insert(example_test3)
feed 'gg'
meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S', end_row = 2})
@@ -1987,7 +2792,7 @@ l5
it('can add multiple signs (multiple extmarks)', function()
pending('TODO(lewis6991): Support ranged signs')
- insert(example_text)
+ insert(example_test3)
feed'gg'
meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S1'})
@@ -2009,7 +2814,7 @@ l5
end)
it('can add multiple signs (multiple extmarks) 2', function()
- insert(example_text)
+ insert(example_test3)
feed 'gg'
meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S1'})
@@ -2049,7 +2854,7 @@ l5
it('can add multiple signs (multiple extmarks) 3', function()
pending('TODO(lewis6991): Support ranged signs')
- insert(example_text)
+ insert(example_test3)
feed 'gg'
meths.buf_set_extmark(0, ns, 1, -1, {sign_text='S1', end_row=2})
@@ -2070,7 +2875,7 @@ l5
end)
it('can add multiple signs (multiple extmarks) 4', function()
- insert(example_text)
+ insert(example_test3)
feed 'gg'
meths.buf_set_extmark(0, ns, 0, -1, {sign_text='S1', end_row=0})
@@ -2091,7 +2896,7 @@ l5
end)
it('works with old signs', function()
- insert(example_text)
+ insert(example_test3)
feed 'gg'
helpers.command('sign define Oldsign text=x')
@@ -2118,7 +2923,7 @@ l5
it('works with old signs (with range)', function()
pending('TODO(lewis6991): Support ranged signs')
- insert(example_text)
+ insert(example_test3)
feed 'gg'
helpers.command('sign define Oldsign text=x')
@@ -2147,7 +2952,7 @@ l5
it('can add a ranged sign (with start out of view)', function()
pending('TODO(lewis6991): Support ranged signs')
- insert(example_text)
+ insert(example_test3)
command 'set signcolumn=yes:2'
feed 'gg'
feed '2<C-e>'
@@ -2204,7 +3009,7 @@ l5
it('works with priority #19716', function()
screen:try_resize(20, 3)
- insert(example_text)
+ insert(example_test3)
feed 'gg'
helpers.command('sign define Oldsign text=O3')
@@ -2222,7 +3027,7 @@ l5
]]}
-- Check truncation works too
- meths.set_option_value('signcolumn', 'auto', {win = 0})
+ meths.set_option_value('signcolumn', 'auto', {})
screen:expect{grid=[[
S5^l1 |
@@ -2233,8 +3038,8 @@ l5
it('does not set signcolumn for signs without text', function()
screen:try_resize(20, 3)
- meths.set_option_value('signcolumn', 'auto', {win = 0})
- insert(example_text)
+ meths.set_option_value('signcolumn', 'auto', {})
+ insert(example_test3)
feed 'gg'
meths.buf_set_extmark(0, ns, 0, -1, {number_hl_group='Error'})
screen:expect{grid=[[
diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua
index 15819aef40..0f553d4a9b 100644
--- a/test/functional/ui/spell_spec.lua
+++ b/test/functional/ui/spell_spec.lua
@@ -254,4 +254,19 @@ describe("'spell'", function()
]])
end)
+ it('and syntax does not clear extmark highlighting at the start of a word', function()
+ screen:try_resize(43, 3)
+ command([[
+ set spell
+ syntax match Constant "^.*$"
+ call setline(1, "This is some text without any spell errors.")
+ ]])
+ local ns = meths.create_namespace("spell")
+ curbufmeths.set_extmark(ns, 0, 0, { hl_group = 'WarningMsg', end_col = 43 })
+ screen:expect([[
+ {6:^This is some text without any spell errors.}|
+ {0:~ }|
+ |
+ ]])
+ end)
end)
diff --git a/test/functional/vimscript/buf_functions_spec.lua b/test/functional/vimscript/buf_functions_spec.lua
index 2d6d4b8e04..2a5720fbd7 100644
--- a/test/functional/vimscript/buf_functions_spec.lua
+++ b/test/functional/vimscript/buf_functions_spec.lua
@@ -268,7 +268,7 @@ describe('setbufvar() function', function()
end)
it('may set options, including window-local and global values', function()
local buf1 = meths.get_current_buf()
- eq(false, meths.get_option_value('number', {win=0}))
+ eq(false, meths.get_option_value('number', {}))
command('split')
command('new')
eq(2, bufmeths.get_number(curwinmeths.get_buf()))