mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
Merge pull request #25859 from luukvbaal/extmarkdel
refactor(extmarks): extmark_del() with MarkTreeIter
This commit is contained in:
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user