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)
diff --git a/src/sign.c b/src/sign.c
index 8f1de4a..e8288d6 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -308,6 +308,78 @@
 }
 
 /*
+ * 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.
  */
     static void
@@ -331,6 +403,7 @@
 	    // Update an existing sign
 	    sign->typenr = typenr;
 	    sign->priority = prio;
+	    sign_sort_by_prio_on_line(buf, sign);
 	    return;
 	}
 	else if (lnum < sign->lnum)