fix(messages): unwanted newlines with ext_messages #37733

Problem:  Newlines intended to write messages below the cmdline or to
          mark the start of a new message on message grid are emitted
          through ext_messages. This results in unnecessary newlines for
          a UI that has decoupled its message area from the cmdline.
          msg_col is set directly in some places which is not transmitted
          to msg_show events.
          Various missing message kind for list commands.
          Trailing newlines on various list commands.

Solution: Only emit such newlines without ext_messages enabled.
          Use msg_advance() instead of setting msg_col directly.
          Assign them the "list_cmd" kind.
          Ensure no trailing newline is printed.
This commit is contained in:
luukvbaal
2026-02-08 15:47:02 +01:00
committed by GitHub
parent 0f73873d4f
commit 4260f73e13
28 changed files with 168 additions and 108 deletions
+2 -2
View File
@@ -245,7 +245,7 @@ static void au_show_for_event(int group, event_T event, const char *pat)
return;
}
msg_col = 4;
msg_advance(4);
msg_outtrans(ac->pat->pat, 0, false);
}
@@ -256,7 +256,7 @@ static void au_show_for_event(int group, event_T event, const char *pat)
if (msg_col >= 14) {
msg_putchar('\n');
}
msg_col = 14;
msg_advance(14);
if (got_int) {
return;
}
+3 -1
View File
@@ -2966,7 +2966,9 @@ void buflist_list(exarg_T *eap)
ro_char = terminal_running(buf->terminal) ? 'R' : 'F';
}
msg_putchar('\n');
if (!ui_has(kUIMessages) || msg_col > 0) {
msg_putchar('\n');
}
int len = (int)vim_snprintf_safelen(IObuff, IOSIZE - 20, "%3d%c%c%c%c%c \"%s\"",
buf->b_fnum,
buf->b_p_bl ? ' ' : 'u',
+3 -1
View File
@@ -1140,7 +1140,9 @@ int showmatches(expand_T *xp, bool display_wildmenu, bool display_list, bool nos
if (display_list) {
msg_didany = false; // lines_left will be set
msg_start(); // prepare for paging
msg_putchar('\n');
if (!ui_has(kUIMessages)) {
msg_putchar('\n');
}
ui_flush();
cmdline_row = msg_row;
msg_didany = false; // lines_left will be set again
+1
View File
@@ -601,6 +601,7 @@ void ex_history(exarg_T *eap)
char *end;
char *arg = eap->arg;
msg_ext_set_kind("list_cmd");
if (hislen == 0) {
msg(_("'history' option is zero"), 0);
return;
+1 -4
View File
@@ -1851,10 +1851,7 @@ static void printdigraph(const digr_T *dp, result_T *previous)
// Make msg_col a multiple of list_width by using spaces.
if (msg_col % list_width != 0) {
int spaces = (msg_col / list_width + 1) * list_width - msg_col;
while (spaces--) {
msg_putchar(' ');
}
msg_advance((msg_col / list_width + 1) * list_width);
}
char *p = &buf[0];
+1
View File
@@ -6310,6 +6310,7 @@ void last_set_msg(sctx_T script_ctx)
bool should_free;
char *p = get_scriptname(script_ctx, &should_free);
msg_ext_skip_verbose = true; // no verbose kind for last set messages: too noisy
verbose_enter();
msg_puts(_("\n\tLast set from "));
+2
View File
@@ -2241,6 +2241,7 @@ static void list_functions(regmatch_T *regmatch)
size_t todo = func_hashtab.ht_used;
const hashitem_T *const ht_array = func_hashtab.ht_array;
msg_ext_set_kind("list_cmd");
for (const hashitem_T *hi = ht_array; todo > 0 && !got_int; hi++) {
if (!HASHITEM_EMPTY(hi)) {
ufunc_T *fp = HI2UF(hi);
@@ -2318,6 +2319,7 @@ static ufunc_T *list_one_function(exarg_T *eap, char *name, char *p)
// the more prompt. "fp" may then be invalid.
const int prev_ht_changed = func_hashtab.ht_changed;
msg_ext_set_kind("list_cmd");
if (list_func_head(fp, !eap->forceit, eap->forceit) != OK) {
return fp;
}
+6 -2
View File
@@ -1323,7 +1323,9 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b
no_wait_return++; // don't call wait_return() while busy
if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
false, false, false, true) == FAIL) {
msg_putchar('\n'); // Keep message from buf_write().
if (!ui_has(kUIMessages)) {
msg_putchar('\n'); // Keep message from buf_write().
}
no_wait_return--;
if (!aborting()) {
// will call wait_return()
@@ -3981,7 +3983,9 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
memset(prompt + sc, '^', (size_t)(ec - sc) + 1);
char *resp = getcmdline_prompt(-1, prompt, 0, EXPAND_NOTHING, NULL,
CALLBACK_NONE, false, NULL);
msg_putchar('\n');
if (!ui_has(kUIMessages)) {
msg_putchar('\n');
}
xfree(prompt);
if (resp != NULL) {
typed = (uint8_t)(*resp);
+4 -1
View File
@@ -5697,6 +5697,7 @@ static void ex_tabs(exarg_T *eap)
{
int tabcount = 1;
msg_ext_set_kind("list_cmd");
msg_start();
msg_scroll = true;
@@ -5709,7 +5710,9 @@ static void ex_tabs(exarg_T *eap)
break;
}
msg_putchar('\n');
if (msg_col > 0) {
msg_putchar('\n');
}
vim_snprintf(IObuff, IOSIZE, _("Tab page %d"), tabcount++);
msg_outtrans(IObuff, HLF_T, false);
os_breakcheck();
+9 -3
View File
@@ -845,7 +845,9 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
});
if (ERROR_SET(&err)) {
msg_putchar('\n');
if (!ui_has(kUIMessages)) {
msg_putchar('\n');
}
msg_scroll = true;
msg_puts_hl(err.msg, HLF_E, true);
api_clear_error(&err);
@@ -977,7 +979,9 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
redir_off = false;
if (ERROR_SET(&err)) {
msg_putchar('\n');
if (!ui_has(kUIMessages)) {
msg_putchar('\n');
}
emsg(err.msg);
did_emsg = false;
api_clear_error(&err);
@@ -2844,7 +2848,9 @@ static void do_autocmd_cmdlinechanged(int firstc)
restore_v_event(dict, &save_v_event);
});
if (ERROR_SET(&err)) {
msg_putchar('\n');
if (!ui_has(kUIMessages)) {
msg_putchar('\n');
}
msg_scroll = true;
msg_puts_hl(err.msg, HLF_E, true);
api_clear_error(&err);
+3 -1
View File
@@ -1900,7 +1900,9 @@ bool syn_list_header(const bool did_header, const int outlen, const int id, bool
bool adjust = true;
if (!did_header) {
msg_putchar('\n');
if (!ui_has(kUIMessages) || msg_col > 0) {
msg_putchar('\n');
}
if (got_int) {
return true;
}
+1 -2
View File
@@ -214,8 +214,7 @@ static void showmap(mapblock_T *mp, bool local)
return;
}
// When ext_messages is active, msg_didout is never set.
if (msg_didout || msg_silent != 0 || ui_has(kUIMessages)) {
if (msg_col > 0 || msg_silent != 0) {
msg_putchar('\n');
if (got_int) { // 'q' typed at MORE prompt
return;
+9 -4
View File
@@ -1673,7 +1673,7 @@ void msg_start(void)
if (!msg_scroll && full_screen) { // overwrite last message
msg_row = cmdline_row;
msg_col = 0;
} else if (msg_didout || (p_ch == 0 && !ui_has(kUIMessages))) { // start message on next line
} else if ((msg_didout || p_ch == 0) && !ui_has(kUIMessages)) { // start message on next line
msg_putchar('\n');
did_return = true;
cmdline_row = msg_row;
@@ -2232,6 +2232,7 @@ void msg_puts(const char *s)
void msg_puts_title(const char *s)
{
s += (ui_has(kUIMessages) && *s == '\n');
msg_puts_hl(s, HLF_T, false);
}
@@ -3457,10 +3458,14 @@ void verbose_enter(void)
if (*p_vfile != NUL) {
msg_silent++;
}
if (msg_ext_kind != verbose_kind) {
pre_verbose_kind = msg_ext_kind;
// last_set_msg unsets p_verbose to avoid setting the verbose kind.
if (!msg_ext_skip_verbose) {
if (msg_ext_kind != verbose_kind) {
pre_verbose_kind = msg_ext_kind;
}
msg_ext_set_kind("verbose");
}
msg_ext_set_kind("verbose");
msg_ext_skip_verbose = false;
}
/// After giving verbose message.
+2
View File
@@ -37,6 +37,8 @@ EXTERN bool msg_ext_skip_flush INIT( = false);
EXTERN bool msg_ext_append INIT( = false);
/// Set to true when previous message should be overwritten.
EXTERN bool msg_ext_overwrite INIT( = false);
/// Set to true to avoid setting "verbose" kind for last set messages.
EXTERN bool msg_ext_skip_verbose INIT( = false);
/// allocated grid for messages. Used unless ext_messages is active.
/// See also the description at msg_scroll_flush()
+4 -2
View File
@@ -4089,7 +4089,7 @@ static void showoptions(bool all, int opt_flags)
}
int col = 0;
for (int i = row; i < item_count; i += rows) {
msg_col = col; // make columns
msg_advance(col); // make columns
showoneopt(items[i], opt_flags);
col += INC;
}
@@ -4160,7 +4160,9 @@ static void showoneopt(vimoption_T *opt, int opt_flags)
msg_putchar('=');
// put value string in NameBuff
option_value2string(opt, opt_flags);
msg_outtrans(NameBuff, 0, false);
if (*NameBuff != NUL) {
msg_outtrans(NameBuff, 0, false);
}
}
silent_mode = save_silent;
+7 -2
View File
@@ -3356,7 +3356,9 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
return;
}
msg_putchar('\n');
if (msg_col > 0) {
msg_putchar('\n');
}
msg_outtrans(IObuff, cursel ? HLF_QFL : qfFile_hl_id, false);
if (qfp->qf_lnum != 0) {
@@ -3368,7 +3370,9 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
}
ga_concat(gap, qf_types(qfp->qf_type, qfp->qf_nr));
ga_append(gap, NUL);
msg_puts_hl(gap->ga_data, qfLine_hl_id, false);
if (*(char *)gap->ga_data != NUL) {
msg_puts_hl(gap->ga_data, qfLine_hl_id, false);
}
msg_puts_hl(":", qfSep_hl_id, false);
if (qfp->qf_pattern != NULL) {
gap = qfga_get();
@@ -3453,6 +3457,7 @@ void qf_list(exarg_T *eap)
if (qfl->qf_nonevalid) {
all = true;
}
msg_ext_set_kind("list_cmd");
qfline_T *qfp;
FOR_ALL_QFL_ITEMS(qfl, qfp, i) {
if ((qfp->qf_valid || all) && idx1 <= i && i <= idx2) {
+4 -1
View File
@@ -2445,12 +2445,15 @@ void ex_scriptnames(exarg_T *eap)
return;
}
msg_ext_set_kind("list_cmd");
for (int i = 1; i <= script_items.ga_len && !got_int; i++) {
if (SCRIPT_ITEM(i)->sn_name != NULL) {
home_replace(NULL, SCRIPT_ITEM(i)->sn_name, NameBuff, MAXPATHL, true);
vim_snprintf(IObuff, IOSIZE, "%3d: %s", i, NameBuff);
if (!message_filtered(IObuff)) {
msg_putchar('\n');
if (msg_col > 0) {
msg_putchar('\n');
}
msg_outtrans(IObuff, 0, false);
line_breakcheck();
}
+5 -3
View File
@@ -260,13 +260,12 @@ static void sign_list_placed(buf_T *rbuf, char *group)
int64_t ns = group_get_ns(group);
msg_puts_title(_("\n--- Signs ---"));
msg_putchar('\n');
while (buf != NULL && !got_int) {
if (buf_has_signs(buf)) {
msg_putchar('\n');
vim_snprintf(lbuf, MSG_BUF_LEN, _("Signs for %s:"), buf->b_fname);
msg_puts_hl(lbuf, HLF_D, false);
msg_putchar('\n');
}
if (ns >= 0) {
@@ -285,6 +284,7 @@ static void sign_list_placed(buf_T *rbuf, char *group)
if (kv_size(signs)) {
qsort((void *)&kv_A(signs, 0), kv_size(signs), sizeof(MTKey), sign_row_cmp);
msg_putchar('\n');
for (size_t i = 0; i < kv_size(signs); i++) {
namebuf[0] = NUL;
@@ -301,7 +301,9 @@ static void sign_list_placed(buf_T *rbuf, char *group)
vim_snprintf(lbuf, MSG_BUF_LEN, _(" line=%" PRIdLINENR " id=%u%s%s priority=%d"),
mark.pos.row + 1, mark.id, groupbuf, namebuf, sh->priority);
msg_puts(lbuf);
msg_putchar('\n');
if (i < kv_size(signs) - 1) {
msg_putchar('\n');
}
}
kv_destroy(signs);
}
+7 -2
View File
@@ -3187,16 +3187,21 @@ void ex_spellinfo(exarg_T *eap)
return;
}
msg_ext_set_kind("list_cmd");
msg_start();
for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len && !got_int; lpi++) {
langp_T *const lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
msg_puts("file: ");
msg_puts(lp->lp_slang->sl_fname);
msg_putchar('\n');
const char *const p = lp->lp_slang->sl_info;
if (lpi < curwin->w_s->b_langp.ga_len || p != NULL) {
msg_putchar('\n');
}
if (p != NULL) {
msg_puts(p);
msg_putchar('\n');
if (lpi < curwin->w_s->b_langp.ga_len - 1) {
msg_putchar('\n');
}
}
}
msg_end();
+1
View File
@@ -3212,6 +3212,7 @@ static void syn_cmd_list(exarg_T *eap, int syncing)
return;
}
msg_ext_set_kind("list_cmd");
if (!syntax_present(curwin)) {
msg(_(msg_no_items), 0);
return;
+1
View File
@@ -2717,6 +2717,7 @@ void ex_undolist(exarg_T *eap)
}
}
msg_ext_set_kind("list_cmd");
if (GA_EMPTY(&ga)) {
msg(_("Nothing to undo"), 0);
} else {
@@ -86,7 +86,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
[No Name]
Tab page 2
@@ -137,7 +136,6 @@ describe('tabpage/previous', function()
feed(characters)
eq(
dedent([=[
Tab page 1
[No Name]
Tab page 2
@@ -189,7 +187,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
# [No Name]
Tab page 2
@@ -241,7 +238,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
> [No Name]
Tab page 2
@@ -291,7 +287,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
[No Name]
Tab page 2
@@ -343,7 +338,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
# [No Name]
Tab page 2
@@ -393,7 +387,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
[No Name]
Tab page 2
@@ -445,7 +438,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
[No Name]
Tab page 2
@@ -544,7 +536,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
[No Name]
Tab page 2
@@ -681,7 +672,6 @@ describe('tabpage/previous', function()
eq(
dedent([=[
Tab page 1
[No Name]
Tab page 2
+2 -2
View File
@@ -20,8 +20,8 @@ describe('sign', function()
command('sign place 34 line=3 name=Foo buffer=' .. buf2)
-- now unplace without specifying a buffer
command('sign unplace 34')
eq('--- Signs ---\n', api.nvim_exec('sign place buffer=' .. buf1, true))
eq('--- Signs ---\n', api.nvim_exec('sign place buffer=' .. buf2, true))
eq('--- Signs ---', api.nvim_exec('sign place buffer=' .. buf1, true))
eq('--- Signs ---', api.nvim_exec('sign place buffer=' .. buf2, true))
end)
end)
end)
+1 -2
View File
@@ -82,11 +82,10 @@ describe('messages2', function()
feed('Q')
screen:expect([[
^ |
{1:~ }|*8
{1:~ }|*9
{3: }|
foo |
bar |
|
1 %a "[No Name]" line 1 |
]])
feed('<C-L>')
+65 -38
View File
@@ -175,7 +175,7 @@ describe('ui/ext_messages', function()
messages = {
{
content = {
{ '\n@character ' },
{ '@character ' },
{ 'xxx', 26, '@character' },
{ ' ' },
{ 'links to', 18, 'Directory' },
@@ -292,44 +292,38 @@ describe('ui/ext_messages', function()
messages = {
{
content = {
{ '\nDiffAdd ' },
{ 'DiffAdd ' },
{ 'xxx', 22, 'DiffAdd' },
{ ' ' },
{ 'ctermbg=', 18, 'Directory' },
{ '81 ' },
{ 'guibg=', 18, 'Directory' },
{ 'LightBlue' },
},
kind = 'list_cmd',
},
{
content = { { '\n\tLast set from Lua (run Nvim with -V1 for more details)' } },
kind = 'verbose',
},
{
content = {
{ '\nDiffChange ' },
{
'LightBlue\n\tLast set from Lua (run Nvim with -V1 for more details)\nDiffChange ',
},
{ 'xxx', 4, 'DiffChange' },
{ ' ' },
{ 'ctermbg=', 18, 'Directory' },
{ '225 ' },
{ 'guibg=', 18, 'Directory' },
{ 'LightMagenta' },
{ 'LightMagenta\n\tLast set from Lua (run Nvim with -V1 for more details)' },
},
kind = 'list_cmd',
},
{
content = { { '\n\tLast set from Lua (run Nvim with -V1 for more details)' } },
kind = 'verbose',
},
},
})
exec([[
set verbose=9
augroup verbose
augroup group1
autocmd BufEnter * echoh "BufEnter"
autocmd BufWinEnter * bdelete
autocmd ExitPre pat1 foo
autocmd ExitPre pat2 bar
augroup END
augroup group2
autocmd ExitPre pat1 foo
autocmd ExitPre pat2 bar
augroup END
]])
feed(':edit! foo<CR>')
@@ -357,8 +351,39 @@ describe('ui/ext_messages', function()
{ content = { { '\n' } }, kind = '' },
},
})
command('autocmd! verbose')
command('augroup! verbose')
feed(':au ExitPre<CR>')
screen:expect({
grid = [[
line 1 |
^line |
{1:~ }|*3
]],
messages = {
{
content = {
{ '--- Autocommands ---', 101, 'Title' },
{ '\n' },
{ 'group1', 101, 'Title' },
{ ' ' },
{ 'ExitPre', 101, 'Title' },
{
'\n pat1 foo\n\tLast set from anonymous :source line 5\n pat2 bar\n\tLast set from anonymous :source line 6\n',
},
{ 'group2', 101, 'Title' },
{ ' ' },
{ 'ExitPre', 101, 'Title' },
{
'\n pat1 foo\n\tLast set from anonymous :source line 9\n pat2 bar\n\tLast set from anonymous :source line 10',
},
},
kind = 'list_cmd',
},
},
})
command('autocmd! group1')
command('autocmd! group2')
command('augroup! group1')
command('augroup! group2')
command('set verbose=0')
n.add_builddir_to_rtp()
@@ -432,7 +457,7 @@ describe('ui/ext_messages', function()
]],
messages = {
{
content = { { '\nType Name Content', 101, 'Title' }, { '\n c ". ' } },
content = { { 'Type Name Content', 101, 'Title' }, { '\n c ". ' } },
kind = 'list_cmd',
},
},
@@ -448,10 +473,10 @@ describe('ui/ext_messages', function()
messages = {
{
content = {
{ '\n--- Autocommands ---', 101, 'Title' },
{ '--- Autocommands ---', 101, 'Title' },
{ '\n' },
{ 'ChanInfo', 101, 'Title' },
{ '\n*foo' },
{ '\n * foo' },
},
kind = 'list_cmd',
},
@@ -476,10 +501,7 @@ describe('ui/ext_messages', function()
^line |
{1:~ }|*3
]],
messages = {
{ content = { { '\n' } }, kind = '' },
{ content = { { 'line 1\nline ' } }, kind = 'list_cmd' },
},
messages = { { content = { { 'line 1\nline ' } }, kind = 'list_cmd' } },
})
command('command Foo Bar')
@@ -493,7 +515,7 @@ describe('ui/ext_messages', function()
messages = {
{
content = {
{ '\n Name Args Address Complete Definition', 101, 'Title' },
{ ' Name Args Address Complete Definition', 101, 'Title' },
{ '\n ' },
{ 'Foo', 18, 'Directory' },
{ ' 0 Bar' },
@@ -541,6 +563,17 @@ describe('ui/ext_messages', function()
{ content = {}, kind = 'empty' },
},
})
-- No empty message event for empty option value
feed(':set foldclose<CR>')
screen:expect({
grid = [[
line 1 |
^line |
{1:~ }|*3
]],
messages = { { content = { { ' foldclose=' } }, history = true, kind = 'list_cmd' } },
})
end)
it(':echoerr', function()
@@ -1192,7 +1225,7 @@ stack traceback:
messages = {
{
content = {
{ '\nn Q @@\nn Y y$\nn j ' },
{ 'n Q @@\nn Y y$\nn j ' },
{ '*', 18, 'SpecialKey' },
{ ' k' },
},
@@ -1213,10 +1246,7 @@ stack traceback:
^ |
{1:~ }|*6
]],
messages = {
{ content = { { '\n' } }, kind = '' },
{ content = { { 'wildmenu wildmode\n' } }, kind = 'wildlist' },
},
messages = { { content = { { 'wildmenu wildmode\n' } }, kind = 'wildlist' } },
cmdline = { { firstc = ':', content = { { 'set wildm' } }, pos = 9 } },
}
end)
@@ -1322,10 +1352,7 @@ stack traceback:
{1:~ }|*4
]],
messages = {
{
content = { { '\n 1 %a "[No Name]" line 1' } },
kind = 'list_cmd',
},
{ content = { { ' 1 %a "[No Name]" line 1' } }, kind = 'list_cmd' },
},
}
+1 -2
View File
@@ -446,13 +446,12 @@ describe('Signs', function()
feed(':sign place<cr>')
screen:expect([[
{101:>>} |
{1:~ }|*6
{1:~ }|*7
{3: }|
:sign place |
{100:--- Signs ---} |
{18:Signs for [NULL]:} |
line=1 id=100000 name=piet priority=10 |
|
{6:Press ENTER or type command to continue}^ |
]])
+1 -1
View File
@@ -38,7 +38,7 @@ func Test_compiler()
w!
call feedkeys(":make\<CR>\<CR>", 'tx')
let a=execute('clist')
call assert_match('\n \d\+ Xfoo.pl:3: Global symbol "$foo" '
call assert_match('\d\+ Xfoo.pl:3: Global symbol "$foo" '
\ . 'requires explicit package name', a)
compiler make
+22 -22
View File
@@ -62,7 +62,7 @@ func Test_sign()
" Check placed signs
let a=execute('sign place')
call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" .
\ " line=3 id=41 name=Sign1 priority=10\n", a)
\ " line=3 id=41 name=Sign1 priority=10", a)
" Unplace the sign and try jumping to it again should fail.
sign unplace 41
@@ -75,7 +75,7 @@ func Test_sign()
4
sign unplace
let a=execute('sign place')
call assert_equal("\n--- Signs ---\n", a)
call assert_equal("\n--- Signs ---", a)
" Try again to unplace sign on current line, it should fail this time.
call assert_fails('sign unplace', 'E159:')
@@ -84,14 +84,14 @@ func Test_sign()
exe 'sign place 41 line=3 name=Sign1 buffer=' . bufnr('%')
sign unplace *
let a=execute('sign place')
call assert_equal("\n--- Signs ---\n", a)
call assert_equal("\n--- Signs ---", a)
" Place a sign without specifying the filename or buffer
sign place 77 line=9 name=Sign2
let a=execute('sign place')
" Nvim: sign line clamped to buffer length
call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n" .
\ " line=4 id=77 name=Sign2 priority=10\n", a)
\ " line=4 id=77 name=Sign2 priority=10", a)
sign unplace *
" Check :jump with file=...
@@ -184,7 +184,7 @@ func Test_sign()
exe 'sign place 20 line=3 name=004 buffer=' . bufnr('')
let a = execute('sign place')
call assert_equal("\n--- Signs ---\nSigns for foo:\n" .
\ " line=3 id=20 name=4 priority=10\n", a)
\ " line=3 id=20 name=4 priority=10", a)
exe 'sign unplace 20 buffer=' . bufnr('')
sign undefine 004
call assert_fails('sign list 4', 'E155:')
@@ -231,11 +231,11 @@ func Test_sign_undefine_still_placed()
" Listing placed sign should show that sign is deleted.
let a=execute('sign place')
call assert_equal("\n--- Signs ---\nSigns for foobar:\n" .
\ " line=1 id=41 name=[Deleted] priority=10\n", a)
\ " line=1 id=41 name=[Deleted] priority=10", a)
sign unplace 41
let a=execute('sign place')
call assert_equal("\n--- Signs ---\n", a)
call assert_equal("\n--- Signs ---", a)
endfunc
func Test_sign_completion()
@@ -742,23 +742,23 @@ func Test_sign_group()
" :sign place file={fname}
let a = execute('sign place file=Xsign')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 name=sign1 priority=10\n", a)
\ " line=10 id=5 name=sign1 priority=10", a)
" :sign place group={group} file={fname}
let a = execute('sign place group=g2 file=Xsign')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 group=g2 name=sign1 priority=10\n", a)
\ " line=10 id=5 group=g2 name=sign1 priority=10", a)
" :sign place group=* file={fname}
let a = execute('sign place group=* file=Xsign')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 group=g2 name=sign1 priority=10\n" .
\ " line=10 id=5 group=g1 name=sign1 priority=10\n" .
\ " line=10 id=5 name=sign1 priority=10\n", a)
\ " line=10 id=5 name=sign1 priority=10", a)
" Error case: non-existing group
let a = execute('sign place group=xyz file=Xsign')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
call assert_equal("\n--- Signs ---\nSigns for Xsign:", a)
call sign_unplace('*')
let bnum = bufnr('Xsign')
@@ -769,28 +769,28 @@ func Test_sign_group()
" :sign place buffer={fname}
let a = execute('sign place buffer=' . bnum)
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 name=sign1 priority=10\n", a)
\ " line=10 id=5 name=sign1 priority=10", a)
" :sign place group={group} buffer={fname}
let a = execute('sign place group=g2 buffer=' . bnum)
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
\ " line=12 id=5 group=g2 name=sign1 priority=10", a)
" :sign place group=* buffer={fname}
let a = execute('sign place group=* buffer=' . bnum)
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 name=sign1 priority=10\n" .
\ " line=11 id=5 group=g1 name=sign1 priority=10\n" .
\ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
\ " line=12 id=5 group=g2 name=sign1 priority=10", a)
" Error case: non-existing group
let a = execute('sign place group=xyz buffer=' . bnum)
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", a)
call assert_equal("\n--- Signs ---\nSigns for Xsign:", a)
" :sign place
let a = execute('sign place')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 name=sign1 priority=10\n", a)
\ " line=10 id=5 name=sign1 priority=10", a)
" Place signs in more than one buffer and list the signs
split foo
@@ -801,21 +801,21 @@ func Test_sign_group()
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 name=sign1 priority=10\n" .
\ "Signs for foo:\n" .
\ " line=1 id=25 name=sign1 priority=99\n", a)
\ " line=1 id=25 name=sign1 priority=99", a)
close
bwipe foo
" :sign place group={group}
let a = execute('sign place group=g1')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=11 id=5 group=g1 name=sign1 priority=10\n", a)
\ " line=11 id=5 group=g1 name=sign1 priority=10", a)
" :sign place group=*
let a = execute('sign place group=*')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 name=sign1 priority=10\n" .
\ " line=11 id=5 group=g1 name=sign1 priority=10\n" .
\ " line=12 id=5 group=g2 name=sign1 priority=10\n", a)
\ " line=12 id=5 group=g2 name=sign1 priority=10", a)
" Test for ':sign jump' command with groups
sign jump 5 group=g1 file=Xsign
@@ -1582,12 +1582,12 @@ func Test_sign_priority()
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 name=sign1 priority=30\n" .
\ " line=10 id=5 group=g2 name=sign1 priority=25\n" .
\ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
\ " line=10 id=5 group=g1 name=sign1 priority=20", a)
" Test for :sign place group={group}
let a = execute('sign place group=g1')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)
\ " line=10 id=5 group=g1 name=sign1 priority=20", a)
call sign_unplace('*')
@@ -1606,7 +1606,7 @@ func Test_sign_priority()
let a = execute('sign place group=g1')
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=3 id=1 group=g1 name=sign4 priority=60\n" .
\ " line=5 id=2 group=g1 name=sign4 priority=60\n", a)
\ " line=5 id=2 group=g1 name=sign4 priority=60", a)
call sign_unplace('*')
call sign_undefine()