-
Notifications
You must be signed in to change notification settings - Fork 70
Open
Description
Disclosure: I used Claude Code to investigate this issue. I have very little experience with lua, neovim scripting, or the language server protocol, so while I believe I've done my due diligence and verified the source of the issue, I could very easily be wrong.
The tsserver_make_tags function in lua/typescript-tools/protocol/utils.luaputs code fences on the same line as the tag, which seems to be invalid markdown (as far as I can tell from the commonmark spec), so it doesn't get highlighted in hover or autocomplete panes.
Example doc with code fence on its own line after the @example tag:
/**
*
* Returns the [Router](#router) object for imperative navigation.
*
* @example
*```tsx
* import { useRouter } from 'expo-router';
* import { Text } from 'react-native';
*
* export default function Route() {
* const router = useRouter();
*
* return (
* <Text onPress={() => router.push('/home')}>Go Home</Text>
* );
*}
* ```
*/
export declare function useRouter(): Router;typescript-tools eats the new line and breaks syntax highlighting:
I have a ugly looking autocmd fix in my current neovim config that resolves the issue:
-- Fix typescript-tools.nvim JSDoc tag formatting
-- The original tsserver_make_tags puts code fences on the same line as @example,
-- which produces invalid markdown that breaks syntax highlighting.
-- See: https://github.com/pmizio/typescript-tools.nvim
vim.api.nvim_create_autocmd("User", {
pattern = "VeryLazy",
callback = function()
local ok, utils = pcall(require, "typescript-tools.protocol.utils")
if not ok then
return
end
local original_docs_to_plain_text = utils.tsserver_docs_to_plain_text
-- Override tsserver_make_tags to properly format code blocks
---@diagnostic disable-next-line: duplicate-set-field
utils.tsserver_make_tags = function(tags)
return table.concat(vim.tbl_map(function(it)
local parts = { "\n_@" }
table.insert(parts, it.name)
if it.text then
local text = original_docs_to_plain_text(it.text, nil, true)
-- If text starts with a code fence, put it on its own line
if text:match("^```") then
table.insert(parts, "_\n\n")
else
table.insert(parts, "_ — ")
end
table.insert(parts, text)
end
return table.concat(parts, "")
end, tags) or {}, "\n")
end
end,
})

Metadata
Metadata
Assignees
Labels
No labels