diff options
-rw-r--r-- | runtime/doc/sign.txt | 33 | ||||
-rw-r--r-- | src/nvim/buffer.c | 100 | ||||
-rw-r--r-- | src/nvim/eval.c | 4 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 60 | ||||
-rw-r--r-- | src/nvim/testdir/test_signs.vim | 459 |
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}) |