mirror of
https://github.com/neovim/neovim.git
synced 2025-09-23 03:28:33 +00:00
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 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)
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
if (mt_paired(old_mark) || end_row > -1) {
|
if (mt_paired(old_mark) || end_row > -1) {
|
||||||
extmark_del(buf, ns_id, id);
|
extmark_del_id(buf, ns_id, id);
|
||||||
} else {
|
} else {
|
||||||
// TODO(bfredl): we need to do more if "revising" a decoration mark.
|
// TODO(bfredl): we need to do more if "revising" a decoration mark.
|
||||||
assert(marktree_itr_valid(itr));
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove an extmark
|
linenr_T extmark_del_id(buf_T *buf, uint32_t ns_id, uint32_t id)
|
||||||
///
|
|
||||||
/// @return 0 on missing id
|
|
||||||
bool extmark_del(buf_T *buf, uint32_t ns_id, uint32_t id)
|
|
||||||
{
|
{
|
||||||
MarkTreeIter itr[1] = { 0 };
|
MarkTreeIter it[1] = { 0 };
|
||||||
MTKey key = marktree_lookup_ns(buf->b_marktree, ns_id, id, false, itr);
|
MTKey key = marktree_lookup_ns(buf->b_marktree, ns_id, id, false, it);
|
||||||
if (!key.id) {
|
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);
|
assert(key.pos.row >= 0);
|
||||||
uint64_t other = marktree_del_itr(buf->b_marktree, itr, false);
|
|
||||||
|
|
||||||
MTKey key2 = key;
|
MTKey key2 = key;
|
||||||
|
uint64_t other = marktree_del_itr(buf->b_marktree, itr, false);
|
||||||
if (other) {
|
if (other) {
|
||||||
key2 = marktree_lookup(buf->b_marktree, other, itr);
|
key2 = marktree_lookup(buf->b_marktree, other, itr);
|
||||||
assert(key2.pos.row >= 0);
|
assert(key2.pos.row >= 0);
|
||||||
marktree_del_itr(buf->b_marktree, itr, false);
|
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) {
|
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?
|
// TODO(bfredl): delete it from current undo header, opportunistically?
|
||||||
return true;
|
return key.pos.row + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free extmarks in a ns between lines
|
/// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool marks_cleared = false;
|
|
||||||
|
|
||||||
bool all_ns = (ns_id == 0);
|
bool all_ns = (ns_id == 0);
|
||||||
uint32_t *ns = NULL;
|
uint32_t *ns = NULL;
|
||||||
if (!all_ns) {
|
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.
|
bool marks_cleared = false;
|
||||||
static Map(uint64_t, ssize_t) delete_set = MAP_INIT;
|
|
||||||
typedef struct { int row1; } DecorItem;
|
|
||||||
static kvec_t(DecorItem) decors;
|
|
||||||
|
|
||||||
MarkTreeIter itr[1] = { 0 };
|
MarkTreeIter itr[1] = { 0 };
|
||||||
marktree_itr_get(buf->b_marktree, l_row, l_col, itr);
|
marktree_itr_get(buf->b_marktree, l_row, l_col, itr);
|
||||||
while (true) {
|
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)) {
|
|| (mark.pos.row == u_row && mark.pos.col > u_col)) {
|
||||||
break;
|
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) {
|
if (mark.ns == ns_id || all_ns) {
|
||||||
marks_cleared = true;
|
marks_cleared = true;
|
||||||
if (mark.decor_full && !mt_paired(mark)) { // if paired: deal with it later
|
extmark_del(buf, itr, mark, true);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
marktree_itr_next(buf->b_marktree, itr);
|
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;
|
return marks_cleared;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user