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