aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluukvbaal <luukvbaal@gmail.com>2025-02-28 13:36:25 +0100
committerGitHub <noreply@github.com>2025-02-28 13:36:25 +0100
commit86046c5a31034af65f128626103526269cf1bc49 (patch)
tree869a0ffeb9bd867be37516721c19fb7931f510d5
parent77626ed7fd369b797dcb2ad0714a84bfd9afff36 (diff)
downloadrneovim-86046c5a31034af65f128626103526269cf1bc49.tar.gz
rneovim-86046c5a31034af65f128626103526269cf1bc49.tar.bz2
rneovim-86046c5a31034af65f128626103526269cf1bc49.zip
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'.
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua3
-rw-r--r--src/nvim/buffer_defs.h6
-rw-r--r--src/nvim/decoration.c20
-rw-r--r--src/nvim/decoration_provider.c19
-rw-r--r--src/nvim/decoration_provider.h2
-rw-r--r--test/functional/plugin/lsp/utils_spec.lua16
6 files changed, 27 insertions, 39 deletions
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
index 4d70179052..46f02628ad 100644
--- a/runtime/lua/vim/treesitter/highlighter.lua
+++ b/runtime/lua/vim/treesitter/highlighter.lua
@@ -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
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index dd98a1eb9f..95cee3c442 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -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
};
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 326589c36e..1226bba436 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -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)
diff --git a/src/nvim/decoration_provider.c b/src/nvim/decoration_provider.c
index f5ff8be416..2dbf8dd5d9 100644
--- a/src/nvim/decoration_provider.c
+++ b/src/nvim/decoration_provider.c
@@ -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;
}
diff --git a/src/nvim/decoration_provider.h b/src/nvim/decoration_provider.h
index ad6fb7ac19..22960ad91c 100644
--- a/src/nvim/decoration_provider.h
+++ b/src/nvim/decoration_provider.h
@@ -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
diff --git a/test/functional/plugin/lsp/utils_spec.lua b/test/functional/plugin/lsp/utils_spec.lua
index 2a7d877eb1..ccefc3cb99 100644
--- a/test/functional/plugin/lsp/utils_spec.lua
+++ b/test/functional/plugin/lsp/utils_spec.lua
@@ -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)