Skip to content

Commit f6e7960

Browse files
authored
plugins/lazy.nvim: new plugin manager (#1175)
1 parent ba5a0b8 commit f6e7960

File tree

4 files changed

+298
-1
lines changed

4 files changed

+298
-1
lines changed

plugins/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
./dap
9595

9696
./pluginmanagers/packer.nix
97+
./pluginmanagers/lazy.nix
9798

9899
./snippets/friendly-snippets.nix
99100
./snippets/luasnip

plugins/filetrees/nvim-tree.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ in {
759759
helpers.defaultNullOpts.mkNullable (with types; attrsOf (listOf str))
760760
''
761761
{
762-
filetype = [ "notify" "packer" "qf" "diff" "fugitive" "fugitiveblame" ];
762+
filetype = [ "notify" "lazy" "packer" "qf" "diff" "fugitive" "fugitiveblame" ];
763763
buftype = [ "nofile" "terminal" "help" ];
764764
};
765765
''

plugins/pluginmanagers/lazy.nix

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
{
2+
lib,
3+
helpers,
4+
config,
5+
pkgs,
6+
...
7+
}:
8+
with lib; let
9+
cfg = config.plugins.lazy;
10+
lazyPlugins = cfg.plugins;
11+
12+
processPlugin = plugin: let
13+
mkEntryFromDrv = p:
14+
if lib.isDerivation p
15+
then {
16+
name = "${lib.getName p}";
17+
path = p;
18+
}
19+
else {
20+
name = "${lib.getName p.pkg}";
21+
path = p.pkg;
22+
};
23+
processDependencies =
24+
if plugin ? dependencies && plugin.dependencies != null
25+
then builtins.concatMap processPlugin plugin.dependencies
26+
else [];
27+
in
28+
[(mkEntryFromDrv plugin)] ++ processDependencies;
29+
30+
processedPlugins = builtins.concatLists (builtins.map processPlugin lazyPlugins);
31+
lazyPath = pkgs.linkFarm "lazy-plugins" processedPlugins;
32+
in {
33+
options = {
34+
plugins.lazy = {
35+
enable = mkEnableOption "lazy.nvim";
36+
37+
plugins = with types; let
38+
pluginType =
39+
either
40+
package
41+
(submodule {
42+
options = {
43+
dir = helpers.mkNullOrOption str "A directory pointing to a local plugin";
44+
45+
pkg = mkOption {
46+
type = package;
47+
description = "Vim plugin to install";
48+
};
49+
50+
name = helpers.mkNullOrOption str "Name of the plugin to install";
51+
52+
dev = helpers.defaultNullOpts.mkBool false ''
53+
When true, a local plugin directory will be used instead.
54+
See config.dev
55+
'';
56+
57+
lazy = helpers.defaultNullOpts.mkBool true ''
58+
When true, the plugin will only be loaded when needed.
59+
Lazy-loaded plugins are automatically loaded when their Lua modules are required,
60+
or when one of the lazy-loading handlers triggers
61+
'';
62+
63+
enabled = helpers.defaultNullOpts.mkStrLuaFnOr types.bool "`true`" ''
64+
When false then this plugin will not be included in the spec. (accepts fun():boolean)
65+
'';
66+
67+
cond =
68+
helpers.defaultNullOpts.mkStrLuaFnOr types.bool "`true`"
69+
''
70+
When false, or if the function returns false,
71+
then this plugin will not be loaded. Useful to disable some plugins in vscode,
72+
or firenvim for example. (accepts fun(LazyPlugin):boolean)
73+
'';
74+
75+
dependencies =
76+
helpers.mkNullOrOption (helpers.nixvimTypes.eitherRecursive str listOfPlugins)
77+
"Plugin dependencies";
78+
79+
init =
80+
helpers.mkNullOrLuaFn
81+
"init functions are always executed during startup";
82+
83+
config = helpers.mkNullOrStrLuaFnOr (types.enum [true]) ''
84+
config is executed when the plugin loads.
85+
The default implementation will automatically run require(MAIN).setup(opts).
86+
Lazy uses several heuristics to determine the plugin's MAIN module automatically based on the plugin's name.
87+
See also opts. To use the default implementation without opts set config to true.
88+
'';
89+
90+
main = helpers.mkNullOrOption str ''
91+
You can specify the main module to use for config() and opts(),
92+
in case it can not be determined automatically. See config()
93+
'';
94+
95+
submodules = helpers.defaultNullOpts.mkBool true ''
96+
When false, git submodules will not be fetched.
97+
Defaults to true
98+
'';
99+
100+
event = with helpers.nixvimTypes;
101+
helpers.mkNullOrOption (maybeRaw (either str (listOf str)))
102+
"Lazy-load on event. Events can be specified as BufEnter or with a pattern like BufEnter *.lua";
103+
104+
cmd = with helpers.nixvimTypes;
105+
helpers.mkNullOrOption (maybeRaw (either str (listOf str)))
106+
"Lazy-load on command";
107+
108+
ft = with helpers.nixvimTypes;
109+
helpers.mkNullOrOption (maybeRaw (either str (listOf str)))
110+
"Lazy-load on filetype";
111+
112+
keys = with helpers.nixvimTypes;
113+
helpers.mkNullOrOption (maybeRaw (either str (listOf str)))
114+
"Lazy-load on key mapping";
115+
116+
module = helpers.mkNullOrOption (enum [false]) ''
117+
Do not automatically load this Lua module when it's required somewhere
118+
'';
119+
120+
priority = helpers.mkNullOrOption number ''
121+
Only useful for start plugins (lazy=false) to force loading certain plugins first.
122+
Default priority is 50. It's recommended to set this to a high number for colorschemes.
123+
'';
124+
125+
optional = helpers.defaultNullOpts.mkBool false ''
126+
When a spec is tagged optional, it will only be included in the final spec,
127+
when the same plugin has been specified at least once somewhere else without optional.
128+
This is mainly useful for Neovim distros, to allow setting options on plugins that may/may not be part
129+
of the user's plugins
130+
'';
131+
132+
opts = with helpers.nixvimTypes;
133+
helpers.mkNullOrOption (maybeRaw (attrsOf anything)) ''
134+
opts should be a table (will be merged with parent specs),
135+
return a table (replaces parent specs) or should change a table.
136+
The table will be passed to the Plugin.config() function.
137+
Setting this value will imply Plugin.config()
138+
'';
139+
};
140+
});
141+
142+
listOfPlugins = types.listOf pluginType;
143+
in
144+
mkOption {
145+
type = listOfPlugins;
146+
default = [];
147+
description = "List of plugins";
148+
};
149+
};
150+
};
151+
152+
config = mkIf cfg.enable {
153+
extraPlugins = [pkgs.vimPlugins.lazy-nvim];
154+
extraPackages = [pkgs.git];
155+
156+
extraConfigLua = let
157+
pluginToLua = plugin: let
158+
keyExists = keyToCheck: attrSet: lib.elem keyToCheck (lib.attrNames attrSet);
159+
in
160+
if isDerivation plugin
161+
then {
162+
dir = "${lazyPath}/${lib.getName plugin}";
163+
}
164+
else {
165+
"__unkeyed" = plugin.name;
166+
167+
inherit
168+
(plugin)
169+
cmd
170+
cond
171+
config
172+
dev
173+
enabled
174+
event
175+
ft
176+
init
177+
keys
178+
lazy
179+
main
180+
module
181+
name
182+
optional
183+
opts
184+
priority
185+
submodules
186+
;
187+
188+
dependencies =
189+
helpers.ifNonNull' plugin.dependencies
190+
(
191+
if isList plugin.dependencies
192+
then (pluginListToLua plugin.dependencies)
193+
else plugin.dependencies
194+
);
195+
196+
dir =
197+
if plugin ? dir && plugin.dir != null
198+
then plugin.dir
199+
else "${lazyPath}/${lib.getName plugin.pkg}";
200+
};
201+
202+
pluginListToLua = map pluginToLua;
203+
204+
plugins = pluginListToLua cfg.plugins;
205+
206+
packedPlugins =
207+
if length plugins == 1
208+
then head plugins
209+
else plugins;
210+
in
211+
mkIf (cfg.plugins != []) ''
212+
require('lazy').setup(
213+
{
214+
dev = {
215+
path = "${lazyPath}",
216+
patterns = {"."},
217+
fallback = false
218+
},
219+
spec = ${helpers.toLuaObject packedPlugins}
220+
}
221+
)
222+
'';
223+
};
224+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{pkgs, ...}: {
2+
# Empty configuration
3+
empty = {
4+
plugins.lazy.enable = true;
5+
};
6+
7+
test = {
8+
plugins.lazy = with pkgs.vimPlugins; {
9+
enable = true;
10+
11+
plugins = [
12+
vim-closer
13+
14+
# Load on specific commands
15+
{
16+
pkg = vim-dispatch;
17+
optional = true;
18+
cmd = ["Dispatch" "Make" "Focus" "Start"];
19+
}
20+
21+
# Load on an autocommand event
22+
{
23+
pkg = vim-matchup;
24+
event = "VimEnter";
25+
}
26+
27+
# Load on a combination of conditions: specific filetypes or commands
28+
{
29+
pkg = ale;
30+
name = "w0rp/ale";
31+
ft = ["sh" "zsh" "bash" "c" "cpp" "cmake" "html" "markdown" "racket" "vim" "tex"];
32+
cmd = "ALEEnable";
33+
}
34+
35+
# Plugins can have dependencies on other plugins
36+
{
37+
pkg = completion-nvim;
38+
optional = true;
39+
dependencies = [
40+
{
41+
pkg = vim-vsnip;
42+
optional = true;
43+
}
44+
{
45+
pkg = vim-vsnip-integ;
46+
optional = true;
47+
}
48+
];
49+
}
50+
51+
# Plugins can have post-install/update hooks
52+
{
53+
pkg = markdown-preview-nvim;
54+
cmd = "MarkdownPreview";
55+
}
56+
57+
# Post-install/update hook with neovim command
58+
{
59+
pkg = nvim-treesitter;
60+
opts = {ensure_installed = {};};
61+
}
62+
63+
# Use dependency and run lua function after load
64+
{
65+
pkg = gitsigns-nvim;
66+
dependencies = [plenary-nvim];
67+
config = ''function() require("gitsigns").setup() end'';
68+
}
69+
];
70+
};
71+
};
72+
}

0 commit comments

Comments
 (0)