aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuuk van Baal <luukvbaal@gmail.com>2023-10-31 23:53:52 +0100
committerLuuk van Baal <luukvbaal@gmail.com>2023-11-01 23:20:38 +0100
commit14c7bf391625d5f24096d3c06b48d955d78e9e5d (patch)
treeca98cf9b334b348631b13b95b73af486bef3fbfa
parent746a153bc1a1bc1433a1246fcf454eeb058b9de1 (diff)
downloadrneovim-14c7bf391625d5f24096d3c06b48d955d78e9e5d.tar.gz
rneovim-14c7bf391625d5f24096d3c06b48d955d78e9e5d.tar.bz2
rneovim-14c7bf391625d5f24096d3c06b48d955d78e9e5d.zip
refactor(extmarks): extmark_del() with MarkTreeIter
-rw-r--r--src/nvim/api/extmark.c2
-rw-r--r--src/nvim/extmark.c80
2 files changed, 23 insertions, 59 deletions
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index 14454b626e..0b372c57e5 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -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)
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index 23fe0f82c6..a988e864db 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -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;
}