mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
decorations: memory error with ephemeral virt_text
This commit is contained in:
parent
80e122ae5d
commit
06c191848b
@ -145,8 +145,7 @@ bool decor_redraw_reset(buf_T *buf, DecorState *state)
|
|||||||
for (size_t i = 0; i < kv_size(state->active); i++) {
|
for (size_t i = 0; i < kv_size(state->active); i++) {
|
||||||
HlRange item = kv_A(state->active, i);
|
HlRange item = kv_A(state->active, i);
|
||||||
if (item.virt_text_owned) {
|
if (item.virt_text_owned) {
|
||||||
clear_virttext(item.virt_text);
|
clear_virttext(&item.virt_text);
|
||||||
xfree(item.virt_text);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kv_size(state->active) = 0;
|
kv_size(state->active) = 0;
|
||||||
@ -229,7 +228,7 @@ static void decor_add(DecorState *state, int start_row, int start_col,
|
|||||||
|
|
||||||
HlRange range = { start_row, start_col, end_row, end_col,
|
HlRange range = { start_row, start_col, end_row, end_col,
|
||||||
attr_id, MAX(priority, decor->priority),
|
attr_id, MAX(priority, decor->priority),
|
||||||
kv_size(decor->virt_text) ? &decor->virt_text : NULL,
|
decor->virt_text,
|
||||||
decor->virt_text_pos, decor->virt_text_hide, decor->hl_mode,
|
decor->virt_text_pos, decor->virt_text_hide, decor->hl_mode,
|
||||||
kv_size(decor->virt_text) && owned, -1 };
|
kv_size(decor->virt_text) && owned, -1 };
|
||||||
|
|
||||||
@ -304,7 +303,7 @@ next_mark:
|
|||||||
bool active = false, keep = true;
|
bool active = false, keep = true;
|
||||||
if (item.end_row < state->row
|
if (item.end_row < state->row
|
||||||
|| (item.end_row == state->row && item.end_col <= col)) {
|
|| (item.end_row == state->row && item.end_col <= col)) {
|
||||||
if (!(item.start_row >= state->row && item.virt_text)) {
|
if (!(item.start_row >= state->row && kv_size(item.virt_text))) {
|
||||||
keep = false;
|
keep = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -324,14 +323,13 @@ next_mark:
|
|||||||
attr = hl_combine_attr(attr, item.attr_id);
|
attr = hl_combine_attr(attr, item.attr_id);
|
||||||
}
|
}
|
||||||
if ((item.start_row == state->row && item.start_col <= col)
|
if ((item.start_row == state->row && item.start_col <= col)
|
||||||
&& item.virt_text && item.virt_col == -1) {
|
&& kv_size(item.virt_text) && item.virt_col == -1) {
|
||||||
item.virt_col = (item.virt_text_hide && hidden) ? -2 : virt_col;
|
item.virt_col = (item.virt_text_hide && hidden) ? -2 : virt_col;
|
||||||
}
|
}
|
||||||
if (keep) {
|
if (keep) {
|
||||||
kv_A(state->active, j++) = item;
|
kv_A(state->active, j++) = item;
|
||||||
} else if (item.virt_text_owned) {
|
} else if (item.virt_text_owned) {
|
||||||
clear_virttext(item.virt_text);
|
clear_virttext(&item.virt_text);
|
||||||
xfree(item.virt_text);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kv_size(state->active) = j;
|
kv_size(state->active) = j;
|
||||||
@ -344,22 +342,26 @@ void decor_redraw_end(DecorState *state)
|
|||||||
state->buf = NULL;
|
state->buf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtText *decor_redraw_virt_text(buf_T *buf, DecorState *state)
|
VirtText decor_redraw_virt_text(buf_T *buf, DecorState *state)
|
||||||
{
|
{
|
||||||
decor_redraw_col(buf, MAXCOL, MAXCOL, false, state);
|
decor_redraw_col(buf, MAXCOL, MAXCOL, false, state);
|
||||||
for (size_t i = 0; i < kv_size(state->active); i++) {
|
for (size_t i = 0; i < kv_size(state->active); i++) {
|
||||||
HlRange item = kv_A(state->active, i);
|
HlRange item = kv_A(state->active, i);
|
||||||
if (item.start_row == state->row && item.virt_text
|
if (item.start_row == state->row && kv_size(item.virt_text)
|
||||||
&& item.virt_text_pos == kVTEndOfLine) {
|
&& item.virt_text_pos == kVTEndOfLine) {
|
||||||
return item.virt_text;
|
return item.virt_text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return VIRTTEXT_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col,
|
void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col,
|
||||||
Decoration *decor, DecorPriority priority)
|
Decoration *decor, DecorPriority priority)
|
||||||
{
|
{
|
||||||
|
if (end_row == -1) {
|
||||||
|
end_row = start_row;
|
||||||
|
end_col = start_col;
|
||||||
|
}
|
||||||
decor_add(&decor_state, start_row, start_col, end_row, end_col, decor, true,
|
decor_add(&decor_state, start_row, start_col, end_row, end_col, decor, true,
|
||||||
priority);
|
priority);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ typedef struct {
|
|||||||
// TODO(bfredl): embed decoration instead, perhaps using an arena
|
// TODO(bfredl): embed decoration instead, perhaps using an arena
|
||||||
// for ephemerals?
|
// for ephemerals?
|
||||||
DecorPriority priority;
|
DecorPriority priority;
|
||||||
VirtText *virt_text;
|
VirtText virt_text;
|
||||||
VirtTextPos virt_text_pos;
|
VirtTextPos virt_text_pos;
|
||||||
bool virt_text_hide;
|
bool virt_text_hide;
|
||||||
HlMode hl_mode;
|
HlMode hl_mode;
|
||||||
|
@ -3921,9 +3921,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
|
|||||||
.hl_id = hl_err }));
|
.hl_id = hl_err }));
|
||||||
do_virttext = true;
|
do_virttext = true;
|
||||||
} else if (has_decor) {
|
} else if (has_decor) {
|
||||||
VirtText *vp = decor_redraw_virt_text(wp->w_buffer, &decor_state);
|
virt_text = decor_redraw_virt_text(wp->w_buffer, &decor_state);
|
||||||
if (vp) {
|
if (kv_size(virt_text)) {
|
||||||
virt_text = *vp;
|
|
||||||
do_virttext = true;
|
do_virttext = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4353,10 +4352,10 @@ void draw_virt_text(buf_T *buf, int *end_col, int max_col)
|
|||||||
DecorState *state = &decor_state;
|
DecorState *state = &decor_state;
|
||||||
for (size_t i = 0; i < kv_size(state->active); i++) {
|
for (size_t i = 0; i < kv_size(state->active); i++) {
|
||||||
HlRange *item = &kv_A(state->active, i);
|
HlRange *item = &kv_A(state->active, i);
|
||||||
if (item->start_row == state->row && item->virt_text
|
if (item->start_row == state->row && kv_size(item->virt_text)
|
||||||
&& item->virt_text_pos == kVTOverlay
|
&& item->virt_text_pos == kVTOverlay
|
||||||
&& item->virt_col >= 0) {
|
&& item->virt_col >= 0) {
|
||||||
VirtText vt = *item->virt_text;
|
VirtText vt = item->virt_text;
|
||||||
LineState s = LINE_STATE("");
|
LineState s = LINE_STATE("");
|
||||||
int virt_attr = 0;
|
int virt_attr = 0;
|
||||||
int col = item->virt_col;
|
int col = item->virt_col;
|
||||||
|
@ -302,6 +302,35 @@ describe('decorations providers', function()
|
|||||||
|
|
|
|
||||||
]]}
|
]]}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('can have virtual text', function()
|
||||||
|
insert(mulholland)
|
||||||
|
setup_provider [[
|
||||||
|
local hl = a.nvim_get_hl_id_by_name "ErrorMsg"
|
||||||
|
local test_ns = a.nvim_create_namespace "mulholland"
|
||||||
|
function on_do(event, ...)
|
||||||
|
if event == "line" then
|
||||||
|
local win, buf, line = ...
|
||||||
|
a.nvim_buf_set_extmark(buf, test_ns, line, 0, {
|
||||||
|
virt_text = {{'+', 'ErrorMsg'}};
|
||||||
|
virt_text_pos='overlay';
|
||||||
|
ephemeral = true;
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
|
screen:expect{grid=[[
|
||||||
|
{2:+}/ just to see if there was an accident |
|
||||||
|
{2:+}/ on Mulholland Drive |
|
||||||
|
{2:+}ry_start(); |
|
||||||
|
{2:+}ufref_T save_buf; |
|
||||||
|
{2:+}witch_buffer(&save_buf, buf); |
|
||||||
|
{2:+}osp = getmark(mark, false); |
|
||||||
|
{2:+}estore_buffer(&save_buf);^ |
|
||||||
|
|
|
||||||
|
]]}
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('extmark decorations', function()
|
describe('extmark decorations', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user