dotfiles/modules/programs/nvim/default.nix

260 lines
7.3 KiB
Nix

{ config
, lib
, pkgs
, ...
}:
with lib;
let
cfg = config.my.programs.nvim;
boolToString = bool: if bool then "true" else "false";
quote = str: ''"${toString str}"'';
id = x: x;
listToString = sep: f: list: ''{ ${concatStringsSep sep (map f list)} }'';
listToStringOneLine = listToString ", ";
listToStringMultiLine = listToString ",\n";
keybinding =
{ key
, cmd
, func
, mode
, desc
}:
let
cmdString =
if cmd != null
then quote cmd
else
(
if func != null
then func
else abort "Either cmd or function must be set"
);
in
''{ ${quote key}, ${cmdString}, mode = ${quote mode}, ${optionalString (desc != null) "desc = ${quote desc},"} }'';
lazySpecFromPlugin =
{ plugin
, dependencies
, init
, conf
, lazy
, event
, enabled
, cmd
, ft
, priority
, keys
}:
listToStringMultiLine id
([
"dir = ${quote plugin}"
"name = ${quote (getName plugin)}"
]
++ (optional (lazy != null) "lazy = ${boolToString lazy}")
++ (optional (!enabled) "enabled = ${boolToString enabled}")
++ (optional (dependencies != [ ]) "dependencies = ${listToStringMultiLine id (map lazySpecFromPlugin dependencies)}")
++ (optional (init != null) "init = function(plugin)\n${toString init}\nend")
++ (optional (conf != null) "config = function(plugin, opts)\n${toString conf}\nend")
++ (optional (keys != [ ]) "keys = ${listToStringMultiLine id (map keybinding keys)}")
++ (optional (event != [ ]) "event = ${listToStringOneLine quote event}")
++ (optional (cmd != [ ]) "cmd = ${listToStringOneLine quote cmd}")
++ (optional (ft != [ ]) "ft = ${listToStringOneLine quote ft}")
++ (optional (priority != null) "priority = ${toString priority}")
);
lazySpecs = listToStringMultiLine id (map lazySpecFromPlugin cfg.plugins);
lazy = ''
require("lazy").setup({
${lazySpecs}
})
'';
in
{
imports = [ ./plugins ];
options.my.programs.nvim = {
enable = mkEnableOption "nvim";
plugins = mkOption {
default = [ ];
description = ''
List of plugins with config.
'';
type = with types; listOf (
let
sub = submodule {
options = {
conf = mkOption {
type = nullOr str;
default = null;
description = ''
Lua function to be executed when the plugin is loaded.
'';
};
dependencies = mkOption {
type = listOf sub;
default = [ ];
description = ''
List of plugins this plugin depends on.
'';
};
init = mkOption {
type = nullOr str;
default = null;
description = ''
Lua code to be executed when the plugin is initialized.
'';
};
event = mkOption {
type = listOf str;
default = [ ];
description = ''
Event to load the plugin on.
'';
};
lazy = mkOption {
type = nullOr bool;
default = null;
description = ''
Whether to load the plugin lazily.
'';
};
plugin = mkOption {
type = package;
description = ''
The plugin package.
'';
};
enabled = mkOption {
type = bool;
default = true;
description = ''
Whether to enable the plugin.
'';
};
cmd = mkOption {
type = listOf str;
default = [ ];
description = ''
Command to load the plugin.
'';
};
ft = mkOption {
type = listOf str;
default = [ ];
description = ''
Filetype to load the plugin on.
'';
};
priority = mkOption {
type = nullOr int;
default = null;
description = ''
Priority to load the plugin.
'';
};
keys = mkOption {
default = [ ];
description = ''
List of keybindings.
'';
type = listOf (submodule {
options = {
key = mkOption {
type = str;
description = ''
Key to bind.
'';
};
cmd = mkOption {
type = nullOr str;
default = null;
description = ''
Command to execute.
'';
};
func = mkOption {
type = nullOr str;
default = null;
description = ''
Function to execute.
'';
};
mode = mkOption {
type = str;
default = "n";
description = ''
Mode to bind the key in.
'';
};
desc = mkOption {
type = nullOr str;
default = null;
description = ''
Description of the keybinding.
'';
};
};
});
};
};
};
in
sub
);
};
};
config = mkIf cfg.enable {
home-manager.users.moritz = {
home.packages = with pkgs; [
(
if config.my.programs.hyprland.enable
then neovide-hyprland
else neovide
)
];
programs.neovim = {
enable = true;
package = pkgs.neovim-nightly;
vimAlias = true;
vimdiffAlias = true;
withNodeJs = true;
withPython3 = true;
extraLuaConfig = lib.concatLines [ (builtins.readFile ./options.lua) lazy ];
extraPython3Packages = ps:
let
plugins = map (getAttr "plugin") cfg.plugins;
depAttrName = "python3Dependencies";
filtered = filter (hasAttr depAttrName) plugins;
funcs = map (getAttr depAttrName) filtered;
in
foldl (list: f: list ++ (f ps)) [ ] funcs;
extraPackages = with pkgs;
[
alejandra
black
deadnix
isort
jq
nil
nixpkgs-fmt
nodePackages.bash-language-server
rustfmt
shellcheck
shfmt
statix
stylua
sumneko-lua-language-server
taplo
typst
typst-lsp
yamlfmt
];
plugins = [
pkgs.vimPlugins.lazy-nvim
];
};
};
};
}