1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 cfg = config.programs.neovim;
10in
11{
12 options.programs.neovim = {
13 enable = lib.mkOption {
14 type = lib.types.bool;
15 default = false;
16 example = true;
17 description = ''
18 Whether to enable Neovim.
19
20 When enabled through this option, Neovim is wrapped to use a
21 configuration managed by this module. The configuration file in the
22 user's home directory at {file}`~/.config/nvim/init.vim` is no longer
23 loaded by default.
24 '';
25 };
26
27 defaultEditor = lib.mkOption {
28 type = lib.types.bool;
29 default = false;
30 description = ''
31 When enabled, installs neovim and configures neovim to be the default editor
32 using the EDITOR environment variable.
33 '';
34 };
35
36 viAlias = lib.mkOption {
37 type = lib.types.bool;
38 default = false;
39 description = ''
40 Symlink {command}`vi` to {command}`nvim` binary.
41 '';
42 };
43
44 vimAlias = lib.mkOption {
45 type = lib.types.bool;
46 default = false;
47 description = ''
48 Symlink {command}`vim` to {command}`nvim` binary.
49 '';
50 };
51
52 withRuby = lib.mkOption {
53 type = lib.types.bool;
54 default = true;
55 description = "Enable Ruby provider.";
56 };
57
58 withPython3 = lib.mkOption {
59 type = lib.types.bool;
60 default = true;
61 description = "Enable Python 3 provider.";
62 };
63
64 withNodeJs = lib.mkOption {
65 type = lib.types.bool;
66 default = false;
67 description = "Enable Node provider.";
68 };
69
70 configure = lib.mkOption {
71 type = lib.types.attrs;
72 default = { };
73 example = lib.literalExpression ''
74 {
75 customRC = '''
76 " here your custom VimScript configuration goes!
77 ''';
78 customLuaRC = '''
79 -- here your custom Lua configuration goes!
80 ''';
81 packages.myVimPackage = with pkgs.vimPlugins; {
82 # loaded on launch
83 start = [ fugitive ];
84 # manually loadable by calling `:packadd $plugin-name`
85 opt = [ ];
86 };
87 }
88 '';
89 description = ''
90 Generate your init file from your list of plugins and custom commands.
91 Neovim will then be wrapped to load {command}`nvim -u /nix/store/«hash»-vimrc`
92 '';
93 };
94
95 package = lib.mkPackageOption pkgs "neovim-unwrapped" { };
96
97 finalPackage = lib.mkOption {
98 type = lib.types.package;
99 visible = false;
100 readOnly = true;
101 description = "Resulting customized neovim package.";
102 };
103
104 runtime = lib.mkOption {
105 default = { };
106 example = lib.literalExpression ''
107 { "ftplugin/c.vim".text = "setlocal omnifunc=v:lua.vim.lsp.omnifunc"; }
108 '';
109 description = ''
110 Set of files that have to be linked in {file}`runtime`.
111 '';
112
113 type =
114 with lib.types;
115 attrsOf (
116 submodule (
117 { name, config, ... }:
118 {
119 options = {
120
121 enable = lib.mkOption {
122 type = lib.types.bool;
123 default = true;
124 description = ''
125 Whether this runtime directory should be generated. This
126 option allows specific runtime files to be disabled.
127 '';
128 };
129
130 target = lib.mkOption {
131 type = lib.types.str;
132 description = ''
133 Name of symlink. Defaults to the attribute
134 name.
135 '';
136 };
137
138 text = lib.mkOption {
139 default = null;
140 type = lib.types.nullOr lib.types.lines;
141 description = "Text of the file.";
142 };
143
144 source = lib.mkOption {
145 default = null;
146 type = lib.types.nullOr lib.types.path;
147 description = "Path of the source file.";
148 };
149
150 };
151
152 config.target = lib.mkDefault name;
153 }
154 )
155 );
156
157 };
158 };
159
160 config = lib.mkIf cfg.enable {
161 environment.systemPackages = [
162 cfg.finalPackage
163 ];
164 environment.variables.EDITOR = lib.mkIf cfg.defaultEditor (lib.mkOverride 900 "nvim");
165 # On most NixOS configurations /share is already included, so it includes
166 # this directory as well. But This makes sure that /share/nvim/site paths
167 # from other packages will be used by neovim.
168 environment.pathsToLink = [ "/share/nvim" ];
169
170 environment.etc = builtins.listToAttrs (
171 builtins.attrValues (
172 builtins.mapAttrs (name: value: {
173 name = "xdg/nvim/${name}";
174 value = builtins.removeAttrs (
175 value
176 // {
177 target = "xdg/nvim/${value.target}";
178 }
179 ) (lib.optionals (builtins.isNull value.source) [ "source" ]);
180 }) cfg.runtime
181 )
182 );
183
184 programs.neovim.finalPackage = pkgs.wrapNeovim cfg.package {
185 inherit (cfg)
186 viAlias
187 vimAlias
188 withPython3
189 withNodeJs
190 withRuby
191 configure
192 ;
193 };
194 };
195}