From 1eff241ec68ebec76ef1e3e5c6d68bfb64602cf5 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Thu, 28 Jul 2016 22:42:22 +0200 Subject: bufhl: use kbtree for bufhl --- src/nvim/buffer.c | 114 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 40 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 0d7df7ef77..8491e77e73 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5138,6 +5138,26 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a // bufhl: plugin highlights associated with a buffer +/// Get reference to line in kbtree_t, allocating it if neccessary. +BufhlLine *bufhl_tree_ref(kbtree_t(bufhl) *b, linenr_T line, bool put) { + BufhlLine t, *p, **pp; + t.line = line; + + // put() only works if key is absent + pp = kb_get(bufhl, b, &t); + if (pp) { + return *pp; + } else if (!put) { + return NULL; + } + + p = xcalloc(sizeof(*p), 1); + p->line = line; + // p->items zero initialized + kb_put(bufhl, b, p); + return p; +} + /// Adds a highlight to buffer. /// /// Unlike matchaddpos() highlights follow changes to line numbering (as lines @@ -5176,12 +5196,12 @@ int bufhl_add_hl(buf_T *buf, return src_id; } if (!buf->b_bufhl_info) { - buf->b_bufhl_info = map_new(linenr_T, bufhl_vec_T)(); + buf->b_bufhl_info = kb_init(bufhl, KB_DEFAULT_SIZE); } - bufhl_vec_T* lineinfo = map_ref(linenr_T, bufhl_vec_T)(buf->b_bufhl_info, - lnum, true); - bufhl_hl_item_T *hlentry = kv_pushp(*lineinfo); + 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; hlentry->hl_id = hl_id; hlentry->start = col_start; @@ -5207,14 +5227,20 @@ void bufhl_clear_line_range(buf_T *buf, if (!buf->b_bufhl_info) { return; } - linenr_T line; linenr_T first_changed = MAXLNUM, last_changed = -1; - // In the case line_start - line_end << bufhl_info->size - // it might be better to reverse this, i e loop over the lines - // to clear on. - bufhl_vec_T unused; - map_foreach(buf->b_bufhl_info, line, unused, { - (void)unused; + // TODO: implement kb_itr_interval and jump directly to the first line + kbitr_t itr; + BufhlLine *l; + for (kb_itr_first(bufhl, buf->b_bufhl_info, &itr); + kb_itr_valid(&itr); + kb_itr_next(bufhl, buf->b_bufhl_info, &itr)) { + l = kb_itr_key(BufhlLine *, &itr); + linenr_T line = l->line; + if (line < line_start) { + continue; + } else if (line > line_end) { + break; + } if (line_start <= line && line <= line_end) { if (bufhl_clear_line(buf->b_bufhl_info, src_id, line)) { if (line > last_changed) { @@ -5225,7 +5251,7 @@ void bufhl_clear_line_range(buf_T *buf, } } } - }) + } if (last_changed != -1) { changed_lines_buf(buf, first_changed, last_changed+1, 0); @@ -5241,38 +5267,38 @@ void bufhl_clear_line_range(buf_T *buf, static bool bufhl_clear_line(bufhl_info_T *bufhl_info, int src_id, linenr_T lnum) { - bufhl_vec_T *lineinfo = map_ref(linenr_T, bufhl_vec_T)(bufhl_info, - lnum, false); - size_t oldsize = kv_size(*lineinfo); + BufhlLine *lineinfo = bufhl_tree_ref(bufhl_info, lnum, false); + size_t oldsize = kv_size(lineinfo->items); if (src_id < 0) { - kv_size(*lineinfo) = 0; + kv_size(lineinfo->items) = 0; } else { size_t newind = 0; - for (size_t i = 0; i < kv_size(*lineinfo); i++) { - if (kv_A(*lineinfo, i).src_id != src_id) { + for (size_t i = 0; i < kv_size(lineinfo->items); i++) { + if (kv_A(lineinfo->items, i).src_id != src_id) { if (i != newind) { - kv_A(*lineinfo, newind) = kv_A(*lineinfo, i); + kv_A(lineinfo->items, newind) = kv_A(lineinfo->items, i); } newind++; } } - kv_size(*lineinfo) = newind; + kv_size(lineinfo->items) = newind; } - if (kv_size(*lineinfo) == 0) { - kv_destroy(*lineinfo); - map_del(linenr_T, bufhl_vec_T)(bufhl_info, lnum); + if (kv_size(lineinfo->items) == 0) { + kv_destroy(lineinfo->items); + kb_del(bufhl, bufhl_info, lineinfo); } - return kv_size(*lineinfo) != oldsize; + return kv_size(lineinfo->items) != oldsize; } /// Remove all highlights and free the highlight data -void bufhl_clear_all(buf_T* buf) { +void bufhl_clear_all(buf_T *buf) +{ if (!buf->b_bufhl_info) { return; } bufhl_clear_line_range(buf, -1, 1, MAXLNUM); - map_free(linenr_T, bufhl_vec_T)(buf->b_bufhl_info); + kb_destroy(bufhl, buf->b_bufhl_info); buf->b_bufhl_info = NULL; } @@ -5285,25 +5311,29 @@ void bufhl_mark_adjust(buf_T* buf, if (!buf->b_bufhl_info) { return; } + // XXX: does not support move + // we need to detect this case and - bufhl_info_T *newmap = map_new(linenr_T, bufhl_vec_T)(); - linenr_T line; - bufhl_vec_T lineinfo; - map_foreach(buf->b_bufhl_info, line, lineinfo, { - if (line >= line1 && line <= line2) { + kbitr_t itr; + BufhlLine *l; + for (kb_itr_first(bufhl, buf->b_bufhl_info, &itr); + kb_itr_valid(&itr); + kb_itr_next(bufhl, buf->b_bufhl_info, &itr)) { + l = kb_itr_key(BufhlLine *, &itr); + if (l->line >= line1 && l->line <= line2) { if (amount == MAXLNUM) { - bufhl_clear_line(buf->b_bufhl_info, -1, line); + bufhl_clear_line(buf->b_bufhl_info, -1, l->line); continue; } else { - line += amount; + l->line += amount; + } + } else if (l->line > line2) { + if (amount_after == 0) { + break; } - } else if (line > line2) { - line += amount_after; + l->line += amount_after; } - map_put(linenr_T, bufhl_vec_T)(newmap, line, lineinfo); - }); - map_free(linenr_T, bufhl_vec_T)(buf->b_bufhl_info); - buf->b_bufhl_info = newmap; + } } @@ -5318,8 +5348,12 @@ bool bufhl_start_line(buf_T *buf, linenr_T lnum, bufhl_lineinfo_T *info) { return false; } + BufhlLine *lineinfo = bufhl_tree_ref(buf->b_bufhl_info, lnum, false); + if (!lineinfo) { + return false; + } info->valid_to = -1; - info->entries = map_get(linenr_T, bufhl_vec_T)(buf->b_bufhl_info, lnum); + info->entries = lineinfo->items; return kv_size(info->entries) > 0; } -- cgit From 6712e08bba2d50899853bf98b786bdf48c3c79be Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Fri, 29 Jul 2016 20:27:50 +0200 Subject: kbtree: allow iterators to start at arbitrary position --- src/nvim/buffer.c | 51 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 8491e77e73..580eb07d6b 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -74,6 +74,12 @@ #include "nvim/os/time.h" #include "nvim/os/input.h" +typedef enum { + kBLSUnchanged = 0, + kBLSChanged = 1, + kBLSDeleted = 2, +} BufhlLineStatus; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "buffer.c.generated.h" #endif @@ -5228,21 +5234,21 @@ void bufhl_clear_line_range(buf_T *buf, return; } linenr_T first_changed = MAXLNUM, last_changed = -1; - // TODO: implement kb_itr_interval and jump directly to the first line + kbitr_t itr; - BufhlLine *l; - for (kb_itr_first(bufhl, buf->b_bufhl_info, &itr); - kb_itr_valid(&itr); - kb_itr_next(bufhl, buf->b_bufhl_info, &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); + } + for (; kb_itr_valid(&itr); kb_itr_next(bufhl, buf->b_bufhl_info, &itr)) { l = kb_itr_key(BufhlLine *, &itr); linenr_T line = l->line; - if (line < line_start) { - continue; - } else if (line > line_end) { + if (line > line_end) { break; } if (line_start <= line && line <= line_end) { - if (bufhl_clear_line(buf->b_bufhl_info, src_id, line)) { + BufhlLineStatus status = bufhl_clear_line(buf->b_bufhl_info, src_id, line); + if (status != kBLSUnchanged) { if (line > last_changed) { last_changed = line; } @@ -5250,6 +5256,9 @@ void bufhl_clear_line_range(buf_T *buf, first_changed = line; } } + if (status == kBLSDeleted) { + kb_del_itr(bufhl, buf->b_bufhl_info, &itr); + } } } @@ -5264,8 +5273,8 @@ 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 bool bufhl_clear_line(bufhl_info_T *bufhl_info, int src_id, - linenr_T lnum) +static BufhlLineStatus bufhl_clear_line(bufhl_info_T *bufhl_info, int src_id, + linenr_T lnum) { BufhlLine *lineinfo = bufhl_tree_ref(bufhl_info, lnum, false); size_t oldsize = kv_size(lineinfo->items); @@ -5286,9 +5295,9 @@ static bool bufhl_clear_line(bufhl_info_T *bufhl_info, int src_id, if (kv_size(lineinfo->items) == 0) { kv_destroy(lineinfo->items); - kb_del(bufhl, bufhl_info, lineinfo); + return kBLSDeleted; } - return kv_size(lineinfo->items) != oldsize; + return kv_size(lineinfo->items) != oldsize ? kBLSChanged : kBLSUnchanged; } /// Remove all highlights and free the highlight data @@ -5315,15 +5324,19 @@ void bufhl_mark_adjust(buf_T* buf, // we need to detect this case and kbitr_t itr; - BufhlLine *l; - for (kb_itr_first(bufhl, buf->b_bufhl_info, &itr); - kb_itr_valid(&itr); - kb_itr_next(bufhl, buf->b_bufhl_info, &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); + } + for (; kb_itr_valid(&itr); kb_itr_next(bufhl, buf->b_bufhl_info, &itr)) { l = kb_itr_key(BufhlLine *, &itr); if (l->line >= line1 && l->line <= line2) { if (amount == MAXLNUM) { - bufhl_clear_line(buf->b_bufhl_info, -1, l->line); - continue; + if (bufhl_clear_line(buf->b_bufhl_info, -1, l->line) == kBLSDeleted) { + kb_del_itr(bufhl, buf->b_bufhl_info, &itr); + } else { + assert(false); + } } else { l->line += amount; } -- cgit From 53cf88c27bcea1099d48a1ca6dc0a4d7c44e0a98 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sat, 6 Aug 2016 09:15:43 +0200 Subject: kbtree: use proper structs --- src/nvim/buffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 580eb07d6b..26dc07e4bc 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5202,7 +5202,7 @@ int bufhl_add_hl(buf_T *buf, return src_id; } if (!buf->b_bufhl_info) { - buf->b_bufhl_info = kb_init(bufhl, KB_DEFAULT_SIZE); + buf->b_bufhl_info = kb_init(bufhl); } BufhlLine *lineinfo = bufhl_tree_ref(buf->b_bufhl_info, lnum, true); @@ -5235,13 +5235,13 @@ void bufhl_clear_line_range(buf_T *buf, } linenr_T first_changed = MAXLNUM, last_changed = -1; - kbitr_t itr; + 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); } for (; kb_itr_valid(&itr); kb_itr_next(bufhl, buf->b_bufhl_info, &itr)) { - l = kb_itr_key(BufhlLine *, &itr); + l = kb_itr_key(&itr); linenr_T line = l->line; if (line > line_end) { break; @@ -5323,13 +5323,13 @@ void bufhl_mark_adjust(buf_T* buf, // XXX: does not support move // we need to detect this case and - kbitr_t itr; + 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); } for (; kb_itr_valid(&itr); kb_itr_next(bufhl, buf->b_bufhl_info, &itr)) { - l = kb_itr_key(BufhlLine *, &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) { -- cgit From 14e19b8aaf458270ec94deb941be8ee78706851a Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 28 Aug 2016 13:01:33 +0200 Subject: kbtree: eliminate unneccesary heap allocation --- src/nvim/buffer.c | 57 +++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 35 deletions(-) (limited to 'src/nvim/buffer.c') 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; } -- cgit From 28a549d597a286330ba87ff4fffe1e2d09e0f611 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 28 Aug 2016 13:26:01 +0200 Subject: kbtree: make warning free and delete deprecated macros --- src/nvim/buffer.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index fc28b0de70..39014d903a 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5144,22 +5144,25 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a // bufhl: plugin highlights associated with a buffer -/// Get reference to line in kbtree_t, allocating it if neccessary. +/// Get reference to line in kbtree_t +/// +/// @param b the three +/// @param line the linenumber to lookup +/// @param put if true, put a new line when not found +/// if false, return NULL when not found BufhlLine *bufhl_tree_ref(kbtree_t(bufhl) *b, linenr_T line, bool put) { - BufhlLine t, *p, **pp; - t.line = line; + BufhlLine t = BUFHLLINE_INIT(line); - // put() only works if key is absent - pp = kb_get(bufhl, b, &t); + // kp_put() only works if key is absent, try get first + BufhlLine **pp = kb_get(bufhl, b, &t); if (pp) { return *pp; } else if (!put) { return NULL; } - p = xcalloc(sizeof(*p), 1); - p->line = line; - // p->items zero initialized + BufhlLine *p = xmalloc(sizeof(*p)); + *p = (BufhlLine)BUFHLLINE_INIT(line); kb_put(bufhl, b, p); return p; } @@ -5231,7 +5234,7 @@ void bufhl_clear_line_range(buf_T *buf, linenr_T first_changed = MAXLNUM, last_changed = -1; kbitr_t(bufhl) itr; - BufhlLine *l, t = {line_start}; + BufhlLine *l, t = BUFHLLINE_INIT(line_start); if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) { kb_itr_next(bufhl, &buf->b_bufhl_info, &itr); } @@ -5313,7 +5316,7 @@ void bufhl_mark_adjust(buf_T* buf, // we need to detect this case and kbitr_t(bufhl) itr; - BufhlLine *l, t = {line1}; + BufhlLine *l, t = BUFHLLINE_INIT(line1); if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) { kb_itr_next(bufhl, &buf->b_bufhl_info, &itr); } -- cgit From 7873660e1ebbb6350609f4200296fc2ac4bf3035 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 28 Aug 2016 13:32:48 +0200 Subject: bufhl: some style cleanup --- src/nvim/buffer.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 39014d903a..ebb38fe709 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5150,7 +5150,8 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a /// @param line the linenumber to lookup /// @param put if true, put a new line when not found /// if false, return NULL when not found -BufhlLine *bufhl_tree_ref(kbtree_t(bufhl) *b, linenr_T line, bool put) { +BufhlLine *bufhl_tree_ref(BufhlInfo *b, linenr_T line, bool put) +{ BufhlLine t = BUFHLLINE_INIT(line); // kp_put() only works if key is absent, try get first @@ -5207,7 +5208,7 @@ int bufhl_add_hl(buf_T *buf, BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, true); - bufhl_hl_item_T *hlentry = kv_pushp(lineinfo->items); + BufhlItem *hlentry = kv_pushp(lineinfo->items); hlentry->src_id = src_id; hlentry->hl_id = hl_id; hlentry->start = col_start; @@ -5279,16 +5280,16 @@ static BufhlLineStatus bufhl_clear_line(BufhlLine *lineinfo, int src_id, if (src_id < 0) { kv_size(lineinfo->items) = 0; } else { - size_t newind = 0; + size_t newidx = 0; for (size_t i = 0; i < kv_size(lineinfo->items); i++) { if (kv_A(lineinfo->items, i).src_id != src_id) { - if (i != newind) { - kv_A(lineinfo->items, newind) = kv_A(lineinfo->items, i); + if (i != newidx) { + kv_A(lineinfo->items, newidx) = kv_A(lineinfo->items, i); } - newind++; + newidx++; } } - kv_size(lineinfo->items) = newind; + kv_size(lineinfo->items) = newidx; } if (kv_size(lineinfo->items) == 0) { @@ -5349,7 +5350,7 @@ 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) +bool bufhl_start_line(buf_T *buf, linenr_T lnum, BufhlLineInfo *info) { BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, false); if (!lineinfo) { @@ -5370,14 +5371,14 @@ bool bufhl_start_line(buf_T *buf, linenr_T lnum, bufhl_lineinfo_T *info) /// @param info The info returned by bufhl_start_line /// @param col The column to get the attr for /// @return The highilight attr to display at the column -int bufhl_get_attr(bufhl_lineinfo_T *info, colnr_T col) { +int bufhl_get_attr(BufhlLineInfo *info, colnr_T col) { if (col <= info->valid_to) { return info->current; } int attr = 0; info->valid_to = MAXCOL; for (size_t i = 0; i < kv_size(info->entries); i++) { - bufhl_hl_item_T entry = kv_A(info->entries, i); + BufhlItem entry = kv_A(info->entries, i); if (entry.start <= col && col <= entry.stop) { int entry_attr = syn_id2attr(entry.hl_id); attr = hl_combine_attr(attr, entry_attr); -- cgit From 8b375cf471359ad7632af7fa6a2298c9b7596691 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Sun, 28 Aug 2016 15:36:18 +0200 Subject: bufhl: fix move --- src/nvim/buffer.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index ebb38fe709..b5ca6543c5 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5304,6 +5304,9 @@ void bufhl_clear_all(buf_T *buf) { bufhl_clear_line_range(buf, -1, 1, MAXLNUM); kb_destroy(bufhl, (&buf->b_bufhl_info)); + kb_init(&buf->b_bufhl_info); + kv_destroy(buf->b_bufhl_move_space); + kv_init(buf->b_bufhl_move_space); } /// Adjust a placed highlight for inserted/deleted lines. @@ -5311,19 +5314,32 @@ void bufhl_mark_adjust(buf_T* buf, linenr_T line1, linenr_T line2, long amount, - long amount_after) + long amount_after, + bool end_temp) { - // XXX: does not support move - // we need to detect this case and - kbitr_t(bufhl) itr; BufhlLine *l, t = BUFHLLINE_INIT(line1); + if (end_temp && amount < 0) { + // Move all items from b_bufhl_move_space to the btree. + for (size_t i = 0; i < kv_size(buf->b_bufhl_move_space); i++) { + l = kv_A(buf->b_bufhl_move_space, i); + l->line += amount; + kb_put(bufhl, &buf->b_bufhl_info, l); + } + kv_size(buf->b_bufhl_move_space) = 0; + return; + } + 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)) { l = kb_itr_key(&itr); if (l->line >= line1 && l->line <= line2) { + if (end_temp && amount > 0) { + kb_del_itr(bufhl, &buf->b_bufhl_info, &itr); + kv_push(buf->b_bufhl_move_space, l); + } if (amount == MAXLNUM) { if (bufhl_clear_line(l, -1, l->line) == kBLSDeleted) { kb_del_itr(bufhl, &buf->b_bufhl_info, &itr); @@ -5371,7 +5387,8 @@ bool bufhl_start_line(buf_T *buf, linenr_T lnum, BufhlLineInfo *info) /// @param info The info returned by bufhl_start_line /// @param col The column to get the attr for /// @return The highilight attr to display at the column -int bufhl_get_attr(BufhlLineInfo *info, colnr_T col) { +int bufhl_get_attr(BufhlLineInfo *info, colnr_T col) +{ if (col <= info->valid_to) { return info->current; } -- cgit