1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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
|