mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #11842 from bfredl/decotest
treesitter: use internal "decorations" buffer
This commit is contained in:
commit
a723d60549
@ -85,7 +85,6 @@ end
|
||||
|
||||
function TSHighlighter:on_window(_, _win, _buf, _topline, botline)
|
||||
self.iter = nil
|
||||
self.active_nodes = {}
|
||||
self.nextrow = 0
|
||||
self.botline = botline
|
||||
self.redraw_count = self.redraw_count + 1
|
||||
@ -107,34 +106,13 @@ function TSHighlighter:on_line(_, _win, buf, line)
|
||||
end
|
||||
local start_row, start_col, end_row, end_col = node:range()
|
||||
local hl = self.id_map[capture]
|
||||
if hl > 0 and active then
|
||||
if start_row == line and end_row == line then
|
||||
a.nvim__put_attr(hl, start_col, end_col)
|
||||
elseif end_row >= line then
|
||||
-- TODO(bfredl): this is quite messy. Togheter with multiline bufhl we should support
|
||||
-- luahl generating multiline highlights (and other kinds of annotations)
|
||||
self.active_nodes[{hl=hl, start_row=start_row, start_col=start_col, end_row=end_row, end_col=end_col}] = true
|
||||
end
|
||||
if hl > 0 and active and end_row >= line then
|
||||
a.nvim__put_attr(hl, start_row, start_col, end_row, end_col)
|
||||
end
|
||||
if start_row > line then
|
||||
self.nextrow = start_row
|
||||
end
|
||||
end
|
||||
for node,_ in pairs(self.active_nodes) do
|
||||
if node.start_row <= line and node.end_row >= line then
|
||||
local start_col, end_col = node.start_col, node.end_col
|
||||
if node.start_row < line then
|
||||
start_col = 0
|
||||
end
|
||||
if node.end_row > line then
|
||||
end_col = 9000
|
||||
end
|
||||
a.nvim__put_attr(node.hl, start_col, end_col)
|
||||
end
|
||||
if node.end_row <= line then
|
||||
self.active_nodes[node] = nil
|
||||
end
|
||||
end
|
||||
self.line_count[line] = (self.line_count[line] or 0) + 1
|
||||
--return tostring(self.line_count[line])
|
||||
end
|
||||
|
@ -2598,7 +2598,8 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Error *err)
|
||||
/// interface should probably be derived from a reformed
|
||||
/// bufhl/virttext interface with full support for multi-line
|
||||
/// ranges etc
|
||||
void nvim__put_attr(Integer id, Integer c0, Integer c1)
|
||||
void nvim__put_attr(Integer id, Integer start_row, Integer start_col,
|
||||
Integer end_row, Integer end_col)
|
||||
FUNC_API_LUA_ONLY
|
||||
{
|
||||
if (!lua_attr_active) {
|
||||
@ -2608,10 +2609,9 @@ void nvim__put_attr(Integer id, Integer c0, Integer c1)
|
||||
return;
|
||||
}
|
||||
int attr = syn_id2attr((int)id);
|
||||
c0 = MAX(c0, 0);
|
||||
c1 = MIN(c1, (Integer)lua_attr_bufsize);
|
||||
for (Integer c = c0; c < c1; c++) {
|
||||
lua_attr_buf[c] = (sattr_T)hl_combine_attr(lua_attr_buf[c], (int)attr);
|
||||
if (attr == 0) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
decorations_add_luahl_attr(attr, (int)start_row, (colnr_T)start_col,
|
||||
(int)end_row, (colnr_T)end_col);
|
||||
}
|
||||
|
@ -296,10 +296,7 @@ void buf_updates_send_splice(buf_T *buf,
|
||||
BufUpdateCallbacks cb = kv_A(buf->update_callbacks, i);
|
||||
bool keep = true;
|
||||
if (cb.on_bytes != LUA_NOREF) {
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
Object items[8];
|
||||
args.size = 8;
|
||||
args.items = items;
|
||||
FIXED_TEMP_ARRAY(args, 8);
|
||||
|
||||
// the first argument is always the buffer handle
|
||||
args.items[0] = BUFFER_OBJ(buf->handle);
|
||||
|
@ -756,17 +756,17 @@ VirtText *extmark_find_virttext(buf_T *buf, int row, uint64_t ns_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool extmark_decorations_reset(buf_T *buf, DecorationState *state)
|
||||
bool decorations_redraw_reset(buf_T *buf, DecorationRedrawState *state)
|
||||
{
|
||||
state->row = -1;
|
||||
return buf->b_extmark_index;
|
||||
kv_size(state->active) = 0;
|
||||
return buf->b_extmark_index || buf->b_luahl;
|
||||
}
|
||||
|
||||
|
||||
bool extmark_decorations_start(buf_T *buf, int top_row, DecorationState *state)
|
||||
bool decorations_redraw_start(buf_T *buf, int top_row,
|
||||
DecorationRedrawState *state)
|
||||
{
|
||||
kv_size(state->active) = 0;
|
||||
state->top_row = top_row;
|
||||
marktree_itr_get(buf->b_marktree, top_row, 0, state->itr);
|
||||
if (!state->itr->node) {
|
||||
@ -817,17 +817,17 @@ next_mark:
|
||||
return true; // TODO(bfredl): check if available in the region
|
||||
}
|
||||
|
||||
bool extmark_decorations_line(buf_T *buf, int row, DecorationState *state)
|
||||
bool decorations_redraw_line(buf_T *buf, int row, DecorationRedrawState *state)
|
||||
{
|
||||
if (state->row == -1) {
|
||||
extmark_decorations_start(buf, row, state);
|
||||
decorations_redraw_start(buf, row, state);
|
||||
}
|
||||
state->row = row;
|
||||
state->col_until = -1;
|
||||
return true; // TODO(bfredl): be more precise
|
||||
}
|
||||
|
||||
int extmark_decorations_col(buf_T *buf, int col, DecorationState *state)
|
||||
int decorations_redraw_col(buf_T *buf, int col, DecorationRedrawState *state)
|
||||
{
|
||||
if (col <= state->col_until) {
|
||||
return state->current;
|
||||
@ -906,9 +906,9 @@ next_mark:
|
||||
return attr;
|
||||
}
|
||||
|
||||
VirtText *extmark_decorations_virt_text(buf_T *buf, DecorationState *state)
|
||||
VirtText *decorations_redraw_virt_text(buf_T *buf, DecorationRedrawState *state)
|
||||
{
|
||||
extmark_decorations_col(buf, MAXCOL, state);
|
||||
decorations_redraw_col(buf, MAXCOL, state);
|
||||
for (size_t i = 0; i < kv_size(state->active); i++) {
|
||||
HlRange item = kv_A(state->active, i);
|
||||
if (item.start_row == state->row && item.virt_text) {
|
||||
|
@ -83,7 +83,7 @@ typedef struct {
|
||||
int col_until;
|
||||
int current;
|
||||
VirtText *virt_text;
|
||||
} DecorationState;
|
||||
} DecorationRedrawState;
|
||||
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
|
@ -127,10 +127,6 @@ typedef off_t off_T;
|
||||
EXTERN int mod_mask INIT(= 0x0); /* current key modifiers */
|
||||
|
||||
|
||||
// TODO(bfredl): for the final interface this should find a more suitable
|
||||
// location.
|
||||
EXTERN sattr_T *lua_attr_buf INIT(= NULL);
|
||||
EXTERN size_t lua_attr_bufsize INIT(= 0);
|
||||
EXTERN bool lua_attr_active INIT(= false);
|
||||
|
||||
/*
|
||||
|
@ -634,9 +634,17 @@ bool win_cursorline_standout(const win_T *wp)
|
||||
|| (wp->w_p_cole > 0 && (VIsual_active || !conceal_cursor_line(wp)));
|
||||
}
|
||||
|
||||
static DecorationState decorations;
|
||||
static DecorationRedrawState decorations;
|
||||
bool decorations_active = false;
|
||||
|
||||
void decorations_add_luahl_attr(int attr_id,
|
||||
int start_row, int start_col,
|
||||
int end_row, int end_col)
|
||||
{
|
||||
kv_push(decorations.active,
|
||||
((HlRange){ start_row, start_col, end_row, end_col, attr_id, NULL }));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a single window.
|
||||
*
|
||||
@ -1228,6 +1236,8 @@ static void win_update(win_T *wp)
|
||||
srow = 0;
|
||||
lnum = wp->w_topline; // first line shown in window
|
||||
|
||||
decorations_active = decorations_redraw_reset(buf, &decorations);
|
||||
|
||||
if (buf->b_luahl && buf->b_luahl_window != LUA_NOREF) {
|
||||
Error err = ERROR_INIT;
|
||||
FIXED_TEMP_ARRAY(args, 4);
|
||||
@ -1248,7 +1258,6 @@ static void win_update(win_T *wp)
|
||||
}
|
||||
}
|
||||
|
||||
decorations_active = extmark_decorations_reset(buf, &decorations);
|
||||
|
||||
for (;; ) {
|
||||
/* stop updating when reached the end of the window (check for _past_
|
||||
@ -2311,6 +2320,8 @@ win_line (
|
||||
|
||||
char *luatext = NULL;
|
||||
|
||||
buf_T *buf = wp->w_buffer;
|
||||
|
||||
if (!number_only) {
|
||||
// To speed up the loop below, set extra_check when there is linebreak,
|
||||
// trailing white space and/or syntax processing to be done.
|
||||
@ -2333,8 +2344,31 @@ win_line (
|
||||
}
|
||||
|
||||
if (decorations_active) {
|
||||
has_decorations = extmark_decorations_line(wp->w_buffer, lnum-1,
|
||||
&decorations);
|
||||
if (buf->b_luahl && buf->b_luahl_line != LUA_NOREF) {
|
||||
Error err = ERROR_INIT;
|
||||
FIXED_TEMP_ARRAY(args, 3);
|
||||
args.items[0] = WINDOW_OBJ(wp->handle);
|
||||
args.items[1] = BUFFER_OBJ(buf->handle);
|
||||
args.items[2] = INTEGER_OBJ(lnum-1);
|
||||
lua_attr_active = true;
|
||||
extra_check = true;
|
||||
Object o = executor_exec_lua_cb(buf->b_luahl_line, "line",
|
||||
args, true, &err);
|
||||
lua_attr_active = false;
|
||||
if (o.type == kObjectTypeString) {
|
||||
// TODO(bfredl): this is a bit of a hack. A final API should use an
|
||||
// "unified" interface where luahl can add both bufhl and virttext
|
||||
luatext = o.data.string.data;
|
||||
do_virttext = true;
|
||||
} else if (ERROR_SET(&err)) {
|
||||
ELOG("error in luahl line: %s", err.msg);
|
||||
luatext = err.msg;
|
||||
do_virttext = true;
|
||||
}
|
||||
}
|
||||
|
||||
has_decorations = decorations_redraw_line(wp->w_buffer, lnum-1,
|
||||
&decorations);
|
||||
if (has_decorations) {
|
||||
extra_check = true;
|
||||
}
|
||||
@ -2532,41 +2566,6 @@ win_line (
|
||||
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
|
||||
ptr = line;
|
||||
|
||||
buf_T *buf = wp->w_buffer;
|
||||
if (buf->b_luahl && buf->b_luahl_line != LUA_NOREF) {
|
||||
size_t size = STRLEN(line);
|
||||
if (lua_attr_bufsize < size) {
|
||||
xfree(lua_attr_buf);
|
||||
lua_attr_buf = xcalloc(size, sizeof(*lua_attr_buf));
|
||||
lua_attr_bufsize = size;
|
||||
} else if (lua_attr_buf) {
|
||||
memset(lua_attr_buf, 0, size * sizeof(*lua_attr_buf));
|
||||
}
|
||||
Error err = ERROR_INIT;
|
||||
// TODO(bfredl): build a macro for the "static array" pattern
|
||||
// in buf_updates_send_changes?
|
||||
FIXED_TEMP_ARRAY(args, 3);
|
||||
args.items[0] = WINDOW_OBJ(wp->handle);
|
||||
args.items[1] = BUFFER_OBJ(buf->handle);
|
||||
args.items[2] = INTEGER_OBJ(lnum-1);
|
||||
lua_attr_active = true;
|
||||
extra_check = true;
|
||||
Object o = executor_exec_lua_cb(buf->b_luahl_line, "line",
|
||||
args, true, &err);
|
||||
lua_attr_active = false;
|
||||
if (o.type == kObjectTypeString) {
|
||||
// TODO(bfredl): this is a bit of a hack. A final API should use an
|
||||
// "unified" interface where luahl can add both bufhl and virttext
|
||||
luatext = o.data.string.data;
|
||||
do_virttext = true;
|
||||
} else if (ERROR_SET(&err)) {
|
||||
ELOG("error in luahl line: %s", err.msg);
|
||||
luatext = err.msg;
|
||||
do_virttext = true;
|
||||
api_clear_error(&err);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_spell && !number_only) {
|
||||
// For checking first word with a capital skip white space.
|
||||
if (cap_col == 0) {
|
||||
@ -3538,8 +3537,8 @@ win_line (
|
||||
}
|
||||
|
||||
if (has_decorations && v > 0) {
|
||||
int extmark_attr = extmark_decorations_col(wp->w_buffer, (colnr_T)v-1,
|
||||
&decorations);
|
||||
int extmark_attr = decorations_redraw_col(wp->w_buffer, (colnr_T)v-1,
|
||||
&decorations);
|
||||
if (extmark_attr != 0) {
|
||||
if (!attr_pri) {
|
||||
char_attr = hl_combine_attr(char_attr, extmark_attr);
|
||||
@ -3549,15 +3548,6 @@ win_line (
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(bfredl): luahl should reuse the "active decorations" buffer
|
||||
if (buf->b_luahl && v > 0 && v < (long)lua_attr_bufsize+1) {
|
||||
if (!attr_pri) {
|
||||
char_attr = hl_combine_attr(char_attr, lua_attr_buf[v-1]);
|
||||
} else {
|
||||
char_attr = hl_combine_attr(lua_attr_buf[v-1], char_attr);
|
||||
}
|
||||
}
|
||||
|
||||
if (wp->w_buffer->terminal) {
|
||||
char_attr = hl_combine_attr(term_attrs[vcol], char_attr);
|
||||
}
|
||||
@ -4042,8 +4032,7 @@ win_line (
|
||||
kv_push(virt_text, ((VirtTextChunk){ .text = luatext, .hl_id = 0 }));
|
||||
do_virttext = true;
|
||||
} else if (has_decorations) {
|
||||
VirtText *vp = extmark_decorations_virt_text(wp->w_buffer,
|
||||
&decorations);
|
||||
VirtText *vp = decorations_redraw_virt_text(wp->w_buffer, &decorations);
|
||||
if (vp) {
|
||||
virt_text = *vp;
|
||||
do_virttext = true;
|
||||
|
Loading…
Reference in New Issue
Block a user