diff options
-rw-r--r-- | src/nvim/buffer.c | 57 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/lib/kbtree.h | 52 |
3 files changed, 49 insertions, 62 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 26dc07e4bc..fc28b0de70 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5201,11 +5201,8 @@ int bufhl_add_hl(buf_T *buf, // no highlight group or invalid line, just return src_id return src_id; } - if (!buf->b_bufhl_info) { - buf->b_bufhl_info = kb_init(bufhl); - } - BufhlLine *lineinfo = bufhl_tree_ref(buf->b_bufhl_info, lnum, true); + BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, true); bufhl_hl_item_T *hlentry = kv_pushp(lineinfo->items); hlentry->src_id = src_id; @@ -5229,25 +5226,23 @@ int bufhl_add_hl(buf_T *buf, void bufhl_clear_line_range(buf_T *buf, int src_id, linenr_T line_start, - linenr_T line_end) { - if (!buf->b_bufhl_info) { - return; - } + linenr_T line_end) +{ linenr_T first_changed = MAXLNUM, last_changed = -1; kbitr_t(bufhl) itr; BufhlLine *l, t = {line_start}; - if (!kb_itr_get(bufhl, buf->b_bufhl_info, &t, &itr)) { - kb_itr_next(bufhl, buf->b_bufhl_info, &itr); + if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) { + kb_itr_next(bufhl, &buf->b_bufhl_info, &itr); } - for (; kb_itr_valid(&itr); kb_itr_next(bufhl, buf->b_bufhl_info, &itr)) { + for (; kb_itr_valid(&itr); kb_itr_next(bufhl, &buf->b_bufhl_info, &itr)) { l = kb_itr_key(&itr); linenr_T line = l->line; if (line > line_end) { break; } if (line_start <= line && line <= line_end) { - BufhlLineStatus status = bufhl_clear_line(buf->b_bufhl_info, src_id, line); + BufhlLineStatus status = bufhl_clear_line(l, src_id, line); if (status != kBLSUnchanged) { if (line > last_changed) { last_changed = line; @@ -5257,7 +5252,8 @@ void bufhl_clear_line_range(buf_T *buf, } } if (status == kBLSDeleted) { - kb_del_itr(bufhl, buf->b_bufhl_info, &itr); + kb_del_itr(bufhl, &buf->b_bufhl_info, &itr); + xfree(l); } } } @@ -5273,10 +5269,9 @@ void bufhl_clear_line_range(buf_T *buf, /// @param bufhl_info The highlight info for the buffer /// @param src_id Highlight source group to clear, or -1 to clear all groups. /// @param lnum Linenr where the highlight should be cleared -static BufhlLineStatus bufhl_clear_line(bufhl_info_T *bufhl_info, int src_id, +static BufhlLineStatus bufhl_clear_line(BufhlLine *lineinfo, int src_id, linenr_T lnum) { - BufhlLine *lineinfo = bufhl_tree_ref(bufhl_info, lnum, false); size_t oldsize = kv_size(lineinfo->items); if (src_id < 0) { kv_size(lineinfo->items) = 0; @@ -5303,12 +5298,8 @@ static BufhlLineStatus bufhl_clear_line(bufhl_info_T *bufhl_info, int src_id, /// Remove all highlights and free the highlight data void bufhl_clear_all(buf_T *buf) { - if (!buf->b_bufhl_info) { - return; - } bufhl_clear_line_range(buf, -1, 1, MAXLNUM); - kb_destroy(bufhl, buf->b_bufhl_info); - buf->b_bufhl_info = NULL; + kb_destroy(bufhl, (&buf->b_bufhl_info)); } /// Adjust a placed highlight for inserted/deleted lines. @@ -5316,24 +5307,23 @@ void bufhl_mark_adjust(buf_T* buf, linenr_T line1, linenr_T line2, long amount, - long amount_after) { - if (!buf->b_bufhl_info) { - return; - } + long amount_after) +{ // XXX: does not support move // we need to detect this case and kbitr_t(bufhl) itr; BufhlLine *l, t = {line1}; - if (!kb_itr_get(bufhl, buf->b_bufhl_info, &t, &itr)) { - kb_itr_next(bufhl, buf->b_bufhl_info, &itr); + if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) { + kb_itr_next(bufhl, &buf->b_bufhl_info, &itr); } - for (; kb_itr_valid(&itr); kb_itr_next(bufhl, buf->b_bufhl_info, &itr)) { + for (; kb_itr_valid(&itr); kb_itr_next(bufhl, &buf->b_bufhl_info, &itr)) { l = kb_itr_key(&itr); if (l->line >= line1 && l->line <= line2) { if (amount == MAXLNUM) { - if (bufhl_clear_line(buf->b_bufhl_info, -1, l->line) == kBLSDeleted) { - kb_del_itr(bufhl, buf->b_bufhl_info, &itr); + if (bufhl_clear_line(l, -1, l->line) == kBLSDeleted) { + kb_del_itr(bufhl, &buf->b_bufhl_info, &itr); + xfree(l); } else { assert(false); } @@ -5356,12 +5346,9 @@ void bufhl_mark_adjust(buf_T* buf, /// @param lnum The line number /// @param[out] info The highligts for the line /// @return true if there was highlights to display -bool bufhl_start_line(buf_T *buf, linenr_T lnum, bufhl_lineinfo_T *info) { - if (!buf->b_bufhl_info) { - return false; - } - - BufhlLine *lineinfo = bufhl_tree_ref(buf->b_bufhl_info, lnum, false); +bool bufhl_start_line(buf_T *buf, linenr_T lnum, bufhl_lineinfo_T *info) +{ + BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, false); if (!lineinfo) { return false; } diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index adced27f58..c027dc4512 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -760,7 +760,7 @@ struct file_buffer { int b_mapped_ctrl_c; // modes where CTRL-C is mapped - bufhl_info_T *b_bufhl_info; // buffer stored highlights + bufhl_info_T b_bufhl_info; // buffer stored highlights }; /* diff --git a/src/nvim/lib/kbtree.h b/src/nvim/lib/kbtree.h index bfea068206..d72c1d5690 100644 --- a/src/nvim/lib/kbtree.h +++ b/src/nvim/lib/kbtree.h @@ -40,18 +40,19 @@ #define __KB_PTR(btr, x) (x->ptr) #define __KB_TREE_T(name,key_t,T) \ -typedef struct kbnode_##name##_s kbnode_##name##_t; \ -struct kbnode_##name##_s { \ - int32_t n; \ - bool is_internal; \ - key_t key[2*T-1]; \ - kbnode_##name##_t *ptr[0]; \ -} ; \ - \ - typedef struct { \ - kbnode_##name##_t *root; \ - int n_keys, n_nodes; \ - } kbtree_##name##_t; \ + typedef struct kbnode_##name##_s kbnode_##name##_t; \ + struct kbnode_##name##_s { \ + int32_t n; \ + bool is_internal; \ + key_t key[2*T-1]; \ + kbnode_##name##_t *ptr[0]; \ + } ; \ + \ + typedef struct { \ + kbnode_##name##_t *root; \ + int n_keys, n_nodes; \ + } kbtree_##name##_t; \ + \ typedef struct { \ kbnode_##name##_t *x; \ int i; \ @@ -61,21 +62,11 @@ struct kbnode_##name##_s { \ } kbitr_##name##_t; \ -#define __KB_INIT(name, key_t, kbnode_t, T, ILEN) \ - static inline kbtree_##name##_t *kb_init_##name() \ - { \ - kbtree_##name##_t *b; \ - b = (kbtree_##name##_t*)xcalloc(1, sizeof(kbtree_##name##_t)); \ - b->root = (kbnode_t*)xcalloc(1, ILEN); \ - ++b->n_nodes; \ - return b; \ - } \ - #define __kb_destroy(kbnode_t,b) do { \ int i; \ unsigned int max = 8; \ kbnode_t *x, **top, **stack = 0; \ - if (b) { \ + if (b->root) { \ top = stack = (kbnode_t**)xcalloc(max, sizeof(kbnode_t*)); \ *top++ = (b)->root; \ while (top != stack) { \ @@ -93,7 +84,7 @@ struct kbnode_##name##_s { \ xfree(x); \ } \ } \ - xfree(b); xfree(stack); \ + xfree(stack); \ } while (0) #define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \ @@ -115,6 +106,9 @@ struct kbnode_##name##_s { \ #define __KB_GET(name, key_t, kbnode_t) \ static key_t *kb_getp_##name(kbtree_##name##_t *b, const key_t * __restrict k) \ { \ + if (!b->root) { \ + return 0; \ + } \ int i, r = 0; \ kbnode_t *x = b->root; \ while (x) { \ @@ -133,6 +127,9 @@ struct kbnode_##name##_s { \ #define __KB_INTERVAL(name, key_t, kbnode_t) \ static void kb_intervalp_##name(kbtree_##name##_t *b, const key_t * __restrict k, key_t **lower, key_t **upper) \ { \ + if (!b->root) { \ + return; \ + } \ int i, r = 0; \ kbnode_t *x = b->root; \ *lower = *upper = 0; \ @@ -194,6 +191,10 @@ struct kbnode_##name##_s { \ } \ static key_t *kb_putp_##name(kbtree_##name##_t *b, const key_t * __restrict k) \ { \ + if (!b->root) { \ + b->root = (kbnode_t*)xcalloc(1, ILEN); \ + ++b->n_nodes; \ + } \ kbnode_t *r, *s; \ ++b->n_keys; \ r = b->root; \ @@ -358,6 +359,7 @@ struct kbnode_##name##_s { \ } \ static int kb_itr_getp_##name(kbtree_##name##_t *b, const key_t * __restrict k, kbitr_##name##_t *itr) \ { \ + if (b->n_keys == 0) return 0; \ int i, r = 0; \ itr->p = itr->stack; \ itr->p->x = b->root; \ @@ -388,7 +390,6 @@ struct kbnode_##name##_s { \ #define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \ __KB_TREE_T(name, key_t, T) \ - __KB_INIT(name, key_t, kbnode_t, T, ILEN) \ __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \ __KB_GET(name, key_t, kbnode_t) \ __KB_INTERVAL(name, key_t, kbnode_t) \ @@ -400,7 +401,6 @@ struct kbnode_##name##_s { \ #define kbtree_t(name) kbtree_##name##_t #define kbitr_t(name) kbitr_##name##_t -#define kb_init(name) kb_init_##name() #define kb_destroy(name, b) __kb_destroy(kbnode_##name##_t, b) #define kb_get(name, b, k) kb_get_##name(b, k) #define kb_put(name, b, k) kb_put_##name(b, k) |