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