|
2 | 2 | lib, |
3 | 3 | helpers, |
4 | 4 | config, |
| 5 | + options, |
5 | 6 | pkgs, |
6 | 7 | ... |
7 | 8 | }: |
8 | 9 | with lib; |
9 | | -let |
10 | | - cfg = config.plugins.none-ls; |
11 | | -in |
12 | | -{ |
13 | | - imports = [ |
14 | | - ./servers.nix |
15 | | - (mkRenamedOptionModule |
16 | | - [ |
17 | | - "plugins" |
| 10 | +helpers.neovim-plugin.mkNeovimPlugin config { |
| 11 | + name = "none-ls"; |
| 12 | + originalName = "none-ls.nvim"; |
| 13 | + luaName = "null-ls"; |
| 14 | + defaultPackage = pkgs.vimPlugins.none-ls-nvim; |
| 15 | + |
| 16 | + maintainers = [ maintainers.MattSturgeon ]; |
| 17 | + |
| 18 | + # TODO: introduced 2024-06-18, remove after 24.11 |
| 19 | + deprecateExtraOptions = true; |
| 20 | + optionsRenamedToSettings = [ |
| 21 | + "border" |
| 22 | + "cmd" |
| 23 | + "debounce" |
| 24 | + "debug" |
| 25 | + "defaultTimeout" |
| 26 | + "diagnosticConfig" |
| 27 | + "diagnosticsFormat" |
| 28 | + "fallbackSeverity" |
| 29 | + "logLevel" |
| 30 | + "notifyFormat" |
| 31 | + "onAttach" |
| 32 | + "onInit" |
| 33 | + "onExit" |
| 34 | + "rootDir" |
| 35 | + "shouldAttach" |
| 36 | + "tempDir" |
| 37 | + "updateInInsert" |
| 38 | + ]; |
| 39 | + |
| 40 | + imports = |
| 41 | + let |
| 42 | + namespace = "plugins"; |
| 43 | + oldPluginPath = [ |
| 44 | + namespace |
18 | 45 | "null-ls" |
19 | | - ] |
20 | | - [ |
21 | | - "plugins" |
| 46 | + ]; |
| 47 | + basePluginPath = [ |
| 48 | + namespace |
22 | 49 | "none-ls" |
23 | | - ] |
24 | | - ) |
25 | | - ]; |
| 50 | + ]; |
| 51 | + settingsPath = basePluginPath ++ [ "settings" ]; |
| 52 | + in |
| 53 | + [ |
| 54 | + ./servers.nix |
| 55 | + (mkRenamedOptionModule oldPluginPath basePluginPath) |
| 56 | + (mkRenamedOptionModule (basePluginPath ++ [ "sourcesItems" ]) (settingsPath ++ [ "sources" ])) |
| 57 | + ]; |
26 | 58 |
|
27 | | - options.plugins.none-ls = helpers.neovim-plugin.extraOptionsOptions // { |
28 | | - enable = mkEnableOption "none-ls"; |
| 59 | + # TODO: |
| 60 | + # settingsExample = { |
| 61 | + # }; |
29 | 62 |
|
30 | | - package = mkOption { |
31 | | - type = types.package; |
32 | | - default = pkgs.vimPlugins.none-ls-nvim; |
33 | | - description = "Plugin to use for none-ls"; |
34 | | - }; |
| 63 | + settingsOptions = import ./settings.nix { inherit helpers; }; |
35 | 64 |
|
| 65 | + extraOptions = { |
36 | 66 | enableLspFormat = mkOption { |
37 | 67 | type = types.bool; |
| 68 | + # TODO: consider default = false and enabling lsp-format automatically instead? |
38 | 69 | default = config.plugins.lsp-format.enable; |
| 70 | + defaultText = literalExpression "plugins.lsp-format.enable"; |
| 71 | + example = false; |
39 | 72 | description = '' |
40 | | - Automatically enable the `lsp-format` plugin and configure `none-ls` accordingly. |
| 73 | + Automatically configure `none-ls` to use the `lsp-format` plugin. |
| 74 | +
|
| 75 | + Enabled automatically when `plugins.lsp-format` is enabled. |
| 76 | + Set `false` to disable that behavior. |
41 | 77 | ''; |
42 | | - example = true; |
43 | 78 | }; |
44 | | - |
45 | | - border = helpers.defaultNullOpts.mkBorder null "`:NullLsInfo` UI window." '' |
46 | | - Uses `NullLsInfoBorder` highlight group (see [Highlight Groups](#highlight-groups)). |
47 | | - ''; |
48 | | - |
49 | | - cmd = helpers.defaultNullOpts.mkNullable (types.listOf types.str) ''["nvim"]'' '' |
50 | | - Defines the command used to start the null-ls server. If you do not have an |
51 | | - `nvim` binary available on your `$PATH`, you should change this to an absolute |
52 | | - path to the binary. |
53 | | - ''; |
54 | | - |
55 | | - debounce = helpers.defaultNullOpts.mkInt 250 '' |
56 | | - The `debounce` setting controls the amount of time between the last change to a buffer and the |
57 | | - next `textDocument/didChange` notification. |
58 | | - These notifications cause null-ls to generate diagnostics, so this setting indirectly controls |
59 | | - the rate of diagnostic generation (affected by `update_in_insert`, described below). |
60 | | -
|
61 | | - Lowering `debounce` will result in quicker diagnostic refreshes at the cost of running |
62 | | - diagnostic sources more frequently, which can affect performance. |
63 | | - The default value should be enough to provide near-instantaneous feedback from most sources |
64 | | - without unnecessary resource usage. |
65 | | - ''; |
66 | | - |
67 | | - debug = helpers.defaultNullOpts.mkBool false '' |
68 | | - Displays all possible log messages and writes them to the null-ls log, which you |
69 | | - can view with the command `:NullLsLog`. This option can slow down Neovim, so |
70 | | - it's strongly recommended to disable it for normal use. |
71 | | -
|
72 | | - `debug = true` is the same as setting `logLevel` to `"trace"`. |
73 | | - ''; |
74 | | - |
75 | | - defaultTimeout = helpers.defaultNullOpts.mkInt 5000 '' |
76 | | - Sets the amount of time (in milliseconds) after which built-in sources will time out. |
77 | | - Note that built-in sources can define their own timeout period and that users can override the |
78 | | - timeout period on a per-source basis, too (see [BUILTIN_CONFIG.md](BUILTIN_CONFIG.md)). |
79 | | -
|
80 | | - Specifying a timeout with a value less than zero will prevent commands from timing out. |
81 | | - ''; |
82 | | - |
83 | | - diagnosticConfig = helpers.defaultNullOpts.mkNullable types.attrs null '' |
84 | | - Specifies diagnostic display options for null-ls sources, as described in |
85 | | - `:help vim.diagnostic.config()`. |
86 | | - (null-ls uses separate namespaces for each source, so server-wide configuration will not work |
87 | | - as expected.) |
88 | | -
|
89 | | - You can also configure `diagnostic_config` per built-in by using the `with` method, described |
90 | | - in BUILTIN_CONFIG.md. |
91 | | - ''; |
92 | | - |
93 | | - diagnosticsFormat = helpers.defaultNullOpts.mkStr "#{m}" '' |
94 | | - Sets the default format used for diagnostics. The plugin will replace the following special |
95 | | - components with the relevant diagnostic information: |
96 | | -
|
97 | | - - `#{m}`: message |
98 | | - - `#{s}`: source name (defaults to `null-ls` if not specified) |
99 | | - - `#{c}`: code (if available) |
100 | | -
|
101 | | - For example, setting `diagnostics_format` to the following: |
102 | | -
|
103 | | - ```lua |
104 | | - diagnostics_format = "[#{c}] #{m} (#{s})" |
105 | | - ``` |
106 | | -
|
107 | | - Formats diagnostics as follows: |
108 | | -
|
109 | | - ```txt |
110 | | - [2148] Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive. (shellcheck) |
111 | | - ``` |
112 | | -
|
113 | | - You can also configure `diagnostics_format` per built-in by using the `with` |
114 | | - method, described in [BUILTIN_CONFIG](BUILTIN_CONFIG.md). |
115 | | - ''; |
116 | | - |
117 | | - fallbackSeverity = helpers.defaultNullOpts.mkSeverity "error" '' |
118 | | - Defines the severity used when a diagnostic source does not explicitly define a severity. |
119 | | - See `:help diagnostic-severity` for available values. |
120 | | - ''; |
121 | | - |
122 | | - logLevel = |
123 | | - helpers.defaultNullOpts.mkEnum |
124 | | - [ |
125 | | - "off" |
126 | | - "error" |
127 | | - "warn" |
128 | | - "info" |
129 | | - "debug" |
130 | | - "trace" |
131 | | - ] |
132 | | - "warn" |
133 | | - '' |
134 | | - Enables or disables logging to file. |
135 | | -
|
136 | | - Plugin logs messages on several logging levels to following destinations: |
137 | | -
|
138 | | - - file, can be inspected by `:NullLsLog`. |
139 | | - - neovim's notification area. |
140 | | - ''; |
141 | | - |
142 | | - notifyFormat = helpers.defaultNullOpts.mkStr "[null-ls] %s" '' |
143 | | - Sets the default format for `vim.notify()` messages. |
144 | | - Can be used to customize 3rd party notification plugins like |
145 | | - [nvim-notify](https://github.com/rcarriga/nvim-notify). |
146 | | - ''; |
147 | | - |
148 | | - onAttach = helpers.defaultNullOpts.mkStr null '' |
149 | | - Defines an `on_attach` callback to run whenever null-ls attaches to a buffer. |
150 | | - If you have a common `on_attach` you're using for LSP servers, you can reuse that here, use a |
151 | | - custom callback for null-ls, or leave this undefined. |
152 | | - ''; |
153 | | - |
154 | | - onInit = helpers.defaultNullOpts.mkLuaFn null '' |
155 | | - Defines an `on_init` callback to run when null-ls initializes. From here, you |
156 | | - can make changes to the client (the first argument) or `initialize_result` (the |
157 | | - second argument, which as of now is not used). |
158 | | - ''; |
159 | | - |
160 | | - onExit = helpers.defaultNullOpts.mkLuaFn null '' |
161 | | - Defines an `on_exit` callback to run when the null-ls client exits. |
162 | | - ''; |
163 | | - |
164 | | - rootDir = helpers.defaultNullOpts.mkLuaFn null '' |
165 | | - Determines the root of the null-ls server. On startup, null-ls will call |
166 | | - `root_dir` with the full path to the first file that null-ls attaches to. |
167 | | -
|
168 | | - ```lua |
169 | | - local root_dir = function(fname) |
170 | | - return fname:match("my-project") and "my-project-root" |
171 | | - end |
172 | | - ``` |
173 | | -
|
174 | | - If `root_dir` returns `nil`, the root will resolve to the current working |
175 | | - directory. |
176 | | - ''; |
177 | | - |
178 | | - shouldAttach = helpers.defaultNullOpts.mkLuaFn null '' |
179 | | - A user-defined function that controls whether to enable null-ls for a given |
180 | | - buffer. Receives `bufnr` as its first argument. |
181 | | -
|
182 | | - To cut down potentially expensive calls, null-ls will call `should_attach` after |
183 | | - its own internal checks pass, so it's not guaranteed to run on each new buffer. |
184 | | -
|
185 | | - ```lua |
186 | | - require("null-ls.nvim").setup({ |
187 | | - should_attach = function(bufnr) |
188 | | - return not vim.api.nvim_buf_get_name(bufnr):match("^git://") |
189 | | - end, |
190 | | - }) |
191 | | - ``` |
192 | | - ''; |
193 | | - |
194 | | - tempDir = helpers.defaultNullOpts.mkStr null '' |
195 | | - Defines the directory used to create temporary files for sources that rely on them (a |
196 | | - workaround used for command-based sources that do not support `stdio`). |
197 | | -
|
198 | | - To maximize compatibility, null-ls defaults to creating temp files in the same directory as |
199 | | - the parent file. |
200 | | - If this is causing issues, you can set it to `/tmp` (or another appropriate directory) here. |
201 | | - Otherwise, there is no need to change this setting. |
202 | | -
|
203 | | - **Note**: some null-ls built-in sources expect temp files to exist within a project for |
204 | | - context and so will not work if this option changes. |
205 | | -
|
206 | | - You can also configure `temp_dir` per built-in by using the `with` method, described in |
207 | | - BUILTIN_CONFIG.md. |
208 | | - ''; |
209 | | - |
210 | | - updateInInsert = helpers.defaultNullOpts.mkBool false '' |
211 | | - Controls whether diagnostic sources run in insert mode. |
212 | | - If set to `false`, diagnostic sources will run upon exiting insert mode, which greatly |
213 | | - improves performance but can create a slight delay before diagnostics show up. |
214 | | - Set this to `true` if you don't experience performance issues with your sources. |
215 | | -
|
216 | | - Note that by default, Neovim will not display updated diagnostics in insert mode. |
217 | | - Together with the option above, you need to pass `update_in_insert = true` to |
218 | | - `vim.diagnostic.config` for diagnostics to work as expected. |
219 | | - See `:help vim.diagnostic.config` for more info. |
220 | | - ''; |
221 | | - |
222 | | - sourcesItems = helpers.mkNullOrOption ( |
223 | | - with types; listOf (attrsOf str) |
224 | | - ) "The list of sources to enable, should be strings of lua code. Don't use this directly"; |
225 | 79 | }; |
226 | 80 |
|
227 | | - config = mkIf cfg.enable { |
228 | | - warnings = optional (cfg.enableLspFormat && (cfg.onAttach != null)) '' |
229 | | - You have enabled the lsp-format integration with none-ls. |
230 | | - However, you have provided a custom value to `plugins.none-ls.onAttach`. |
231 | | -
|
232 | | - -> The `enableLspFormat` option will thus not be able to add the `require('lsp-format').on_attach` snippet to `none-ls`. |
233 | | - ''; |
234 | | - |
235 | | - assertions = [ |
236 | | - { |
237 | | - assertion = cfg.enableLspFormat -> config.plugins.lsp-format.enable; |
238 | | - message = '' |
239 | | - Nixvim: You have enabled the `lsp-format` integration with none-ls. |
240 | | - However, you have not enabled the `lsp-format` plugin itself (`plugins.lsp-format.enable = true`). |
241 | | - ''; |
242 | | - } |
243 | | - ]; |
244 | | - |
245 | | - extraPlugins = [ cfg.package ]; |
246 | | - |
247 | | - extraConfigLua = |
248 | | - let |
249 | | - onAttach' = |
250 | | - if (cfg.onAttach == null) && cfg.enableLspFormat then |
251 | | - '' |
252 | | - require('lsp-format').on_attach |
253 | | - '' |
254 | | - else |
255 | | - cfg.onAttach; |
256 | | - |
257 | | - setupOptions = |
258 | | - with cfg; |
259 | | - { |
260 | | - inherit |
261 | | - border |
262 | | - cmd |
263 | | - debounce |
264 | | - debug |
265 | | - ; |
266 | | - default_timeout = defaultTimeout; |
267 | | - diagnostic_config = diagnosticConfig; |
268 | | - diagnostics_format = diagnosticsFormat; |
269 | | - fallback_severity = fallbackSeverity; |
270 | | - log_level = logLevel; |
271 | | - notify_format = notifyFormat; |
272 | | - on_attach = helpers.mkRaw onAttach'; |
273 | | - on_init = onInit; |
274 | | - on_exit = onExit; |
275 | | - root_dir = rootDir; |
276 | | - should_attach = shouldAttach; |
277 | | - temp_dir = tempDir; |
278 | | - update_in_insert = updateInInsert; |
| 81 | + callSetup = false; |
| 82 | + extraConfig = |
| 83 | + cfg: |
| 84 | + let |
| 85 | + # Set a custom on_attach when enableLspFormat is enabled |
| 86 | + # FIXME: Using `mkIf (...) (mkDefault "...")` would be better, |
| 87 | + # but that'd make it difficult to implement the "has no effect" warning. |
| 88 | + setupOptions = |
| 89 | + cfg.settings |
| 90 | + // optionalAttrs (cfg.enableLspFormat && cfg.settings.on_attach == null) { |
| 91 | + on_attach.__raw = '' |
| 92 | + require('lsp-format').on_attach |
| 93 | + ''; |
| 94 | + }; |
| 95 | + in |
| 96 | + { |
| 97 | + warnings = optional (cfg.enableLspFormat && cfg.settings.on_attach != null) '' |
| 98 | + You have enabled the lsp-format integration with none-ls. |
| 99 | + However, you have provided a custom value to `plugins.none-ls.settings.on_attach`. |
| 100 | + This means the `enableLspFormat` option will have no effect. |
| 101 | + Final value is: |
| 102 | + ${generators.toPretty { } cfg.settings.on_attach} |
| 103 | + ''; |
279 | 104 |
|
280 | | - sources = sourcesItems; |
281 | | - } |
282 | | - // cfg.extraOptions; |
283 | | - in |
284 | | - '' |
| 105 | + assertions = [ |
| 106 | + { |
| 107 | + assertion = cfg.enableLspFormat -> config.plugins.lsp-format.enable; |
| 108 | + message = '' |
| 109 | + Nixvim: You have enabled the lsp-format integration with none-ls. |
| 110 | + However, you have not enabled `plugins.lsp-format` itself. |
| 111 | + Note: `plugins.none-ls.enableLspFormat` is enabled by default when `plugins.lsp-format` is enabled. |
| 112 | + `plugins.none-ls.enableLspFormat` definitions: ${lib.options.showDefs options.plugins.none-ls.enableLspFormat.definitionsWithLocations} |
| 113 | + ''; |
| 114 | + } |
| 115 | + ]; |
| 116 | + |
| 117 | + # We only do this here because of enableLspFormat |
| 118 | + extraConfigLua = '' |
285 | 119 | require("null-ls").setup(${helpers.toLuaObject setupOptions}) |
286 | 120 | ''; |
287 | | - }; |
| 121 | + }; |
288 | 122 | } |
0 commit comments