mirror of
https://github.com/LazyVim/LazyVim.git
synced 2026-07-21 20:11:06 +00:00
feat(typescript): split typescript extra in main, vtsls and tsgo
This commit is contained in:
parent
1b4be534f1
commit
9029d928d2
5 changed files with 319 additions and 229 deletions
|
|
@ -348,13 +348,81 @@ function M.init()
|
|||
M.json.load()
|
||||
end
|
||||
|
||||
---@alias LazyVimDefault {name: string, extra: string, enabled?: boolean, origin?: "global" | "default" | "extra" }
|
||||
|
||||
---@alias LazyVimDefault {name: string, group: string, extra: string, import: string, enabled?: boolean, origin?: "global" | "default" | "extra" }
|
||||
---
|
||||
local default_extras ---@type table<string, LazyVimDefault>
|
||||
|
||||
---@param name string
|
||||
---@param extras LazyVimDefault[]
|
||||
function M.register_defaults(name, extras)
|
||||
assert(default_extras, "defaults should be loaded by now, this should never happen")
|
||||
local valid = vim.tbl_map(function(extra)
|
||||
return extra.name
|
||||
end, extras) --[[@as string[] ]]
|
||||
|
||||
local origin = "default"
|
||||
local ret ---@type LazyVimDefault?
|
||||
local use ---@type string?
|
||||
|
||||
local global = vim.g["lazyvim_" .. name]
|
||||
if vim.tbl_contains(valid, global) then
|
||||
origin = "global" -- was set by the user in their config
|
||||
use = global
|
||||
else
|
||||
if global and global ~= "auto" then
|
||||
vim.notify(
|
||||
("Invalid value for `vim.g.lazyvim_%s`: `%s`\nValid options are: %s"):format(
|
||||
name,
|
||||
global,
|
||||
table.concat(valid, ", ")
|
||||
),
|
||||
vim.log.levels.ERROR,
|
||||
{ title = "LazyVim" }
|
||||
)
|
||||
end
|
||||
for _, extra in ipairs(extras) do
|
||||
if LazyVim.has_extra(extra.extra) then
|
||||
use = extra.name -- was imported by the user in their lazy spec or added by LazyExtras
|
||||
origin = "extra"
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
use = use or valid[1] -- fallback to the first one if nothing was set
|
||||
|
||||
for _, extra in ipairs(extras) do
|
||||
local import = "lazyvim.plugins.extras." .. extra.extra
|
||||
extra = vim.deepcopy(extra)
|
||||
extra.enabled = extra.name == use
|
||||
extra.import = import
|
||||
extra.group = name
|
||||
if extra.enabled then
|
||||
extra.origin = origin
|
||||
ret = extra
|
||||
end
|
||||
default_extras[import] = extra
|
||||
end
|
||||
|
||||
return assert(ret, "One of the extras should be enabled, this should never happen")
|
||||
end
|
||||
|
||||
---@param group string
|
||||
---@return LazyVimDefault?
|
||||
function M.get_default(group)
|
||||
for _, extra in pairs(M.get_defaults()) do
|
||||
if extra.group == group and extra.enabled then
|
||||
return extra
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_defaults()
|
||||
if default_extras then
|
||||
return default_extras
|
||||
end
|
||||
default_extras = {}
|
||||
|
||||
---@type table<string, LazyVimDefault[]>
|
||||
local checks = {
|
||||
picker = {
|
||||
|
|
@ -378,36 +446,10 @@ function M.get_defaults()
|
|||
table.insert(checks.explorer, 1, table.remove(checks.explorer, 2))
|
||||
end
|
||||
|
||||
default_extras = {}
|
||||
for name, check in pairs(checks) do
|
||||
local valid = {} ---@type string[]
|
||||
for _, extra in ipairs(check) do
|
||||
if extra.enabled ~= false then
|
||||
valid[#valid + 1] = extra.name
|
||||
end
|
||||
end
|
||||
local origin = "default"
|
||||
local use = vim.g["lazyvim_" .. name]
|
||||
use = vim.tbl_contains(valid, use or "auto") and use or nil
|
||||
origin = use and "global" or origin
|
||||
for _, extra in ipairs(use and {} or check) do
|
||||
if extra.enabled ~= false and LazyVim.has_extra(extra.extra) then
|
||||
use = extra.name
|
||||
break
|
||||
end
|
||||
end
|
||||
origin = use and "extra" or origin
|
||||
use = use or valid[1]
|
||||
for _, extra in ipairs(check) do
|
||||
local import = "lazyvim.plugins.extras." .. extra.extra
|
||||
extra = vim.deepcopy(extra)
|
||||
extra.enabled = extra.name == use
|
||||
if extra.enabled then
|
||||
extra.origin = origin
|
||||
end
|
||||
default_extras[import] = extra
|
||||
end
|
||||
for name, extras in pairs(checks) do
|
||||
M.register_defaults(name, extras)
|
||||
end
|
||||
|
||||
return default_extras
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
if lazyvim_docs then
|
||||
-- LSP Server to use for TypeScript.
|
||||
vim.g.lazyvim_ts_lsp = "vtsls" -- currently the default
|
||||
-- Set to "tsgo" to use the new typescript-language-server implementation instead of tsserver.
|
||||
vim.g.lazyvim_ts_lsp = "tsgo"
|
||||
end
|
||||
|
||||
local lsp = vim.g.lazyvim_ts_lsp or "vtsls"
|
||||
local extra = LazyVim.config.register_defaults("ts_lsp", {
|
||||
{ name = "vtsls", extra = "lang.typescript.vtsls" },
|
||||
{ name = "tsgo", extra = "lang.typescript.tsgo" },
|
||||
})
|
||||
|
||||
return {
|
||||
recommended = function()
|
||||
|
|
@ -22,200 +18,13 @@ return {
|
|||
})
|
||||
end,
|
||||
|
||||
{ import = extra.import },
|
||||
|
||||
-- correctly setup lspconfig
|
||||
{
|
||||
"neovim/nvim-lspconfig",
|
||||
opts = {
|
||||
-- make sure mason installs the server
|
||||
servers = {
|
||||
---@type lspconfig.settings.tsgo
|
||||
tsgo = {
|
||||
-- explicitly add default filetypes, so that we can extend
|
||||
-- them in related extras
|
||||
filetypes = {
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"javascript.jsx",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"typescript.tsx",
|
||||
},
|
||||
settings = {
|
||||
typescript = {
|
||||
inlayHints = {
|
||||
parameterNames = {
|
||||
enabled = "literals",
|
||||
suppressWhenArgumentMatchesName = true,
|
||||
},
|
||||
parameterTypes = { enabled = true },
|
||||
variableTypes = { enabled = true },
|
||||
propertyDeclarationTypes = { enabled = true },
|
||||
functionLikeReturnTypes = { enabled = true },
|
||||
enumMemberValues = { enabled = true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
vtsls = {
|
||||
-- explicitly add default filetypes, so that we can extend
|
||||
-- them in related extras
|
||||
filetypes = {
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"javascript.jsx",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"typescript.tsx",
|
||||
},
|
||||
settings = {
|
||||
complete_function_calls = true,
|
||||
vtsls = {
|
||||
enableMoveToFileCodeAction = true,
|
||||
autoUseWorkspaceTsdk = true,
|
||||
experimental = {
|
||||
maxInlayHintLength = 30,
|
||||
completion = {
|
||||
enableServerSideFuzzyMatch = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
typescript = {
|
||||
updateImportsOnFileMove = { enabled = "always" },
|
||||
suggest = {
|
||||
completeFunctionCalls = true,
|
||||
},
|
||||
inlayHints = {
|
||||
enumMemberValues = { enabled = true },
|
||||
functionLikeReturnTypes = { enabled = true },
|
||||
parameterNames = { enabled = "literals" },
|
||||
parameterTypes = { enabled = true },
|
||||
propertyDeclarationTypes = { enabled = true },
|
||||
variableTypes = { enabled = false },
|
||||
},
|
||||
},
|
||||
},
|
||||
keys = {
|
||||
{
|
||||
"gD",
|
||||
function()
|
||||
local win = vim.api.nvim_get_current_win()
|
||||
local params = vim.lsp.util.make_position_params(win, "utf-16")
|
||||
LazyVim.lsp.execute({
|
||||
command = "typescript.goToSourceDefinition",
|
||||
arguments = { params.textDocument.uri, params.position },
|
||||
open = true,
|
||||
})
|
||||
end,
|
||||
desc = "Goto Source Definition",
|
||||
},
|
||||
{
|
||||
"gR",
|
||||
function()
|
||||
LazyVim.lsp.execute({
|
||||
command = "typescript.findAllFileReferences",
|
||||
arguments = { vim.uri_from_bufnr(0) },
|
||||
open = true,
|
||||
})
|
||||
end,
|
||||
desc = "File References",
|
||||
},
|
||||
{
|
||||
"<leader>cM",
|
||||
LazyVim.lsp.action["source.addMissingImports.ts"],
|
||||
desc = "Add missing imports",
|
||||
},
|
||||
{
|
||||
"<leader>cD",
|
||||
LazyVim.lsp.action["source.fixAll.ts"],
|
||||
desc = "Fix all diagnostics",
|
||||
},
|
||||
{
|
||||
"<leader>cV",
|
||||
function()
|
||||
LazyVim.lsp.execute({
|
||||
title = "Select TypeScript Version",
|
||||
filter = "vtsls",
|
||||
command = "typescript.selectTypeScriptVersion",
|
||||
})
|
||||
end,
|
||||
desc = "Select TS workspace version",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
setup = {
|
||||
--- @deprecated -- tsserver renamed to ts_ls but not yet released, so keep this for now
|
||||
--- the proper approach is to check the nvim-lspconfig release version when it's released to determine the server name dynamically
|
||||
tsserver = function()
|
||||
-- disable tsserver
|
||||
return true
|
||||
end,
|
||||
ts_ls = function()
|
||||
-- disable tsserver
|
||||
return true
|
||||
end,
|
||||
vtsls = function(_, opts)
|
||||
Snacks.util.lsp.on({ name = "vtsls" }, function(buffer, client)
|
||||
client.commands["_typescript.moveToFileRefactoring"] = function(command, ctx)
|
||||
---@type string, string, lsp.Range
|
||||
local action, uri, range = unpack(command.arguments)
|
||||
|
||||
local function move(newf)
|
||||
client:request("workspace/executeCommand", {
|
||||
command = command.command,
|
||||
arguments = { action, uri, range, newf },
|
||||
})
|
||||
end
|
||||
|
||||
local fname = vim.uri_to_fname(uri)
|
||||
client:request("workspace/executeCommand", {
|
||||
command = "typescript.tsserverRequest",
|
||||
arguments = {
|
||||
"getMoveToRefactoringFileSuggestions",
|
||||
{
|
||||
file = fname,
|
||||
startLine = range.start.line + 1,
|
||||
startOffset = range.start.character + 1,
|
||||
endLine = range["end"].line + 1,
|
||||
endOffset = range["end"].character + 1,
|
||||
},
|
||||
},
|
||||
}, function(_, result)
|
||||
---@type string[]
|
||||
local files = result.body.files
|
||||
table.insert(files, 1, "Enter new path...")
|
||||
vim.ui.select(files, {
|
||||
prompt = "Select move destination:",
|
||||
format_item = function(f)
|
||||
return vim.fn.fnamemodify(f, ":~:.")
|
||||
end,
|
||||
}, function(f)
|
||||
if f and f:find("^Enter new path") then
|
||||
vim.ui.input({
|
||||
prompt = "Enter move destination:",
|
||||
default = vim.fn.fnamemodify(fname, ":h") .. "/",
|
||||
completion = "file",
|
||||
}, function(newf)
|
||||
return newf and move(newf)
|
||||
end)
|
||||
elseif f then
|
||||
move(f)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
-- copy typescript settings to javascript
|
||||
opts.settings.javascript =
|
||||
vim.tbl_deep_extend("force", {}, opts.settings.typescript, opts.settings.javascript or {})
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"neovim/nvim-lspconfig",
|
||||
opts = function(_, opts)
|
||||
local lsp = extra.name or "vtsls"
|
||||
local servers = { "tsserver", "ts_ls", "vtsls", "tsgo", lsp }
|
||||
for _, server in ipairs(servers) do
|
||||
opts.servers[server] = opts.servers[server] or {}
|
||||
|
|
|
|||
58
lua/lazyvim/plugins/extras/lang/typescript/tsgo.lua
Normal file
58
lua/lazyvim/plugins/extras/lang/typescript/tsgo.lua
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
return {
|
||||
recommended = function()
|
||||
return LazyVim.extras.wants({
|
||||
ft = {
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"javascript.jsx",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"typescript.tsx",
|
||||
},
|
||||
root = { "tsconfig.json", "package.json", "jsconfig.json" },
|
||||
})
|
||||
end,
|
||||
|
||||
-- correctly setup lspconfig
|
||||
{
|
||||
"neovim/nvim-lspconfig",
|
||||
opts = {
|
||||
-- make sure mason installs the server
|
||||
servers = {
|
||||
---@type lspconfig.settings.tsgo
|
||||
tsgo = {
|
||||
-- explicitly add default filetypes, so that we can extend
|
||||
-- them in related extras
|
||||
filetypes = {
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"javascript.jsx",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"typescript.tsx",
|
||||
},
|
||||
settings = {
|
||||
typescript = {
|
||||
inlayHints = {
|
||||
parameterNames = {
|
||||
enabled = "literals",
|
||||
suppressWhenArgumentMatchesName = true,
|
||||
},
|
||||
parameterTypes = { enabled = true },
|
||||
variableTypes = { enabled = true },
|
||||
propertyDeclarationTypes = { enabled = true },
|
||||
functionLikeReturnTypes = { enabled = true },
|
||||
enumMemberValues = { enabled = true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
-- correctly setup lspconfig
|
||||
{
|
||||
"neovim/nvim-lspconfig",
|
||||
opts = {},
|
||||
},
|
||||
}
|
||||
174
lua/lazyvim/plugins/extras/lang/typescript/vtsls.lua
Normal file
174
lua/lazyvim/plugins/extras/lang/typescript/vtsls.lua
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
return {
|
||||
recommended = function()
|
||||
return LazyVim.extras.wants({
|
||||
ft = {
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"javascript.jsx",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"typescript.tsx",
|
||||
},
|
||||
root = { "tsconfig.json", "package.json", "jsconfig.json" },
|
||||
})
|
||||
end,
|
||||
|
||||
-- correctly setup lspconfig
|
||||
{
|
||||
"neovim/nvim-lspconfig",
|
||||
opts = {
|
||||
-- make sure mason installs the server
|
||||
servers = {
|
||||
vtsls = {
|
||||
-- explicitly add default filetypes, so that we can extend
|
||||
-- them in related extras
|
||||
filetypes = {
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"javascript.jsx",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"typescript.tsx",
|
||||
},
|
||||
settings = {
|
||||
complete_function_calls = true,
|
||||
vtsls = {
|
||||
enableMoveToFileCodeAction = true,
|
||||
autoUseWorkspaceTsdk = true,
|
||||
experimental = {
|
||||
maxInlayHintLength = 30,
|
||||
completion = {
|
||||
enableServerSideFuzzyMatch = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
typescript = {
|
||||
updateImportsOnFileMove = { enabled = "always" },
|
||||
suggest = {
|
||||
completeFunctionCalls = true,
|
||||
},
|
||||
inlayHints = {
|
||||
enumMemberValues = { enabled = true },
|
||||
functionLikeReturnTypes = { enabled = true },
|
||||
parameterNames = { enabled = "literals" },
|
||||
parameterTypes = { enabled = true },
|
||||
propertyDeclarationTypes = { enabled = true },
|
||||
variableTypes = { enabled = false },
|
||||
},
|
||||
},
|
||||
},
|
||||
keys = {
|
||||
{
|
||||
"gD",
|
||||
function()
|
||||
local win = vim.api.nvim_get_current_win()
|
||||
local params = vim.lsp.util.make_position_params(win, "utf-16")
|
||||
LazyVim.lsp.execute({
|
||||
command = "typescript.goToSourceDefinition",
|
||||
arguments = { params.textDocument.uri, params.position },
|
||||
open = true,
|
||||
})
|
||||
end,
|
||||
desc = "Goto Source Definition",
|
||||
},
|
||||
{
|
||||
"gR",
|
||||
function()
|
||||
LazyVim.lsp.execute({
|
||||
command = "typescript.findAllFileReferences",
|
||||
arguments = { vim.uri_from_bufnr(0) },
|
||||
open = true,
|
||||
})
|
||||
end,
|
||||
desc = "File References",
|
||||
},
|
||||
{
|
||||
"<leader>cM",
|
||||
LazyVim.lsp.action["source.addMissingImports.ts"],
|
||||
desc = "Add missing imports",
|
||||
},
|
||||
{
|
||||
"<leader>cD",
|
||||
LazyVim.lsp.action["source.fixAll.ts"],
|
||||
desc = "Fix all diagnostics",
|
||||
},
|
||||
{
|
||||
"<leader>cV",
|
||||
function()
|
||||
LazyVim.lsp.execute({
|
||||
title = "Select TypeScript Version",
|
||||
filter = "vtsls",
|
||||
command = "typescript.selectTypeScriptVersion",
|
||||
})
|
||||
end,
|
||||
desc = "Select TS workspace version",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
setup = {
|
||||
vtsls = function(_, opts)
|
||||
Snacks.util.lsp.on({ name = "vtsls" }, function(buffer, client)
|
||||
client.commands["_typescript.moveToFileRefactoring"] = function(command, ctx)
|
||||
---@type string, string, lsp.Range
|
||||
local action, uri, range = unpack(command.arguments)
|
||||
|
||||
local function move(newf)
|
||||
client:request("workspace/executeCommand", {
|
||||
command = command.command,
|
||||
arguments = { action, uri, range, newf },
|
||||
})
|
||||
end
|
||||
|
||||
local fname = vim.uri_to_fname(uri)
|
||||
client:request("workspace/executeCommand", {
|
||||
command = "typescript.tsserverRequest",
|
||||
arguments = {
|
||||
"getMoveToRefactoringFileSuggestions",
|
||||
{
|
||||
file = fname,
|
||||
startLine = range.start.line + 1,
|
||||
startOffset = range.start.character + 1,
|
||||
endLine = range["end"].line + 1,
|
||||
endOffset = range["end"].character + 1,
|
||||
},
|
||||
},
|
||||
}, function(_, result)
|
||||
---@type string[]
|
||||
local files = result.body.files
|
||||
table.insert(files, 1, "Enter new path...")
|
||||
vim.ui.select(files, {
|
||||
prompt = "Select move destination:",
|
||||
format_item = function(f)
|
||||
return vim.fn.fnamemodify(f, ":~:.")
|
||||
end,
|
||||
}, function(f)
|
||||
if f and f:find("^Enter new path") then
|
||||
vim.ui.input({
|
||||
prompt = "Enter move destination:",
|
||||
default = vim.fn.fnamemodify(fname, ":h") .. "/",
|
||||
completion = "file",
|
||||
}, function(newf)
|
||||
return newf and move(newf)
|
||||
end)
|
||||
elseif f then
|
||||
move(f)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
-- copy typescript settings to javascript
|
||||
opts.settings.javascript =
|
||||
vim.tbl_deep_extend("force", {}, opts.settings.typescript, opts.settings.javascript or {})
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
-- correctly setup lspconfig
|
||||
{
|
||||
"neovim/nvim-lspconfig",
|
||||
opts = {},
|
||||
},
|
||||
}
|
||||
|
|
@ -115,6 +115,13 @@ function M.get_extra(source, modname)
|
|||
recommended = M.wants(recommended)
|
||||
end
|
||||
|
||||
-- language extras that are disabled because a conflict with another extra is enabled are not recommended
|
||||
local defaults = LazyVim.config.get_defaults()
|
||||
local def = defaults[modname]
|
||||
if def and def.enabled == false and vim.startswith(modname, "lazyvim.plugins.extras.lang.") then
|
||||
recommended = false
|
||||
end
|
||||
|
||||
---@type LazyExtra
|
||||
return {
|
||||
source = source,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue