Patch 8.1.1489
Problem:    Sign order wrong when priority was changed.
Solution:   Reorder signs when priority is changed. (Yegappan Lakshmanan,
            closes #4502)
Files:      src/quickfix.c, src/sign.c, src/testdir/test_signs.vim


*** ../vim-8.1.1488/src/quickfix.c      2019-05-28 23:08:12.072648675 +0200
--- src/quickfix.c      2019-06-07 21:33:08.102748800 +0200
***************
*** 5320,5326 ****
   * the list. If linewise is TRUE, then treat multiple entries on a single line
   * as one.
   */
!     static qfline_T *
  qf_get_nth_below_entry(qfline_T *entry, int n, int linewise, int *errornr)
  {
      while (n-- > 0 && !got_int)
--- 5320,5326 ----
   * the list. If linewise is TRUE, then treat multiple entries on a single line
   * as one.
   */
!     static void
  qf_get_nth_below_entry(qfline_T *entry, int n, int linewise, int *errornr)
  {
      while (n-- > 0 && !got_int)
***************
*** 5348,5355 ****
        entry = entry->qf_next;
        ++*errornr;
      }
- 
-     return entry;
  }
  
  /*
--- 5348,5353 ----
***************
*** 5357,5363 ****
   * the list. If linewise is TRUE, then treat multiple entries on a single line
   * as one.
   */
!     static qfline_T *
  qf_get_nth_above_entry(qfline_T *entry, int n, int linewise, int *errornr)
  {
      while (n-- > 0 && !got_int)
--- 5355,5361 ----
   * the list. If linewise is TRUE, then treat multiple entries on a single line
   * as one.
   */
!     static void
  qf_get_nth_above_entry(qfline_T *entry, int n, int linewise, int *errornr)
  {
      while (n-- > 0 && !got_int)
***************
*** 5373,5380 ****
        if (linewise)
            entry = qf_find_first_entry_on_line(entry, errornr);
      }
- 
-     return entry;
  }
  
  /*
--- 5371,5376 ----
***************
*** 5403,5413 ****
      {
        // Go to the n'th entry in the current buffer
        if (dir == FORWARD)
!           adj_entry = qf_get_nth_below_entry(adj_entry, n, linewise,
!                   &errornr);
        else
!           adj_entry = qf_get_nth_above_entry(adj_entry, n, linewise,
!                   &errornr);
      }
  
      return errornr;
--- 5399,5407 ----
      {
        // Go to the n'th entry in the current buffer
        if (dir == FORWARD)
!           qf_get_nth_below_entry(adj_entry, n, linewise, &errornr);
        else
!           qf_get_nth_above_entry(adj_entry, n, linewise, &errornr);
      }
  
      return errornr;
*** ../vim-8.1.1488/src/sign.c  2019-06-04 22:48:11.437416223 +0200
--- src/sign.c  2019-06-07 21:36:20.657594248 +0200
***************
*** 308,313 ****
--- 308,385 ----
  }
  
  /*
+  * 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,336 ****
--- 403,409 ----
            // Update an existing sign
            sign->typenr = typenr;
            sign->priority = prio;
+           sign_sort_by_prio_on_line(buf, sign);
            return;
        }
        else if (lnum < sign->lnum)
*** ../vim-8.1.1488/src/testdir/test_signs.vim  2019-06-04 22:48:11.437416223 
+0200
--- src/testdir/test_signs.vim  2019-06-07 21:33:08.102748800 +0200
***************
*** 1183,1188 ****
--- 1183,1483 ----
              \ 'priority' : 10}],
              \ s[0].signs)
  
+   call sign_unplace('*')
+ 
+   " Three signs on different lines with changing priorities
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 11, 'priority' : 50})
+   call sign_place(2, '', 'sign2', 'Xsign',
+             \ {'lnum' : 12, 'priority' : 60})
+   call sign_place(3, '', 'sign3', 'Xsign',
+             \ {'lnum' : 13, 'priority' : 70})
+   call sign_place(2, '', 'sign2', 'Xsign',
+             \ {'lnum' : 12, 'priority' : 40})
+   call sign_place(3, '', 'sign3', 'Xsign',
+             \ {'lnum' : 13, 'priority' : 30})
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 11, 'priority' : 50})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, 'group' : '',
+             \ 'priority' : 50},
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 12, 'group' : '',
+             \ 'priority' : 40},
+             \ {'id' : 3, 'name' : 'sign3', 'lnum' : 13, 'group' : '',
+             \ 'priority' : 30}],
+             \ s[0].signs)
+ 
+   call sign_unplace('*')
+ 
+   " Two signs on the same line with changing priorities
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 20})
+   call sign_place(2, '', 'sign2', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 30})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 30},
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20}],
+             \ s[0].signs)
+   " Change the priority of the last sign to highest
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 40})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 40},
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 30}],
+             \ s[0].signs)
+   " Change the priority of the first sign to lowest
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 25})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 30},
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 25}],
+             \ s[0].signs)
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 45})
+   call sign_place(2, '', 'sign2', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 55})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 55},
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 45}],
+             \ s[0].signs)
+ 
+   call sign_unplace('*')
+ 
+   " Three signs on the same line with changing priorities
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 40})
+   call sign_place(2, '', 'sign2', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 30})
+   call sign_place(3, '', 'sign3', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 20})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 40},
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 30},
+             \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20}],
+             \ s[0].signs)
+ 
+   " Change the priority of the middle sign to the highest
+   call sign_place(2, '', 'sign2', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 50})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 50},
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 40},
+             \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20}],
+             \ s[0].signs)
+ 
+   " Change the priority of the middle sign to the lowest
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 15})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 50},
+             \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20},
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 15}],
+             \ s[0].signs)
+ 
+   " Change the priority of the last sign to the highest
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 55})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 55},
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 50},
+             \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20}],
+             \ s[0].signs)
+ 
+   " Change the priority of the first sign to the lowest
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 15})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 50},
+             \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20},
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 15}],
+             \ s[0].signs)
+ 
+   call sign_unplace('*')
+ 
+   " Three signs on the same line with changing priorities along with other
+   " signs
+   call sign_place(1, '', 'sign1', 'Xsign',
+             \ {'lnum' : 2, 'priority' : 10})
+   call sign_place(2, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 30})
+   call sign_place(3, '', 'sign2', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 20})
+   call sign_place(4, '', 'sign3', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 25})
+   call sign_place(5, '', 'sign2', 'Xsign',
+             \ {'lnum' : 6, 'priority' : 80})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+             \ 'priority' : 10},
+             \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 30},
+             \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 25},
+             \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20},
+             \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+             \ 'priority' : 80}],
+             \ s[0].signs)
+ 
+   " Change the priority of the first sign to lowest
+   call sign_place(2, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 15})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+             \ 'priority' : 10},
+             \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 25},
+             \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20},
+             \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 15},
+             \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+             \ 'priority' : 80}],
+             \ s[0].signs)
+ 
+   " Change the priority of the last sign to highest
+   call sign_place(2, '', 'sign1', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 30})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+             \ 'priority' : 10},
+             \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 30},
+             \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 25},
+             \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20},
+             \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+             \ 'priority' : 80}],
+             \ s[0].signs)
+ 
+   " Change the priority of the middle sign to lowest
+   call sign_place(4, '', 'sign3', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 15})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+             \ 'priority' : 10},
+             \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 30},
+             \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 20},
+             \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 15},
+             \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+             \ 'priority' : 80}],
+             \ s[0].signs)
+ 
+   " Change the priority of the middle sign to highest
+   call sign_place(3, '', 'sign2', 'Xsign',
+             \ {'lnum' : 4, 'priority' : 35})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+             \ {'id' : 1, 'name' : 'sign1', 'lnum' : 2, 'group' : '',
+             \ 'priority' : 10},
+             \ {'id' : 3, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 35},
+             \ {'id' : 2, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 30},
+             \ {'id' : 4, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+             \ 'priority' : 15},
+             \ {'id' : 5, 'name' : 'sign2', 'lnum' : 6, 'group' : '',
+             \ 'priority' : 80}],
+             \ s[0].signs)
+ 
+   call sign_unplace('*')
+ 
+   " Multiple signs with the same priority on the same line
+   call sign_place(1, '', 'sign1', 'Xsign',
+               \ {'lnum' : 4, 'priority' : 20})
+   call sign_place(2, '', 'sign2', 'Xsign',
+               \ {'lnum' : 4, 'priority' : 20})
+   call sign_place(3, '', 'sign3', 'Xsign',
+               \ {'lnum' : 4, 'priority' : 20})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+               \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20},
+               \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20},
+               \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20}],
+               \ s[0].signs)
+   " Place the last sign again with the same priority
+   call sign_place(1, '', 'sign1', 'Xsign',
+               \ {'lnum' : 4, 'priority' : 20})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+               \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20},
+               \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20},
+               \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20}],
+               \ s[0].signs)
+   " Place the first sign again with the same priority
+   call sign_place(1, '', 'sign1', 'Xsign',
+               \ {'lnum' : 4, 'priority' : 20})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+               \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20},
+               \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20},
+               \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20}],
+               \ s[0].signs)
+   " Place the middle sign again with the same priority
+   call sign_place(3, '', 'sign3', 'Xsign',
+               \ {'lnum' : 4, 'priority' : 20})
+   let s = sign_getplaced('Xsign', {'group' : '*'})
+   call assert_equal([
+               \ {'id' : 3, 'name' : 'sign3', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20},
+               \ {'id' : 1, 'name' : 'sign1', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20},
+               \ {'id' : 2, 'name' : 'sign2', 'lnum' : 4, 'group' : '',
+               \ 'priority' : 20}],
+               \ s[0].signs)
+ 
+   call sign_unplace('*')
+ 
    " Place multiple signs with same id on a line with different priority
    call sign_place(1, '', 'sign1', 'Xsign',
              \ {'lnum' : 5, 'priority' : 20})
*** ../vim-8.1.1488/src/version.c       2019-06-07 21:29:44.500007647 +0200
--- src/version.c       2019-06-07 21:37:02.545346568 +0200
***************
*** 769,770 ****
--- 769,772 ----
  {   /* Add new patch number below this line */
+ /**/
+     1489,
  /**/

-- 
FIXME and XXX are two common keywords used to mark broken or incomplete code
not only since XXX as a sex reference would grab everybody's attention but
simply due to the fact that Vim would highlight these words.
                                        -- Hendrik Scholz

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201906071938.x57Jceap006380%40masaka.moolenaar.net.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui