fix(column): use a single path for sign sorting (#27431)

Problem:  #25826 added a (duplicate) sign comparison function, which was
modified and strayed from the original in #27418.
Solution: Merge the two functions and add a display test that actually
tests for this order in addition to the legacy tests.
This commit is contained in:
luukvbaal 2024-02-11 23:41:44 +01:00 committed by GitHub
parent 9605cfe06c
commit 5a4e0b837f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 23 deletions

View File

@ -664,11 +664,6 @@ next_mark:
return attr;
}
typedef struct {
DecorSignHighlight *sh;
uint32_t id;
} SignItem;
int sign_item_cmp(const void *p1, const void *p2)
{
const SignItem *s1 = (SignItem *)p1;
@ -683,7 +678,7 @@ int sign_item_cmp(const void *p1, const void *p2)
}
if (s1->sh->sign_add_id != s2->sh->sign_add_id) {
return s1->sh->sign_add_id > s2->sh->sign_add_id ? 1 : -1;
return s1->sh->sign_add_id < s2->sh->sign_add_id ? 1 : -1;
}
return 0;

View File

@ -168,7 +168,7 @@ static int buf_findsign(buf_T *buf, int id, char *group)
}
/// qsort() function to sort signs by line number, priority, id and recency.
int sign_cmp(const void *p1, const void *p2)
static int sign_row_cmp(const void *p1, const void *p2)
{
const MTKey *s1 = (MTKey *)p1;
const MTKey *s2 = (MTKey *)p2;
@ -180,20 +180,10 @@ int sign_cmp(const void *p1, const void *p2)
DecorSignHighlight *sh1 = decor_find_sign(mt_decor(*s1));
DecorSignHighlight *sh2 = decor_find_sign(mt_decor(*s2));
assert(sh1 && sh2);
SignItem si1 = { sh1, s1->id };
SignItem si2 = { sh2, s2->id };
if (sh1->priority != sh2->priority) {
return sh1->priority < sh2->priority ? 1 : -1;
}
if (s1->id != s2->id) {
return s1->id < s2->id ? 1 : -1;
}
if (sh1->sign_add_id != sh2->sign_add_id) {
return sh1->sign_add_id < sh2->sign_add_id ? 1 : -1;
}
return 0;
return sign_item_cmp(&si1, &si2);
}
/// Delete the specified sign(s)
@ -249,7 +239,7 @@ static int buf_delete_signs(buf_T *buf, char *group, int id, linenr_T atlnum)
// Sort to remove the highest priority sign at a specific line number.
if (kv_size(signs)) {
qsort((void *)&kv_A(signs, 0), kv_size(signs), sizeof(MTKey), sign_cmp);
qsort((void *)&kv_A(signs, 0), kv_size(signs), sizeof(MTKey), sign_row_cmp);
extmark_del_id(buf, kv_A(signs, 0).ns, kv_A(signs, 0).id);
kv_destroy(signs);
} else if (atlnum > 0) {
@ -304,7 +294,7 @@ static void sign_list_placed(buf_T *rbuf, char *group)
}
if (kv_size(signs)) {
qsort((void *)&kv_A(signs, 0), kv_size(signs), sizeof(MTKey), sign_cmp);
qsort((void *)&kv_A(signs, 0), kv_size(signs), sizeof(MTKey), sign_row_cmp);
for (size_t i = 0; i < kv_size(signs); i++) {
namebuf[0] = '\0';
@ -1002,7 +992,7 @@ static void sign_get_placed_in_buf(buf_T *buf, linenr_T lnum, int sign_id, const
}
if (kv_size(signs)) {
qsort((void *)&kv_A(signs, 0), kv_size(signs), sizeof(MTKey), sign_cmp);
qsort((void *)&kv_A(signs, 0), kv_size(signs), sizeof(MTKey), sign_row_cmp);
for (size_t i = 0; i < kv_size(signs); i++) {
tv_list_append_dict(l, sign_get_placed_info_dict(kv_A(signs, i)));
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "nvim/decoration_defs.h"
#include "nvim/types_defs.h"
/// Sign attributes. Used by the screen refresh routines.
@ -19,5 +20,10 @@ typedef struct {
int sn_num_hl; // highlight ID for line number
} sign_T;
typedef struct {
DecorSignHighlight *sh;
uint32_t id;
} SignItem;
enum { SIGN_SHOW_MAX = 9, }; ///< Maximum number of signs shown on a single line
enum { SIGN_DEF_PRIO = 10, }; ///< Default sign highlight priority

View File

@ -5160,6 +5160,18 @@ l5
|
]]}
end)
it('correct sort order with multiple namespaces and same id', function()
local ns2 = api.nvim_create_namespace('')
api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text = 'S1', id = 1})
api.nvim_buf_set_extmark(0, ns2, 0, 0, {sign_text = 'S2', id = 1})
screen:expect{grid=[[
S1S2^ |
{2:~ }|*8
|
]]}
end)
end)
describe('decorations: virt_text', function()