diff --git a/lua/ember/lsp/typescript.lua b/lua/ember/lsp/typescript.lua index 079f7f4..99f2879 100644 --- a/lua/ember/lsp/typescript.lua +++ b/lua/ember/lsp/typescript.lua @@ -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', { + 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') diff --git a/lua/ember/lsp/utils.lua b/lua/ember/lsp/utils.lua index dcc2b1b..87052ba 100644 --- a/lua/ember/lsp/utils.lua +++ b/lua/ember/lsp/utils.lua @@ -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 @@ -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 @@ -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 @@ -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, }