diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2024-10-06 12:20:40 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-06 12:20:40 -0700 |
commit | 27f3750817b188c9ababe94eade22c30d8819585 (patch) | |
tree | b916d804083d1f5a0c991390d06c5bfd37f95339 /runtime/lua/vim | |
parent | 5da2a171f72cb11f70cf5568d800a0d672b07548 (diff) | |
download | rneovim-27f3750817b188c9ababe94eade22c30d8819585.tar.gz rneovim-27f3750817b188c9ababe94eade22c30d8819585.tar.bz2 rneovim-27f3750817b188c9ababe94eade22c30d8819585.zip |
feat(lsp): improve LSP doc hover rendering #30695
Problem:
- Some servers like LuaLS add unwanted blank lines after multiline
`@param` description.
- List items do not wrap nicely.
Solution:
- When rendering the LSP doc hover, remove blank lines in each `@param`
or `@return`.
- But ensure exactly one empty line before each.
- Set 'breakindent'.
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 9ee7dc8df7..a08825b735 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -99,9 +99,26 @@ local function get_border_size(opts) return { height = height, width = width } end -local function split_lines(value) - value = string.gsub(value, '\r\n?', '\n') - return split(value, '\n', { plain = true, trimempty = true }) +--- Splits string at newlines, optionally removing unwanted blank lines. +--- +--- @param s string Multiline string +--- @param no_blank boolean? Drop blank lines for each @param/@return (except one empty line +--- separating each). Workaround for https://github.com/LuaLS/lua-language-server/issues/2333 +local function split_lines(s, no_blank) + s = string.gsub(s, '\r\n?', '\n') + local lines = {} + local in_desc = true -- Main description block, before seeing any @foo. + for line in vim.gsplit(s, '\n', { plain = true, trimempty = true }) do + local start_annotation = not not line:find('^ ?%@.?[pr]') + in_desc = (not start_annotation) and in_desc or false + if start_annotation and no_blank and not (lines[#lines] or ''):find('^%s*$') then + table.insert(lines, '') -- Separate each @foo with a blank line. + end + if in_desc or not no_blank or not line:find('^%s*$') then + table.insert(lines, line) + end + end + return lines end local function create_window_without_focus() @@ -116,7 +133,7 @@ end --- Convenience wrapper around vim.str_utfindex ---@param line string line to be indexed ---@param index integer|nil byte index (utf-8), or `nil` for length ----@param encoding string|nil utf-8|utf-16|utf-32|nil defaults to utf-16 +---@param encoding 'utf-8'|'utf-16'|'utf-32'|nil defaults to utf-16 ---@return integer `encoding` index of `index` in `line` function M._str_utfindex_enc(line, index, encoding) local len32, len16 = vim.str_utfindex(line) @@ -735,13 +752,13 @@ function M.convert_input_to_markdown_lines(input, contents) contents = contents or {} -- MarkedString variation 1 if type(input) == 'string' then - list_extend(contents, split_lines(input)) + list_extend(contents, split_lines(input, true)) else assert(type(input) == 'table', 'Expected a table for LSP input') -- MarkupContent if input.kind then local value = input.value or '' - list_extend(contents, split_lines(value)) + list_extend(contents, split_lines(value, true)) -- MarkupString variation 2 elseif input.language then table.insert(contents, '```' .. input.language) @@ -1633,10 +1650,9 @@ function M.open_floating_preview(contents, syntax, opts) if do_stylize then vim.wo[floating_winnr].conceallevel = 2 end - -- disable folding - vim.wo[floating_winnr].foldenable = false - -- soft wrapping - vim.wo[floating_winnr].wrap = opts.wrap + vim.wo[floating_winnr].foldenable = false -- Disable folding. + vim.wo[floating_winnr].wrap = opts.wrap -- Soft wrapping. + vim.wo[floating_winnr].breakindent = true -- Slightly better list presentation. vim.bo[floating_bufnr].modifiable = false vim.bo[floating_bufnr].bufhidden = 'wipe' |