aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/api.txt20
-rw-r--r--runtime/doc/lsp.txt10
-rw-r--r--runtime/filetype.vim9
-rw-r--r--runtime/lua/vim/lsp.lua36
-rw-r--r--src/nvim/api/buffer.c42
-rw-r--r--src/nvim/api/private/helpers.c37
-rw-r--r--src/nvim/api/vim.c42
-rw-r--r--src/nvim/decoration.c2
-rw-r--r--src/nvim/extmark.c9
-rw-r--r--src/nvim/lua/vim.lua11
-rw-r--r--src/nvim/message.c34
-rw-r--r--src/nvim/message.h9
-rw-r--r--src/nvim/normal.c29
-rw-r--r--src/nvim/po/uk.po250
-rw-r--r--src/nvim/spell.c11
-rw-r--r--src/nvim/testdir/test_filetype.vim17
-rw-r--r--src/nvim/testdir/test_fold.vim35
-rw-r--r--src/nvim/testdir/test_highlight.vim14
-rw-r--r--test/functional/api/extmark_spec.lua34
-rw-r--r--test/functional/api/vim_spec.lua73
20 files changed, 576 insertions, 148 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 485c93b0dd..717a7caadf 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -663,6 +663,17 @@ nvim_del_var({name}) *nvim_del_var()*
Parameters: ~
{name} Variable name
+nvim_echo({chunks}, {history}, {opts}) *nvim_echo()*
+ Echo a message.
+
+ Parameters: ~
+ {chunks} A list of [text, hl_group] arrays, each
+ representing a text chunk with specified
+ highlight. `hl_group` element can be omitted
+ for no highlight.
+ {history} if true, add to |message-history|.
+ {opts} Optional parameters. Reserved for future use.
+
nvim_err_write({str}) *nvim_err_write()*
Writes a message to the Vim error buffer. Does not append
"\n", the message is buffered (won't display) until a linefeed
@@ -2153,6 +2164,15 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts})
mark will only be used for the current redraw
cycle, and not be permantently stored in the
buffer.
+ • right_gravity : boolean that indicates the
+ direction the extmark will be shifted in when
+ new text is inserted (true for right, false
+ for left). defaults to true.
+ • end_right_gravity : boolean that indicates the
+ direction the extmark end position (if it
+ exists) will be shifted in when new text is
+ inserted (true for right, false for left).
+ Defaults to false.
Return: ~
Id of the created/updated extmark
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 772afdcc1a..06666c3a27 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -679,6 +679,14 @@ get_active_clients() *vim.lsp.get_active_clients()*
Return: ~
Table of |vim.lsp.client| objects
+ *vim.lsp.get_buffers_by_client_id()*
+get_buffers_by_client_id({client_id})
+ Parameters: ~
+ {client_id} client id
+
+ Return: ~
+ list of buffer ids
+
get_client_by_id({client_id}) *vim.lsp.get_client_by_id()*
Gets a client by id, or nil if the id is invalid. The returned
client may not yet be fully initialized.
@@ -1754,7 +1762,7 @@ make_workspace_params({added}, {removed})
Create the workspace params
Parameters: ~
- {added}
+ {added}
{removed}
*vim.lsp.util.open_floating_preview()*
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index 9104519451..1343a1fd0b 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -1733,8 +1733,13 @@ au BufNewFile,BufRead *.tli setf tli
" Telix Salt
au BufNewFile,BufRead *.slt setf tsalt
-" Tera Term Language
-au BufRead,BufNewFile *.ttl setf teraterm
+" Tera Term Language or Turtle
+au BufRead,BufNewFile *.ttl
+ \ if getline(1) =~ '^@\?\(prefix\|base\)' |
+ \ setf turtle |
+ \ else |
+ \ setf teraterm |
+ \ endif
" Terminfo
au BufNewFile,BufRead *.ti setf terminfo
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 64d08e9733..6229ee7359 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -121,6 +121,9 @@ local active_clients = {}
local all_buffer_active_clients = {}
local uninitialized_clients = {}
+-- Tracks all buffers attached to a client.
+local all_client_active_buffers = {}
+
--@private
--- Invokes a function for each LSP client attached to the buffer {bufnr}.
---
@@ -933,7 +936,7 @@ function lsp.buf_attach_client(bufnr, client_id)
on_lines = text_document_did_change_handler;
on_detach = function()
local params = { textDocument = { uri = uri; } }
- for_each_buffer_client(bufnr, function(client, _client_id)
+ for_each_buffer_client(bufnr, function(client, _)
if client.resolved_capabilities.text_document_open_close then
client.notify('textDocument/didClose', params)
end
@@ -947,6 +950,13 @@ function lsp.buf_attach_client(bufnr, client_id)
utf_sizes = true;
})
end
+
+ if not all_client_active_buffers[client_id] then
+ all_client_active_buffers[client_id] = {}
+ end
+
+ table.insert(all_client_active_buffers[client_id], bufnr)
+
if buffer_client_ids[client_id] then return end
-- This is our first time attaching this client to this buffer.
buffer_client_ids[client_id] = true
@@ -978,6 +988,19 @@ function lsp.get_client_by_id(client_id)
return active_clients[client_id] or uninitialized_clients[client_id]
end
+--- Returns list of buffers attached to client_id.
+--
+--@param client_id client id
+--@returns list of buffer ids
+function lsp.get_buffers_by_client_id(client_id)
+ local active_client_buffers = all_client_active_buffers[client_id]
+ if active_client_buffers then
+ return active_client_buffers
+ else
+ return {}
+ end
+end
+
--- Stops a client(s).
---
--- You can also use the `stop()` function on a |vim.lsp.client| object.
@@ -995,12 +1018,23 @@ end
function lsp.stop_client(client_id, force)
local ids = type(client_id) == 'table' and client_id or {client_id}
for _, id in ipairs(ids) do
+ local resolved_client_id
if type(id) == 'table' and id.stop ~= nil then
id.stop(force)
+ resolved_client_id = id.id
elseif active_clients[id] then
active_clients[id].stop(force)
+ resolved_client_id = id
elseif uninitialized_clients[id] then
uninitialized_clients[id].stop(true)
+ resolved_client_id = id
+ end
+ if resolved_client_id then
+ local client_buffers = lsp.get_buffers_by_client_id(resolved_client_id)
+ for idx = 1, #client_buffers do
+ lsp.diagnostic.clear(client_buffers[idx], resolved_client_id)
+ end
+ all_client_active_buffers[resolved_client_id] = nil
end
end
end
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 8d82d22040..2890d89bc0 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1400,6 +1400,13 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
/// callbacks. The mark will only be used for the current
/// redraw cycle, and not be permantently stored in the
/// buffer.
+/// - right_gravity : boolean that indicates the direction
+/// the extmark will be shifted in when new text is inserted
+/// (true for right, false for left). defaults to true.
+/// - end_right_gravity : boolean that indicates the direction
+/// the extmark end position (if it exists) will be shifted
+/// in when new text is inserted (true for right, false
+/// for left). Defaults to false.
/// @param[out] err Error details, if any
/// @return Id of the created/updated extmark
Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
@@ -1440,6 +1447,10 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
DecorPriority priority = DECOR_PRIORITY_BASE;
colnr_T col2 = 0;
VirtText virt_text = KV_INITIAL_VALUE;
+ bool right_gravity = true;
+ bool end_right_gravity = false;
+ bool end_gravity_set = false;
+
for (size_t i = 0; i < opts.size; i++) {
String k = opts.items[i].key;
Object *v = &opts.items[i].value;
@@ -1522,12 +1533,35 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
goto error;
}
priority = (DecorPriority)v->data.integer;
+ } else if (strequal("right_gravity", k.data)) {
+ if (v->type != kObjectTypeBoolean) {
+ api_set_error(err, kErrorTypeValidation,
+ "right_gravity must be a boolean");
+ goto error;
+ }
+ right_gravity = v->data.boolean;
+ } else if (strequal("end_right_gravity", k.data)) {
+ if (v->type != kObjectTypeBoolean) {
+ api_set_error(err, kErrorTypeValidation,
+ "end_right_gravity must be a boolean");
+ goto error;
+ }
+ end_right_gravity = v->data.boolean;
+ end_gravity_set = true;
} else {
api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
goto error;
}
}
+ // Only error out if they try to set end_right_gravity without
+ // setting end_col or end_line
+ if (line2 == -1 && col2 == 0 && end_gravity_set) {
+ api_set_error(err, kErrorTypeValidation,
+ "cannot set end_right_gravity "
+ "without setting end_line or end_col");
+ }
+
if (col2 >= 0) {
if (line2 >= 0 && line2 < buf->b_ml.ml_line_count) {
len = STRLEN(ml_get_buf(buf, (linenr_T)line2 + 1, false));
@@ -1572,7 +1606,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
}
id = extmark_set(buf, (uint64_t)ns_id, id, (int)line, (colnr_T)col,
- line2, col2, decor, kExtmarkNoUndo);
+ line2, col2, decor, right_gravity,
+ end_right_gravity, kExtmarkNoUndo);
}
return (Integer)id;
@@ -1687,7 +1722,7 @@ Integer nvim_buf_add_highlight(Buffer buffer,
extmark_set(buf, ns_id, 0,
(int)line, (colnr_T)col_start,
end_line, (colnr_T)col_end,
- decor_hl(hl_id), kExtmarkNoUndo);
+ decor_hl(hl_id), true, false, kExtmarkNoUndo);
return src_id;
}
@@ -1796,7 +1831,8 @@ Integer nvim_buf_set_virtual_text(Buffer buffer,
Decoration *decor = xcalloc(1, sizeof(*decor));
decor->virt_text = virt_text;
- extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, kExtmarkNoUndo);
+ extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true,
+ false, kExtmarkNoUndo);
return src_id;
}
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 8f224e8c78..7cee569989 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1645,6 +1645,43 @@ bool api_object_to_bool(Object obj, const char *what,
}
}
+HlMessage parse_hl_msg(Array chunks, Error *err)
+{
+ HlMessage hl_msg = KV_INITIAL_VALUE;
+ for (size_t i = 0; i < chunks.size; i++) {
+ if (chunks.items[i].type != kObjectTypeArray) {
+ api_set_error(err, kErrorTypeValidation, "Chunk is not an array");
+ goto free_exit;
+ }
+ Array chunk = chunks.items[i].data.array;
+ if (chunk.size == 0 || chunk.size > 2
+ || chunk.items[0].type != kObjectTypeString
+ || (chunk.size == 2 && chunk.items[1].type != kObjectTypeString)) {
+ api_set_error(err, kErrorTypeValidation,
+ "Chunk is not an array with one or two strings");
+ goto free_exit;
+ }
+
+ String str = copy_string(chunk.items[0].data.string);
+
+ int attr = 0;
+ if (chunk.size == 2) {
+ String hl = chunk.items[1].data.string;
+ if (hl.size > 0) {
+ int hl_id = syn_check_group((char_u *)hl.data, (int)hl.size);
+ attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
+ }
+ }
+ kv_push(hl_msg, ((HlMessageChunk){ .text = str, .attr = attr }));
+ }
+
+ return hl_msg;
+
+free_exit:
+ clear_hl_msg(&hl_msg);
+ return hl_msg;
+}
+
const char *describe_ns(NS ns_id)
{
String name;
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 1e972e01be..09895a2119 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -990,6 +990,48 @@ void nvim_set_option(uint64_t channel_id, String name, Object value, Error *err)
set_option_to(channel_id, NULL, SREQ_GLOBAL, name, value, err);
}
+/// Echo a message.
+///
+/// @param chunks A list of [text, hl_group] arrays, each representing a
+/// text chunk with specified highlight. `hl_group` element
+/// can be omitted for no highlight.
+/// @param history if true, add to |message-history|.
+/// @param opts Optional parameters. Reserved for future use.
+void nvim_echo(Array chunks, Boolean history, Dictionary opts, Error *err)
+ FUNC_API_SINCE(7)
+{
+ HlMessage hl_msg = parse_hl_msg(chunks, err);
+ if (ERROR_SET(err)) {
+ goto error;
+ }
+
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
+ goto error;
+ }
+
+ no_wait_return++;
+ msg_start();
+ msg_clr_eos();
+ bool need_clear = false;
+ for (uint32_t i = 0; i < kv_size(hl_msg); i++) {
+ HlMessageChunk chunk = kv_A(hl_msg, i);
+ msg_multiline_attr((const char *)chunk.text.data, chunk.attr,
+ false, &need_clear);
+ }
+ if (history) {
+ msg_ext_set_kind("echomsg");
+ add_hl_msg_hist(hl_msg);
+ } else {
+ msg_ext_set_kind("echo");
+ }
+ no_wait_return--;
+ msg_end();
+
+error:
+ clear_hl_msg(&hl_msg);
+}
+
/// Writes a message to the Vim output buffer. Does not append "\n", the
/// message is buffered (won't display) until a linefeed is written.
///
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index e6a616c927..f3ee42fab1 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -69,7 +69,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf,
}
(void)extmark_set(buf, (uint64_t)src_id, 0,
(int)lnum-1, hl_start, (int)lnum-1+end_off, hl_end,
- decor, kExtmarkNoUndo);
+ decor, true, false, kExtmarkNoUndo);
}
}
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index b2d8532cd7..cacbeddb32 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -71,7 +71,8 @@ static ExtmarkNs *buf_ns_ref(buf_T *buf, uint64_t ns_id, bool put) {
/// @returns the mark id
uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id,
int row, colnr_T col, int end_row, colnr_T end_col,
- Decoration *decor, ExtmarkOp op)
+ Decoration *decor, bool right_gravity,
+ bool end_right_gravity, ExtmarkOp op)
{
ExtmarkNs *ns = buf_ns_ref(buf, ns_id, true);
assert(ns != NULL);
@@ -109,10 +110,10 @@ uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id,
if (end_row > -1) {
mark = marktree_put_pair(buf->b_marktree,
- row, col, true,
- end_row, end_col, false);
+ row, col, right_gravity,
+ end_row, end_col, end_right_gravity);
} else {
- mark = marktree_put(buf->b_marktree, row, col, true);
+ mark = marktree_put(buf->b_marktree, row, col, right_gravity);
}
revised:
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index b20fbbf038..80b311de2c 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -121,10 +121,17 @@ function vim._load_package(name)
end
for _,trail in ipairs(vim._so_trails) do
- local path = "lua/"..trail:gsub('?',basename)
+ local path = "lua"..trail:gsub('?', basename) -- so_trails contains a leading slash
local found = vim.api.nvim_get_runtime_file(path, false)
if #found > 0 then
- local f, err = package.loadlib(found[1])
+ -- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
+ -- a) strip prefix up to and including the first dash, if any
+ -- b) replace all dots by underscores
+ -- c) prepend "luaopen_"
+ -- So "foo-bar.baz" should result in "luaopen_bar_baz"
+ local dash = name:find("-", 1, true)
+ local modname = dash and name:sub(dash + 1) or name
+ local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
return f or error(err)
end
end
diff --git a/src/nvim/message.c b/src/nvim/message.c
index f94529c687..ba7a667a60 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -890,6 +890,40 @@ char_u *msg_may_trunc(int force, char_u *s)
return s;
}
+void clear_hl_msg(HlMessage *hl_msg)
+{
+ for (size_t i = 0; i < kv_size(*hl_msg); i++) {
+ xfree(kv_A(*hl_msg, i).text.data);
+ }
+ kv_destroy(*hl_msg);
+ *hl_msg = (HlMessage)KV_INITIAL_VALUE;
+}
+
+#define LINE_BUFFER_SIZE 4096
+
+void add_hl_msg_hist(HlMessage hl_msg)
+{
+ // TODO(notomo): support multi highlighted message history
+ size_t pos = 0;
+ char buf[LINE_BUFFER_SIZE];
+ for (uint32_t i = 0; i < kv_size(hl_msg); i++) {
+ HlMessageChunk chunk = kv_A(hl_msg, i);
+ for (uint32_t j = 0; j < chunk.text.size; j++) {
+ if (pos == LINE_BUFFER_SIZE - 1) {
+ buf[pos] = NUL;
+ add_msg_hist((const char *)buf, -1, MSG_HIST, true);
+ pos = 0;
+ continue;
+ }
+ buf[pos++] = chunk.text.data[j];
+ }
+ }
+ if (pos != 0) {
+ buf[pos] = NUL;
+ add_msg_hist((const char *)buf, -1, MSG_HIST, true);
+ }
+}
+
/// @param[in] len Length of s or -1.
static void add_msg_hist(const char *s, int len, int attr, bool multiline)
{
diff --git a/src/nvim/message.h b/src/nvim/message.h
index fdb9bc96ca..377c725fa1 100644
--- a/src/nvim/message.h
+++ b/src/nvim/message.h
@@ -8,6 +8,8 @@
#include "nvim/macros.h"
#include "nvim/types.h"
#include "nvim/grid_defs.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/lib/kvec.h"
/*
* Types of dialogs passed to do_dialog().
@@ -75,6 +77,13 @@
/// Like #MSG_PUTS_ATTR, but if middle part of long messages will be replaced
#define MSG_PUTS_LONG_ATTR(s, a) msg_puts_long_attr((char_u *)(s), (a))
+typedef struct {
+ String text;
+ int attr;
+} HlMessageChunk;
+
+typedef kvec_t(HlMessageChunk) HlMessage;
+
/// Message history for `:messages`
typedef struct msg_hist {
struct msg_hist *next; ///< Next message.
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 4e955667dc..8f22243348 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -3978,16 +3978,19 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
curwin->w_curswant -= width2;
} else {
// to previous line
+
+ // Move to the start of a closed fold. Don't do that when
+ // 'foldopen' contains "all": it will open in a moment.
+ if (!(fdo_flags & FDO_ALL)) {
+ (void)hasFolding(curwin->w_cursor.lnum,
+ &curwin->w_cursor.lnum, NULL);
+ }
if (curwin->w_cursor.lnum == 1) {
retval = false;
break;
}
- --curwin->w_cursor.lnum;
- /* Move to the start of a closed fold. Don't do that when
- * 'foldopen' contains "all": it will open in a moment. */
- if (!(fdo_flags & FDO_ALL))
- (void)hasFolding(curwin->w_cursor.lnum,
- &curwin->w_cursor.lnum, NULL);
+ curwin->w_cursor.lnum--;
+
linelen = linetabsize(get_cursor_line_ptr());
if (linelen > width1) {
int w = (((linelen - width1 - 1) / width2) + 1) * width2;
@@ -6708,11 +6711,8 @@ static void nv_g_cmd(cmdarg_T *cap)
*/
case 'j':
case K_DOWN:
- /* with 'nowrap' it works just like the normal "j" command; also when
- * in a closed fold */
- if (!curwin->w_p_wrap
- || hasFolding(curwin->w_cursor.lnum, NULL, NULL)
- ) {
+ // with 'nowrap' it works just like the normal "j" command.
+ if (!curwin->w_p_wrap) {
oap->motion_type = kMTLineWise;
i = cursor_down(cap->count1, oap->op_type == OP_NOP);
} else
@@ -6723,11 +6723,8 @@ static void nv_g_cmd(cmdarg_T *cap)
case 'k':
case K_UP:
- /* with 'nowrap' it works just like the normal "k" command; also when
- * in a closed fold */
- if (!curwin->w_p_wrap
- || hasFolding(curwin->w_cursor.lnum, NULL, NULL)
- ) {
+ // with 'nowrap' it works just like the normal "k" command.
+ if (!curwin->w_p_wrap) {
oap->motion_type = kMTLineWise;
i = cursor_up(cap->count1, oap->op_type == OP_NOP);
} else
diff --git a/src/nvim/po/uk.po b/src/nvim/po/uk.po
index 2a5cb54f7b..f0ae154648 100644
--- a/src/nvim/po/uk.po
+++ b/src/nvim/po/uk.po
@@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vim 7.4\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-08-23 18:45+0300\n"
+"POT-Creation-Date: 2021-01-18 17:46+0200\n"
"PO-Revision-Date: 2020-08-23 20:19+0300\n"
"Last-Translator: Анатолій Сахнік <sakhnik@gmail.com>\n"
"Language-Team: Ukrainian\n"
@@ -23,6 +23,67 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+msgid "--Deleted--"
+msgstr "--Знищено--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "Автоматичне знищення автокоманди: %s <буфер=%d>"
+
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Немає такої групи: «%s»"
+
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Не вдалося знищити цю групу"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: Знищення автогрупи, яка все ще використовується"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Недозволений символ після *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Немає такої події: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Немає такої групи чи події: %s"
+
+msgid ""
+"\n"
+"--- Autocommands ---"
+msgstr ""
+"\n"
+"--- Автокоманди ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <буфер=%d>: некоректний номер буфера "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Не можу виконувати автокоманди для УСІХ подій"
+
+msgid "No matching autocommands"
+msgstr "Немає відповідних автокоманд"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: Забагато вкладених автокоманд"
+
+#, c-format
+msgid "%s Autocommands for \"%s\""
+msgstr "%s Автокоманди для «%s»"
+
+#, c-format
+msgid "Executing %s"
+msgstr "Виконується %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "автокоманда %s"
+
msgid "[Location List]"
msgstr "[Список місць]"
@@ -95,9 +156,15 @@ msgid ""
"E89: No write since last change for buffer %<PRId64> (add ! to override)"
msgstr "E89: Буфер %<PRId64> має зміни (! щоб не зважати)"
+msgid "E948: Job still running (add ! to end the job)"
+msgstr "E948: Задача все ще виконується (! щоб закінчити)"
+
msgid "E37: No write since last change (add ! to override)"
msgstr "E37: Зміни не було записано (! щоб не зважати)"
+msgid "E948: Job still running"
+msgstr "E948: Задача все ще виконується"
+
msgid "E37: No write since last change"
msgstr "E37: Не записано після останніх змін"
@@ -465,6 +532,10 @@ msgid "E957: Invalid window number"
msgstr "E957: Некоректний номер вікна"
#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: Неможливо заблокувати чи розблокувати змінну %s"
+
+#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: Неправильний тип змінної для %s="
@@ -544,10 +615,6 @@ msgstr "E690: Пропущено «in» після :for"
msgid "E108: No such variable: \"%s\""
msgstr "E108: Змінної немає: «%s»"
-#, c-format
-msgid "E940: Cannot lock or unlock variable %s"
-msgstr "E940: Неможливо заблокувати чи розблокувати змінну %s"
-
msgid "E109: Missing ':' after '?'"
msgstr "E109: Бракує ':' після '?'"
@@ -950,9 +1017,6 @@ msgstr "E684: Індекс списку поза межами: %<PRId64>"
msgid "E686: Argument of %s must be a List"
msgstr "E686: Аргумент у %s має бути списком"
-msgid "E928: String required"
-msgstr "E928: Потрібен String"
-
#, c-format
msgid "Error converting the call result: %s"
msgstr "Не вдалося перетворити результат виклику: %s"
@@ -1591,6 +1655,10 @@ msgid "Close \"%s\"?"
msgstr "Закрити «%s»?"
#, c-format
+msgid "E947: Job still running in buffer \"%s\""
+msgstr "E947: Задача все ще запущена у буфері «%s»"
+
+#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Буфер «%s» має незбережені зміни"
@@ -1615,18 +1683,6 @@ msgid "E666: compiler not supported: %s"
msgstr "E666: Компілятор не підтримується: %s"
#, c-format
-msgid "Searching for \"%s\" in \"%s\""
-msgstr "Пошук «%s» в «%s»"
-
-#, c-format
-msgid "Searching for \"%s\""
-msgstr "Пошук «%s»"
-
-#, c-format
-msgid "not found in '%s': \"%s\""
-msgstr "не знайдено в '%s': «%s»"
-
-#, c-format
msgid ":source error parsing command %s"
msgstr ":source помилка розбору команди %s"
@@ -1702,12 +1758,16 @@ msgstr "Режим Ex. Для повернення до нормального
msgid "E501: At end-of-file"
msgstr "E501: Кінець файлу"
-msgid "E169: Command too recursive"
-msgstr "E169: Команда занадто рекурсивна"
+#, c-format
+msgid "Executing: %s"
+msgstr "Виконується: %s"
msgid "line %"
msgstr "рядок %"
+msgid "E169: Command too recursive"
+msgstr "E169: Команда занадто рекурсивна"
+
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Виняткова ситуація не оброблена: %s"
@@ -1724,9 +1784,6 @@ msgstr "E464: Неоднозначний вжиток команди корис
msgid "E492: Not an editor command"
msgstr "E492: Це не команда редактора"
-msgid "E981: Command not allowed in restricted mode"
-msgstr "E981: Команду не дозволено у обмеженому режимі"
-
msgid "E493: Backwards range given"
msgstr "E493: Інтервал задано навиворіт"
@@ -1736,6 +1793,11 @@ msgstr "Інтервал задано навиворіт, щоб помінят
msgid "E494: Use w or w>>"
msgstr "E494: Спробуйте w або w>>"
+msgid ""
+"INTERNAL: Cannot use EX_DFLALL with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"
+msgstr ""
+"ВНУТРІШНЄ: Не можна вживати EX_DFLALL з ADDR_NONE, ADDR_UNSIGNED чи ADDR_QUICKFIX"
+
msgid "E943: Command table needs to be updated, run 'make'"
msgstr "E943: Потрібно поновити таблицю команд, запустіть 'make'"
@@ -1762,10 +1824,10 @@ msgstr "E174: Команда вже існує, ! щоб замінити її:
msgid ""
"\n"
-" Name Args Address Complete Definition"
+" Name Args Address Complete Definition"
msgstr ""
"\n"
-" Назва Арг. Адреса Доповнення Визначення"
+" Назва Арг. Адреса Доповнення Визначення"
msgid "No user-defined commands found"
msgstr "Не знайдено команд користувача"
@@ -2077,12 +2139,12 @@ msgstr "E347: У шляху пошуку більше немає файлів «
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: Автокоманди змінили буфер чи його назву"
-msgid "Illegal file name"
-msgstr "Недозволена назва файлу"
-
msgid "is a directory"
msgstr "каталог"
+msgid "Illegal file name"
+msgstr "Недозволена назва файлу"
+
msgid "is not a file"
msgstr "не файл"
@@ -2104,9 +2166,6 @@ msgstr "E201: Автокоманди *ReadPre не повинні змінюва
msgid "E202: Conversion made file unreadable!"
msgstr "E202: Конвертація унеможливила читання файлу!"
-msgid "[fifo/socket]"
-msgstr "[канал/сокет]"
-
msgid "[fifo]"
msgstr "[канал]"
@@ -2353,67 +2412,6 @@ msgstr "E462: Не вдалося підготувати «%s», щоб пере
msgid "E321: Could not reload \"%s\""
msgstr "E321: Не вдалося перечитати «%s»"
-msgid "--Deleted--"
-msgstr "--Знищено--"
-
-#, c-format
-msgid "auto-removing autocommand: %s <buffer=%d>"
-msgstr "Автоматичне знищення автокоманди: %s <буфер=%d>"
-
-#, c-format
-msgid "E367: No such group: \"%s\""
-msgstr "E367: Немає такої групи: «%s»"
-
-msgid "E936: Cannot delete the current group"
-msgstr "E936: Не вдалося знищити цю групу"
-
-msgid "W19: Deleting augroup that is still in use"
-msgstr "W19: Знищення автогрупи, яка все ще використовується"
-
-#, c-format
-msgid "E215: Illegal character after *: %s"
-msgstr "E215: Недозволений символ після *: %s"
-
-#, c-format
-msgid "E216: No such event: %s"
-msgstr "E216: Немає такої події: %s"
-
-#, c-format
-msgid "E216: No such group or event: %s"
-msgstr "E216: Немає такої групи чи події: %s"
-
-msgid ""
-"\n"
-"--- Autocommands ---"
-msgstr ""
-"\n"
-"--- Автокоманди ---"
-
-#, c-format
-msgid "E680: <buffer=%d>: invalid buffer number "
-msgstr "E680: <буфер=%d>: некоректний номер буфера "
-
-msgid "E217: Can't execute autocommands for ALL events"
-msgstr "E217: Не можу виконувати автокоманди для УСІХ подій"
-
-msgid "No matching autocommands"
-msgstr "Немає відповідних автокоманд"
-
-msgid "E218: autocommand nesting too deep"
-msgstr "E218: Забагато вкладених автокоманд"
-
-#, c-format
-msgid "%s Autocommands for \"%s\""
-msgstr "%s Автокоманди для «%s»"
-
-#, c-format
-msgid "Executing %s"
-msgstr "Виконується %s"
-
-#, c-format
-msgid "autocommand %s"
-msgstr "автокоманда %s"
-
msgid "E219: Missing {."
msgstr "E219: Бракує {."
@@ -2519,9 +2517,6 @@ msgstr "E685: Внутрішня помилка: %s"
msgid "Interrupted"
msgstr "Перервано"
-msgid "E14: Invalid address"
-msgstr "E14: Неправильна адреса"
-
msgid "E474: Invalid argument"
msgstr "E474: Некоректний аргумент"
@@ -2719,6 +2714,9 @@ msgstr "E45: Встановлено опцію 'readonly' (! щоб не зва
msgid "E46: Cannot change read-only variable \"%.*s\""
msgstr "E46: Змінна тільки для читання: «%.*s»"
+msgid "E928: String required"
+msgstr "E928: Потрібен String"
+
msgid "E715: Dictionary required"
msgstr "E715: Потрібен словник"
@@ -2727,8 +2725,8 @@ msgid "E118: Too many arguments for function: %s"
msgstr "E118: Забагато аргументів для функції: %s"
#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Немає такого ключа у словнику: %s"
+msgid "E716: Key not present in Dictionary: \"%s\""
+msgstr "E716: Немає такого ключа у словнику: «%s»"
msgid "E714: List required"
msgstr "E714: Потрібен список"
@@ -3158,6 +3156,10 @@ msgid "E5106: Error while creating shared module: %.*s"
msgstr "E5106: Помилка створення розділюваного модуля: %.*s"
#, c-format
+msgid "E5106: Error while creating inspect module: %.*s"
+msgstr "E5106: Помилка створення модуля inspect: %.*s"
+
+#, c-format
msgid "E5106: Error while creating vim module: %.*s"
msgstr "E5106: Помилка створення модуля vim: %.*s"
@@ -3165,10 +3167,6 @@ msgid "E970: Failed to initialize lua interpreter"
msgstr "E970: Не вдалося ініціалізувати інтерпретатор lua"
#, c-format
-msgid "E5117: Error while updating package paths: %.*s"
-msgstr "E5117: Помилка оновлення шляхів пакунку: %.*s"
-
-#, c-format
msgid "E5114: Error while converting print argument #%i: %.*s"
msgstr "E5114: Не вдалося перетворити аргумент #%i друку: %.*s"
@@ -3256,6 +3254,10 @@ msgid "pre-vimrc command line"
msgstr "команди перед vimrc"
#, c-format
+msgid "Conflicting configs: \"%s\" \"%s\""
+msgstr "Суперечливі конфігурації: «%s» «%s»"
+
+#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Не вдалося прочитати з «%s»"
@@ -4002,8 +4004,7 @@ msgstr ""
"Введіть :qa! і натисність <Enter> щоб відкинути всі зміни і вийти Nvim"
msgid "Type :qa and press <Enter> to exit Nvim"
-msgstr ""
-"Введіть :qa і натисність <Enter> щоб вийти з Nvim"
+msgstr "Введіть :qa і натисність <Enter> щоб вийти з Nvim"
#, c-format
msgid "1 line %sed 1 time"
@@ -4068,10 +4069,10 @@ msgstr "E353: У регістрі %s нічого немає"
msgid ""
"\n"
-"--- Registers ---"
+"Type Name Content"
msgstr ""
"\n"
-"--- Регістри ---"
+"Тип Наз. Вміст "
msgid ""
"E883: search pattern and expression register may not contain two or more "
@@ -4184,9 +4185,6 @@ msgstr "E537: 'commentstring' має бути порожньою чи місти
msgid "E540: Unclosed expression sequence"
msgstr "E540: Послідовність виразів не завершено"
-msgid "E541: too many items"
-msgstr "E541: Забагато елементів"
-
msgid "E542: unbalanced groups"
msgstr "E542: Групи не збалансовано"
@@ -4274,6 +4272,9 @@ msgstr ""
msgid "E5677: Error writing input to shell-command: %s"
msgstr "E5677: Не вдалося записати на вхід команди оболонки: %s"
+msgid "%a %b %d %H:%M:%S %Y"
+msgstr "%H:%M:%S %a, %d %B %Y р."
+
#, c-format
msgid "E447: Can't find file \"%s\" in path"
msgstr "E447: Файл «%s» не знайдено у шляху пошуку"
@@ -4281,8 +4282,11 @@ msgstr "E447: Файл «%s» не знайдено у шляху пошуку"
msgid "E553: No more items"
msgstr "E553: Немає більше елементів"
+msgid "E925: Current quickfix list was changed"
+msgstr "E925: Поточний список quickfix змінився"
+
msgid "E926: Current location list was changed"
-msgstr "E926: Цей список місць було змінено"
+msgstr "E926: Поточний список місць змінився"
#, c-format
msgid "E372: Too many %%%c in format string"
@@ -4316,9 +4320,6 @@ msgstr "E379: Пропущена чи порожня назва каталогу
msgid "E924: Current window was closed"
msgstr "E924: Активне вікно було закрито"
-msgid "E925: Current quickfix was changed"
-msgstr "E925: Цей quickfix було змінено"
-
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d з %d)%s%s: "
@@ -4346,6 +4347,9 @@ msgstr "E683: Пропущено назву файлу чи некоректни
msgid "Cannot open file \"%s\""
msgstr "Не вдалося відкрити файл «%s»"
+msgid "cannot have both a list and a \"what\" argument"
+msgstr "не можна задавати одночасно список і аргумент «що»"
+
msgid "E681: Buffer is not loaded"
msgstr "E681: Буфер не завантажено"
@@ -4466,6 +4470,18 @@ msgstr ""
msgid "Switching to backtracking RE engine for pattern: "
msgstr "Перемикання до простого рушія регулярних виразів: "
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Пошук «%s» в «%s»"
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Пошук «%s»"
+
+#, c-format
+msgid "not found in '%s': \"%s\""
+msgstr "не знайдено в '%s': «%s»"
+
msgid " TERMINAL"
msgstr " ТЕРМІНАЛ"
@@ -5249,6 +5265,9 @@ msgstr "синхронізується по коментарях стилю С"
msgid "no syncing"
msgstr "без синхронізації"
+msgid "syncing starts at the first line"
+msgstr "синхронізація починається з першого рядка"
+
msgid "syncing starts "
msgstr "починається синхронізація за "
@@ -5280,6 +5299,9 @@ msgstr ""
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Немає такого синтаксичного кластера: %s"
+msgid "from the first line"
+msgstr "з першого рядка"
+
msgid "minimal "
msgstr "мінімальний "
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 5714f5e425..6425c9fed5 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -3123,6 +3123,7 @@ spell_find_suggest (
static bool expr_busy = false;
int c;
langp_T *lp;
+ bool did_intern = false;
// Set the info in "*su".
memset(su, 0, sizeof(suginfo_T));
@@ -3206,14 +3207,16 @@ spell_find_suggest (
spell_suggest_expr(su, buf + 5);
expr_busy = false;
}
- } else if (STRNCMP(buf, "file:", 5) == 0)
+ } else if (STRNCMP(buf, "file:", 5) == 0) {
// Use list of suggestions in a file.
spell_suggest_file(su, buf + 5);
- else {
- // Use internal method.
+ } else if (!did_intern) {
+ // Use internal method once.
spell_suggest_intern(su, interactive);
- if (sps_flags & SPS_DOUBLE)
+ if (sps_flags & SPS_DOUBLE) {
do_combine = true;
+ }
+ did_intern = true;
}
}
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 180170fe9a..815827e224 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -692,6 +692,23 @@ func Test_ts_file()
filetype off
endfunc
+func Test_ttl_file()
+ filetype on
+
+ call writefile(['@base <http://example.org/> .'], 'Xfile.ttl')
+ split Xfile.ttl
+ call assert_equal('turtle', &filetype)
+ bwipe!
+
+ call writefile(['looks like Tera Term Language'], 'Xfile.ttl')
+ split Xfile.ttl
+ call assert_equal('teraterm', &filetype)
+ bwipe!
+
+ call delete('Xfile.ttl')
+ filetype off
+endfunc
+
func Test_pp_file()
filetype on
diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim
index 88ce64b9eb..18f328acf4 100644
--- a/src/nvim/testdir/test_fold.vim
+++ b/src/nvim/testdir/test_fold.vim
@@ -822,4 +822,39 @@ func Test_fold_create_delete()
bwipe!
endfunc
+func Test_fold_relative_move()
+ enew!
+ set fdm=indent sw=2 wrap tw=80
+
+ let content = [ ' foo', ' bar', ' baz',
+ \ repeat('x', 100),
+ \ ' foo', ' bar', ' baz'
+ \ ]
+ call append(0, content)
+
+ normal zM
+
+ call cursor(3, 1)
+ call assert_true(foldclosed(line('.')))
+ normal gj
+ call assert_equal(2, winline())
+
+ call cursor(2, 1)
+ call assert_true(foldclosed(line('.')))
+ normal 2gj
+ call assert_equal(3, winline())
+
+ call cursor(5, 1)
+ call assert_true(foldclosed(line('.')))
+ normal gk
+ call assert_equal(3, winline())
+
+ call cursor(6, 1)
+ call assert_true(foldclosed(line('.')))
+ normal 2gk
+ call assert_equal(2, winline())
+
+ set fdm& sw& wrap& tw&
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim
index 8f6834c2ab..4cc4d775d1 100644
--- a/src/nvim/testdir/test_highlight.vim
+++ b/src/nvim/testdir/test_highlight.vim
@@ -2,6 +2,7 @@
source view_util.vim
source screendump.vim
+source check.vim
func Test_highlight()
" basic test if ":highlight" doesn't crash
@@ -610,3 +611,16 @@ func Test_1_highlight_Normalgroup_exists()
call assert_match('hi Normal\s*font=.*', hlNormal)
endif
endfunc
+
+" Test for using RGB color values in a highlight group
+func Test_xxlast_highlight_RGB_color()
+ CheckCanRunGui
+ gui -f
+ hi MySearch guifg=#110000 guibg=#001100 guisp=#000011
+ call assert_equal('#110000', synIDattr(synIDtrans(hlID('MySearch')), 'fg#'))
+ call assert_equal('#001100', synIDattr(synIDtrans(hlID('MySearch')), 'bg#'))
+ call assert_equal('#000011', synIDattr(synIDtrans(hlID('MySearch')), 'sp#'))
+ hi clear
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/functional/api/extmark_spec.lua b/test/functional/api/extmark_spec.lua
index ab913ba4a4..d2b555ee5b 100644
--- a/test/functional/api/extmark_spec.lua
+++ b/test/functional/api/extmark_spec.lua
@@ -1389,6 +1389,40 @@ describe('API/extmarks', function()
undo]],false)
eq(2, meths.eval('1+1')) -- did not crash
end)
+
+ it('works with left and right gravity', function()
+ -- right gravity should move with inserted text, while
+ -- left gravity should stay in place.
+ curbufmeths.set_extmark(ns, 0, 5, {right_gravity = false})
+ curbufmeths.set_extmark(ns, 0, 5, {right_gravity = true})
+ feed([[Aasdfasdf]])
+
+ eq({ {1, 0, 5}, {2, 0, 13} },
+ curbufmeths.get_extmarks(ns, 0, -1, {}))
+
+ -- but both move when text is inserted before
+ feed([[<esc>Iasdf<esc>]])
+ -- eq({}, curbufmeths.get_lines(0, -1, true))
+ eq({ {1, 0, 9}, {2, 0, 17} },
+ curbufmeths.get_extmarks(ns, 0, -1, {}))
+
+ -- clear text
+ curbufmeths.set_text(0, 0, 0, 17, {})
+
+ -- handles set_text correctly as well
+ eq({ {1, 0, 0}, {2, 0, 0} },
+ meths.buf_get_extmarks(0, ns, 0, -1, {}))
+ curbufmeths.set_text(0, 0, 0, 0, {'asdfasdf'})
+ eq({ {1, 0, 0}, {2, 0, 8} },
+ curbufmeths.get_extmarks(ns, 0, -1, {}))
+
+ feed('u')
+ -- handles pasting
+ meths.exec([[let @a='asdfasdf']], false)
+ feed([["ap]])
+ eq({ {1, 0, 0}, {2, 0, 8} },
+ meths.buf_get_extmarks(0, ns, 0, -1, {}))
+ end)
end)
describe('Extmarks buffer api with many marks', function()
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 30128e9c40..3ff3efb8c9 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -2002,4 +2002,77 @@ describe('API', function()
}, meths.get_option_info'showcmd')
end)
end)
+
+ describe('nvim_echo', function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(40, 8)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [0] = {bold=true, foreground=Screen.colors.Blue},
+ [1] = {bold = true, foreground = Screen.colors.SeaGreen},
+ [2] = {bold = true, reverse = true},
+ [3] = {foreground = Screen.colors.Brown, bold = true}, -- Statement
+ [4] = {foreground = Screen.colors.SlateBlue}, -- Special
+ })
+ command('highlight Statement gui=bold guifg=Brown')
+ command('highlight Special guifg=SlateBlue')
+ end)
+
+ it('should clear cmdline message before echo', function()
+ feed(':call nvim_echo([["msg"]], v:false, {})<CR>')
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ msg |
+ ]]}
+ end)
+
+ it('can show highlighted line', function()
+ nvim_async("echo", {{"msg_a"}, {"msg_b", "Statement"}, {"msg_c", "Special"}}, true, {})
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ msg_a{3:msg_b}{4:msg_c} |
+ ]]}
+ end)
+
+ it('can show highlighted multiline', function()
+ nvim_async("echo", {{"msg_a\nmsg_a", "Statement"}, {"msg_b", "Special"}}, true, {})
+ screen:expect{grid=[[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {2: }|
+ {3:msg_a} |
+ {3:msg_a}{4:msg_b} |
+ {1:Press ENTER or type command to continue}^ |
+ ]]}
+ end)
+
+ it('can save message history', function()
+ nvim('command', 'set cmdheight=2') -- suppress Press ENTER
+ nvim("echo", {{"msg\nmsg"}, {"msg"}}, true, {})
+ eq("msg\nmsgmsg", meths.exec('messages', true))
+ end)
+
+ it('can disable saving message history', function()
+ nvim('command', 'set cmdheight=2') -- suppress Press ENTER
+ nvim_async("echo", {{"msg\nmsg"}, {"msg"}}, false, {})
+ eq("", meths.exec("messages", true))
+ end)
+ end)
end)