diff options
Diffstat (limited to 'src/nvim/extmark.c')
-rw-r--r-- | src/nvim/extmark.c | 61 |
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); - } -} - |