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