fix(lsp): convert_input_to_markdown_lines: preserve plaintext

This commit is contained in:
Folke Lemaitre 2021-06-10 17:40:26 +02:00
parent 988f88c24e
commit afb0274c28
No known key found for this signature in database
GPG Key ID: 707FE6FEB82F7984

View File

@ -806,14 +806,20 @@ function M.convert_input_to_markdown_lines(input, contents)
assert(type(input) == 'table', "Expected a table for Hover.contents") assert(type(input) == 'table', "Expected a table for Hover.contents")
-- MarkupContent -- MarkupContent
if input.kind then if input.kind then
-- The kind can be either plaintext or markdown. However, either way we -- The kind can be either plaintext or markdown.
-- will just be rendering markdown, so we handle them both the same way. -- If it's plaintext, then wrap it in a <text></text> block
-- TODO these can have escaped/sanitized html codes in markdown. We
-- should make sure we handle this correctly.
-- Some servers send input.value as empty, so let's ignore this :( -- Some servers send input.value as empty, so let's ignore this :(
input.value = input.value or ''
if input.kind == "plaintext" then
-- wrap this in a <text></text> block so that stylize_markdown
-- can properly process it as plaintext
input.value = string.format("<text>\n%s\n</text>", input.value or "")
end
-- assert(type(input.value) == 'string') -- assert(type(input.value) == 'string')
list_extend(contents, split_lines(input.value or '')) list_extend(contents, split_lines(input.value))
-- MarkupString variation 2 -- MarkupString variation 2
elseif input.language then elseif input.language then
-- Some servers send input.value as empty, so let's ignore this :( -- Some servers send input.value as empty, so let's ignore this :(
@ -1134,26 +1140,45 @@ function M.stylize_markdown(bufnr, contents, opts)
} }
opts = opts or {} opts = opts or {}
-- table of fence types to {ft, begin, end}
-- when ft is nil, we get the ft from the regex match
local matchers = {
block = {nil, "```+([a-zA-Z0-9_]*)", "```+"},
pre = {"", "<pre>", "</pre>"},
code = {"", "<code>", "</code>"},
text = {"plaintex", "<text>", "</text>"},
}
local match_begin = function(line)
for type, pattern in pairs(matchers) do
local ret = line:match(string.format("^%%s*%s%%s*$", pattern[2]))
if ret then
return {
type = type,
ft = pattern[1] or ret
}
end
end
end
local match_end = function(line, match)
local pattern = matchers[match.type]
return line:match(string.format("^%%s*%s%%s*$", pattern[3]))
end
local stripped = {} local stripped = {}
local highlights = {} local highlights = {}
do do
local i = 1 local i = 1
while i <= #contents do while i <= #contents do
local line = contents[i] local line = contents[i]
-- TODO(ashkan): use a more strict regex for filetype? local match = match_begin(line)
local ft = line:match("^```([a-zA-Z0-9_]*)$") if match then
-- local ft = line:match("^```(.*)$")
-- TODO(ashkan): validate the filetype here.
local is_pre = line:match("^%s*<pre>%s*$")
if is_pre then
ft = ""
end
if ft then
local start = #stripped local start = #stripped
i = i + 1 i = i + 1
while i <= #contents do while i <= #contents do
line = contents[i] line = contents[i]
if line == "```" or (is_pre and line:match("^%s*</pre>%s*$")) then if match_end(line, match) then
i = i + 1 i = i + 1
break break
end end
@ -1161,7 +1186,7 @@ function M.stylize_markdown(bufnr, contents, opts)
i = i + 1 i = i + 1
end end
table.insert(highlights, { table.insert(highlights, {
ft = ft; ft = match.ft;
start = start + 1; start = start + 1;
finish = #stripped + 1 - 1; finish = #stripped + 1 - 1;
}) })