Skip to content

Commit

Permalink
patch 9.1.0538: not possible to assign priority when defining a sign
Browse files Browse the repository at this point in the history
Problem:  not possible to assign priority when defining a sign
          (Mathias Fußenegger)
Solution: Add the priority argument for the :sign-define ex command and
          the sign_define() function (LemonBoy)

Use the specified value instead of the default one (SIGN_DEF_PRIO) when
no priority is explicitly specified in sign_place or :sign place.

fixes: vim#8334
closes: vim#15124

Signed-off-by: LemonBoy <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
  • Loading branch information
LemonBoy authored and chrisbra committed Jul 6, 2024
1 parent 25ac6d6 commit b975ddf
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 22 deletions.
23 changes: 14 additions & 9 deletions runtime/doc/sign.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*sign.txt* For Vim version 9.1. Last change: 2024 Jun 08
*sign.txt* For Vim version 9.1. Last change: 2024 Jul 06


VIM REFERENCE MANUAL by Gordon Prieur
Expand Down Expand Up @@ -80,8 +80,9 @@ used by popup windows where 'cursorline' is set.
*sign-priority*
Each placed sign is assigned a priority value. When multiple signs are placed
on the same line, the attributes of the sign with the highest priority is used
independently of the sign group. The default priority for a sign is 10. The
priority is assigned at the time of placing a sign.
independently of the sign group. The default priority for a sign is 10, this
value can be changed for different signs by specifying a different value at
definition time. The priority is assigned at the time of placing a sign.

When two signs with the same priority are present, and one has an icon or text
in the signcolumn while the other has line highlighting, then both are
Expand Down Expand Up @@ -135,6 +136,8 @@ See |sign_define()| for the equivalent Vim script function.
Motif pixmap (.xpm)
Win32 .bmp, .ico, .cur
pixmap (.xpm) |+xpm_w32|
priority={prio}
Default priority for the sign, see |sign-priority|.

linehl={group}
Highlighting group used for the whole line the sign is placed
Expand Down Expand Up @@ -209,11 +212,11 @@ See |sign_place()| for the equivalent Vim script function.

By default, the sign is placed in the global sign group.

By default, the sign is assigned a default priority of 10. To
assign a different priority value, use "priority={prio}" to
specify a value. The priority is used to determine the sign
that is displayed when multiple signs are placed on the same
line.
By default, the sign is assigned a default priority of 10,
unless specified otherwise by the sign definition. To assign a
different priority value, use "priority={prio}" to specify a
value. The priority is used to determine the sign that is
displayed when multiple signs are placed on the same line.

Examples: >
:sign place 5 line=3 name=sign1 file=a.py
Expand Down Expand Up @@ -453,6 +456,7 @@ sign_getdefined([{name}]) *sign_getdefined()*
linehl highlight group used for the whole line the
sign is placed in; not present if not set
name name of the sign
priority default priority value of the sign
numhl highlight group used for the line number where
the sign is placed; not present if not set
text text that is displayed when there is no icon
Expand Down Expand Up @@ -646,7 +650,8 @@ sign_placelist({list}) *sign_placelist()*
priority Priority of the sign. When multiple signs are
placed on a line, the sign with the highest
priority is used. If not specified, the
default value of 10 is used. See
default value of 10 is used, unless specified
otherwise by the sign definition. See
|sign-priority| for more information.

If {id} refers to an existing sign, then the existing sign is
Expand Down
1 change: 1 addition & 0 deletions runtime/doc/version9.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41576,6 +41576,7 @@ Changed~
- 'completeopt' is now a |global-local| option.
- 'nrformat' accepts the new "blank" suboption, to determine a signed or
unsigned number based on whitespace in front of a minus sign.
- allow to specify a priority when defining a new sign |:sign-define|

*added-9.2*
Added ~
Expand Down
4 changes: 2 additions & 2 deletions src/popupwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,8 +699,8 @@ popup_highlight_curline(win_T *wp)

if (syn_name2id((char_u *)linehl) == 0)
linehl = "PmenuSel";
sign_define_by_name(sign_name, NULL, (char_u *)linehl,
NULL, NULL, NULL, NULL);
sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL,
NULL, SIGN_DEF_PRIO);
}

sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name,
Expand Down
2 changes: 1 addition & 1 deletion src/proto/sign.pro
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ int buf_findsigntype_id(buf_T *buf, linenr_T lnum, int typenr);
int buf_signcount(buf_T *buf, linenr_T lnum);
void buf_delete_signs(buf_T *buf, char_u *group);
void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after);
int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl);
int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl, int prio);
int sign_exists_by_name(char_u *name);
int sign_undefine_by_name(char_u *name, int give_error);
int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio);
Expand Down
38 changes: 32 additions & 6 deletions src/sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct sign
int sn_text_hl; // highlight ID for text
int sn_cul_hl; // highlight ID for text on current line when 'cursorline' is set
int sn_num_hl; // highlight ID for line number
int sn_priority; // default priority of this sign, -1 means SIGN_DEF_PRIO
};

static sign_T *first_sign = NULL;
Expand Down Expand Up @@ -1047,7 +1048,8 @@ sign_define_by_name(
char_u *text,
char_u *texthl,
char_u *culhl,
char_u *numhl)
char_u *numhl,
int prio)
{
sign_T *sp_prev;
sign_T *sp;
Expand Down Expand Up @@ -1083,6 +1085,8 @@ sign_define_by_name(
if (text != NULL && (sign_define_init_text(sp, text) == FAIL))
return FAIL;

sp->sn_priority = prio;

if (linehl != NULL)
{
if (*linehl == NUL)
Expand Down Expand Up @@ -1206,6 +1210,10 @@ sign_place(
if (*sign_id == 0)
*sign_id = sign_group_get_next_signid(buf, sign_group);

// Use the default priority value for this sign.
if (prio == -1)
prio = (sp->sn_priority != -1) ? sp->sn_priority : SIGN_DEF_PRIO;

if (lnum > 0)
// ":sign place {id} line={lnum} name={name} file={fname}":
// place a sign
Expand Down Expand Up @@ -1338,6 +1346,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
char_u *texthl = NULL;
char_u *culhl = NULL;
char_u *numhl = NULL;
int prio = -1;
int failed = FALSE;

// set values for a defined sign.
Expand Down Expand Up @@ -1377,6 +1386,12 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
arg += 6;
numhl = vim_strnsave(arg, p - arg);
}
else if (STRNCMP(arg, "priority=", 9) == 0)
{
arg += 9;
prio = atoi((char *)arg);
arg = skiptowhite(arg);
}
else
{
semsg(_(e_invalid_argument_str), arg);
Expand All @@ -1386,7 +1401,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
}

if (!failed)
sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl);
sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl, prio);

vim_free(icon);
vim_free(text);
Expand Down Expand Up @@ -1721,7 +1736,7 @@ ex_sign(exarg_T *eap)
linenr_T lnum = -1;
char_u *sign_name = NULL;
char_u *group = NULL;
int prio = SIGN_DEF_PRIO;
int prio = -1;

// Parse command line arguments
if (parse_sign_cmd_args(idx, arg, &sign_name, &id, &group, &prio,
Expand Down Expand Up @@ -1750,6 +1765,8 @@ sign_getinfo(sign_T *sp, dict_T *retdict)
dict_add_string(retdict, "icon", sp->sn_icon);
if (sp->sn_text != NULL)
dict_add_string(retdict, "text", sp->sn_text);
if (sp->sn_priority > 0)
dict_add_number(retdict, "priority", sp->sn_priority);
if (sp->sn_line_hl > 0)
{
p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE);
Expand Down Expand Up @@ -1913,6 +1930,7 @@ sign_gui_started(void)
sign_list_defined(sign_T *sp)
{
char_u *p;
char lbuf[MSG_BUF_LEN];

smsg("sign %s", sp->sn_name);
if (sp->sn_icon != NULL)
Expand All @@ -1931,6 +1949,11 @@ sign_list_defined(sign_T *sp)
msg_puts(" text=");
msg_outtrans(sp->sn_text);
}
if (sp->sn_priority > 0)
{
vim_snprintf(lbuf, MSG_BUF_LEN, " priority=%d", sp->sn_priority);
msg_puts(lbuf);
}
if (sp->sn_line_hl > 0)
{
msg_puts(" linehl=");
Expand Down Expand Up @@ -2088,7 +2111,8 @@ get_sign_name(expand_T *xp UNUSED, int idx)
{
char *define_arg[] =
{
"culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", NULL
"culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", "priority=",
NULL
};
return (char_u *)define_arg[idx];
}
Expand Down Expand Up @@ -2261,6 +2285,7 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict)
char_u *texthl = NULL;
char_u *culhl = NULL;
char_u *numhl = NULL;
int prio = -1;
int retval = -1;

if (name_arg == NULL)
Expand All @@ -2281,9 +2306,10 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict)
texthl = dict_get_string(dict, "texthl", TRUE);
culhl = dict_get_string(dict, "culhl", TRUE);
numhl = dict_get_string(dict, "numhl", TRUE);
prio = dict_get_number_def(dict, "priority", -1);
}

if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl) == OK)
if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl, prio) == OK)
retval = 0;

cleanup:
Expand Down Expand Up @@ -2511,7 +2537,7 @@ sign_place_from_dict(
buf_T *buf = NULL;
dictitem_T *di;
linenr_T lnum = 0;
int prio = SIGN_DEF_PRIO;
int prio = -1;
int notanum = FALSE;
int ret_sign_id = -1;

Expand Down
2 changes: 1 addition & 1 deletion src/testdir/dumps/Test_wildmenu_pum_11.dump
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @10| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@46
|~| @10| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@46
|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=> @55
2 changes: 1 addition & 1 deletion src/testdir/dumps/Test_wildmenu_pum_12.dump
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @17| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@39
|~| @17| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@39
|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=| |c|u|l|h|l|=> @48
2 changes: 1 addition & 1 deletion src/testdir/dumps/Test_wildmenu_pum_13.dump
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @24| +0#0000001#e0e0e08|c|u|l|h|l|=| @8| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|i|c|o|n|=| @9| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|l|i|n|e|h|l|=| @7| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|n|u|m|h|l|=| @8| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|p|r|i|o|r|i|t|y|=| @5| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|t|e|x|t|=| @9| +0#4040ff13#ffffff0@32
|~| @24| +0#0000001#ffd7ff255|t|e|x|t|h|l|=| @7| +0#4040ff13#ffffff0@32
|:+0#0000000&|s|i|g|n| |d|e|f|i|n|e| |c|u|l|h|l|=| |c|u|l|h|l|=| |c|u|l|h|l|=> @41
40 changes: 39 additions & 1 deletion src/testdir/test_signs.vim
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func Test_sign_completion()
call assert_equal('"sign define jump list place undefine unplace', @:)

call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign define Sign culhl= icon= linehl= numhl= text= texthl=', @:)
call assert_equal('"sign define Sign culhl= icon= linehl= numhl= priority= text= texthl=', @:)

for hl in ['culhl', 'linehl', 'numhl', 'texthl']
call feedkeys(":sign define Sign "..hl.."=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
Expand Down Expand Up @@ -1231,6 +1231,25 @@ func Test_sign_priority()
call sign_define("sign1", attr)
call sign_define("sign2", attr)
call sign_define("sign3", attr)
let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Search', 'priority': 60}
call sign_define("sign4", attr)

" Test for :sign list
let a = execute('sign list')
call assert_equal("\nsign sign1 text==> linehl=Search texthl=Search\n" .
\ "sign sign2 text==> linehl=Search texthl=Search\n" .
\ "sign sign3 text==> linehl=Search texthl=Search\n" .
\ "sign sign4 text==> priority=60 linehl=Search texthl=Search", a)

" Test for sign_getdefined()
let s = sign_getdefined()
call assert_equal([
\ {'name': 'sign1', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
\ {'name': 'sign2', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
\ {'name': 'sign3', 'texthl': 'Search', 'linehl': 'Search', 'text': '=>'},
\ {'name': 'sign4', 'priority': 60, 'texthl': 'Search', 'linehl': 'Search',
\ 'text': '=>'}],
\ s)

" Place three signs with different priority in the same line
call writefile(repeat(["Sun is shining"], 30), "Xsign", 'D')
Expand Down Expand Up @@ -1585,6 +1604,25 @@ func Test_sign_priority()
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
\ " line=10 id=5 group=g1 name=sign1 priority=20\n", a)

call sign_unplace('*')

" Test for sign with default priority.
call sign_place(1, 'g1', 'sign4', 'Xsign', {'lnum' : 3})
sign place 2 line=5 name=sign4 group=g1 file=Xsign

let s = sign_getplaced('Xsign', {'group' : '*'})
call assert_equal([
\ {'id' : 1, 'name' : 'sign4', 'lnum' : 3, 'group' : 'g1',
\ 'priority' : 60},
\ {'id' : 2, 'name' : 'sign4', 'lnum' : 5, 'group' : 'g1',
\ 'priority' : 60}],
\ s[0].signs)

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)

call sign_unplace('*')
call sign_undefine()
enew | only
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
538,
/**/
537,
/**/
Expand Down

0 comments on commit b975ddf

Please sign in to comment.