Merge pull request #25859 from luukvbaal/extmarkdel

refactor(extmarks): extmark_del() with MarkTreeIter
This commit is contained in:
bfredl
2023-11-02 10:55:56 +01:00
committed by GitHub
2 changed files with 23 additions and 59 deletions

View File

@ -862,7 +862,7 @@ Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, Error *er
return false;
}
return extmark_del(buf, (uint32_t)ns_id, (uint32_t)id);
return extmark_del_id(buf, (uint32_t)ns_id, (uint32_t)id);
}
uint32_t src2ns(Integer *src_id)

View File

@ -93,7 +93,7 @@ void extmark_set(buf_T *buf, uint32_t ns_id, uint32_t *idp, int row, colnr_T col
goto error;
}
if (mt_paired(old_mark) || end_row > -1) {
extmark_del(buf, ns_id, id);
extmark_del_id(buf, ns_id, id);
} else {
// TODO(bfredl): we need to do more if "revising" a decoration mark.
assert(marktree_itr_valid(itr));
@ -194,25 +194,33 @@ static bool extmark_setraw(buf_T *buf, uint64_t mark, int row, colnr_T col)
return true;
}
/// Remove an extmark
///
/// @return 0 on missing id
bool extmark_del(buf_T *buf, uint32_t ns_id, uint32_t id)
linenr_T extmark_del_id(buf_T *buf, uint32_t ns_id, uint32_t id)
{
MarkTreeIter itr[1] = { 0 };
MTKey key = marktree_lookup_ns(buf->b_marktree, ns_id, id, false, itr);
MarkTreeIter it[1] = { 0 };
MTKey key = marktree_lookup_ns(buf->b_marktree, ns_id, id, false, it);
if (!key.id) {
return false;
return 0;
}
return extmark_del(buf, it, key, false);
}
/// Remove a (paired) extmark "key" pointed to by "itr"
///
/// @return line number of the deleted mark
linenr_T extmark_del(buf_T *buf, MarkTreeIter *itr, MTKey key, bool restore)
{
assert(key.pos.row >= 0);
uint64_t other = marktree_del_itr(buf->b_marktree, itr, false);
MTKey key2 = key;
uint64_t other = marktree_del_itr(buf->b_marktree, itr, false);
if (other) {
key2 = marktree_lookup(buf->b_marktree, other, itr);
assert(key2.pos.row >= 0);
marktree_del_itr(buf->b_marktree, itr, false);
if (restore) {
marktree_itr_get(buf->b_marktree, key.pos.row, key.pos.col, itr);
}
}
if (marktree_decor_level(key) > kDecorLevelNone) {
@ -220,7 +228,7 @@ bool extmark_del(buf_T *buf, uint32_t ns_id, uint32_t id)
}
// TODO(bfredl): delete it from current undo header, opportunistically?
return true;
return key.pos.row + 1;
}
/// Free extmarks in a ns between lines
@ -231,8 +239,6 @@ bool extmark_clear(buf_T *buf, uint32_t ns_id, int l_row, colnr_T l_col, int u_r
return false;
}
bool marks_cleared = false;
bool all_ns = (ns_id == 0);
uint32_t *ns = NULL;
if (!all_ns) {
@ -243,11 +249,7 @@ bool extmark_clear(buf_T *buf, uint32_t ns_id, int l_row, colnr_T l_col, int u_r
}
}
// the value is either zero or the lnum (row+1) if highlight was present.
static Map(uint64_t, ssize_t) delete_set = MAP_INIT;
typedef struct { int row1; } DecorItem;
static kvec_t(DecorItem) decors;
bool marks_cleared = false;
MarkTreeIter itr[1] = { 0 };
marktree_itr_get(buf->b_marktree, l_row, l_col, itr);
while (true) {
@ -257,52 +259,14 @@ bool extmark_clear(buf_T *buf, uint32_t ns_id, int l_row, colnr_T l_col, int u_r
|| (mark.pos.row == u_row && mark.pos.col > u_col)) {
break;
}
ssize_t *del_status = map_ref(uint64_t, ssize_t)(&delete_set, mt_lookup_key(mark), NULL);
if (del_status) {
marktree_del_itr(buf->b_marktree, itr, false);
if (*del_status >= 0) { // we had a decor_id
DecorItem it = kv_A(decors, *del_status);
decor_remove(buf, it.row1, mark.pos.row, mark.decor_full);
}
map_del(uint64_t, ssize_t)(&delete_set, mt_lookup_key(mark), NULL);
continue;
}
assert(mark.ns > 0 && mark.id > 0);
if (mark.ns == ns_id || all_ns) {
marks_cleared = true;
if (mark.decor_full && !mt_paired(mark)) { // if paired: deal with it later
decor_remove(buf, mark.pos.row, mark.pos.row, mark.decor_full);
}
uint64_t other = marktree_del_itr(buf->b_marktree, itr, false);
if (mt_paired(mark)) {
ssize_t decor_id = -1;
if (marktree_decor_level(mark) > kDecorLevelNone) {
// Save the decoration and the first pos. Clear the decoration
// later when we know the full range.
decor_id = (ssize_t)kv_size(decors);
kv_push(decors,
((DecorItem) { .row1 = mark.pos.row }));
}
map_put(uint64_t, ssize_t)(&delete_set, other, decor_id);
}
extmark_del(buf, itr, mark, true);
} else {
marktree_itr_next(buf->b_marktree, itr);
}
}
uint64_t id;
ssize_t decor_id;
map_foreach(&delete_set, id, decor_id, {
MTKey mark = marktree_lookup(buf->b_marktree, id, itr);
assert(marktree_itr_valid(itr));
marktree_del_itr(buf->b_marktree, itr, false);
if (decor_id >= 0) {
DecorItem it = kv_A(decors, decor_id);
decor_remove(buf, it.row1, mark.pos.row, mark.decor_full);
}
});
map_clear(uint64_t, &delete_set);
kv_size(decors) = 0;
return marks_cleared;
}