1
0
forked from aniani/vim

patch 8.1.1489: sign order wrong when priority was changed

Problem:    Sign order wrong when priority was changed.
Solution:   Reorder signs when priority is changed. (Yegappan Lakshmanan,
            closes #4502)
This commit is contained in:
Bram Moolenaar
2019-06-07 21:37:13 +02:00
parent 150f0550f4
commit 64416127fc
4 changed files with 374 additions and 10 deletions

View File

@@ -307,6 +307,78 @@ sign_get_info(signlist_T *sign)
return d;
}
/*
* Sort the signs placed on the same line as "sign" by priority. Invoked after
* changing the priority of an already placed sign. Assumes the signs in the
* buffer are sorted by line number and priority.
*/
static void
sign_sort_by_prio_on_line(buf_T *buf, signlist_T *sign)
{
signlist_T *p = NULL;
// If there is only one sign in the buffer or only one sign on the line or
// the sign is already sorted by priority, then return.
if ((sign->prev == NULL
|| sign->prev->lnum != sign->lnum
|| sign->prev->priority > sign->priority)
&& (sign->next == NULL
|| sign->next->lnum != sign->lnum
|| sign->next->priority < sign->priority))
return;
// One or more signs on the same line as 'sign'
// Find a sign after which 'sign' should be inserted
// First search backward for a sign with higher priority on the same line
p = sign;
while (p->prev != NULL && p->prev->lnum == sign->lnum
&& p->prev->priority <= sign->priority)
p = p->prev;
if (p == sign)
{
// Sign not found. Search forward for a sign with priority just before
// 'sign'.
p = sign->next;
while (p->next != NULL && p->next->lnum == sign->lnum
&& p->next->priority > sign->priority)
p = p->next;
}
// Remove 'sign' from the list
if (buf->b_signlist == sign)
buf->b_signlist = sign->next;
if (sign->prev != NULL)
sign->prev->next = sign->next;
if (sign->next != NULL)
sign->next->prev = sign->prev;
sign->prev = NULL;
sign->next = NULL;
// Re-insert 'sign' at the right place
if (p->priority <= sign->priority)
{
// 'sign' has a higher priority and should be inserted before 'p'
sign->prev = p->prev;
sign->next = p;
p->prev = sign;
if (sign->prev != NULL)
sign->prev->next = sign;
if (buf->b_signlist == p)
buf->b_signlist = sign;
}
else
{
// 'sign' has a lower priority and should be inserted after 'p'
sign->prev = p;
sign->next = p->next;
p->next = sign;
if (sign->next != NULL)
sign->next->prev = sign;
}
}
/*
* Add the sign into the signlist. Find the right spot to do it though.
*/
@@ -331,6 +403,7 @@ buf_addsign(
// Update an existing sign
sign->typenr = typenr;
sign->priority = prio;
sign_sort_by_prio_on_line(buf, sign);
return;
}
else if (lnum < sign->lnum)