aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/extmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/extmark.c')
-rw-r--r--src/nvim/extmark.c61
1 files changed, 22 insertions, 39 deletions
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index dc73e34111..c4d8f75a21 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -30,7 +30,7 @@
#include <assert.h>
-#include "nvim/api/vim.h"
+#include "nvim/api/extmark.h"
#include "nvim/buffer.h"
#include "nvim/buffer_updates.h"
#include "nvim/charset.h"
@@ -48,7 +48,8 @@
# include "extmark.c.generated.h"
#endif
-static ExtmarkNs *buf_ns_ref(buf_T *buf, uint64_t ns_id, bool put) {
+static ExtmarkNs *buf_ns_ref(buf_T *buf, uint64_t ns_id, bool put)
+{
return map_ref(uint64_t, ExtmarkNs)(buf->b_extmark_ns, ns_id, put);
}
@@ -67,6 +68,14 @@ uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t *idp, int row, colnr_T
uint64_t mark = 0;
uint64_t id = idp ? *idp : 0;
+ uint8_t decor_level = kDecorLevelNone; // no decor
+ if (decor) {
+ decor_level = kDecorLevelVisible; // decor affects redraw
+ if (kv_size(decor->virt_lines)) {
+ decor_level = kDecorLevelVirtLine; // decor affects horizontal size
+ }
+ }
+
if (id == 0) {
id = ns->free_id++;
} else {
@@ -75,7 +84,6 @@ uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t *idp, int row, colnr_T
if (old_mark & MARKTREE_PAIRED_FLAG || end_row > -1) {
extmark_del(buf, ns_id, id);
} else {
- // TODO(bfredl): we need to do more if "revising" a decoration mark.
MarkTreeIter itr[1] = { 0 };
old_pos = marktree_lookup(buf->b_marktree, old_mark, itr);
assert(itr->node);
@@ -83,10 +91,9 @@ uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t *idp, int row, colnr_T
ExtmarkItem it = map_del(uint64_t, ExtmarkItem)(buf->b_extmark_index,
old_mark);
if (it.decor) {
- decor_redraw(buf, row, row, it.decor);
- decor_free(it.decor);
+ decor_remove(buf, row, row, it.decor);
}
- mark = marktree_revise(buf->b_marktree, itr);
+ mark = marktree_revise(buf->b_marktree, itr, decor_level);
goto revised;
}
marktree_del_itr(buf->b_marktree, itr, false);
@@ -99,9 +106,9 @@ uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t *idp, int row, colnr_T
if (end_row > -1) {
mark = marktree_put_pair(buf->b_marktree,
row, col, right_gravity,
- end_row, end_col, end_right_gravity);
+ end_row, end_col, end_right_gravity, decor_level);
} else {
- mark = marktree_put(buf->b_marktree, row, col, right_gravity);
+ mark = marktree_put(buf->b_marktree, row, col, right_gravity, decor_level);
}
revised:
@@ -117,6 +124,9 @@ revised:
}
if (decor) {
+ if (kv_size(decor->virt_lines)) {
+ buf->b_virt_line_blocks++;
+ }
decor_redraw(buf, row, end_row > -1 ? end_row : row, decor);
}
@@ -170,12 +180,7 @@ bool extmark_del(buf_T *buf, uint64_t ns_id, uint64_t id)
}
if (item.decor) {
- decor_redraw(buf, pos.row, pos2.row, item.decor);
- decor_free(item.decor);
- }
-
- if (mark == buf->b_virt_line_mark) {
- clear_virt_lines(buf, pos.row);
+ decor_remove(buf, pos.row, pos2.row, item.decor);
}
map_del(uint64_t, uint64_t)(ns->map, id);
@@ -228,17 +233,13 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_r
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_redraw(buf, it.row1, mark.row, it.decor);
- decor_free(it.decor);
+ decor_remove(buf, it.row1, mark.row, it.decor);
}
map_del(uint64_t, ssize_t)(&delete_set, mark.id);
continue;
}
uint64_t start_id = mark.id & ~MARKTREE_END_FLAG;
- if (start_id == buf->b_virt_line_mark) {
- clear_virt_lines(buf, mark.row);
- }
ExtmarkItem item = map_get(uint64_t, ExtmarkItem)(buf->b_extmark_index,
start_id);
@@ -257,8 +258,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_r
}
map_put(uint64_t, ssize_t)(&delete_set, other, decor_id);
} else if (item.decor) {
- decor_redraw(buf, mark.row, mark.row, item.decor);
- decor_free(item.decor);
+ decor_remove(buf, mark.row, mark.row, item.decor);
}
ExtmarkNs *my_ns = all_ns ? buf_ns_ref(buf, item.ns_id, false) : ns;
map_del(uint64_t, uint64_t)(my_ns->map, item.mark_id);
@@ -276,8 +276,7 @@ bool extmark_clear(buf_T *buf, uint64_t ns_id, int l_row, colnr_T l_col, int u_r
marktree_del_itr(buf->b_marktree, itr, false);
if (decor_id >= 0) {
DecorItem it = kv_A(decors, decor_id);
- decor_redraw(buf, it.row1, pos.row, it.decor);
- decor_free(it.decor);
+ decor_remove(buf, it.row1, pos.row, it.decor);
}
});
map_clear(uint64_t, ssize_t)(&delete_set);
@@ -508,7 +507,6 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo)
kExtmarkNoUndo);
}
}
- curbuf->b_virt_line_pos = -1;
}
@@ -588,7 +586,6 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t
colnr_T new_col, bcount_t new_byte, ExtmarkOp undo)
{
buf->deleted_bytes2 = 0;
- buf->b_virt_line_pos = -1;
buf_updates_send_splice(buf, start_row, start_col, start_byte,
old_row, old_col, old_byte,
new_row, new_col, new_byte);
@@ -680,7 +677,6 @@ void extmark_move_region(buf_T *buf, int start_row, colnr_T start_col, bcount_t
colnr_T new_col, bcount_t new_byte, ExtmarkOp undo)
{
buf->deleted_bytes2 = 0;
- buf->b_virt_line_pos = -1;
// TODO(bfredl): this is not synced to the buffer state inside the callback.
// But unless we make the undo implementation smarter, this is not ensured
// anyway.
@@ -719,16 +715,3 @@ void extmark_move_region(buf_T *buf, int start_row, colnr_T start_col, bcount_t
.data.move = move }));
}
}
-
-uint64_t src2ns(Integer *src_id)
-{
- if (*src_id == 0) {
- *src_id = nvim_create_namespace((String)STRING_INIT);
- }
- if (*src_id < 0) {
- return UINT64_MAX;
- } else {
- return (uint64_t)(*src_id);
- }
-}
-