Skip to content

Commit 261dec9

Browse files
authored
docs(wrapperModules.neovim): improve tips and tricks section (#207)
1 parent 9339648 commit 261dec9

File tree

1 file changed

+152
-49
lines changed

1 file changed

+152
-49
lines changed

wrapperModules/n/neovim/post_desc.md

Lines changed: 152 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## Tips and Tricks:
1+
# Tips and Tricks:
22

33
The main `init.lua` of your config directory is added to the specs DAG under the name `INIT_MAIN`.
44

@@ -12,65 +12,65 @@ Use this for a quick feedback mode while editing, and then switch it back to the
1212

1313
---
1414

15-
- lazy loading
16-
17-
If you mark a spec as lazy, (or mark a parent spec and don't override the value in the child spec by default),
18-
it will be placed in `pack/myNeovimPackages/opt/<pname>` on the runtime path.
15+
The wrapper makes a lot of information available to you in your lua config via the info plugin!
1916

20-
It will not be loaded yet. Use `vim.cmd.packadd("<pname>")` to load it via `lua` (or `vimscript` or `fennel`) at a time of your choosing.
21-
22-
There are great plugins for this.
17+
```lua
18+
local nixInfo = require(vim.g.nix_info_plugin_name)
19+
local default = nil
20+
local value = nixInfo(default, "path", "to", "value", "in", "plugin")
21+
```
2322

24-
See [lze](https://github.com/BirdeeHub/lze) and [lz.n](https://github.com/nvim-neorocks/lz.n), which work beautifully with this method of installing plugins.
23+
It is just a table! Run `:=require(vim.g.nix_info_plugin_name)` to look at it!
2524

26-
They also work great with the builtin `neovim` plugin manager, `vim.pack.add`!
25+
A useful function to see if nix installed a plugin for you is:
2726

28-
---
27+
```lua
28+
local nixInfo = require(vim.g.nix_info_plugin_name)
29+
local function get_nix_plugin_path(name)
30+
return nixInfo(nil, "plugins", "lazy", name) or nixInfo(nil, "plugins", "start", name)
31+
end
32+
```
2933

30-
- Use `nvim-lib.mkPlugin` to build plugins from sources outside nixpkgs (e.g., git flake inputs)
34+
For another example, you might want to tell your info plugin about the top-level specs which you have enabled,
35+
which you can do like this in your module:
3136

3237
```nix
33-
inputs.treesj = {
34-
url = "github:Wansmer/treesj";
35-
flake = false;
36-
};
38+
config.info.cats = builtins.mapAttrs (_: v: v.enable) config.specs;
3739
```
3840

39-
```nix
40-
config.specs.treesj = config.nvim-lib.mkPlugin "treesj" inputs.treesj;
41+
And then get it in `lua` with:
42+
43+
```lua
44+
local nixInfo = require(vim.g.nix_info_plugin_name)
45+
local cat_is_present = nixInfo(false, "info", "cats", "<specs_attribute_name>")
4146
```
4247

4348
---
4449

45-
- To use a different version of neovim, set `config.package` to the version you want to use!
50+
- lazy loading
4651

47-
```nix
48-
config.package = inputs.neovim-nightly-overlay.packages.${pkgs.stdenv.hostPlatform.system}.neovim;
49-
```
52+
If you mark a spec as lazy, (or mark a parent spec and don't override the value in the child spec by default),
53+
it will be placed in `pack/myNeovimPackages/opt/<pname>` on the runtime path.
54+
55+
It will not be loaded yet. Use `vim.cmd.packadd("<pname>")` to load it via `lua` (or `vimscript` or `fennel`) at a time of your choosing.
56+
57+
There are great plugins for this.
58+
59+
See [lze](https://github.com/BirdeeHub/lze) and [lz.n](https://github.com/nvim-neorocks/lz.n), which work beautifully with this method of installing plugins.
60+
61+
They also work great with the builtin `neovim` plugin manager, `vim.pack.add`!
62+
63+
`lze` can also be used to do some interesting bulk modifications to your plugins.
64+
You might want to disable the ones nix didn't install automatically, for example.
65+
You could use the `modify` field of a `handler` with `set_lazy = false` also set within it to do that,
66+
using one of the functions from the previous tip.
5067

5168
---
5269

53-
- Make a new host!
70+
- To use a different version of `neovim`, set `config.package` to the version you want to use!
5471

5572
```nix
56-
config.hosts.neovide =
57-
{
58-
lib,
59-
wlib,
60-
pkgs,
61-
...
62-
}:
63-
{
64-
imports = [ wlib.modules.default ];
65-
config.nvim-host.enable = lib.mkDefault false;
66-
config.package = pkgs.neovide;
67-
# also offers nvim-host wrapper arguments which run in the context of the final nvim drv!
68-
config.nvim-host.flags."--neovim-bin" = "${placeholder "out"}/bin/${config.binName}";
69-
};
70-
71-
# This one is included!
72-
# To add a wrapped $out/bin/${config.binName}-neovide to the resulting neovim derivation
73-
config.hosts.neovide.nvim-host.enable = true;
73+
config.package = inputs.neovim-nightly-overlay.packages.${pkgs.stdenv.hostPlatform.system}.neovim;
7474
```
7575

7676
---
@@ -87,21 +87,22 @@ config.settings.aliases = [ ];
8787

8888
---
8989

90-
- Change defaults and allow parent overrides of the default to propagate default values to child specs:
90+
- Use `nvim-lib.mkPlugin` to build plugins from sources outside nixpkgs (e.g., git flake inputs)
9191

9292
```nix
93-
config.specMods = { parentSpec, ... }: {
94-
config.collateGrammars = lib.mkDefault (parentSpec.collateGrammars or true);
93+
inputs.treesj = {
94+
url = "github:Wansmer/treesj";
95+
flake = false;
9596
};
9697
```
9798

98-
---
99-
100-
- Use `specMaps` for advanced spec processing only when `specMods` and `specCollect` is not flexible enough
99+
```nix
100+
config.specs.treesj = config.nvim-lib.mkPlugin "treesj" inputs.treesj;
101+
```
101102

102103
---
103104

104-
- building many plugins from outside nixpkgs at once
105+
- Building many plugins from outside `nixpkgs` at once
105106

106107
In your flake inputs, if you named your inputs like so:
107108

@@ -112,7 +113,7 @@ inputs.plugins-treesitter-textobjects = {
112113
};
113114
```
114115

115-
You could identify them and pre-build them as plugins all at once!
116+
You could identify them and build them as plugins all at once!
116117

117118
Here is a useful module to import which gives you a helper function
118119
in `config.nvim-lib` for that!
@@ -154,3 +155,105 @@ in {
154155
specs.treesitter-textobjects = neovimPlugins.treesitter-textobjects;
155156
}
156157
```
158+
159+
---
160+
161+
- Change defaults and allow parent values to propagate default values to child specs:
162+
163+
```nix
164+
config.specMods = { parentSpec, ... }: {
165+
config.collateGrammars = lib.mkDefault (parentSpec.collateGrammars or true);
166+
};
167+
```
168+
169+
You have full control over them via the module system! This module will apply to the `wlib.types.spec` type of both specs in both the outer set and inner lists!
170+
171+
In the outer set, `parentSpec` is `null` and in the inner lists, it receives the `config` argument from the outer set!
172+
173+
It also receives `parentOpts`, which contains the `options` argument.
174+
175+
---
176+
177+
- You may want to move the installation of things like language servers into your specs. You can do that!
178+
179+
```nix
180+
{ config, lib, wlib, ... }: {
181+
config.specMods = {
182+
options.extraPackages = lib.mkOption {
183+
type = lib.types.listOf wlib.types.stringable;
184+
default = [ ];
185+
description = "a extraPackages spec field to put packages to suffix to the PATH";
186+
};
187+
};
188+
config.extraPackages = config.specCollect (acc: v: acc ++ (v.extraPackages or [ ])) [ ];
189+
}
190+
```
191+
192+
---
193+
194+
- Use `specMaps` for advanced spec processing only when `specMods` and `specCollect` is not flexible enough.
195+
196+
`specMaps` has free-reign to modify the whole structure of specs provided as desired after the module evaluation,
197+
before `specCollect` runs, and before the wrapper evaluates the builtin fields of the specs.
198+
199+
Be careful with this option, but an advanced user might use this to preprocess the items in truly amazing ways!
200+
201+
This also means items in `specCollect` may occasionally be missing fields, do not rely on them being there when using it! Use `or` to catch indexing errors.
202+
203+
---
204+
205+
- Make a new host!
206+
207+
```nix
208+
# an attribute set of wrapper modules
209+
config.hosts.neovide =
210+
{
211+
lib,
212+
wlib,
213+
pkgs,
214+
...
215+
}:
216+
{
217+
imports = [ wlib.modules.default ];
218+
config.nvim-host.enable = lib.mkDefault false;
219+
config.package = pkgs.neovide;
220+
# also offers nvim-host wrapper arguments which run in the context of the final nvim drv!
221+
config.nvim-host.flags."--neovim-bin" = "${placeholder "out"}/bin/${config.binName}";
222+
};
223+
224+
# This one is included!
225+
# To add a wrapped $out/bin/${config.binName}-neovide to the resulting neovim derivation
226+
config.hosts.neovide.nvim-host.enable = true;
227+
```
228+
229+
---
230+
231+
- Non-nix compatibility:
232+
233+
If you always use the fetcher function form to access items in the plugin from nix,
234+
then this mostly takes care of non-nix compatibility. Non-nix compatibility meaning,
235+
trying to use the same config directory without using nix to install it.
236+
237+
```lua
238+
do
239+
local ok
240+
ok, _G.nixInfo = pcall(require, vim.g.nix_info_plugin_name)
241+
if not ok then
242+
package.loaded[vim.g.nix_info_plugin_name] = setmetatable({}, {
243+
__call = function (_, default) return default end
244+
})
245+
end
246+
require(vim.g.nix_info_plugin_name).isNix = vim.g.nix_info_plugin_name ~= nil
247+
end
248+
```
249+
250+
You would have to have a file that installs the plugins with `vim.pack.add` if not nix
251+
and install the lsps some other way.
252+
253+
As a reminder, the fetcher function form is:
254+
255+
```lua
256+
local nixInfo = require(vim.g.nix_info_plugin_name)
257+
local default = nil
258+
local value = nixInfo(default, "path", "to", "value", "in", "plugin")
259+
```

0 commit comments

Comments
 (0)