Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions lua/ember/lsp/typescript.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,31 @@ vim.lsp.config('glint', {
filetypes = allFiletypes,
})

-- TypeScript 7's native LSP (nvim-lspconfig's `tsc`), for projects that
-- declare `contentMappers` in tsconfig.json (e.g. ember-content-mapper).
-- The mapper transforms gts/gjs for TypeScript itself, so ts_ls and glint
-- both stay detached in these projects (see lsp/utils.lua).
vim.lsp.config('tsc', {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nvim-lspconfig's config for TypeScript 7's native LSP (tsc --lsp --stdio, resolved from the workspace node_modules/.bin/tsc; tsgo is its deprecated alias). ts_ls can't serve these projects: it wraps tsserver, which doesn't exist in the TS 7 package, so it falls back to a bundled TS 5/6 that neither understands contentMappers nor loads @glint/tsserver-plugin (TS 7 dropped the tsserver plugin system; content mappers are its replacement extension point).

root_dir = utils.is_content_mapper_project,
filetypes = tsFiletypes,
init_options = {
-- Content mappers spawn processes declared by the project, so TypeScript
-- requires this explicit opt-in (VS Code sends it for trusted workspaces).
runExternalCode = true,
},
get_language_id = function(_, filetype)
if filetype == 'typescript.glimmer' then
return 'typescript'
end

if filetype == 'javascript.glimmer' then
return 'javascript'
end

return filetype
end,
})

vim.lsp.enable('ts_ls')
vim.lsp.enable('glint')
vim.lsp.enable('tsc')
28 changes: 28 additions & 0 deletions lua/ember/lsp/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,15 @@ local function read_nearest_ts_config()
-- is used.
local isGlintV1 = string.find(contents, '"glint"')
local hasGlintPlugin = string.find(manifest, "@glint/ember%-tsc")
-- TypeScript 7 content mappers (e.g. ember-content-mapper):
-- tsconfig.json declares the mappers directly, and TypeScript's own LSP
-- handles gts/gjs, so neither ts_ls nor glint should attach.
local hasContentMappers = string.find(contents, '"contentMappers"')

return {
isGlintV1 = not not isGlintV1,
isGlintV2 = not not hasGlintPlugin,
isContentMapper = not not hasContentMappers,
rootDir = rootDir,
};
end
Expand All @@ -55,6 +60,10 @@ local function is_glint_project(bufnr, onDir)
return nil
end

if (result.isContentMapper) then
return nil
end

if (result.isGlintV2) then
return nil
end
Expand All @@ -73,6 +82,10 @@ local function is_ts_project(bufnr, onDir)
return nil
end

if (result.isContentMapper) then
return nil
end

if (result.isGlintV2) then
return onDir(result.rootDir)
end
Expand All @@ -84,7 +97,22 @@ local function is_ts_project(bufnr, onDir)
return onDir(result.rootDir)
end

local function is_content_mapper_project(bufnr, onDir)
local result = read_nearest_ts_config()

if not result then
return nil
end

if (not result.isContentMapper) then
return nil
end

return onDir(result.rootDir)
end

return {
is_glint_v1_project = is_glint_project,
is_ts_project = is_ts_project,
is_content_mapper_project = is_content_mapper_project,
}