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