fix(api): avoid double hit-enter prompt with nvim_err_writeln (#22879)

This commit is contained in:
zeertzjq 2023-04-04 08:59:11 +08:00 committed by GitHub
parent eb1da498d6
commit 7c8c155073
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 12 deletions

View File

@ -737,7 +737,7 @@ error:
void nvim_out_write(String str)
FUNC_API_SINCE(1)
{
write_msg(str, false);
write_msg(str, false, false);
}
/// Writes a message to the Vim error buffer. Does not append "\n", the
@ -747,7 +747,7 @@ void nvim_out_write(String str)
void nvim_err_write(String str)
FUNC_API_SINCE(1)
{
write_msg(str, true);
write_msg(str, true, false);
}
/// Writes a message to the Vim error buffer. Appends "\n", so the buffer is
@ -758,8 +758,7 @@ void nvim_err_write(String str)
void nvim_err_writeln(String str)
FUNC_API_SINCE(1)
{
nvim_err_write(str);
nvim_err_write((String) { .data = "\n", .size = 1 });
write_msg(str, true, true);
}
/// Gets the current list of buffer handles
@ -1672,23 +1671,24 @@ theend:
///
/// @param message Message to write
/// @param to_err true: message is an error (uses `emsg` instead of `msg`)
static void write_msg(String message, bool to_err)
/// @param writeln Append a trailing newline
static void write_msg(String message, bool to_err, bool writeln)
{
static StringBuilder out_line_buf = KV_INITIAL_VALUE;
static StringBuilder err_line_buf = KV_INITIAL_VALUE;
#define PUSH_CHAR(i, line_buf, msg) \
#define PUSH_CHAR(c, line_buf, msg) \
if (kv_max(line_buf) == 0) { \
kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \
} \
if (message.data[i] == NL) { \
if (c == NL) { \
kv_push(line_buf, NUL); \
msg(line_buf.items); \
kv_drop(line_buf, kv_size(line_buf)); \
kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \
continue; \
} \
kv_push(line_buf, message.data[i]);
} else { \
kv_push(line_buf, c); \
}
no_wait_return++;
for (uint32_t i = 0; i < message.size; i++) {
@ -1696,9 +1696,16 @@ static void write_msg(String message, bool to_err)
break;
}
if (to_err) {
PUSH_CHAR(i, err_line_buf, emsg);
PUSH_CHAR(message.data[i], err_line_buf, emsg);
} else {
PUSH_CHAR(i, out_line_buf, msg);
PUSH_CHAR(message.data[i], out_line_buf, msg);
}
}
if (writeln) {
if (to_err) {
PUSH_CHAR(NL, err_line_buf, emsg);
} else {
PUSH_CHAR(NL, out_line_buf, msg);
}
}
no_wait_return--;

View File

@ -2080,6 +2080,46 @@ describe('API', function()
end)
end)
describe('nvim_err_writeln', function()
local screen
before_each(function()
screen = Screen.new(40, 8)
screen:attach()
screen:set_default_attr_ids({
[0] = {bold=true, foreground=Screen.colors.Blue},
[1] = {foreground = Screen.colors.White, background = Screen.colors.Red},
[2] = {bold = true, foreground = Screen.colors.SeaGreen},
[3] = {bold = true, reverse = true},
})
end)
it('shows only one return prompt after all lines are shown', function()
nvim_async('err_writeln', 'FAILURE\nERROR\nEXCEPTION\nTRACEBACK')
screen:expect([[
|
{0:~ }|
{3: }|
{1:FAILURE} |
{1:ERROR} |
{1:EXCEPTION} |
{1:TRACEBACK} |
{2:Press ENTER or type command to continue}^ |
]])
feed('<CR>')
screen:expect([[
^ |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
|
]])
end)
end)
describe('nvim_list_chans, nvim_get_chan_info', function()
before_each(function()
command('autocmd ChanOpen * let g:opened_event = deepcopy(v:event)')