summaryrefslogtreecommitdiff
path: root/.config/nvim/lua/lsp/null-ls.lua
diff options
context:
space:
mode:
authorGustaf Rydholm <gustaf.rydholm@gmail.com>2021-08-10 23:15:04 +0200
committerGustaf Rydholm <gustaf.rydholm@gmail.com>2021-08-10 23:15:04 +0200
commit540268d618627079c9b958a955b586e1888b46a8 (patch)
tree1a22a5feb457135178b9d4fe8b6c1755f5ca66bc /.config/nvim/lua/lsp/null-ls.lua
parente79bd3273f58ba38e8fcd716090b89326791afbb (diff)
Major refactor of nvim
Diffstat (limited to '.config/nvim/lua/lsp/null-ls.lua')
-rw-r--r--.config/nvim/lua/lsp/null-ls.lua141
1 files changed, 141 insertions, 0 deletions
diff --git a/.config/nvim/lua/lsp/null-ls.lua b/.config/nvim/lua/lsp/null-ls.lua
new file mode 100644
index 0000000..81c6648
--- /dev/null
+++ b/.config/nvim/lua/lsp/null-ls.lua
@@ -0,0 +1,141 @@
+local M = {}
+local Log = require "core.log"
+
+local null_ls = require "null-ls"
+
+local nodejs_local_providers = { "prettier", "prettierd", "prettier_d_slim", "eslint_d", "eslint" }
+
+M.requested_providers = {}
+
+function M.get_registered_providers_by_filetype(ft)
+ local matches = {}
+ for _, provider in pairs(M.requested_providers) do
+ if vim.tbl_contains(provider.filetypes, ft) then
+ local provider_name = provider.name
+ -- special case: show "eslint_d" instead of eslint
+ -- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/9b8458bd1648e84169a7e8638091ba15c2f20fc0/doc/BUILTINS.md#eslint
+ if string.find(provider._opts.command, "eslint_d") then
+ provider_name = "eslint_d"
+ end
+ table.insert(matches, provider_name)
+ end
+ end
+
+ return matches
+end
+
+function M.get_missing_providers_by_filetype(ft)
+ local matches = {}
+ for _, provider in pairs(M.requested_providers) do
+ if vim.tbl_contains(provider.filetypes, ft) then
+ local provider_name = provider.name
+
+ table.insert(matches, provider_name)
+ end
+ end
+
+ return matches
+end
+
+local function register_failed_request(ft, provider, operation)
+ if not options.lang[ft][operation]._failed_requests then
+ options.lang[ft][operation]._failed_requests = {}
+ end
+ table.insert(options.lang[ft][operation]._failed_requests, provider)
+end
+
+local function validate_nodejs_provider(provider)
+ local command_path
+ local root_dir
+ if options.builtin.rooter.active then
+ --- use vim-rooter to set root_dir
+ vim.cmd "let root_dir = FindRootDirectory()"
+ root_dir = vim.api.nvim_get_var "root_dir"
+ else
+ --- use LSP to set root_dir
+ local ts_client = require("utils").get_active_client_by_ft "typescript"
+ if ts_client == nil then
+ Log:get_default().error "Unable to determine root directory since tsserver didn't start correctly"
+ return
+ end
+ root_dir = ts_client.config.root_dir
+ end
+ local local_nodejs_command = root_dir .. "/node_modules/.bin/" .. provider._opts.command
+ Log:get_default().debug("checking for local node module: ", vim.inspect(provider))
+
+ if vim.fn.executable(local_nodejs_command) == 1 then
+ command_path = local_nodejs_command
+ elseif vim.fn.executable(provider._opts.command) == 1 then
+ Log:get_default().debug("checking in global path instead for node module", provider._opts.command)
+ command_path = provider._opts.command
+ else
+ Log:get_default().debug("Unable to find node module", provider._opts.command)
+ end
+ return command_path
+end
+
+local function validate_provider_request(provider)
+ if provider == "" or provider == nil then
+ return
+ end
+ -- NOTE: we can't use provider.name because eslint_d uses eslint name
+ if vim.tbl_contains(nodejs_local_providers, provider._opts.command) then
+ return validate_nodejs_provider(provider)
+ end
+ if vim.fn.executable(provider._opts.command) ~= 1 then
+ Log:get_default().warn("Unable to find the path for", vim.inspect(provider))
+ return
+ end
+ return provider._opts.command
+end
+
+-- TODO: for linters and formatters with spaces and '-' replace with '_'
+function M.setup(filetype)
+ for _, formatter in pairs(options.lang[filetype].formatters) do
+ Log:get_default().debug("validating format provider: ", formatter.exe)
+ local builtin_formatter = null_ls.builtins.formatting[formatter.exe]
+ if not vim.tbl_contains(M.requested_providers, builtin_formatter) then
+ -- FIXME: why doesn't this work?
+ -- builtin_formatter._opts.args = formatter.args or builtin_formatter._opts.args
+ -- builtin_formatter._opts.to_stdin = formatter.stdin or builtin_formatter._opts.to_stdin
+ local resolved_path = validate_provider_request(builtin_formatter)
+ if resolved_path then
+ builtin_formatter._opts.command = resolved_path
+ table.insert(M.requested_providers, builtin_formatter)
+ Log:get_default().info("Using format provider", builtin_formatter.name)
+ else
+ -- mark it here to avoid re-doing the lookup again
+ register_failed_request(filetype, formatter.exe, "formatters")
+ end
+ end
+ end
+
+ for _, linter in pairs(options.lang[filetype].linters) do
+ local builtin_diagnoser = null_ls.builtins.diagnostics[linter.exe]
+ Log:get_default().debug("validating lint provider: ", linter.exe)
+ -- special case: fallback to "eslint"
+ -- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/9b8458bd1648e84169a7e8638091ba15c2f20fc0/doc/BUILTINS.md#eslint
+ -- if provider.exe
+ if linter.exe == "eslint_d" then
+ builtin_diagnoser = null_ls.builtins.diagnostics.eslint.with { command = "eslint_d" }
+ end
+ if not vim.tbl_contains(M.requested_providers, builtin_diagnoser) then
+ -- FIXME: why doesn't this work?
+ -- builtin_diagnoser._opts.args = linter.args or builtin_diagnoser._opts.args
+ -- builtin_diagnoser._opts.to_stdin = linter.stdin or builtin_diagnoser._opts.to_stdin
+ local resolved_path = validate_provider_request(builtin_diagnoser)
+ if resolved_path then
+ builtin_diagnoser._opts.command = resolved_path
+ table.insert(M.requested_providers, builtin_diagnoser)
+ Log:get_default().info("Using linter provider", builtin_diagnoser.name)
+ else
+ -- mark it here to avoid re-doing the lookup again
+ register_failed_request(filetype, linter.exe, "linters")
+ end
+ end
+ end
+
+ null_ls.register { sources = M.requested_providers }
+end
+
+return M