Skip to content
Permalink
Browse files

patch 8.1.0658: deleting signs and completion for :sign is insufficient

Problem:    Deleting signs and completion for :sign is insufficient.
Solution:   Add deleting signs in a specified or any group from the current
            cursor location.  Add group and priority to sign command
            completion. Add tests for different sign unplace commands. Update
            help text.  Add tests for sign jump with group. Update help for
            sign jump. (Yegappan Lakshmanan, closes #3731)
  • Loading branch information...
brammool committed Dec 29, 2018
1 parent 01e51e5 commit 7d83bf4f2b785b46d87c7bc376fc9d0a862af782
Showing with 499 additions and 141 deletions.
  1. +29 −6 runtime/doc/sign.txt
  2. +25 −14 src/buffer.c
  3. +2 −2 src/evalfunc.c
  4. +45 −23 src/ex_cmds.c
  5. +2 −2 src/netbeans.c
  6. +7 −9 src/proto/buffer.pro
  7. +6 −7 src/proto/ex_cmds.pro
  8. +381 −78 src/testdir/test_signs.vim
  9. +2 −0 src/version.c
@@ -251,13 +251,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*
@@ -271,20 +282,26 @@ 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=*
List placed signs in all sign groups in all files.
:sign place List placed signs in the global group in all files.

:sign place group={group}
List placed signs with sign group {group} in all files.

:sign place group=*
List placed signs in all sign groups in all files.


JUMPING TO A SIGN *:sign-jump* *E157*

@@ -295,9 +312,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:
@@ -6077,10 +6077,10 @@ 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));
}

/*
@@ -6207,6 +6207,7 @@ buf_getsigntype(
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
{
@@ -6220,7 +6221,9 @@ buf_delsign(
for (sign = buf->b_signlist; sign != NULL; sign = next)
{
next = sign->next;
if ((id == 0 || sign->id == id) && sign_in_group(sign, group))
if ((id == 0 || sign->id == id) &&
(atlnum == 0 || sign->lnum == atlnum) &&
sign_in_group(sign, group))

{
*lastp = next;
@@ -6230,8 +6233,14 @@ buf_delsign(
if (sign->group != NULL)
sign_group_unref(sign->group->sg_name);
vim_free(sign);
update_debug_sign(buf, lnum);
// Check whether only one sign needs to be deleted
if (group == NULL || (*group != '*' && id != 0))
// 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
@@ -6272,17 +6281,18 @@ 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;

return NULL;
@@ -6312,11 +6322,12 @@ 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;

@@ -6401,16 +6412,16 @@ buf_delete_signs(buf_T *buf, char_u *group)
}

/*
* Delete all signs in all buffers.
* Delete all the signs in the specified group in all the buffers.
*/
void
buf_delete_all_signs(void)
buf_delete_all_signs(char_u *groupname)
{
buf_T *buf; /* buffer we are checking for signs */

FOR_ALL_BUFFERS(buf)
if (buf->b_signlist != NULL)
buf_delete_signs(buf, (char_u *)"*");
buf_delete_signs(buf, groupname);
}

/*
@@ -11600,12 +11600,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;
}
vim_free(group);
@@ -7895,7 +7895,7 @@ 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)
{
@@ -7908,15 +7908,29 @@ 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);
}

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
*/
@@ -8047,14 +8061,8 @@ 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));
return;
@@ -8063,7 +8071,7 @@ 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;
}

@@ -8084,7 +8092,7 @@ ex_sign(exarg_T *eap)
{
/* ":sign unplace {id}": remove placed sign by number */
FOR_ALL_BUFFERS(buf)
sign_unplace(id, NULL, buf);
sign_unplace(id, NULL, buf, 0);
return;
}
}
@@ -8183,7 +8191,8 @@ ex_sign(exarg_T *eap)
}
else if (idx == SIGNCMD_JUMP)
{
/* ":sign jump {id} file={fname}" */
// ":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)
@@ -8225,7 +8234,7 @@ ex_sign(exarg_T *eap)
{
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)
@@ -8238,14 +8247,26 @@ 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);
}
}
}
}
/* idx == SIGNCMD_PLACE */
@@ -8581,13 +8602,14 @@ get_sign_name(expand_T *xp UNUSED, int idx)
{
char *place_arg[] =
{
"line=", "name=", "file=", "buffer=", NULL
"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:
@@ -1251,12 +1251,12 @@ nb_do_cmd(
/* delete signs from the lines being deleted */
for (i = del_from_lnum; i <= del_to_lnum; i++)
{
int id = buf_findsign_id(buf->bufp, (linenr_T)i);
int id = buf_findsign_id(buf->bufp, (linenr_T)i, NULL);
if (id > 0)
{
nbdebug((" Deleting sign %d on line %d\n",
id, i));
buf_delsign(buf->bufp, id, NULL);
buf_delsign(buf->bufp, 0, id, NULL);
}
else
{
@@ -69,23 +69,21 @@ char_u *buf_spname(buf_T *buf);
void switch_to_win_for_buf(buf_T *buf, win_T **save_curwinp, tabpage_T **save_curtabp, bufref_T *save_curbuf);
void restore_win_for_buf(win_T *save_curwin, tabpage_T *save_curtab, bufref_T *save_curbuf);
int find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp);
void buf_addsign(buf_T *buf, int id, char_u *group, int prio, linenr_T lnum, int typenr);
linenr_T buf_change_sign_type(buf_T *buf, int markId, char_u *group, int typenr);
int buf_getsigntype(buf_T *buf, linenr_T lnum, int type);
linenr_T buf_delsign(buf_T *buf, int id, char_u *group);
int buf_findsign(buf_T *buf, int id, char_u *group);
#ifdef FEAT_SIGNS
void init_signs(void);
int sign_group_get_next_signid(buf_T *buf, char_u *groupname);
int sign_in_group(signlist_T *sign, char_u *group);
dict_T *sign_get_info(signlist_T *sign);
void buf_addsign(buf_T *buf, int id, char_u *groupname, int prio, linenr_T lnum, int typenr);
linenr_T buf_change_sign_type(buf_T *buf, int markId, char_u *group, int typenr);
int buf_getsigntype(buf_T *buf, linenr_T lnum, int type);
linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char_u *group);
int buf_findsign(buf_T *buf, int id, char_u *group);
signlist_T *buf_getsign_with_id(buf_T *buf, int id, char_u *group);
#endif
int buf_findsign_id(buf_T *buf, linenr_T lnum);
int buf_findsign_id(buf_T *buf, linenr_T lnum, char_u *groupname);
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 buf_delete_all_signs(void);
void buf_delete_all_signs(char_u *groupname);
void sign_list_placed(buf_T *rbuf, char_u *sign_group);
void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after);
void set_buflisted(int on);

0 comments on commit 7d83bf4

Please sign in to comment.
You can’t perform that action at this time.