feat: lazy, mason, ts

This commit is contained in:
Tomas Mirchev 2025-10-23 05:08:38 +03:00
parent 08c5a0536e
commit bb12a11cc0
9 changed files with 587 additions and 90 deletions

View File

@ -1,8 +1,7 @@
{ {
"conform.nvim": { "branch": "master", "commit": "235dd79731c1dc51ec04abb4045cbc54727a172a" }, "conform.nvim": { "branch": "master", "commit": "9fd3d5e0b689ec1bf400c53cbbec72c6fdf24081" },
"invero.nvim": { "branch": "main", "commit": "6acdefa2f2fdf544b53b5786e748be0ae8e9fd23" }, "invero.nvim": { "branch": "main", "commit": "6acdefa2f2fdf544b53b5786e748be0ae8e9fd23" },
"lazy.nvim": { "branch": "main", "commit": "1ea3c4085785f460fb0e46d2fe1ee895f5f9e7c1" }, "lazy.nvim": { "branch": "main", "commit": "1ea3c4085785f460fb0e46d2fe1ee895f5f9e7c1" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "2304ff65ecc8cb2afc2484de3e2ed9a407edf0b9" },
"mason.nvim": { "branch": "main", "commit": "ad7146aa61dcaeb54fa900144d768f040090bff0" }, "mason.nvim": { "branch": "main", "commit": "ad7146aa61dcaeb54fa900144d768f040090bff0" },
"nvim-autopairs": { "branch": "master", "commit": "7a2c97cccd60abc559344042fefb1d5a85b3e33b" }, "nvim-autopairs": { "branch": "master", "commit": "7a2c97cccd60abc559344042fefb1d5a85b3e33b" },
"nvim-lint": { "branch": "master", "commit": "9da1fb942dd0668d5182f9c8dee801b9c190e2bb" }, "nvim-lint": { "branch": "master", "commit": "9da1fb942dd0668d5182f9c8dee801b9c190e2bb" },

29
lsp/bashls.lua Normal file
View File

@ -0,0 +1,29 @@
---@brief
---
--- https://github.com/bash-lsp/bash-language-server
---
--- `bash-language-server` can be installed via `npm`:
--- ```sh
--- npm i -g bash-language-server
--- ```
---
--- Language server for bash, written using tree sitter in typescript.
---@type vim.lsp.Config
return {
cmd = { 'bash-language-server', 'start' },
settings = {
bashIde = {
-- Glob pattern for finding and parsing shell script files in the workspace.
-- Used by the background analysis features across files.
-- Prevent recursive scanning which will cause issues when opening a file
-- directly in the home directory (e.g. ~/foo.sh).
--
-- Default upstream pattern is "**/*@(.sh|.inc|.bash|.command)".
globPattern = vim.env.GLOB_PATTERN or '*@(.sh|.inc|.bash|.command)',
},
},
filetypes = { 'bash', 'sh' },
root_markers = { '.git' },
}

100
lsp/clangd.lua Normal file
View File

@ -0,0 +1,100 @@
---@brief
---
--- https://clangd.llvm.org/installation.html
---
--- - **NOTE:** Clang >= 11 is recommended! See [#23](https://github.com/neovim/nvim-lspconfig/issues/23).
--- - If `compile_commands.json` lives in a build directory, you should
--- symlink it to the root of your source tree.
--- ```
--- ln -s /path/to/myproject/build/compile_commands.json /path/to/myproject/
--- ```
--- - clangd relies on a [JSON compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
--- specified as compile_commands.json, see https://clangd.llvm.org/installation#compile_commandsjson
-- https://clangd.llvm.org/extensions.html#switch-between-sourceheader
local function switch_source_header(bufnr, client)
local method_name = 'textDocument/switchSourceHeader'
---@diagnostic disable-next-line:param-type-mismatch
if not client or not client:supports_method(method_name) then
return vim.notify(('method %s is not supported by any servers active on the current buffer'):format(method_name))
end
local params = vim.lsp.util.make_text_document_params(bufnr)
---@diagnostic disable-next-line:param-type-mismatch
client:request(method_name, params, function(err, result)
if err then
error(tostring(err))
end
if not result then
vim.notify('corresponding file cannot be determined')
return
end
vim.cmd.edit(vim.uri_to_fname(result))
end, bufnr)
end
local function symbol_info(bufnr, client)
local method_name = 'textDocument/symbolInfo'
---@diagnostic disable-next-line:param-type-mismatch
if not client or not client:supports_method(method_name) then
return vim.notify('Clangd client not found', vim.log.levels.ERROR)
end
local win = vim.api.nvim_get_current_win()
local params = vim.lsp.util.make_position_params(win, client.offset_encoding)
---@diagnostic disable-next-line:param-type-mismatch
client:request(method_name, params, function(err, res)
if err or #res == 0 then
-- Clangd always returns an error, there is no reason to parse it
return
end
local container = string.format('container: %s', res[1].containerName) ---@type string
local name = string.format('name: %s', res[1].name) ---@type string
vim.lsp.util.open_floating_preview({ name, container }, '', {
height = 2,
width = math.max(string.len(name), string.len(container)),
focusable = false,
focus = false,
title = 'Symbol Info',
})
end, bufnr)
end
---@class ClangdInitializeResult: lsp.InitializeResult
---@field offsetEncoding? string
---@type vim.lsp.Config
return {
cmd = { 'clangd' },
filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' },
root_markers = {
'.clangd',
'.clang-tidy',
'.clang-format',
'compile_commands.json',
'compile_flags.txt',
'configure.ac', -- AutoTools
'.git',
},
capabilities = {
textDocument = {
completion = {
editsNearCursor = true,
},
},
offsetEncoding = { 'utf-8', 'utf-16' },
},
---@param init_result ClangdInitializeResult
on_init = function(client, init_result)
if init_result.offsetEncoding then
client.offset_encoding = init_result.offsetEncoding
end
end,
on_attach = function(client, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, 'LspClangdSwitchSourceHeader', function()
switch_source_header(bufnr, client)
end, { desc = 'Switch between source/header' })
vim.api.nvim_buf_create_user_command(bufnr, 'LspClangdShowSymbolInfo', function()
symbol_info(bufnr, client)
end, { desc = 'Show symbol info' })
end,
}

85
lsp/lua_ls.lua Normal file
View File

@ -0,0 +1,85 @@
---@brief
---
--- https://github.com/luals/lua-language-server
---
--- Lua language server.
---
--- `lua-language-server` can be installed by following the instructions [here](https://luals.github.io/#neovim-install).
---
--- The default `cmd` assumes that the `lua-language-server` binary can be found in `$PATH`.
---
--- If you primarily use `lua-language-server` for Neovim, and want to provide completions,
--- analysis, and location handling for plugins on runtime path, you can use the following
--- settings.
---
--- ```lua
--- vim.lsp.config('lua_ls', {
--- on_init = function(client)
--- if client.workspace_folders then
--- local path = client.workspace_folders[1].name
--- if
--- path ~= vim.fn.stdpath('config')
--- and (vim.uv.fs_stat(path .. '/.luarc.json') or vim.uv.fs_stat(path .. '/.luarc.jsonc'))
--- then
--- return
--- end
--- end
---
--- client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, {
--- runtime = {
--- -- Tell the language server which version of Lua you're using (most
--- -- likely LuaJIT in the case of Neovim)
--- version = 'LuaJIT',
--- -- Tell the language server how to find Lua modules same way as Neovim
--- -- (see `:h lua-module-load`)
--- path = {
--- 'lua/?.lua',
--- 'lua/?/init.lua',
--- },
--- },
--- -- Make the server aware of Neovim runtime files
--- workspace = {
--- checkThirdParty = false,
--- library = {
--- vim.env.VIMRUNTIME
--- -- Depending on the usage, you might want to add additional paths
--- -- here.
--- -- '${3rd}/luv/library'
--- -- '${3rd}/busted/library'
--- }
--- -- Or pull in all of 'runtimepath'.
--- -- NOTE: this is a lot slower and will cause issues when working on
--- -- your own configuration.
--- -- See https://github.com/neovim/nvim-lspconfig/issues/3189
--- -- library = {
--- -- vim.api.nvim_get_runtime_file('', true),
--- -- }
--- }
--- })
--- end,
--- settings = {
--- Lua = {}
--- }
--- })
--- ```
---
--- See `lua-language-server`'s [documentation](https://luals.github.io/wiki/settings/) for an explanation of the above fields:
--- * [Lua.runtime.path](https://luals.github.io/wiki/settings/#runtimepath)
--- * [Lua.workspace.library](https://luals.github.io/wiki/settings/#workspacelibrary)
---
---@type vim.lsp.Config
return {
cmd = { 'lua-language-server' },
filetypes = { 'lua' },
root_markers = {
'.luarc.json',
'.luarc.jsonc',
'.luacheckrc',
'.stylua.toml',
'stylua.toml',
'selene.toml',
'selene.yml',
'.git',
},
}

View File

@ -1,14 +0,0 @@
return {
cmd = { "lua-language-server" },
filetypes = { "lua" },
root_markers = {
".luarc.json",
".luarc.jsonc",
".luacheckrc",
".stylua.toml",
"stylua.toml",
"selene.toml",
"selene.yml",
".git",
},
}

65
lsp/pyright.lua Normal file
View File

@ -0,0 +1,65 @@
---@brief
---
--- https://github.com/microsoft/pyright
---
--- `pyright`, a static type checker and language server for python
local function set_python_path(command)
local path = command.args
local clients = vim.lsp.get_clients {
bufnr = vim.api.nvim_get_current_buf(),
name = 'pyright',
}
for _, client in ipairs(clients) do
if client.settings then
client.settings.python = vim.tbl_deep_extend('force', client.settings.python, { pythonPath = path })
else
client.config.settings = vim.tbl_deep_extend('force', client.config.settings, { python = { pythonPath = path } })
end
client:notify('workspace/didChangeConfiguration', { settings = nil })
end
end
---@type vim.lsp.Config
return {
cmd = { 'pyright-langserver', '--stdio' },
filetypes = { 'python' },
root_markers = {
'pyproject.toml',
'setup.py',
'setup.cfg',
'requirements.txt',
'Pipfile',
'pyrightconfig.json',
'.git',
},
settings = {
python = {
analysis = {
autoSearchPaths = true,
useLibraryCodeForTypes = true,
diagnosticMode = 'openFilesOnly',
},
},
},
on_attach = function(client, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightOrganizeImports', function()
local params = {
command = 'pyright.organizeimports',
arguments = { vim.uri_from_bufnr(bufnr) },
}
-- Using client.request() directly because "pyright.organizeimports" is private
-- (not advertised via capabilities), which client:exec_cmd() refuses to call.
-- https://github.com/neovim/neovim/blob/c333d64663d3b6e0dd9aa440e433d346af4a3d81/runtime/lua/vim/lsp/client.lua#L1024-L1030
client.request('workspace/executeCommand', params, nil, bufnr)
end, {
desc = 'Organize Imports',
})
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightSetPythonPath', set_python_path, {
desc = 'Reconfigure pyright with the provided python path',
nargs = 1,
complete = 'file',
})
end,
}

19
lsp/sqls.lua Normal file
View File

@ -0,0 +1,19 @@
---@brief
---
--- https://github.com/sqls-server/sqls
---
--- ```lua
--- vim.lsp.config('sqls', {
--- cmd = {"path/to/command", "-config", "path/to/config.yml"};
--- ...
--- })
--- ```
--- Sqls can be installed via `go install github.com/sqls-server/sqls@latest`. Instructions for compiling Sqls from the source can be found at [sqls-server/sqls](https://github.com/sqls-server/sqls).
---@type vim.lsp.Config
return {
cmd = { 'sqls' },
filetypes = { 'sql', 'mysql' },
root_markers = { 'config.yml' },
settings = {},
}

96
lsp/vtsls.lua Normal file
View File

@ -0,0 +1,96 @@
---@brief
---
--- https://github.com/yioneko/vtsls
---
--- `vtsls` can be installed with npm:
--- ```sh
--- npm install -g @vtsls/language-server
--- ```
---
--- To configure a TypeScript project, add a
--- [`tsconfig.json`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html)
--- or [`jsconfig.json`](https://code.visualstudio.com/docs/languages/jsconfig) to
--- the root of your project.
---
--- ### Vue support
---
--- Since v3.0.0, the Vue language server requires `vtsls` to support TypeScript.
---
--- ```
--- -- If you are using mason.nvim, you can get the ts_plugin_path like this
--- -- For Mason v1,
--- -- local mason_registry = require('mason-registry')
--- -- local vue_language_server_path = mason_registry.get_package('vue-language-server'):get_install_path() .. '/node_modules/@vue/language-server'
--- -- For Mason v2,
--- -- local vue_language_server_path = vim.fn.expand '$MASON/packages' .. '/vue-language-server' .. '/node_modules/@vue/language-server'
--- -- or even
--- -- local vue_language_server_path = vim.fn.stdpath('data') .. "/mason/packages/vue-language-server/node_modules/@vue/language-server"
--- local vue_language_server_path = '/path/to/@vue/language-server'
--- local vue_plugin = {
--- name = '@vue/typescript-plugin',
--- location = vue_language_server_path,
--- languages = { 'vue' },
--- configNamespace = 'typescript',
--- }
--- vim.lsp.config('vtsls', {
--- settings = {
--- vtsls = {
--- tsserver = {
--- globalPlugins = {
--- vue_plugin,
--- },
--- },
--- },
--- },
--- filetypes = { 'typescript', 'javascript', 'javascriptreact', 'typescriptreact', 'vue' },
--- })
--- ```
---
--- - `location` MUST be defined. If the plugin is installed in `node_modules`, `location` can have any value.
--- - `languages` must include vue even if it is listed in filetypes.
--- - `filetypes` is extended here to include Vue SFC.
---
--- You must make sure the Vue language server is setup. For example,
---
--- ```
--- vim.lsp.enable('vue_ls')
--- ```
---
--- See `vue_ls` section and https://github.com/vuejs/language-tools/wiki/Neovim for more information.
---
--- ### Monorepo support
---
--- `vtsls` supports monorepos by default. It will automatically find the `tsconfig.json` or `jsconfig.json` corresponding to the package you are working on.
--- This works without the need of spawning multiple instances of `vtsls`, saving memory.
---
--- It is recommended to use the same version of TypeScript in all packages, and therefore have it available in your workspace root. The location of the TypeScript binary will be determined automatically, but only once.
---@type vim.lsp.Config
return {
cmd = { 'vtsls', '--stdio' },
init_options = {
hostInfo = 'neovim',
},
filetypes = {
'javascript',
'javascriptreact',
'javascript.jsx',
'typescript',
'typescriptreact',
'typescript.tsx',
},
root_dir = function(bufnr, on_dir)
-- The project root is where the LSP can be started from
-- As stated in the documentation above, this LSP supports monorepos and simple projects.
-- We select then from the project root, which is identified by the presence of a package
-- manager lock file.
local root_markers = { 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb', 'bun.lock' }
-- Give the root markers equal priority by wrapping them in a table
root_markers = vim.fn.has('nvim-0.11.3') == 1 and { root_markers, { '.git' } }
or vim.list_extend(root_markers, { '.git' })
-- We fallback to the current working directory if no project root is found
local project_root = vim.fs.root(bufnr, root_markers) or vim.fn.getcwd()
on_dir(project_root)
end,
}

View File

@ -1,7 +1,5 @@
-- <treesitter> or { <treesitter>, <lsp>, <linter>, <formatter>, filetype=<ft> } -- language_spec = { treesitter?, lsp?, linter?, formatter?, filetype? }
-- filetype defaults to <treesitter>. If different, specify it. local language_specs = {
-- any positional argument can be skipped with nil
local languages = {
-- Docs / Config -- Docs / Config
'vim', 'vim',
'vimdoc', 'vimdoc',
@ -15,74 +13,212 @@ local languages = {
'gitignore', 'gitignore',
'dockerfile', 'dockerfile',
'diff', 'diff',
{ 'json', 'jsonls', nil, 'prettier' }, { 'json', nil, nil, 'prettier' },
{ 'jsonc', 'jsonls', nil, 'prettier' }, { 'jsonc', nil, nil, 'prettier' },
-- Shell / Scripting -- Shell / scripting
{ 'bash', 'bashls', 'shellcheck', 'shfmt' }, { 'bash', 'bash-language-server', 'shellcheck', 'shfmt' },
{ 'lua', 'luals', 'luacheck', 'stylua' }, { 'lua', 'lua-language-server', 'luacheck', 'stylua' },
{ 'sql', 'sqlls', nil, 'sqlfluff' }, 'sql',
-- Programming -- Programming
{ 'c', 'clangd', nil, 'clang-format' }, 'c',
{ 'cpp', 'clangd', nil, 'clang-format' }, 'cpp',
{ 'go', 'gopls', 'golangci-lint', 'gofmt' }, 'go',
{ 'rust', 'rust_analyzer', 'clippy', 'rustfmt' }, 'rust',
{ 'python', 'pyright', 'ruff', 'black' }, 'python',
-- { 'python', 'pyright', 'ruff', 'ruff' }, -- install ensurepip
-- Web stack -- Web stack
{ 'html', 'html', nil, 'prettier' }, { 'html', nil, nil, 'prettier' },
{ 'css', 'cssls', 'stylelint', 'prettier' }, { 'css', nil, nil, 'prettier' },
{ 'javascript', 'tsls', 'eslint', 'prettier' }, { 'javascript', 'vtsls', 'eslint_d', 'prettier' },
{ 'typescript', 'tsls', 'eslint', 'prettier' }, { 'typescript', 'vtsls', 'eslint_d', 'prettier' },
{ nil, 'tsls', 'eslint', 'prettier', filetype = 'javascriptreact' }, { nil, 'vtsls', 'eslint_d', 'prettier', filetype = 'javascriptreact' },
{ 'tsx', 'tsls', 'eslint', 'prettier', filetype = 'typescriptreact' }, { 'tsx', 'vtsls', 'eslint_d', 'prettier', filetype = 'typescriptreact' },
} }
local function normalize(lang) local function normalize(spec)
if type(lang) == 'string' then if type(spec) == 'string' then
lang = { lang } spec = { spec }
end end
local t = { return {
treesitter = lang[1], treesitter = spec[1],
lsp = lang[2], lsp = spec[2],
linter = lang[3], linter = spec[3],
formatter = lang[4], formatter = spec[4],
filetype = lang.filetype or lang[1], filetype = spec.filetype or spec[1],
} }
return t
end end
local normalized = vim.tbl_map(normalize, languages) local normalized = vim.tbl_map(normalize, language_specs)
local general = {
ts_parsers = {}, local function uniq(tbl)
lsps = {}, local seen, out = {}, {}
linters_by_ft = {}, for _, v in ipairs(tbl) do
formatters_by_ft = {}, if v and not seen[v] then
seen[v] = true
table.insert(out, v)
end
end
return out
end
local function collect(specs)
local ts, lsps, linters, formatters = {}, {}, {}, {}
for _, s in ipairs(specs) do
if s.treesitter then
table.insert(ts, s.treesitter)
end
if s.lsp then
table.insert(lsps, s.lsp)
end
if s.linter then
linters[s.filetype] = { s.linter }
end
if s.formatter then
formatters[s.filetype] = { s.formatter }
end
end
return {
ts_parsers = uniq(ts),
lsps = uniq(lsps),
linters_by_ft = linters,
formatters_by_ft = formatters,
} }
for _, opts in ipairs(normalized) do
if opts.treesitter then
table.insert(general.ts_parsers, opts.treesitter)
end end
if opts.lsp then local general = collect(normalized)
table.insert(general.lsps, opts.lsp)
end
if opts.linter then ---------------------------------------------------------------------
general.linters_by_ft[opts.filetype] = { opts.linter } -- Mason Install Command
end ---------------------------------------------------------------------
vim.api.nvim_create_user_command('MasonInstallAll', function()
local registry = require('mason-registry')
local list = vim.list_extend(vim.list_extend({}, general.lsps), {})
if opts.formatter then for _, ftmap in pairs({ general.linters_by_ft, general.formatters_by_ft }) do
general.formatters_by_ft[opts.filetype] = { opts.formatter } for _, tools in pairs(ftmap) do
vim.list_extend(list, tools)
end end
end end
list = uniq(list)
local installed = {}
for _, pkg in ipairs(registry.get_installed_packages()) do
installed[pkg.name] = true
end
for _, name in ipairs(list) do
if registry.has_package(name) then
if not installed[name] then
vim.notify('Installing ' .. name, vim.log.levels.INFO)
registry.get_package(name):install()
else
vim.notify('Already installed ' .. name, vim.log.levels.INFO)
end
else
vim.notify('Package not found in registry: ' .. name, vim.log.levels.WARN)
end
end
end, { desc = 'Install all Mason LSPs, linters, and formatters' })
---------------------------------------------------------------------
-- Fetch LSP default configs from nvim-lspconfig
---------------------------------------------------------------------
vim.api.nvim_create_user_command('FetchLspConfigs', function()
local registry = require('mason-registry')
local lspconfig_names = {}
for _, lsp in ipairs(general.lsps) do
if registry.has_package(lsp) then
local pkg = registry.get_package(lsp)
local spec = pkg.spec and pkg.spec.neovim
if spec and spec.lspconfig then
table.insert(lspconfig_names, spec.lspconfig)
else
table.insert(lspconfig_names, lsp)
end
else
table.insert(lspconfig_names, lsp)
end
end
lspconfig_names = uniq(lspconfig_names)
-- base URL same as your original
local base_url = 'https://raw.githubusercontent.com/neovim/nvim-lspconfig/master/lsp/'
-- write to current working directory
local lsp_dir = vim.fs.joinpath(vim.fn.getcwd(), 'lsp')
vim.fn.mkdir(lsp_dir, 'p')
for _, name in ipairs(lspconfig_names) do
local file = vim.fs.joinpath(lsp_dir, name .. '.lua')
if vim.fn.filereadable(file) == 0 then
local url = base_url .. name .. '.lua'
local cmd = string.format('curl -fsSL -o %q %q', file, url)
vim.fn.system(cmd)
if vim.v.shell_error ~= 0 then
vim.notify('Failed to fetch ' .. name .. '.lua', vim.log.levels.ERROR)
vim.fn.delete(file)
else
vim.notify('Fetched ' .. name .. '.lua', vim.log.levels.INFO)
end
else
vim.notify('Skipped existing ' .. name .. '.lua', vim.log.levels.INFO)
end
end
end, { desc = 'Fetch default LSP configs into ./lsp in cwd' })
vim.api.nvim_create_user_command('TreesitterInstallAll', function()
local parsers = require('nvim-treesitter.parsers')
local configs = require('nvim-treesitter.configs')
local langs = configs.get_module('ensure_installed') or {}
if type(langs) == 'string' and langs == 'all' then
vim.notify('Treesitter ensure_installed = "all" not supported here', vim.log.levels.WARN)
return
end
for _, lang in ipairs(langs) do
if not parsers.has_parser(lang) then
vim.cmd('TSInstall ' .. lang)
else
vim.notify('Parser already installed: ' .. lang, vim.log.levels.INFO)
end
end
end, { desc = 'Install all Treesitter parsers defined in ensure_installed' })
---------------------------------------------------------------------
-- Plugins
---------------------------------------------------------------------
return { return {
{ 'windwp/nvim-ts-autotag', config = true }, { 'windwp/nvim-ts-autotag', config = true },
{ 'windwp/nvim-autopairs', event = 'InsertEnter', config = true }, { 'windwp/nvim-autopairs', event = 'InsertEnter', config = true },
{ 'mason-org/mason.nvim', config = true }, {
-- { 'saghen/blink.cmp', version = '1.*' }, 'mason-org/mason.nvim',
config = function()
local mason = require('mason')
local registry = require('mason-registry')
mason.setup()
local lsp_configs = {}
for _, lsp in ipairs(general.lsps) do
if registry.has_package(lsp) then
local pkg = registry.get_package(lsp)
local spec = pkg.spec and pkg.spec.neovim
local lsp_name = (spec and spec.lspconfig) or lsp
table.insert(lsp_configs, lsp_name)
-- Native enable call (Neovim ≥ 0.11)
vim.lsp.enable(lsp_name)
else
vim.notify('Unknown LSP: ' .. lsp, vim.log.levels.WARN)
end
end
vim.notify('Enabled LSPs: ' .. table.concat(lsp_configs, ', '), vim.log.levels.INFO)
end,
},
{ {
'nvim-treesitter/nvim-treesitter', 'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate', build = ':TSUpdate',
@ -90,7 +226,6 @@ return {
opts = { opts = {
highlight = { enable = true }, highlight = { enable = true },
incremental_selection = { enable = true }, incremental_selection = { enable = true },
textobjects = { enable = true },
ensure_installed = general.ts_parsers, ensure_installed = general.ts_parsers,
}, },
}, },
@ -101,6 +236,7 @@ return {
config = function(_, opts) config = function(_, opts)
local lint = require('lint') local lint = require('lint')
lint.linters_by_ft = opts.linters_by_ft lint.linters_by_ft = opts.linters_by_ft
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, {
group = vim.api.nvim_create_augroup('lint_autocmd', { clear = true }), group = vim.api.nvim_create_augroup('lint_autocmd', { clear = true }),
callback = function() callback = function()
@ -113,27 +249,9 @@ return {
'stevearc/conform.nvim', 'stevearc/conform.nvim',
event = { 'BufWritePre' }, event = { 'BufWritePre' },
opts = { opts = {
-- Automatically format on save format_on_save = { timeout_ms = 500, lsp_format = 'fallback' },
format_on_save = {
timeout_ms = 500,
lsp_format = 'fallback', -- Use LSP when no formatter is configured
},
-- Formatters per filetype
default_format_opts = { stop_after_first = true }, default_format_opts = { stop_after_first = true },
formatters_by_ft = general.formatters_by_ft, formatters_by_ft = general.formatters_by_ft,
}, },
config = function(_, opts)
require('conform').setup(opts)
-- Create a command to format manually
vim.api.nvim_create_user_command('Format', function()
require('conform').format({
async = true,
lsp_format = 'fallback',
})
end, { desc = 'Format current buffer' })
end,
}, },
} }