mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
fix(marks): ineffective conceal_line callback optimization (#32662)
Problem: _on_conceal_line callbacks are not invoked if callback has not let Nvim know it wants to receive them. But this may change on factors other than what is currently checked (changed buffer). Solution: Forego this optimization, callback is still guarded behind 'conceallevel'.
This commit is contained in:
@ -431,7 +431,7 @@ end
|
||||
function TSHighlighter._on_conceal_line(_, _, buf, row)
|
||||
local self = TSHighlighter.active[buf]
|
||||
if not self or not self._conceal_line or self._conceal_checked[row] then
|
||||
return self and self._conceal_line
|
||||
return
|
||||
end
|
||||
|
||||
-- Do not affect potentially populated highlight state.
|
||||
@ -440,7 +440,6 @@ function TSHighlighter._on_conceal_line(_, _, buf, row)
|
||||
self:prepare_highlight_states(row, row)
|
||||
on_line_impl(self, buf, row, false, true)
|
||||
self._highlight_states = highlight_states
|
||||
return true
|
||||
end
|
||||
|
||||
---@private
|
||||
|
@ -413,8 +413,7 @@ struct file_buffer {
|
||||
// negative when lines were deleted
|
||||
kvec_t(WinInfo *) b_wininfo; // list of last used info for each window
|
||||
disptick_T b_mod_tick_syn; // last display tick syntax was updated
|
||||
disptick_T b_mod_tick_decor; // last display tick decoration providers
|
||||
// where invoked
|
||||
disptick_T b_mod_tick_decor; // last display tick decoration providers were invoked
|
||||
|
||||
int64_t b_mtime; // last change time of original file
|
||||
int64_t b_mtime_ns; // nanoseconds of last change time
|
||||
@ -1324,7 +1323,4 @@ struct window_S {
|
||||
size_t w_winbar_click_defs_size; // Size of the w_winbar_click_defs array
|
||||
StlClickDefinition *w_statuscol_click_defs; // Status column click definitions
|
||||
size_t w_statuscol_click_defs_size; // Size of the w_statuscol_click_defs array
|
||||
|
||||
buf_T *w_conceal_line_buf; // buffer in win when first invoked
|
||||
bool w_conceal_line_provider; // whether conceal_line provider is active
|
||||
};
|
||||
|
@ -862,15 +862,7 @@ bool decor_conceal_line(win_T *wp, int row, bool check_cursor)
|
||||
|
||||
// No need to scan the marktree if there are no conceal_line marks.
|
||||
if (!buf_meta_total(wp->w_buffer, kMTMetaConcealLines)) {
|
||||
// Only invoke callback when a decor provider has indicated that it may
|
||||
// conceal lines in a certain buffer (the callback's return value).
|
||||
if (wp->w_conceal_line_buf != wp->w_buffer) {
|
||||
wp->w_conceal_line_provider = false;
|
||||
}
|
||||
if (wp->w_conceal_line_provider || wp->w_conceal_line_buf != wp->w_buffer) {
|
||||
goto invoke;
|
||||
}
|
||||
return false;
|
||||
return decor_providers_invoke_conceal_line(wp, row);
|
||||
}
|
||||
|
||||
// Scan the marktree for any conceal_line marks on this row.
|
||||
@ -896,19 +888,13 @@ bool decor_conceal_line(win_T *wp, int row, bool check_cursor)
|
||||
marktree_itr_next_filter(wp->w_buffer->b_marktree, itr, row + 1, 0, conceal_filter);
|
||||
}
|
||||
|
||||
invoke:;
|
||||
// Interpret increase in keys to mean this row is concealed by a callback.
|
||||
size_t keys = wp->w_buffer->b_marktree->n_keys;
|
||||
decor_providers_invoke_conceal_line(wp, row);
|
||||
return wp->w_buffer->b_marktree->n_keys > keys;
|
||||
return decor_providers_invoke_conceal_line(wp, row);
|
||||
}
|
||||
|
||||
/// @return whether a window may have folded or concealed lines
|
||||
bool win_lines_concealed(win_T *wp)
|
||||
{
|
||||
return hasAnyFolding(wp)
|
||||
|| (wp->w_p_cole >= 2
|
||||
&& (wp->w_conceal_line_provider || buf_meta_total(wp->w_buffer, kMTMetaConcealLines)));
|
||||
return hasAnyFolding(wp) || wp->w_p_cole >= 2;
|
||||
}
|
||||
|
||||
int sign_item_cmp(const void *p1, const void *p2)
|
||||
|
@ -47,9 +47,7 @@ static bool decor_provider_invoke(int provider_idx, const char *name, LuaRef ref
|
||||
Error err = ERROR_INIT;
|
||||
|
||||
textlock++;
|
||||
provider_active = true;
|
||||
Object ret = nlua_call_ref(ref, name, args, kRetNilBool, NULL, &err);
|
||||
provider_active = false;
|
||||
textlock--;
|
||||
|
||||
// We get the provider here via an index in case the above call to nlua_call_ref causes
|
||||
@ -92,9 +90,10 @@ void decor_providers_invoke_spell(win_T *wp, int start_row, int start_col, int e
|
||||
}
|
||||
}
|
||||
|
||||
void decor_providers_invoke_conceal_line(win_T *wp, int row)
|
||||
/// @return whether a provider placed any marks in the callback.
|
||||
bool decor_providers_invoke_conceal_line(win_T *wp, int row)
|
||||
{
|
||||
wp->w_conceal_line_buf = wp->w_buffer;
|
||||
size_t keys = wp->w_buffer->b_marktree->n_keys;
|
||||
for (size_t i = 0; i < kv_size(decor_providers); i++) {
|
||||
DecorProvider *p = &kv_A(decor_providers, i);
|
||||
if (p->state != kDecorProviderDisabled && p->conceal_line != LUA_NOREF) {
|
||||
@ -102,11 +101,10 @@ void decor_providers_invoke_conceal_line(win_T *wp, int row)
|
||||
ADD_C(args, INTEGER_OBJ(wp->handle));
|
||||
ADD_C(args, INTEGER_OBJ(wp->w_buffer->handle));
|
||||
ADD_C(args, INTEGER_OBJ(row));
|
||||
if (decor_provider_invoke((int)i, "conceal_line", p->conceal_line, args, false)) {
|
||||
wp->w_conceal_line_provider = true;
|
||||
}
|
||||
decor_provider_invoke((int)i, "conceal_line", p->conceal_line, args, true);
|
||||
}
|
||||
}
|
||||
return wp->w_buffer->b_marktree->n_keys > keys;
|
||||
}
|
||||
|
||||
/// For each provider invoke the 'start' callback
|
||||
@ -279,12 +277,7 @@ void decor_provider_clear(DecorProvider *p)
|
||||
NLUA_CLEAR_REF(p->redraw_line);
|
||||
NLUA_CLEAR_REF(p->redraw_end);
|
||||
NLUA_CLEAR_REF(p->spell_nav);
|
||||
if (p->conceal_line != LUA_NOREF) {
|
||||
NLUA_CLEAR_REF(p->conceal_line);
|
||||
FOR_ALL_TAB_WINDOWS(tp, wp) {
|
||||
wp->w_conceal_line_buf = NULL; // invoke at least once
|
||||
}
|
||||
}
|
||||
NLUA_CLEAR_REF(p->conceal_line);
|
||||
p->state = kDecorProviderDisabled;
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,6 @@
|
||||
#include "nvim/macros_defs.h"
|
||||
#include "nvim/types_defs.h" // IWYU pragma: keep
|
||||
|
||||
EXTERN bool provider_active INIT( = false);
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "decoration_provider.h.generated.h"
|
||||
#endif
|
||||
|
@ -366,5 +366,21 @@ describe('vim.lsp.util', function()
|
||||
{1:~ }|*9
|
||||
|
|
||||
]])
|
||||
-- Correct height when float inherits 'conceallevel' >= 2 #32639
|
||||
command('close | set conceallevel=2')
|
||||
exec_lua([[
|
||||
vim.lsp.util.open_floating_preview({ '```lua', 'local foo', '```' }, 'markdown', {
|
||||
border = 'single',
|
||||
focus = false,
|
||||
})
|
||||
]])
|
||||
screen:expect([[
|
||||
^ |
|
||||
┌─────────┐{1: }|
|
||||
│{100:local}{101: }{102:foo}│{1: }|
|
||||
└─────────┘{1: }|
|
||||
{1:~ }|*9
|
||||
|
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
Reference in New Issue
Block a user