Skip to content

Commit 17b839b

Browse files
feat: reduce height of LSP hover doc window based on concealed lines
## Details Request: #384 Since the `conceal_lines` directive is enabled in the default highlights neovim actively handles reducing the height of LSP hover doc windows to remove unnecessary vertical space. This happens here: https://github.com/neovim/neovim/blob/master/runtime/lua/vim/lsp/util.lua#L1657-L1661 ```lua -- Reduce window height if TS highlighter conceals code block backticks. local conceal_height = api.nvim_win_text_height(floating_winnr, {}).all if conceal_height < api.nvim_win_get_height(floating_winnr) then api.nvim_win_set_height(floating_winnr, conceal_height) end ``` Since our decorations are added separately from highlights and behave very differently there would be no way for neovim to practically pickup highlights added by this plugin. To get around this we essentially re-implement this same logic as part of this plugin. After the first load of a buffer when we are just about to add our `extmark`s check if the buffer is related to LSP hover docs and if it is adjust the height taking into account the concealed lines that will be added (removed) by this plugin. I don't see this as a bug, since adjusting windows to fit their content is not something this plugin ever intended to do and supporting every feature in neovim is not the goal. However, since this is for a very specific scenario and the implementation is straightforward I've added it. > [!CAUTION] > We'll likely need to update how we identify LSP hover doc buffers over > time since the current approach is tied to internal undocumented behavior. > [!NOTE] > See if we can add a marker on LSP buffers that is a documented feature > others can rely on, if such a thing doesn't already exist.
1 parent a6a982d commit 17b839b

File tree

7 files changed

+42
-8
lines changed

7 files changed

+42
-8
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ require('render-markdown').setup({
236236
-- Which elements to always show, ignoring anti conceal behavior. Values can either be
237237
-- booleans to fix the behavior or string lists representing modes where anti conceal
238238
-- behavior will be ignored. Valid values are:
239-
-- head_icon, head_background, head_border, code_language, code_background, code_border
239+
-- head_icon, head_background, head_border, code_language, code_background, code_border,
240240
-- dash, bullet, check_icon, check_scope, quote, table_border, callout, link, sign
241241
ignore = {
242242
code_background = true,

doc/render-markdown.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ Default Configuration ~
301301
-- Which elements to always show, ignoring anti conceal behavior. Values can either be
302302
-- booleans to fix the behavior or string lists representing modes where anti conceal
303303
-- behavior will be ignored. Valid values are:
304-
-- head_icon, head_background, head_border, code_language, code_background, code_border
304+
-- head_icon, head_background, head_border, code_language, code_background, code_border,
305305
-- dash, bullet, check_icon, check_scope, quote, table_border, callout, link, sign
306306
ignore = {
307307
code_background = true,

lua/render-markdown/core/ui.lua

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
local Buffer = require('render-markdown.core.buffer')
2+
local Compat = require('render-markdown.lib.compat')
23
local Context = require('render-markdown.core.context')
34
local Env = require('render-markdown.lib.env')
45
local Extmark = require('render-markdown.core.extmark')
@@ -144,6 +145,9 @@ function M.run_update(buf, win, change)
144145
end
145146
local hidden = config:hidden(mode, row)
146147
local extmarks = buffer:get_marks()
148+
if initial then
149+
Compat.lsp_window_height(win, extmarks)
150+
end
147151
for _, extmark in ipairs(extmarks) do
148152
if extmark:get().conceal and extmark:inside(hidden) then
149153
extmark:hide(M.ns, buf)

lua/render-markdown/health.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local state = require('render-markdown.state')
55
local M = {}
66

77
---@private
8-
M.version = '8.1.24'
8+
M.version = '8.1.25'
99

1010
function M.check()
1111
M.start('version')

lua/render-markdown/init.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ M.default_config = {
417417
-- Which elements to always show, ignoring anti conceal behavior. Values can either be
418418
-- booleans to fix the behavior or string lists representing modes where anti conceal
419419
-- behavior will be ignored. Valid values are:
420-
-- head_icon, head_background, head_border, code_language, code_background, code_border
420+
-- head_icon, head_background, head_border, code_language, code_background, code_border,
421421
-- dash, bullet, check_icon, check_scope, quote, table_border, callout, link, sign
422422
ignore = {
423423
code_background = true,

lua/render-markdown/integ/source.lua

+5-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ end
2929
---@return lsp.CompletionItem[]?
3030
function M.items(buf, row, col)
3131
buf = buf == 0 and Env.buf.current() or buf
32-
local node = M.node(buf, row, col)
32+
local node = M.node(buf, row, col, 'markdown')
3333
if node == nil or node:range() ~= row then
3434
return nil
3535
end
@@ -72,19 +72,20 @@ end
7272
---@param buf integer
7373
---@param row integer
7474
---@param col integer
75+
---@param lang string
7576
---@return TSNode?
76-
function M.node(buf, row, col)
77+
function M.node(buf, row, col, lang)
7778
-- Parse current row to get up to date node
78-
local has_parser, parser = pcall(vim.treesitter.get_parser, buf)
79+
local has_parser, parser = pcall(vim.treesitter.get_parser, buf, lang)
7980
if not has_parser or parser == nil then
8081
return nil
8182
end
8283
parser:parse({ row, row })
8384

8485
local node = vim.treesitter.get_node({
8586
bufnr = buf,
86-
lang = 'markdown',
8787
pos = { row, col },
88+
lang = lang,
8889
})
8990
if node ~= nil and node:type() == 'paragraph' then
9091
node = node:prev_sibling()

lua/render-markdown/lib/compat.lua

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---@class render.md.Compat
2+
local M = {}
3+
4+
---@param win integer
5+
---@param extmarks render.md.Extmark[]
6+
---@see vim.lsp.util.open_floating_preview
7+
function M.lsp_window_height(win, extmarks)
8+
-- This is a fragile way of identifying whether this is a floating LSP buffer,
9+
-- comes from the implementation and not from any documentation
10+
local lsp_buf = pcall(vim.api.nvim_win_get_var, win, 'lsp_floating_bufnr')
11+
if not lsp_buf then
12+
return
13+
end
14+
local concealed = 0
15+
for _, extmark in ipairs(extmarks) do
16+
if extmark:get().opts.conceal_lines ~= nil then
17+
concealed = concealed + 1
18+
end
19+
end
20+
if concealed == 0 then
21+
return
22+
end
23+
local height = vim.api.nvim_win_text_height(win, {}).all - concealed
24+
if height < vim.api.nvim_win_get_height(win) then
25+
vim.api.nvim_win_set_height(win, height)
26+
end
27+
end
28+
29+
return M

0 commit comments

Comments
 (0)