aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/sign.txt33
-rw-r--r--src/nvim/buffer.c100
-rw-r--r--src/nvim/eval.c4
-rw-r--r--src/nvim/ex_cmds.c60
-rw-r--r--src/nvim/testdir/test_signs.vim459
5 files changed, 508 insertions, 148 deletions
diff --git a/runtime/doc/sign.txt b/runtime/doc/sign.txt
index 39c1c61da2..4b9c64e575 100644
--- a/runtime/doc/sign.txt
+++ b/runtime/doc/sign.txt
@@ -244,13 +244,24 @@ See |sign_unplace()| for the equivalent Vim script function.
all the files it appears in.
:sign unplace *
- Remove all placed signs in the global group.
+ Remove placed signs in the global group from all the files.
+
+:sign unplace * group={group}
+ Remove placed signs in group {group} from all the files.
:sign unplace * group=*
- Remove all placed signs in all the groups.
+ Remove placed signs in all the groups from all the files.
:sign unplace
- Remove the placed sign at the cursor position.
+ Remove a placed sign at the cursor position. If multiple signs
+ are placed in the line, then only one is removed.
+
+:sign unplace group={group}
+ Remove a placed sign in group {group} at the cursor
+ position.
+
+:sign unplace group=*
+ Remove a placed sign in any group at the cursor position.
LISTING PLACED SIGNS *:sign-place-list*
@@ -264,17 +275,25 @@ See |sign_getplaced()| for the equivalent Vim script function.
:sign place group={group} file={fname}
List signs in group {group} placed in file {fname}.
+:sign place group=* file={fname}
+ List signs in all the groups placed in file {fname}.
+
+
:sign place buffer={nr}
List signs placed in buffer {nr}.
:sign place group={group} buffer={nr}
List signs in group {group} placed in buffer {nr}.
-:sign place List placed signs in all files.
+:sign place group=* buffer={nr}
+ List signs in all the groups placed in buffer {nr}.
:sign place group={group}
List placed signs in all sign groups in all the files.
+:sign place group=*
+ List placed signs in all sign groups in all files.
+
JUMPING TO A SIGN *:sign-jump* *E157*
@@ -285,9 +304,15 @@ JUMPING TO A SIGN *:sign-jump* *E157*
If the file isn't displayed in window and the current file can
not be |abandon|ed this fails.
+:sign jump {id} group={group} file={fname}
+ Same but jump to the sign in group {group}
+
:sign jump {id} buffer={nr} *E934*
Same, but use buffer {nr}. This fails if buffer {nr} does not
have a name.
+:sign jump {id} group={group} buffer={nr}
+ Same but jump to the sign in group {group}
+
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 06207c93f2..9ccbfa4dd1 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -5548,10 +5548,10 @@ static void insert_sign_by_lnum_prio(
*/
int sign_in_group(signlist_T *sign, char_u *group)
{
- return ((group != NULL && STRCMP(group, "*") == 0) ||
- (group == NULL && sign->group == NULL) ||
- (group != NULL && sign->group != NULL &&
- STRCMP(group, sign->group->sg_name) == 0));
+ return ((group != NULL && STRCMP(group, "*") == 0)
+ || (group == NULL && sign->group == NULL)
+ || (group != NULL && sign->group != NULL
+ && STRCMP(group, sign->group->sg_name) == 0));
}
/*
@@ -5704,45 +5704,55 @@ int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type,
*/
linenr_T buf_delsign(
buf_T *buf, // buffer sign is stored in
+ linenr_T atlnum, // sign at this line, 0 - at any line
int id, // sign id
char_u *group// sign group
-)
+ )
{
- signlist_T **lastp; // pointer to pointer to current sign
- signlist_T *sign; // a sign in a b_signlist
- signlist_T *next; // the next sign in a b_signlist
- linenr_T lnum; // line number whose sign was deleted
-
- buf->b_signcols_max = -1;
- lastp = &buf->b_signlist;
- lnum = 0;
- for (sign = buf->b_signlist; sign != NULL; sign = next) {
- next = sign->next;
- if ((id == 0 || sign->id == id) && sign_in_group(sign, group)) {
- *lastp = next;
- if (next != NULL) {
- next->prev = sign->prev;
- }
- lnum = sign->lnum;
- if (sign->group != NULL)
- sign_group_unref(sign->group->sg_name);
- xfree(sign);
- // Check whether only one sign needs to be deleted
- if (group == NULL || (*group != '*' && id != 0))
- break;
- } else {
- lastp = &sign->next;
- }
+ signlist_T **lastp; // pointer to pointer to current sign
+ signlist_T *sign; // a sign in a b_signlist
+ signlist_T *next; // the next sign in a b_signlist
+ linenr_T lnum; // line number whose sign was deleted
+
+ buf->b_signcols_max = -1;
+ lastp = &buf->b_signlist;
+ lnum = 0;
+ for (sign = buf->b_signlist; sign != NULL; sign = next) {
+ next = sign->next;
+ if ((id == 0 || sign->id == id) &&
+ (atlnum == 0 || sign->lnum == atlnum) &&
+ sign_in_group(sign, group)) {
+ *lastp = next;
+ if (next != NULL) {
+ next->prev = sign->prev;
+ }
+ lnum = sign->lnum;
+ if (sign->group != NULL)
+ sign_group_unref(sign->group->sg_name);
+ xfree(sign);
+ redraw_buf_line_later(buf, lnum);
+ // Check whether only one sign needs to be deleted
+ // If deleting a sign with a specific identifer in a particular
+ // group or deleting any sign at a particular line number, delete
+ // only one sign.
+ if (group == NULL
+ || (*group != '*' && id != 0)
+ || (*group == '*' && atlnum != 0)) {
+ break;
+ }
+ } else {
+ lastp = &sign->next;
}
+ }
- /* When deleted the last sign needs to redraw the windows to remove the
- * sign column. */
- if (buf->b_signlist == NULL) {
- redraw_buf_later(buf, NOT_VALID);
- changed_cline_bef_curs();
- }
+ /* When deleted the last sign needs to redraw the windows to remove the
+ * sign column. */
+ if (buf->b_signlist == NULL) {
+ redraw_buf_later(buf, NOT_VALID);
+ changed_cline_bef_curs();
+ }
- return lnum;
+ return lnum;
}
@@ -5770,17 +5780,18 @@ int buf_findsign(
/*
* Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is
- * not found at the line.
+ * not found at the line. If 'groupname' is NULL, searches in the global group.
*/
static signlist_T * buf_getsign_at_line(
buf_T *buf, // buffer whose sign we are searching for
- linenr_T lnum // line number of sign
+ linenr_T lnum, // line number of sign
+ char_u *groupname // sign group name
)
{
signlist_T *sign; // a sign in the signlist
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (sign->lnum == lnum) {
+ if (sign->lnum == lnum && sign_in_group(sign, groupname)) {
return sign;
}
}
@@ -5813,12 +5824,13 @@ signlist_T *buf_getsign_with_id(
*/
int buf_findsign_id(
buf_T *buf, // buffer whose sign we are searching for
- linenr_T lnum // line number of sign
+ linenr_T lnum, // line number of sign
+ char_u *groupname // sign group name
)
{
signlist_T *sign; // a sign in the signlist
- sign = buf_getsign_at_line(buf, lnum);
+ sign = buf_getsign_at_line(buf, lnum, groupname);
if (sign != NULL) {
return sign->id;
}
@@ -5865,11 +5877,11 @@ void buf_delete_signs(buf_T *buf, char_u *group)
/*
* Delete all signs in all buffers.
*/
-void buf_delete_all_signs(void)
+void buf_delete_all_signs(char_u *groupname)
{
FOR_ALL_BUFFERS(buf) {
if (buf->b_signlist != NULL) {
- buf_delete_signs(buf, (char_u *)"*");
+ buf_delete_signs(buf, groupname);
}
}
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index de2c9168c2..cbe2a89b5b 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -15739,12 +15739,12 @@ f_sign_unplace(typval_T *argvars, typval_T *rettv)
{
// Delete the sign in all the buffers
FOR_ALL_BUFFERS(buf)
- if (sign_unplace(sign_id, group, buf) == OK)
+ if (sign_unplace(sign_id, group, buf, 0) == OK)
rettv->vval.v_number = 0;
}
else
{
- if (sign_unplace(sign_id, group, buf) == OK)
+ if (sign_unplace(sign_id, group, buf, 0) == OK)
rettv->vval.v_number = 0;
}
xfree(group);
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index abfa9ad2e5..5d9dc7508f 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -5828,7 +5828,7 @@ int sign_place(
* Unplace the specified sign
*/
int
-sign_unplace(int sign_id, char_u *sign_group, buf_T *buf)
+sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum)
{
if (sign_id == 0)
{
@@ -5839,15 +5839,31 @@ sign_unplace(int sign_id, char_u *sign_group, buf_T *buf)
linenr_T lnum;
// Delete only the specified signs
- lnum = buf_delsign(buf, sign_id, sign_group);
+ lnum = buf_delsign(buf, atlnum, sign_id, sign_group);
if (lnum == 0) {
return FAIL;
+ update_debug_sign(buf, lnum);
}
redraw_buf_line_later(buf, lnum);
}
return OK;
}
+
+/*
+ * Unplace the sign at the current cursor line.
+ */
+static void sign_unplace_at_cursor(char_u *groupname)
+{
+ int id = -1;
+
+ id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname);
+ if (id > 0) {
+ sign_unplace(id, groupname, curwin->w_buffer, curwin->w_cursor.lnum);
+ } else {
+ EMSG(_("E159: Missing sign number"));
+ }
+}
/*
* ":sign" command
@@ -5962,12 +5978,7 @@ void ex_sign(exarg_T *eap)
sign_list_placed(NULL, NULL);
} else if (idx == SIGNCMD_UNPLACE) {
// ":sign unplace": remove placed sign at cursor
- id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum);
- if (id > 0) {
- sign_unplace(id, NULL, curwin->w_buffer);
- } else {
- EMSG(_("E159: Missing sign number"));
- }
+ sign_unplace_at_cursor(NULL);
} else {
EMSG(_(e_argreq));
}
@@ -5976,7 +5987,7 @@ void ex_sign(exarg_T *eap)
if (idx == SIGNCMD_UNPLACE && arg[0] == '*' && arg[1] == NUL) {
// ":sign unplace *": remove all placed signs
- buf_delete_all_signs();
+ buf_delete_all_signs(NULL);
return;
}
@@ -5992,7 +6003,7 @@ void ex_sign(exarg_T *eap)
if (idx == SIGNCMD_UNPLACE && *arg == NUL) {
// ":sign unplace {id}": remove placed sign by number
FOR_ALL_BUFFERS(buf) {
- sign_unplace(id, NULL, buf);
+ sign_unplace(id, NULL, buf, 0);
}
return;
}
@@ -6075,6 +6086,7 @@ void ex_sign(exarg_T *eap)
}
} else if (idx == SIGNCMD_JUMP) {
// ":sign jump {id} file={fname}"
+ // ":sign jump {id} group={group} file={fname}"
if (lnum >= 0 || sign_name != NULL || buf == NULL){
EMSG(_(e_invarg));
} else if ((lnum = buf_findsign(buf, id, group)) > 0) {
@@ -6108,7 +6120,7 @@ void ex_sign(exarg_T *eap)
} else if (id == -2) {
if (buf != NULL) {
// ":sign unplace * file={fname}"
- sign_unplace(0, group, buf);
+ sign_unplace(0, group, buf, 0);
} else {
// ":sign unplace * group=*": remove all placed signs
FOR_ALL_BUFFERS(buf) {
@@ -6122,14 +6134,21 @@ void ex_sign(exarg_T *eap)
// ":sign unplace {id} file={fname}"
// ":sign unplace {id} group={group} file={fname}"
// ":sign unplace {id} group=* file={fname}"
- sign_unplace(id, group, buf);
+ sign_unplace(id, group, buf, 0);
} else {
- // ":sign unplace {id} group={group}":
- // ":sign unplace {id} group=*":
- // remove all placed signs in this group.
- FOR_ALL_BUFFERS(buf) {
- if (buf->b_signlist != NULL) {
- sign_unplace(id, group, buf);
+ if (id == -1) {
+ // ":sign unplace group={group}":
+ // ":sign unplace group=*":
+ // remove sign in the current line in specified group
+ sign_unplace_at_cursor(group);
+ } else {
+ // ":sign unplace {id} group={group}":
+ // ":sign unplace {id} group=*":
+ // remove all placed signs in this group.
+ FOR_ALL_BUFFERS(buf) {
+ if (buf->b_signlist != NULL) {
+ sign_unplace(id, group, buf, 0);
+ }
}
}
}
@@ -6426,11 +6445,12 @@ char_u * get_sign_name(expand_T *xp, int idx)
return (char_u *)define_arg[idx];
}
case EXP_PLACE: {
- char *place_arg[] = { "line=", "name=", "file=", "buffer=", NULL };
+ char *place_arg[] = { "line=", "name=", "group=", "priority=", "file=",
+ "buffer=", NULL };
return (char_u *)place_arg[idx];
}
case EXP_UNPLACE: {
- char *unplace_arg[] = { "file=", "buffer=", NULL };
+ char *unplace_arg[] = { "group=", "file=", "buffer=", NULL };
return (char_u *)unplace_arg[idx];
}
case EXP_SIGN_NAMES: {
diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim
index b745ee04bd..bb8bfc65d1 100644
--- a/src/nvim/testdir/test_signs.vim
+++ b/src/nvim/testdir/test_signs.vim
@@ -28,8 +28,8 @@ func Test_sign()
let a=execute('sign list Sign1')
call assert_equal("\nsign Sign1 text=x ", a)
- " Split the window to the bottom to verify sign jump will stay in the current window
- " if the buffer is displayed there.
+ " Split the window to the bottom to verify sign jump will stay in the
+ " current window if the buffer is displayed there.
let bn = bufnr('%')
let wn = winnr()
exe 'sign place 41 line=3 name=Sign1 buffer=' . bn
@@ -211,19 +211,20 @@ func Test_sign_completion()
call assert_equal('"sign undefine Sign1 Sign2', @:)
call feedkeys(":sign place 1 \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"sign place 1 buffer= file= line= name=', @:)
+ call assert_equal('"sign place 1 buffer= file= group= line= name= priority=',
+ \ @:)
call feedkeys(":sign place 1 name=\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign place 1 name=Sign1 Sign2', @:)
call feedkeys(":sign unplace 1 \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"sign unplace 1 buffer= file=', @:)
+ call assert_equal('"sign unplace 1 buffer= file= group=', @:)
call feedkeys(":sign list \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"sign list Sign1 Sign2', @:)
call feedkeys(":sign jump 1 \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_equal('"sign jump 1 buffer= file=', @:)
+ call assert_equal('"sign jump 1 buffer= file= group=', @:)
sign undefine Sign1
sign undefine Sign2
@@ -449,7 +450,6 @@ func Test_sign_group()
edit Xsign
let bnum = bufnr('%')
- let fname = fnamemodify('Xsign', ':p')
" Error case
call assert_fails("call sign_place(5, [], 'sign1', 'Xsign',
@@ -466,6 +466,10 @@ func Test_sign_group()
let s = sign_getplaced('Xsign')
call assert_equal(1, len(s[0].signs))
call assert_equal(s[0].signs[0].group, '')
+ let s = sign_getplaced(bnum, {'group' : ''})
+ call assert_equal([{'id' : 5, 'group' : '', 'name' : 'sign1', 'lnum' : 10,
+ \ 'priority' : 10}], s[0].signs)
+ call assert_equal(1, len(s[0].signs))
let s = sign_getplaced(bnum, {'group' : 'g2'})
call assert_equal('g2', s[0].signs[0].group)
let s = sign_getplaced(bnum, {'group' : 'g3'})
@@ -584,134 +588,434 @@ func Test_sign_group()
sign place 5 group=g1 line=10 name=sign1 file=Xsign
sign place 5 group=g2 line=10 name=sign1 file=Xsign
- " Test for :sign place group={group} file={fname}
+ " Tests for the ':sign place' command
+
+ " :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)
+ " :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)
+ " :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)
+ " 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 sign_unplace('*')
-
- " Test for :sign place group={group} buffer={nr}
let bnum = bufnr('Xsign')
exe 'sign place 5 line=10 name=sign1 buffer=' . bnum
exe 'sign place 5 group=g1 line=11 name=sign1 buffer=' . bnum
exe 'sign place 5 group=g2 line=12 name=sign1 buffer=' . bnum
+ " :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)
+ " :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)
+ " :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)
+ " Error case: non-existing group
let a = execute('sign place group=xyz buffer=' . bnum)
call assert_equal("\n--- Signs ---\nSigns for Xsign:\n", 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)
+
+ " :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)
+
+ " :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)
- " Test for :sign unplace
- sign unplace 5 group=g2 file=Xsign
- call assert_equal([], sign_getplaced(bnum, {'group' : 'g2'})[0].signs)
+ " Test for ':sign jump' command with groups
+ sign jump 5 group=g1 file=Xsign
+ call assert_equal(11, line('.'))
+ call assert_equal('Xsign', bufname(''))
+ sign jump 5 group=g2 file=Xsign
+ call assert_equal(12, line('.'))
- exe 'sign unplace 5 group=g1 buffer=' . bnum
- call assert_equal([], sign_getplaced(bnum, {'group' : 'g1'})[0].signs)
+ " Error cases
+ call assert_fails("sign place 3 group= name=sign1 buffer=" . bnum, 'E474:')
- sign unplace 5 group=xy file=Xsign
- call assert_equal(1, len(sign_getplaced(bnum, {'group' : '*'})[0].signs))
+ call delete("Xsign")
+ call sign_unplace('*')
+ call sign_undefine()
+ enew | only
+endfunc
- " Test for removing all the signs. Place the signs again for this test
- sign place 5 group=g1 line=11 name=sign1 file=Xsign
- sign place 5 group=g2 line=12 name=sign1 file=Xsign
- sign place 6 line=20 name=sign1 file=Xsign
- sign place 6 group=g1 line=21 name=sign1 file=Xsign
- sign place 6 group=g2 line=22 name=sign1 file=Xsign
- sign unplace 5 group=* file=Xsign
- let a = execute('sign place group=*')
- call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
- \ " line=20 id=6 name=sign1 priority=10\n" .
- \ " line=21 id=6 group=g1 name=sign1 priority=10\n" .
- \ " line=22 id=6 group=g2 name=sign1 priority=10\n", a)
+" Place signs used for ":sign unplace" command test
+func Place_signs_for_test()
+ call sign_unplace('*')
- " Remove all the signs from the global group
- sign unplace * file=Xsign
- let a = execute('sign place group=*')
- call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
- \ " line=21 id=6 group=g1 name=sign1 priority=10\n" .
- \ " line=22 id=6 group=g2 name=sign1 priority=10\n", a)
+ sign place 3 line=10 name=sign1 file=Xsign1
+ sign place 3 group=g1 line=11 name=sign1 file=Xsign1
+ sign place 3 group=g2 line=12 name=sign1 file=Xsign1
+ sign place 4 line=15 name=sign1 file=Xsign1
+ sign place 4 group=g1 line=16 name=sign1 file=Xsign1
+ sign place 4 group=g2 line=17 name=sign1 file=Xsign1
+ sign place 5 line=20 name=sign1 file=Xsign2
+ sign place 5 group=g1 line=21 name=sign1 file=Xsign2
+ sign place 5 group=g2 line=22 name=sign1 file=Xsign2
+ sign place 6 line=25 name=sign1 file=Xsign2
+ sign place 6 group=g1 line=26 name=sign1 file=Xsign2
+ sign place 6 group=g2 line=27 name=sign1 file=Xsign2
+endfunc
- " Remove all the signs from a particular group
- sign place 5 line=10 name=sign1 file=Xsign
- sign place 5 group=g1 line=11 name=sign1 file=Xsign
- sign place 5 group=g2 line=12 name=sign1 file=Xsign
- sign unplace * group=g1 file=Xsign
- 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=12 id=5 group=g2 name=sign1 priority=10\n" .
- \ " line=22 id=6 group=g2 name=sign1 priority=10\n", a)
-
- " Remove all the signs from all the groups in a file
- sign place 5 group=g1 line=11 name=sign1 file=Xsign
- sign place 6 line=20 name=sign1 file=Xsign
- sign place 6 group=g1 line=21 name=sign1 file=Xsign
- sign unplace * group=* file=Xsign
- let a = execute('sign place group=*')
- call assert_equal("\n--- Signs ---\n", a)
+" Place multiple signs in a single line for test
+func Place_signs_at_line_for_test()
+ call sign_unplace('*')
+ sign place 3 line=13 name=sign1 file=Xsign1
+ sign place 3 group=g1 line=13 name=sign1 file=Xsign1
+ sign place 3 group=g2 line=13 name=sign1 file=Xsign1
+ sign place 4 line=13 name=sign1 file=Xsign1
+ sign place 4 group=g1 line=13 name=sign1 file=Xsign1
+ sign place 4 group=g2 line=13 name=sign1 file=Xsign1
+endfunc
- " Remove a particular sign id in a group from all the files
- sign place 5 group=g1 line=11 name=sign1 file=Xsign
- sign unplace 5 group=g1
- let a = execute('sign place group=*')
- call assert_equal("\n--- Signs ---\n", a)
+" Tests for the ':sign unplace' command
+func Test_sign_unplace()
+ enew | only
+ " Remove all the signs
+ call sign_unplace('*')
+ call sign_undefine()
- " Remove a particular sign id in all the groups from all the files
- sign place 5 line=10 name=sign1 file=Xsign
- sign place 5 group=g1 line=11 name=sign1 file=Xsign
- sign place 5 group=g2 line=12 name=sign1 file=Xsign
- sign place 6 line=20 name=sign1 file=Xsign
- sign place 6 group=g1 line=21 name=sign1 file=Xsign
- sign place 6 group=g2 line=22 name=sign1 file=Xsign
+ " Create two files and define signs
+ call writefile(repeat(["Sun is shining"], 30), "Xsign1")
+ call writefile(repeat(["It is beautiful"], 30), "Xsign2")
+
+ let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'}
+ call sign_define("sign1", attr)
+
+ edit Xsign1
+ let bnum1 = bufnr('%')
+ split Xsign2
+ let bnum2 = bufnr('%')
+
+ let signs1 = [{'id' : 3, 'name' : 'sign1', 'lnum' : 10, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 3, 'name' : 'sign1', 'lnum' : 11, 'group' : 'g1',
+ \ 'priority' : 10},
+ \ {'id' : 3, 'name' : 'sign1', 'lnum' : 12, 'group' : 'g2',
+ \ 'priority' : 10},
+ \ {'id' : 4, 'name' : 'sign1', 'lnum' : 15, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 4, 'name' : 'sign1', 'lnum' : 16, 'group' : 'g1',
+ \ 'priority' : 10},
+ \ {'id' : 4, 'name' : 'sign1', 'lnum' : 17, 'group' : 'g2',
+ \ 'priority' : 10},]
+ let signs2 = [{'id' : 5, 'name' : 'sign1', 'lnum' : 20, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 5, 'name' : 'sign1', 'lnum' : 21, 'group' : 'g1',
+ \ 'priority' : 10},
+ \ {'id' : 5, 'name' : 'sign1', 'lnum' : 22, 'group' : 'g2',
+ \ 'priority' : 10},
+ \ {'id' : 6, 'name' : 'sign1', 'lnum' : 25, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 6, 'name' : 'sign1', 'lnum' : 26, 'group' : 'g1',
+ \ 'priority' : 10},
+ \ {'id' : 6, 'name' : 'sign1', 'lnum' : 27, 'group' : 'g2',
+ \ 'priority' : 10},]
+
+ " Test for :sign unplace {id} file={fname}
+ call Place_signs_for_test()
+ sign unplace 3 file=Xsign1
+ sign unplace 6 file=Xsign2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 3 || val.group != ''}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 6 || val.group != ''}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace {id} group={group} file={fname}
+ call Place_signs_for_test()
+ sign unplace 4 group=g1 file=Xsign1
+ sign unplace 5 group=g2 file=Xsign2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 4 || val.group != 'g1'}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 5 || val.group != 'g2'}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace {id} group=* file={fname}
+ call Place_signs_for_test()
+ sign unplace 3 group=* file=Xsign1
+ sign unplace 6 group=* file=Xsign2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 3}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 6}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace * file={fname}
+ call Place_signs_for_test()
+ sign unplace * file=Xsign1
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.group != ''}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace * group={group} file={fname}
+ call Place_signs_for_test()
+ sign unplace * group=g1 file=Xsign1
+ sign unplace * group=g2 file=Xsign2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.group != 'g1'}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.group != 'g2'}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace * group=* file={fname}
+ call Place_signs_for_test()
+ sign unplace * group=* file=Xsign2
+ call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace {id} buffer={nr}
+ call Place_signs_for_test()
+ exe 'sign unplace 3 buffer=' . bnum1
+ exe 'sign unplace 6 buffer=' . bnum2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 3 || val.group != ''}),
+ \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 6 || val.group != ''}),
+ \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace {id} group={group} buffer={nr}
+ call Place_signs_for_test()
+ exe 'sign unplace 4 group=g1 buffer=' . bnum1
+ exe 'sign unplace 5 group=g2 buffer=' . bnum2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 4 || val.group != 'g1'}),
+ \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 5 || val.group != 'g2'}),
+ \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace {id} group=* buffer={nr}
+ call Place_signs_for_test()
+ exe 'sign unplace 3 group=* buffer=' . bnum1
+ exe 'sign unplace 6 group=* buffer=' . bnum2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 3}),
+ \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 6}),
+ \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace * buffer={nr}
+ call Place_signs_for_test()
+ exe 'sign unplace * buffer=' . bnum1
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.group != ''}),
+ \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
+ call assert_equal(signs2, sign_getplaced(bnum2, {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace * group={group} buffer={nr}
+ call Place_signs_for_test()
+ exe 'sign unplace * group=g1 buffer=' . bnum1
+ exe 'sign unplace * group=g2 buffer=' . bnum2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.group != 'g1'}),
+ \ sign_getplaced(bnum1, {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.group != 'g2'}),
+ \ sign_getplaced(bnum2, {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace * group=* buffer={nr}
+ call Place_signs_for_test()
+ exe 'sign unplace * group=* buffer=' . bnum2
+ call assert_equal(signs1, sign_getplaced(bnum1, {'group' : '*'})[0].signs)
+ call assert_equal([], sign_getplaced(bnum2, {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace {id}
+ call Place_signs_for_test()
+ sign unplace 4
+ sign unplace 6
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 4 || val.group != ''}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 6 || val.group != ''}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace {id} group={group}
+ call Place_signs_for_test()
+ sign unplace 4 group=g1
+ sign unplace 6 group=g2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 4 || val.group != 'g1'}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 6 || val.group != 'g2'}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace {id} group=*
+ call Place_signs_for_test()
+ sign unplace 3 group=*
sign unplace 5 group=*
- let a = execute('sign place group=*')
- call assert_equal("\n--- Signs ---\nSigns for Xsign:\n" .
- \ " line=20 id=6 name=sign1 priority=10\n" .
- \ " line=21 id=6 group=g1 name=sign1 priority=10\n" .
- \ " line=22 id=6 group=g2 name=sign1 priority=10\n", a)
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 3}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.id != 5}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
- " Remove all the signs from all the groups in all the files
- sign place 5 line=10 name=sign1 file=Xsign
- sign place 5 group=g1 line=11 name=sign1 file=Xsign
+ " Test for :sign unplace *
+ call Place_signs_for_test()
+ sign unplace *
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.group != ''}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.group != ''}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace * group={group}
+ call Place_signs_for_test()
+ sign unplace * group=g1
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.group != 'g1'}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(
+ \ filter(copy(signs2),
+ \ {idx, val -> val.group != 'g1'}),
+ \ sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Test for :sign unplace * group=*
+ call Place_signs_for_test()
sign unplace * group=*
- let a = execute('sign place group=*')
- call assert_equal("\n--- Signs ---\n", a)
+ call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal([], sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
- " Error cases
- call assert_fails("sign place 3 group= name=sign1 buffer=" . bnum, 'E474:')
+ " Negative test cases
+ call Place_signs_for_test()
+ sign unplace 3 group=xy file=Xsign1
+ sign unplace * group=xy file=Xsign1
+ silent! sign unplace * group=* file=FileNotPresent
+ call assert_equal(signs1, sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ call assert_equal(signs2, sign_getplaced('Xsign2', {'group' : '*'})[0].signs)
+
+ " Tests for removing sign at the current cursor position
+
+ " Test for ':sign unplace'
+ let signs1 = [{'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2',
+ \ 'priority' : 10},
+ \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1',
+ \ 'priority' : 10},
+ \ {'id' : 4, 'name' : 'sign1', 'lnum' : 13, 'group' : '',
+ \ 'priority' : 10},
+ \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g2',
+ \ 'priority' : 10},
+ \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : 'g1',
+ \ 'priority' : 10},
+ \ {'id' : 3, 'name' : 'sign1', 'lnum' : 13, 'group' : '',
+ \ 'priority' : 10},]
+ exe bufwinnr('Xsign1') . 'wincmd w'
+ call cursor(13, 1)
+
+ " Should remove only one sign in the global group
+ call Place_signs_at_line_for_test()
+ sign unplace
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 4 || val.group != ''}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ " Should remove the second sign in the global group
+ sign unplace
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.group != ''}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+
+ " Test for ':sign unplace group={group}'
+ call Place_signs_at_line_for_test()
+ " Should remove only one sign in group g1
+ sign unplace group=g1
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 4 || val.group != 'g1'}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ sign unplace group=g2
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 4 || val.group == ''}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+
+ " Test for ':sign unplace group=*'
+ call Place_signs_at_line_for_test()
+ sign unplace group=*
+ sign unplace group=*
+ sign unplace group=*
+ call assert_equal(
+ \ filter(copy(signs1),
+ \ {idx, val -> val.id != 4}),
+ \ sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
+ sign unplace group=*
+ sign unplace group=*
+ sign unplace group=*
+ call assert_equal([], sign_getplaced('Xsign1', {'group' : '*'})[0].signs)
- call delete("Xsign")
call sign_unplace('*')
call sign_undefine()
enew | only
+ call delete("Xsign1")
+ call delete("Xsign2")
endfunc
" Tests for auto-generating the sign identifier
@@ -762,7 +1066,6 @@ func Test_sign_priority()
" Place three signs with different priority in the same line
call writefile(repeat(["Sun is shining"], 30), "Xsign")
edit Xsign
- let fname = fnamemodify('Xsign', ':p')
call sign_place(1, 'g1', 'sign1', 'Xsign',
\ {'lnum' : 11, 'priority' : 50})