Skip to content

Commit 6441612

Browse files
committed
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)
1 parent 150f055 commit 6441612

4 files changed

Lines changed: 374 additions & 10 deletions

File tree

src/quickfix.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5320,7 +5320,7 @@ qf_find_closest_entry(
53205320
* the list. If linewise is TRUE, then treat multiple entries on a single line
53215321
* as one.
53225322
*/
5323-
static qfline_T *
5323+
static void
53245324
qf_get_nth_below_entry(qfline_T *entry, int n, int linewise, int *errornr)
53255325
{
53265326
while (n-- > 0 && !got_int)
@@ -5348,16 +5348,14 @@ qf_get_nth_below_entry(qfline_T *entry, int n, int linewise, int *errornr)
53485348
entry = entry->qf_next;
53495349
++*errornr;
53505350
}
5351-
5352-
return entry;
53535351
}
53545352

53555353
/*
53565354
* Get the nth quickfix entry above the specified entry. Searches backwards in
53575355
* the list. If linewise is TRUE, then treat multiple entries on a single line
53585356
* as one.
53595357
*/
5360-
static qfline_T *
5358+
static void
53615359
qf_get_nth_above_entry(qfline_T *entry, int n, int linewise, int *errornr)
53625360
{
53635361
while (n-- > 0 && !got_int)
@@ -5373,8 +5371,6 @@ qf_get_nth_above_entry(qfline_T *entry, int n, int linewise, int *errornr)
53735371
if (linewise)
53745372
entry = qf_find_first_entry_on_line(entry, errornr);
53755373
}
5376-
5377-
return entry;
53785374
}
53795375

53805376
/*
@@ -5403,11 +5399,9 @@ qf_find_nth_adj_entry(
54035399
{
54045400
// Go to the n'th entry in the current buffer
54055401
if (dir == FORWARD)
5406-
adj_entry = qf_get_nth_below_entry(adj_entry, n, linewise,
5407-
&errornr);
5402+
qf_get_nth_below_entry(adj_entry, n, linewise, &errornr);
54085403
else
5409-
adj_entry = qf_get_nth_above_entry(adj_entry, n, linewise,
5410-
&errornr);
5404+
qf_get_nth_above_entry(adj_entry, n, linewise, &errornr);
54115405
}
54125406

54135407
return errornr;

src/sign.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,78 @@ sign_get_info(signlist_T *sign)
307307
return d;
308308
}
309309

310+
/*
311+
* Sort the signs placed on the same line as "sign" by priority. Invoked after
312+
* changing the priority of an already placed sign. Assumes the signs in the
313+
* buffer are sorted by line number and priority.
314+
*/
315+
static void
316+
sign_sort_by_prio_on_line(buf_T *buf, signlist_T *sign)
317+
{
318+
signlist_T *p = NULL;
319+
320+
// If there is only one sign in the buffer or only one sign on the line or
321+
// the sign is already sorted by priority, then return.
322+
if ((sign->prev == NULL
323+
|| sign->prev->lnum != sign->lnum
324+
|| sign->prev->priority > sign->priority)
325+
&& (sign->next == NULL
326+
|| sign->next->lnum != sign->lnum
327+
|| sign->next->priority < sign->priority))
328+
return;
329+
330+
// One or more signs on the same line as 'sign'
331+
// Find a sign after which 'sign' should be inserted
332+
333+
// First search backward for a sign with higher priority on the same line
334+
p = sign;
335+
while (p->prev != NULL && p->prev->lnum == sign->lnum
336+
&& p->prev->priority <= sign->priority)
337+
p = p->prev;
338+
339+
if (p == sign)
340+
{
341+
// Sign not found. Search forward for a sign with priority just before
342+
// 'sign'.
343+
p = sign->next;
344+
while (p->next != NULL && p->next->lnum == sign->lnum
345+
&& p->next->priority > sign->priority)
346+
p = p->next;
347+
}
348+
349+
// Remove 'sign' from the list
350+
if (buf->b_signlist == sign)
351+
buf->b_signlist = sign->next;
352+
if (sign->prev != NULL)
353+
sign->prev->next = sign->next;
354+
if (sign->next != NULL)
355+
sign->next->prev = sign->prev;
356+
sign->prev = NULL;
357+
sign->next = NULL;
358+
359+
// Re-insert 'sign' at the right place
360+
if (p->priority <= sign->priority)
361+
{
362+
// 'sign' has a higher priority and should be inserted before 'p'
363+
sign->prev = p->prev;
364+
sign->next = p;
365+
p->prev = sign;
366+
if (sign->prev != NULL)
367+
sign->prev->next = sign;
368+
if (buf->b_signlist == p)
369+
buf->b_signlist = sign;
370+
}
371+
else
372+
{
373+
// 'sign' has a lower priority and should be inserted after 'p'
374+
sign->prev = p;
375+
sign->next = p->next;
376+
p->next = sign;
377+
if (sign->next != NULL)
378+
sign->next->prev = sign;
379+
}
380+
}
381+
310382
/*
311383
* Add the sign into the signlist. Find the right spot to do it though.
312384
*/
@@ -331,6 +403,7 @@ buf_addsign(
331403
// Update an existing sign
332404
sign->typenr = typenr;
333405
sign->priority = prio;
406+
sign_sort_by_prio_on_line(buf, sign);
334407
return;
335408
}
336409
else if (lnum < sign->lnum)

0 commit comments

Comments
 (0)