Skip to content

Commit

Permalink
feat(lsp): added custom formatters for lsp hover and made :help work …
Browse files Browse the repository at this point in the history
…in hover text
  • Loading branch information
folke committed Oct 25, 2022
1 parent 345fccc commit 63c70a9
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 61 deletions.
14 changes: 14 additions & 0 deletions lua/noice/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,20 @@ M.defaults = {
hover = {
enabled = false,
view = "notify",
opts = {
lang = "markdown",
replace = true,
render = "plain",
buf_options = { iskeyword = '!-~,^*,^|,^",192-255', keywordprg = ":help" },
},
},
hl_patterns = {
["|%S-|"] = "@text.reference",
["@%S+"] = "@parameter",
["^%s*(Parameters:)"] = "@text.title",
["^%s*(Return:)"] = "@text.title",
["^%s*(See also:)"] = "@text.title",
["{%S-}"] = "@parameter",
},
},
throttle = 1000 / 30, -- how frequently does Noice need to check for ui updates? This has no effect when in blocking mode.
Expand Down
2 changes: 1 addition & 1 deletion lua/noice/config/routes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function M.defaults()
{
view = Config.options.lsp.hover.view,
filter = { event = "lsp", kind = "hover" },
opts = { lang = "markdown", replace = true },
opts = Config.options.lsp.hover.opts,
},
{
view = Config.options.lsp.progress.view,
Expand Down
79 changes: 79 additions & 0 deletions lua/noice/source/lsp/format.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
local require = require("noice.util.lazy")

local Message = require("noice.message")
local NoiceText = require("noice.text")
local Config = require("noice.config")

local M = {}

---@alias MarkedString string | { language: string; value: string }
---@alias MarkupContent { kind: ('plaintext' | 'markdown'), value: string}
---@alias MarkupContents MarkedString | MarkedString[] | MarkupContent

---@param contents MarkupContents
---@param kind LspKind
function M.format(contents, kind)
if type(contents) ~= "table" or not vim.tbl_islist(contents) then
contents = { contents }
end

local parts = {}

for _, content in ipairs(contents) do
if type(content) == "string" then
table.insert(parts, content)
elseif content.language then
table.insert(parts, ("```%s\n%s\n```"):format(content.language, content.value))
elseif content.kind == "markdown" then
table.insert(parts, content.value)
elseif content.kind == "plaintext" then
table.insert(parts, ("```\n%s\n```"):format(content.value))
end
end

local text = table.concat(parts, "\n")
text = text:gsub("\n\n\n", "\n\n")
text = text:gsub("\n%s*\n```", "\n```")
text = text:gsub("```\n%s*\n", "```\n")

local lines = vim.split(text, "\n")

local width = 50
for _, line in pairs(lines) do
width = math.max(width, vim.api.nvim_strwidth(line))
end

local message = Message(M.event, kind)
message.once = true
message.opts.title = kind

for _, line in ipairs(lines) do
message:newline()
-- Make the horizontal ruler extend the whole window width
if line:find("^[%*%-_][%*%-_][%*%-_]+$") then
message:append(NoiceText("", {
virt_text_win_col = 0,
virt_text = { { (""):rep(width), "@punctuation.special.markdown" } },
priority = 100,
}))
else
message:append(line)
for pattern, hl_group in pairs(Config.options.lsp.hl_patterns) do
local from, to, match = line:find(pattern)
if match then
from, to = line:find(match, from)
end
if from then
message:append(NoiceText(" ", {
hl_group = hl_group,
col = from - 1,
length = to - from + 1,
}))
end
end
end
end
return message
end

return M
62 changes: 2 additions & 60 deletions lua/noice/source/lsp/init.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
local require = require("noice.util.lazy")

local Message = require("noice.message")
local Manager = require("noice.message.manager")
local NoiceText = require("noice.text")
local Config = require("noice.config")
local Format = require("noice.source.lsp.format")

local M = {}

Expand All @@ -16,63 +15,6 @@ M.kinds = {
hover = "hover",
}

---@alias MarkedString string | { language: string; value: string }
---@alias MarkupContent { kind: ('plaintext' | 'markdown'), value: string}
---@alias MarkupContents MarkedString | MarkedString[] | MarkupContent

---@param contents MarkupContents
---@param kind LspKind
function M.format(contents, kind)
if type(contents) ~= "table" or not vim.tbl_islist(contents) then
contents = { contents }
end

local parts = {}

for _, content in ipairs(contents) do
if type(content) == "string" then
table.insert(parts, content)
elseif content.language then
table.insert(parts, ("```%s\n%s\n```"):format(content.language, content.value))
elseif content.kind == "markdown" then
table.insert(parts, content.value)
elseif content.kind == "plaintext" then
table.insert(parts, ("```\n%s\n```"):format(content.value))
end
end

local text = table.concat(parts, "\n")
text = text:gsub("\n\n\n", "\n\n")
text = text:gsub("\n%s*\n```", "\n```")
text = text:gsub("```\n%s*\n", "```\n")

local lines = vim.split(text, "\n")

local width = 50
for _, line in pairs(lines) do
width = math.max(width, vim.api.nvim_strwidth(line))
end

local message = Message(M.event, kind)
message.once = true
message.opts.title = kind

for _, line in ipairs(lines) do
message:newline()
-- Make the horizontal ruler extend the whole window width
if line:find("^[%*%-_][%*%-_][%*%-_]+$") then
message:append(NoiceText("", {
virt_text_win_col = 0,
virt_text = { { (""):rep(width), "@punctuation.special.markdown" } },
priority = 100,
}))
else
message:append(line)
end
end
return message
end

function M.setup()
if Config.options.lsp.hover.enabled then
vim.lsp.handlers["textDocument/hover"] = M.hover
Expand Down Expand Up @@ -103,7 +45,7 @@ function M.hover(_, result)
return
end

local message = M.format(result.contents, "hover")
local message = Format.format(result.contents, "hover")
M.close_on_move(message)
Manager.add(message)
end
Expand Down

0 comments on commit 63c70a9

Please sign in to comment.