commit e6e03d76ac253d28c4e0abf324e6715995a63607 Author: Moritz Böhme Date: Fri Sep 15 13:35:56 2023 +0200 feat: initial commit diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..6793a47 --- /dev/null +++ b/flake.nix @@ -0,0 +1,8 @@ +{ + description = "Nix flake for lazy.nvim for home-manager"; + + outputs = { self }: { + homeManagerModules.lazy-nvim = import ./home-manager.nix; + homeManagerModules.default = self.homeManagerModules.lazy-nvim; + }; +} diff --git a/home-manager.nix b/home-manager.nix new file mode 100644 index 0000000..293c802 --- /dev/null +++ b/home-manager.nix @@ -0,0 +1,236 @@ +{ config, lib, pkgs, ... }: + +with lib; +with import ./lib.nix { inherit lib; }; +let + cfg = config.programs.neovim.lazy; + + luaList = values: "{" + (concatStringsSep ", " values) + "}"; + + keybinding = { key, cmd, func, mode, desc }: + let + cmdString = + if cmd != null then toLua cmd else + if func != null then func else + abort "Either cmd or function must be set"; + descString = optionalString (desc != null) "desc = ${toLua desc},"; + in + ''{ ${toLua key}, ${cmdString}, mode = ${toLua mode}, ${descString} }''; + + lazySpecFromPlugin = + { cmd + , conf + , dependencies + , enabled + , event + , ft + , init + , keys + , lazy + , opts + , plugin + , priority + }: + + luaList + ([ + "dir = ${string plugin}" + "name = ${toLua (getName plugin)}" + ] + ++ (optional (opts != null) "opts = ${toLua opts}") + ++ (optional (lazy != null) "lazy = ${toLua lazy}") + ++ (optional (!enabled) "enabled = ${toLua enabled}") + ++ (optional (dependencies != [ ]) "dependencies = ${luaList (map lazySpecFromPlugin dependencies)}") + ++ (optional (init != null) "init = function(spec)\n${init}\nend") + ++ (optional (conf != null) "config = function(spec, opts)\n${conf}\nend") + ++ (optional (keys != [ ]) "keys = ${luaList (map keybinding keys)}") + ++ (optional (event != [ ]) "event = ${toLua event}") + ++ (optional (cmd != [ ]) "cmd = ${toLua cmd}") + ++ (optional (ft != [ ]) "ft = ${toLua ft}") + ++ (optional (priority != null) "priority = ${toLua priority}") + ); + lazySpecs = luaList (map lazySpecFromPlugin cfg.plugins); + text = /* lua */ '' + require("lazy").setup(${lazySpecs}) + ''; + + lazy = + pkgs.runCommand "lazy.lua" { inherit text; } '' + touch $out + echo -n "$text" > $out + ${getExe pkgs.stylua} $out + ''; + +in +{ + options.programs.neovim.lazy = { + enable = mkEnableOption "lazy.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. + ''; + }; + opts = mkOption { + type = + let + valueType = nullOr + (oneOf [ + str + bool + int + float + (listOf valueType) + (attrsOf valueType) + ]) // { + description = "Lua value"; + }; + in + nullOr (attrsOf valueType); + default = null; + description = '' + Lua table to be passed to te plugin config function. + ''; + }; + 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 = listOf 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 { + programs.neovim = { + extraLuaConfig = readFile 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; + plugins = [ + pkgs.vimPlugins.lazy-nvim + ]; + }; + }; +} diff --git a/lib.nix b/lib.nix new file mode 100644 index 0000000..e574a8e --- /dev/null +++ b/lib.nix @@ -0,0 +1,24 @@ +{ lib, ... }: + +with lib; +rec { + toLua = value: with builtins; + if value == null then "nil" else + if isBool value then boolToString value else + if isInt value || isFloat value then toString value else + if isString value then string value else + if isAttrs value then attrs value else + if isList value then list value else + abort "should never happen (value = ${value})"; + + string = str: ''"${toString str}"''; + attrs = set: + let + toKeyword = name: value: "['${name}'] = ${toLua value}"; + keywords = concatStringsSep ", " (mapAttrsToList toKeyword set); + in + "{ " + keywords + " }"; + + listContent = values: concatStringsSep ", " (map toLua values); + list = values: "{ " + listContent values + " }"; +}