aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/buffer.c')
-rw-r--r--src/nvim/buffer.c76
1 files changed, 62 insertions, 14 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 3ddd2a7163..06207c93f2 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -5257,6 +5257,16 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp)
}
static hashtab_T sg_table; // sign group (signgroup_T) hashtable
+static int next_sign_id = 1; // next sign id in the global group
+
+/*
+ * Initialize data needed for managing signs
+ */
+ void
+init_signs(void)
+{
+ hash_init(&sg_table); // sign group hash table
+}
/*
* A new sign in group 'groupname' is added. If the group is not present,
@@ -5264,16 +5274,10 @@ static hashtab_T sg_table; // sign group (signgroup_T) hashtable
*/
static signgroup_T * sign_group_ref(char_u *groupname)
{
- static int initialized = FALSE;
hash_T hash;
hashitem_T *hi;
signgroup_T *group;
- if (!initialized) {
- initialized = TRUE;
- hash_init(&sg_table);
- }
-
hash = hash_hash(groupname);
hi = hash_lookup(&sg_table, S_LEN(groupname), hash);
if (HASHITEM_EMPTY(hi))
@@ -5285,6 +5289,7 @@ static signgroup_T * sign_group_ref(char_u *groupname)
return NULL;
STRCPY(group->sg_name, groupname);
group->refcount = 1;
+ group->next_sign_id = 1;
hash_add_item(&sg_table, hi, group->sg_name, hash);
}
else
@@ -5321,6 +5326,49 @@ static void sign_group_unref(char_u *groupname)
}
/*
+ * Get the next free sign identifier in the specified group
+ */
+ int
+sign_group_get_next_signid(buf_T *buf, char_u *groupname)
+{
+ int id = 1;
+ signgroup_T *group = NULL;
+ signlist_T *sign;
+ hashitem_T *hi;
+ int found = FALSE;
+
+ if (groupname != NULL)
+ {
+ hi = hash_find(&sg_table, groupname);
+ if (HASHITEM_EMPTY(hi))
+ return id;
+ group = HI2SG(hi);
+ }
+
+ // Search for the next usuable sign identifier
+ while (!found)
+ {
+ if (group == NULL)
+ id = next_sign_id++; // global group
+ else
+ id = group->next_sign_id++;
+
+ // Check whether this sign is already placed in the buffer
+ found = TRUE;
+ FOR_ALL_SIGNS_IN_BUF(buf, sign)
+ {
+ if (id == sign->id && sign_in_group(sign, groupname))
+ {
+ found = FALSE; // sign identifier is in use
+ break;
+ }
+ }
+ }
+
+ return id;
+}
+
+/*
* Insert a new sign into the signlist for buffer 'buf' between the 'prev' and
* 'next' signs.
*/
@@ -5542,7 +5590,7 @@ void buf_addsign(
signlist_T *prev; // the previous sign
prev = NULL;
- FOR_ALL_SIGNS_IN_BUF(buf) {
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (lnum == sign->lnum && id == sign->id &&
sign_in_group(sign, groupname)) {
// Update an existing sign
@@ -5583,7 +5631,7 @@ linenr_T buf_change_sign_type(
{
signlist_T *sign; // a sign in the signlist
- FOR_ALL_SIGNS_IN_BUF(buf) {
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->id == markId && sign_in_group(sign, group)) {
sign->typenr = typenr;
return sign->lnum;
@@ -5611,7 +5659,7 @@ int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type,
signlist_T *matches[9];
int nr_matches = 0;
- FOR_ALL_SIGNS_IN_BUF(buf) {
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->lnum == lnum
&& (type == SIGN_ANY
|| (type == SIGN_TEXT
@@ -5711,7 +5759,7 @@ int buf_findsign(
{
signlist_T *sign; // a sign in the signlist
- FOR_ALL_SIGNS_IN_BUF(buf) {
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->id == id && sign_in_group(sign, group)){
return (int)sign->lnum;
}
@@ -5731,7 +5779,7 @@ static signlist_T * buf_getsign_at_line(
{
signlist_T *sign; // a sign in the signlist
- FOR_ALL_SIGNS_IN_BUF(buf) {
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->lnum == lnum) {
return sign;
}
@@ -5751,7 +5799,7 @@ signlist_T *buf_getsign_with_id(
{
signlist_T *sign; // a sign in the signlist
- FOR_ALL_SIGNS_IN_BUF(buf) {
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->id == id && sign_in_group(sign, group)) {
return sign;
}
@@ -5849,7 +5897,7 @@ void sign_list_placed(buf_T *rbuf, char_u *sign_group)
MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D));
msg_putchar('\n');
}
- FOR_ALL_SIGNS_IN_BUF(buf) {
+ FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (got_int) {
break;
}
@@ -5887,7 +5935,7 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a
curbuf->b_signcols_max = -1;
lastp = &curbuf->b_signlist;
- FOR_ALL_SIGNS_IN_BUF(curbuf) {
+ FOR_ALL_SIGNS_IN_BUF(curbuf, sign) {
next = sign->next;
if (sign->lnum >= line1 && sign->lnum <= line2) {
if (amount == MAXLNUM) {