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 configuration goes!
77 ''';
78 packages.myVimPackage = with pkgs.vimPlugins; {
79 # loaded on launch
80 start = [ fugitive ];
81 # manually loadable by calling `:packadd $plugin-name`
82 opt = [ ];
83 };
84 }
85 '';
86 description = ''
87 Generate your init file from your list of plugins and custom commands.
88 Neovim will then be wrapped to load {command}`nvim -u /nix/store/«hash»-vimrc`
89 '';
90 };
91
92 package = lib.mkPackageOption pkgs "neovim-unwrapped" { };
93
94 finalPackage = lib.mkOption {
95 type = lib.types.package;
96 visible = false;
97 readOnly = true;
98 description = "Resulting customized neovim package.";
99 };
100
101 runtime = lib.mkOption {
102 default = { };
103 example = lib.literalExpression ''
104 { "ftplugin/c.vim".text = "setlocal omnifunc=v:lua.vim.lsp.omnifunc"; }
105 '';
106 description = ''
107 Set of files that have to be linked in {file}`runtime`.
108 '';
109
110 type =
111 with lib.types;
112 attrsOf (
113 submodule (
114 { name, config, ... }:
115 {
116 options = {
117
118 enable = lib.mkOption {
119 type = lib.types.bool;
120 default = true;
121 description = ''
122 Whether this runtime directory should be generated. This
123 option allows specific runtime files to be disabled.
124 '';
125 };
126
127 target = lib.mkOption {
128 type = lib.types.str;
129 description = ''
130 Name of symlink. Defaults to the attribute
131 name.
132 '';
133 };
134
135 text = lib.mkOption {
136 default = null;
137 type = lib.types.nullOr lib.types.lines;
138 description = "Text of the file.";
139 };
140
141 source = lib.mkOption {
142 default = null;
143 type = lib.types.nullOr lib.types.path;
144 description = "Path of the source file.";
145 };
146
147 };
148
149 config.target = lib.mkDefault name;
150 }
151 )
152 );
153
154 };
155 };
156
157 config = lib.mkIf cfg.enable {
158 environment.systemPackages = [
159 cfg.finalPackage
160 ];
161 environment.variables.EDITOR = lib.mkIf cfg.defaultEditor (lib.mkOverride 900 "nvim");
162 # On most NixOS configurations /share is already included, so it includes
163 # this directory as well. But This makes sure that /share/nvim/site paths
164 # from other packages will be used by neovim.
165 environment.pathsToLink = [ "/share/nvim" ];
166
167 environment.etc = builtins.listToAttrs (
168 builtins.attrValues (
169 builtins.mapAttrs (name: value: {
170 name = "xdg/nvim/${name}";
171 value = builtins.removeAttrs (
172 value
173 // {
174 target = "xdg/nvim/${value.target}";
175 }
176 ) (lib.optionals (builtins.isNull value.source) [ "source" ]);
177 }) cfg.runtime
178 )
179 );
180
181 programs.neovim.finalPackage = pkgs.wrapNeovim cfg.package {
182 inherit (cfg)
183 viAlias
184 vimAlias
185 withPython3
186 withNodeJs
187 withRuby
188 configure
189 ;
190 };
191 };
192}