diff options
| author | Carnavale <adran.carnavale@gmail.com> | 2025-04-21 13:13:47 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-21 09:13:47 -0700 |
| commit | 6fa2b3b9628a759868f5e6d3eda96357deb43f2d (patch) | |
| tree | b50f0b53ae7346cce090ae18eebe79d68da77a67 | |
| parent | docs: update configs.md (diff) | |
| download | nvim-lspconfig-6fa2b3b9628a759868f5e6d3eda96357deb43f2d.tar nvim-lspconfig-6fa2b3b9628a759868f5e6d3eda96357deb43f2d.tar.gz nvim-lspconfig-6fa2b3b9628a759868f5e6d3eda96357deb43f2d.tar.bz2 nvim-lspconfig-6fa2b3b9628a759868f5e6d3eda96357deb43f2d.tar.lz nvim-lspconfig-6fa2b3b9628a759868f5e6d3eda96357deb43f2d.tar.xz nvim-lspconfig-6fa2b3b9628a759868f5e6d3eda96357deb43f2d.tar.zst nvim-lspconfig-6fa2b3b9628a759868f5e6d3eda96357deb43f2d.zip | |
feat(eslint): add vim.lsp.config support #3731
| -rw-r--r-- | lsp/eslint.lua | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/lsp/eslint.lua b/lsp/eslint.lua new file mode 100644 index 00000000..01d324f9 --- /dev/null +++ b/lsp/eslint.lua @@ -0,0 +1,182 @@ +--- @brief +--- +--- https://github.com/hrsh7th/vscode-langservers-extracted +--- +--- `vscode-eslint-language-server` is a linting engine for JavaScript / Typescript. +--- It can be installed via `npm`: +--- +--- ```sh +--- npm i -g vscode-langservers-extracted +--- ``` +--- +--- `vscode-eslint-language-server` provides an `EslintFixAll` command that can be used to format a document on save: +--- ```lua +--- vim.lsp.config('eslint', { +--- --- ... +--- on_attach = function(client, bufnr) +--- vim.api.nvim_create_autocmd("BufWritePre", { +--- buffer = bufnr, +--- command = "EslintFixAll", +--- }) +--- end, +--- }) +--- ``` +--- +--- See [vscode-eslint](https://github.com/microsoft/vscode-eslint/blob/55871979d7af184bf09af491b6ea35ebd56822cf/server/src/eslintServer.ts#L216-L229) for configuration options. +--- +--- Messages handled in lspconfig: `eslint/openDoc`, `eslint/confirmESLintExecution`, `eslint/probeFailed`, `eslint/noLibrary` +--- +--- Additional messages you can handle: `eslint/noConfig` + +local util = require 'lspconfig.util' +local lsp = vim.lsp + +return { + cmd = { 'vscode-eslint-language-server', '--stdio' }, + filetypes = { + 'javascript', + 'javascriptreact', + 'javascript.jsx', + 'typescript', + 'typescriptreact', + 'typescript.tsx', + 'vue', + 'svelte', + 'astro', + }, + on_init = function(client) + vim.api.nvim_create_user_command('LspEslintFixAll', function() + local bufnr = vim.api.nvim_get_current_buf() + + client:exec_cmd({ + title = 'Fix all Eslint errors for current buffer', + command = 'eslint.applyAllFixes', + arguments = { + { + uri = vim.uri_from_bufnr(bufnr), + version = lsp.util.buf_versions[bufnr], + }, + }, + }, { bufnr = bufnr }) + end, {}) + end, + -- https://eslint.org/docs/user-guide/configuring/configuration-files#configuration-file-formats + root_dir = function(bufnr, on_dir) + local root_file_patterns = { + '.eslintrc', + '.eslintrc.js', + '.eslintrc.cjs', + '.eslintrc.yaml', + '.eslintrc.yml', + '.eslintrc.json', + 'eslint.config.js', + 'eslint.config.mjs', + 'eslint.config.cjs', + 'eslint.config.ts', + 'eslint.config.mts', + 'eslint.config.cts', + } + + local fname = vim.api.nvim_buf_get_name(bufnr) + root_file_patterns = util.insert_package_json(root_file_patterns, 'eslintConfig', fname) + local root_dir = vim.fs.dirname(vim.fs.find(root_file_patterns, { path = fname, upward = true })[1]) + on_dir(root_dir) + end, + -- Refer to https://github.com/Microsoft/vscode-eslint#settings-options for documentation. + settings = { + validate = 'on', + packageManager = nil, + useESLintClass = false, + experimental = { + useFlatConfig = false, + }, + codeActionOnSave = { + enable = false, + mode = 'all', + }, + format = true, + quiet = false, + onIgnoredFiles = 'off', + rulesCustomizations = {}, + run = 'onType', + problems = { + shortenToSingleLine = false, + }, + -- nodePath configures the directory in which the eslint server should start its node_modules resolution. + -- This path is relative to the workspace folder (root dir) of the server instance. + nodePath = '', + -- use the workspace folder location or the file location (if no workspace folder is open) as the working directory + workingDirectory = { mode = 'location' }, + codeAction = { + disableRuleComment = { + enable = true, + location = 'separateLine', + }, + showDocumentation = { + enable = true, + }, + }, + }, + before_init = function(_, config) + -- The "workspaceFolder" is a VSCode concept. It limits how far the + -- server will traverse the file system when locating the ESLint config + -- file (e.g., .eslintrc). + local root_dir = config.root_dir + + if root_dir then + config.settings = config.settings or {} + config.settings.workspaceFolder = { + uri = root_dir, + name = vim.fn.fnamemodify(root_dir, ':t'), + } + + -- Support flat config + local flat_config_files = { + 'eslint.config.js', + 'eslint.config.mjs', + 'eslint.config.cjs', + 'eslint.config.ts', + 'eslint.config.mts', + 'eslint.config.cts', + } + + for _, file in ipairs(flat_config_files) do + if vim.fn.filereadable(root_dir .. '/' .. file) == 1 then + config.settings.experimental = config.settings.experimental or {} + config.settings.experimental.useFlatConfig = true + break + end + end + + -- Support Yarn2 (PnP) projects + local pnp_cjs = root_dir .. '/.pnp.cjs' + local pnp_js = root_dir .. '/.pnp.js' + if vim.uv.fs_stat(pnp_cjs) or vim.uv.fs_stat(pnp_js) then + local cmd = config.cmd + config.cmd = vim.list_extend({ 'yarn', 'exec' }, cmd) + end + end + end, + handlers = { + ['eslint/openDoc'] = function(_, result) + if result then + vim.ui.open(result.url) + end + return {} + end, + ['eslint/confirmESLintExecution'] = function(_, result) + if not result then + return + end + return 4 -- approved + end, + ['eslint/probeFailed'] = function() + vim.notify('[lspconfig] ESLint probe failed.', vim.log.levels.WARN) + return {} + end, + ['eslint/noLibrary'] = function() + vim.notify('[lspconfig] Unable to find ESLint library.', vim.log.levels.WARN) + return {} + end, + }, +} |
