2021-02-09 00:03:28 +00:00
|
|
|
{ nixos ? false, nixOnDroid ? false, homeManager ? false }:
|
2022-05-03 17:43:52 +01:00
|
|
|
{ pkgs, lib, config, ... }:
|
2020-12-30 01:05:51 +00:00
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
cfg = config.programs.nixvim;
|
|
|
|
|
|
|
|
pluginWithConfigType = types.submodule {
|
|
|
|
options = {
|
|
|
|
config = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
description = "vimscript for this plugin to be placed in init.vim";
|
|
|
|
default = "";
|
|
|
|
};
|
|
|
|
|
|
|
|
optional = mkEnableOption "optional" // {
|
|
|
|
description = "Don't load by default (load with :packadd)";
|
|
|
|
};
|
|
|
|
|
|
|
|
plugin = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
description = "vim plugin";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2021-01-05 11:26:49 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
mapOption = types.oneOf [
|
|
|
|
types.str
|
|
|
|
(types.submodule {
|
|
|
|
options = {
|
|
|
|
silent = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
description = "Whether this mapping should be silent. Equivalent to adding <silent> to a map.";
|
|
|
|
default = false;
|
|
|
|
};
|
2021-01-05 16:11:56 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
nowait = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
description = "Whether to wait for extra input on ambiguous mappings. Equivalent to adding <nowait> to a map.";
|
|
|
|
default = false;
|
|
|
|
};
|
2021-01-05 16:11:56 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
script = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
description = "Equivalent to adding <script> to a map.";
|
|
|
|
default = false;
|
|
|
|
};
|
2021-01-05 16:11:56 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
expr = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
description = "Means that the action is actually an expression. Equivalent to adding <expr> to a map.";
|
|
|
|
default = false;
|
|
|
|
};
|
2021-01-05 16:11:56 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
unique = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
description = "Whether to fail if the map is already defined. Equivalent to adding <unique> to a map.";
|
|
|
|
default = false;
|
|
|
|
};
|
2021-01-05 16:11:56 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
noremap = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
description = "Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default.";
|
|
|
|
default = true;
|
|
|
|
};
|
2021-01-05 16:11:56 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
action = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = "The action to execute.";
|
|
|
|
};
|
2022-01-10 19:50:13 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
description = mkOption {
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
description = "A textual description of this keybind, to be shown in which-key, if you have it.";
|
|
|
|
default = null;
|
|
|
|
};
|
2022-01-10 19:50:13 +00:00
|
|
|
};
|
2022-05-03 17:43:52 +01:00
|
|
|
})
|
|
|
|
];
|
2021-01-05 16:11:56 +00:00
|
|
|
|
|
|
|
mapOptions = mode: mkOption {
|
|
|
|
description = "Mappings for ${mode} mode";
|
|
|
|
type = types.attrsOf mapOption;
|
2022-05-03 17:43:52 +01:00
|
|
|
default = { };
|
2021-01-05 16:11:56 +00:00
|
|
|
};
|
2022-05-03 17:43:52 +01:00
|
|
|
|
2021-01-05 11:26:49 +00:00
|
|
|
helpers = import ./plugins/helpers.nix { lib = lib; };
|
2020-12-30 01:05:51 +00:00
|
|
|
in
|
|
|
|
{
|
|
|
|
options = {
|
|
|
|
programs.nixvim = {
|
|
|
|
enable = mkEnableOption "enable NixVim";
|
|
|
|
|
|
|
|
package = mkOption {
|
2021-02-08 22:45:02 +00:00
|
|
|
type = types.nullOr types.package;
|
|
|
|
default = null;
|
2020-12-30 01:05:51 +00:00
|
|
|
description = "The package to use for neovim.";
|
|
|
|
};
|
|
|
|
|
|
|
|
extraPlugins = mkOption {
|
|
|
|
type = with types; listOf (either package pluginWithConfigType);
|
2021-02-01 15:54:53 +00:00
|
|
|
default = [ ];
|
2020-12-30 01:05:51 +00:00
|
|
|
description = "List of vim plugins to install.";
|
|
|
|
};
|
|
|
|
|
|
|
|
colorscheme = mkOption {
|
2022-01-10 19:50:13 +00:00
|
|
|
type = types.nullOr types.str;
|
2020-12-30 01:05:51 +00:00
|
|
|
description = "The name of the colorscheme";
|
2022-01-10 19:50:13 +00:00
|
|
|
default = null;
|
2020-12-30 01:05:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extraConfigLua = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = "Extra contents for init.lua";
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfigVim = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
description = "Extra contents for init.vim";
|
|
|
|
};
|
|
|
|
|
2021-01-07 16:06:39 +00:00
|
|
|
extraPackages = mkOption {
|
|
|
|
type = types.listOf types.package;
|
2021-02-01 15:54:53 +00:00
|
|
|
default = [ ];
|
2021-01-07 16:06:39 +00:00
|
|
|
example = "[ pkgs.shfmt ]";
|
|
|
|
description = "Extra packages to be made available to neovim";
|
|
|
|
};
|
|
|
|
|
2020-12-30 01:05:51 +00:00
|
|
|
configure = mkOption {
|
2021-02-10 14:20:36 +00:00
|
|
|
type = types.attrsOf types.anything;
|
2020-12-30 01:05:51 +00:00
|
|
|
default = { };
|
2022-01-10 19:50:13 +00:00
|
|
|
description = "Internal option";
|
2020-12-30 01:05:51 +00:00
|
|
|
};
|
2021-01-05 11:26:49 +00:00
|
|
|
|
|
|
|
options = mkOption {
|
2021-02-10 14:20:36 +00:00
|
|
|
type = types.attrsOf types.anything;
|
2021-01-05 11:26:49 +00:00
|
|
|
default = { };
|
|
|
|
description = "The configuration options, e.g. line numbers";
|
|
|
|
};
|
|
|
|
|
|
|
|
globals = mkOption {
|
2021-02-10 14:20:36 +00:00
|
|
|
type = types.attrsOf types.anything;
|
2021-02-01 15:54:53 +00:00
|
|
|
default = { };
|
2021-01-05 11:26:49 +00:00
|
|
|
description = "Global variables";
|
|
|
|
};
|
2021-01-05 16:11:56 +00:00
|
|
|
|
|
|
|
maps = mkOption {
|
|
|
|
type = types.submodule {
|
|
|
|
options = {
|
|
|
|
normal = mapOptions "normal";
|
|
|
|
insert = mapOptions "insert";
|
|
|
|
select = mapOptions "select";
|
|
|
|
visual = mapOptions "visual and select";
|
|
|
|
terminal = mapOptions "terminal";
|
|
|
|
normalVisualOp = mapOptions "normal, visual, select and operator-pending (same as plain 'map')";
|
|
|
|
|
|
|
|
visualOnly = mapOptions "visual only";
|
|
|
|
operator = mapOptions "operator-pending";
|
|
|
|
insertCommand = mapOptions "insert and command-line";
|
|
|
|
lang = mapOptions "insert, command-line and lang-arg";
|
|
|
|
command = mapOptions "command-line";
|
|
|
|
};
|
|
|
|
};
|
2021-02-01 15:54:53 +00:00
|
|
|
default = { };
|
2021-01-05 16:11:56 +00:00
|
|
|
description = ''
|
|
|
|
Custom keybindings for any mode.
|
|
|
|
|
|
|
|
For plain maps (e.g. just 'map' or 'remap') use maps.normalVisualOp.
|
|
|
|
'';
|
|
|
|
|
|
|
|
example = ''
|
|
|
|
maps = {
|
|
|
|
normalVisualOp.";" = ":"; # Same as noremap ; :
|
|
|
|
normal."<leader>m" = {
|
|
|
|
silent = true;
|
|
|
|
action = "<cmd>make<CR>";
|
|
|
|
}; # Same as nnoremap <leader>m <silent> <cmd>make<CR>
|
|
|
|
};
|
|
|
|
'';
|
|
|
|
};
|
2020-12-30 01:05:51 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
imports = [
|
|
|
|
./plugins
|
|
|
|
];
|
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
config =
|
|
|
|
let
|
|
|
|
neovimConfig = pkgs.neovimUtils.makeNeovimConfig {
|
|
|
|
configure = cfg.configure;
|
|
|
|
plugins = cfg.extraPlugins;
|
|
|
|
};
|
2020-12-30 01:05:51 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
extraWrapperArgs = optionalString (cfg.extraPackages != [ ])
|
|
|
|
''--prefix PATH : "${makeBinPath cfg.extraPackages}"'';
|
|
|
|
|
|
|
|
package = if (cfg.package != null) then cfg.package else pkgs.neovim;
|
|
|
|
|
|
|
|
wrappedNeovim = pkgs.wrapNeovimUnstable package (neovimConfig // {
|
|
|
|
wrapperArgs = lib.escapeShellArgs neovimConfig.wrapperArgs + " "
|
|
|
|
+ extraWrapperArgs;
|
|
|
|
});
|
|
|
|
|
|
|
|
configure = {
|
2022-07-11 18:50:51 +00:00
|
|
|
customRC = cfg.extraConfigVim + (optionalString (cfg.colorscheme != "" && cfg.colorscheme != null) ''
|
2022-05-03 17:43:52 +01:00
|
|
|
colorscheme ${cfg.colorscheme}
|
|
|
|
'') + ''
|
|
|
|
lua <<EOF
|
|
|
|
${cfg.extraConfigLua}
|
|
|
|
EOF
|
|
|
|
'';
|
2021-03-17 22:51:01 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
packages.nixvim = {
|
|
|
|
start = filter (f: f != null) (map
|
|
|
|
(x:
|
|
|
|
if x ? plugin && x.optional == true then null else (x.plugin or x))
|
2021-01-25 17:20:29 +00:00
|
|
|
cfg.extraPlugins);
|
2022-05-03 17:43:52 +01:00
|
|
|
opt = filter (f: f != null)
|
|
|
|
(map (x: if x ? plugin && x.optional == true then x.plugin else null)
|
|
|
|
cfg.extraPlugins);
|
|
|
|
};
|
2021-01-25 17:20:29 +00:00
|
|
|
};
|
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
extraConfigLua = optionalString (cfg.globals != { }) ''
|
|
|
|
-- Set up globals {{{
|
|
|
|
local __nixvim_globals = ${helpers.toLuaObject cfg.globals}
|
|
|
|
|
|
|
|
for k,v in pairs(__nixvim_globals) do
|
|
|
|
vim.g[k] = v
|
|
|
|
end
|
|
|
|
-- }}}
|
|
|
|
'' + optionalString (cfg.options != { }) ''
|
|
|
|
-- Set up options {{{
|
|
|
|
local __nixvim_options = ${helpers.toLuaObject cfg.options}
|
|
|
|
|
|
|
|
for k,v in pairs(__nixvim_options) do
|
|
|
|
vim.o[k] = v
|
|
|
|
end
|
|
|
|
-- }}}
|
|
|
|
'' + optionalString (mappings != [ ]) ''
|
|
|
|
-- Set up keybinds {{{
|
|
|
|
local __nixvim_binds = ${helpers.toLuaObject mappings}
|
|
|
|
|
|
|
|
for i, map in ipairs(__nixvim_binds) do
|
|
|
|
vim.api.nvim_set_keymap(map.mode, map.key, map.action, map.config)
|
|
|
|
end
|
|
|
|
-- }}}
|
|
|
|
'';
|
2020-12-30 01:05:51 +00:00
|
|
|
|
2022-05-03 17:43:52 +01:00
|
|
|
mappings =
|
|
|
|
(helpers.genMaps "" cfg.maps.normalVisualOp) ++
|
|
|
|
(helpers.genMaps "n" cfg.maps.normal) ++
|
|
|
|
(helpers.genMaps "i" cfg.maps.insert) ++
|
|
|
|
(helpers.genMaps "v" cfg.maps.visual) ++
|
|
|
|
(helpers.genMaps "x" cfg.maps.visualOnly) ++
|
|
|
|
(helpers.genMaps "s" cfg.maps.select) ++
|
|
|
|
(helpers.genMaps "t" cfg.maps.terminal) ++
|
|
|
|
(helpers.genMaps "o" cfg.maps.operator) ++
|
|
|
|
(helpers.genMaps "l" cfg.maps.lang) ++
|
|
|
|
(helpers.genMaps "!" cfg.maps.insertCommand) ++
|
|
|
|
(helpers.genMaps "c" cfg.maps.command);
|
|
|
|
|
|
|
|
in
|
|
|
|
mkIf cfg.enable (if nixos then {
|
|
|
|
environment.systemPackages = [ wrappedNeovim ];
|
|
|
|
programs.neovim = {
|
|
|
|
configure = configure;
|
|
|
|
};
|
|
|
|
|
|
|
|
programs.nixvim.extraConfigLua = extraConfigLua;
|
|
|
|
|
|
|
|
environment.etc."xdg/nvim/sysinit.vim".text = neovimConfig.neovimRcContent;
|
|
|
|
} else
|
|
|
|
(if homeManager then {
|
|
|
|
programs.nixvim.extraConfigLua = extraConfigLua;
|
|
|
|
programs.neovim = {
|
|
|
|
enable = true;
|
|
|
|
package = mkIf (cfg.package != null) cfg.package;
|
|
|
|
extraPackages = cfg.extraPackages;
|
|
|
|
extraConfig = configure.customRC;
|
|
|
|
plugins = cfg.extraPlugins;
|
|
|
|
};
|
|
|
|
} else { }));
|
2020-12-30 01:05:51 +00:00
|
|
|
}
|