mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
perf(extmarks): avoid unnecessary marktree traversal with folds (#24306)
Extreme testcase: ```lua vim.cmd([[ call setline(1, ['', '', '']) 2,3fold ]]) local ns = vim.api.nvim_create_namespace('') for _ = 1, 100000 do vim.api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_lines = {{{ '' }}} }) end local start_time = vim.uv.hrtime() vim.api.nvim_win_text_height(0, {}) local stop_time = vim.uv.hrtime() print(stop_time - start_time) ``` Before this PR: 21542011 After this PR: 43874
This commit is contained in:
parent
db8fe63a93
commit
19fb573ad9
@ -592,26 +592,34 @@ int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines, TriState has_fo
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virt_lines = 0;
|
assert(lnum > 0);
|
||||||
int row = MAX(lnum - 2, 0);
|
|
||||||
int end_row = (int)lnum;
|
|
||||||
MarkTreeIter itr[1] = { 0 };
|
|
||||||
marktree_itr_get(buf->b_marktree, row, 0, itr);
|
|
||||||
bool below_fold = lnum > 1 && hasFoldingWin(wp, lnum - 1, NULL, NULL, true, NULL);
|
bool below_fold = lnum > 1 && hasFoldingWin(wp, lnum - 1, NULL, NULL, true, NULL);
|
||||||
if (has_fold == kNone) {
|
if (has_fold == kNone) {
|
||||||
has_fold = hasFoldingWin(wp, lnum, NULL, NULL, true, NULL);
|
has_fold = hasFoldingWin(wp, lnum, NULL, NULL, true, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int row = lnum - 1;
|
||||||
|
const int start_row = below_fold ? row : MAX(row - 1, 0);
|
||||||
|
const int end_row = has_fold ? row : row + 1;
|
||||||
|
if (start_row >= end_row) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virt_lines = 0;
|
||||||
|
MarkTreeIter itr[1] = { 0 };
|
||||||
|
marktree_itr_get(buf->b_marktree, start_row, 0, itr);
|
||||||
while (true) {
|
while (true) {
|
||||||
mtkey_t mark = marktree_itr_current(itr);
|
mtkey_t mark = marktree_itr_current(itr);
|
||||||
if (mark.pos.row < 0 || mark.pos.row >= end_row) {
|
if (mark.pos.row < 0 || mark.pos.row >= end_row) {
|
||||||
break;
|
break;
|
||||||
} else if (mt_end(mark) || marktree_decor_level(mark) < kDecorLevelVirtLine) {
|
} else if (mt_end(mark)
|
||||||
|
|| marktree_decor_level(mark) < kDecorLevelVirtLine
|
||||||
|
|| !mark.decor_full) {
|
||||||
goto next_mark;
|
goto next_mark;
|
||||||
}
|
}
|
||||||
bool above = mark.pos.row > (lnum - 2);
|
Decoration *const decor = mark.decor_full;
|
||||||
bool has_fold_cur = above ? has_fold : below_fold;
|
const int draw_row = mark.pos.row + (decor->virt_lines_above ? 0 : 1);
|
||||||
Decoration *decor = mark.decor_full;
|
if (draw_row == row) {
|
||||||
if (!has_fold_cur && decor && decor->virt_lines_above == above) {
|
|
||||||
virt_lines += (int)kv_size(decor->virt_lines);
|
virt_lines += (int)kv_size(decor->virt_lines);
|
||||||
if (lines) {
|
if (lines) {
|
||||||
kv_splice(*lines, decor->virt_lines);
|
kv_splice(*lines, decor->virt_lines);
|
||||||
|
Loading…
Reference in New Issue
Block a user