diff --git a/plugins/default.nix b/plugins/default.nix index fe713c4c..4bde84fc 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -119,6 +119,7 @@ ./pluginmanagers/packer.nix ./pluginmanagers/lazy.nix + ./pluginmanagers/lz-n.nix ./snippets/friendly-snippets.nix ./snippets/luasnip diff --git a/plugins/pluginmanagers/lz-n.nix b/plugins/pluginmanagers/lz-n.nix new file mode 100644 index 00000000..3645f339 --- /dev/null +++ b/plugins/pluginmanagers/lz-n.nix @@ -0,0 +1,200 @@ +{ + lib, + options, + config, + pkgs, + ... +}: +with lib; +let + inherit (lib.nixvim) defaultNullOpts; +in +nixvim.neovim-plugin.mkNeovimPlugin config { + name = "lz-n"; + originalName = "lz.n"; + maintainers = [ maintainers.psfloyd ]; + defaultPackage = pkgs.vimPlugins.lz-n; + + settingsDescription = '' + Options provided to `vim.g.lz_n`. + + `{ load = "fun"; }` -> `vim.g.lz_n = { load = fun, }` + ''; + + settingsOptions = { + load = defaultNullOpts.mkLuaFn "vim.cmd.packadd" '' + Function used by `lz.n` to load plugins. + ''; + }; + + callSetup = false; # Does not use setup + + extraOptions = + let + lzPluginType = types.submodule { + freeformType = types.attrsOf types.anything; + options = { + __unkeyed-1 = mkOption { + type = types.str; + description = '' + The "unkeyed" attribute is the plugin's name. + This is passed to `load` function and should normally match the repo name of the plugin. + + More specifically, this is the name of the folder in `/pack/opt/{name}` that is loaded with `load` (`packadd` by default). + See `:h packadd`. + ''; + }; + + enabled = nixvim.defaultNullOpts.mkStrLuaFnOr types.bool true '' + When false, or if the function returns false, then this plugin will not be included in the spec. + This option corresponds to the `enabled` property of lz.n. + ''; + + beforeAll = nixvim.mkNullOrLuaFn '' + Always executed before any plugins are loaded. + ''; + + before = nixvim.mkNullOrLuaFn '' + Executed before this plugin is loaded. + ''; + + after = nixvim.mkNullOrLuaFn '' + Executed after this plugin is loaded. + ''; + + load = nixvim.mkNullOrLuaFn '' + Can be used to override the `vim.g.lz_n.load()` function for this plugin. + ''; + + priority = nixvim.defaultNullOpts.mkUnsignedInt (literalMD "`50` (or `1000` if `colorscheme` is set)") '' + Only useful for start plugins (not lazy-loaded) to force loading certain plugins first. + ''; + + event = nixvim.mkNullOrOption' { + type = types.anything; + description = '' + Lazy-load on event. Events can be specified as BufEnter or with a pattern like BufEnter *.lua + ''; + example = [ + "BufEnter *.lua" + "DeferredUIEnter" + ]; + }; + + cmd = nixvim.mkNullOrOption' { + type = types.anything; + description = '' + Lazy-load on command. + ''; + example = [ + "Neotree" + "Telescope" + ]; + }; + + ft = nixvim.mkNullOrOption' { + type = types.anything; + description = '' + Lazy-load on filetype. + ''; + example = [ "tex" ]; + }; + + colorscheme = nixvim.mkNullOrOption' { + type = types.anything; + description = '' + Lazy-load on colorscheme. + ''; + example = "onedarker"; + }; + + keys = nixvim.mkNullOrOption' { + type = types.listOf types.anything; + description = '' + Lazy-load on key mapping. Mode is `n` by default. + ''; + example = [ + "" + [ + "" + "g" + ] + { + __unkeyed-1 = "fb"; + __unkeyed-2 = "Telescope buffers"; + desc = "Telescope buffers"; + } + { __raw = "{ 'ft', 'Neotree toggle', desc = 'NeoTree toggle' }"; } + ]; + }; + }; + }; + in + { + plugins = mkOption { + description = '' + List of plugin specs provided to the `require('lz.n').load` function. + Plugin specs can be ${nixvim.nixvimTypes.rawLua.description}. + ''; + default = [ ]; + type = types.listOf lzPluginType; + example = [ + { + __unkeyed-1 = "neo-tree.nvim"; + enabled = '' + function() + return true + end + ''; + keys = [ + { + __unkeyed-1 = "ft"; + __unkeyed-2 = "Neotree toggle"; + desc = "NeoTree toggle"; + } + ]; + after = '' + function() + require("neo-tree").setup() + end + ''; + } + { + __unkeyed-1 = "telescope.nvim"; + cmd = [ "Telescope" ]; + keys = [ + { + __unkeyed-1 = "fa"; + __unkeyed-2 = "Telescope autocommands"; + desc = "Telescope autocommands"; + } + { + __unkeyed-1 = "fb"; + __unkeyed-2 = "Telescope buffers"; + desc = "Telescope buffers"; + } + ]; + } + { + __unkeyed-1 = "onedarker.nvim"; + colorscheme = [ "onedarker" ]; + } + { + __raw = '' + { + "crates.nvim", + ft = "toml", + }, + ''; + } + ]; + }; + }; + + extraConfig = cfg: { + globals.lz_n = modules.mkAliasAndWrapDefsWithPriority id options.plugins.lz-n.settings; + extraConfigLua = mkIf (cfg.plugins != [ ]) '' + require('lz.n').load( ${nixvim.toLuaObject cfg.plugins}) + ''; + }; +} diff --git a/tests/test-sources/plugins/pluginmanagers/lz-n.nix b/tests/test-sources/plugins/pluginmanagers/lz-n.nix new file mode 100644 index 00000000..654670ea --- /dev/null +++ b/tests/test-sources/plugins/pluginmanagers/lz-n.nix @@ -0,0 +1,170 @@ +let + /* + Transform plugins into attrset and set optional to true + This installs the plugin files to {runtimepath}/pack/opt, instead of {runtimepath}/pack/start. + Plugins in pack/opt are not loaded on startup, but can be later loaded with `:packadd {name}` or `require("lz.n").load({name})` + + See `nixpkgs/pkgs/applications/editors/neovim/utils.nix` + See `nixpkgs/pkgs/applications/editors/vim/plugins/vim-utils.nix` + */ + optionalPlugins = map (x: (if x ? plugin then x else { plugin = x; }) // { optional = true; }); +in +{ + # Empty configuration + empty = { + plugins.lz-n.enable = true; + }; + + # Empty configuration + defaults = { + plugins.lz-n = { + enable = true; + settings = { + load.__raw = "vim.cmd.packadd"; + }; + }; + }; + + # single-plugin and priority of plugins.lz-n.settings to globals.lz-n + example-single-plugin = { + module = + { pkgs, lib, ... }: + { + extraPlugins = optionalPlugins [ pkgs.vimPlugins.neo-tree-nvim ]; + + plugins.lz-n = { + enable = true; + settings = { + load = lib.mkDefault "vim.cmd.packadd"; + }; + plugins = [ + # enabled, on keys as rawLua + { + __unkeyed-1 = "neo-tree.nvim"; + enabled = '' + function() + return true + end + ''; + keys = [ + { + __unkeyed-1 = "ft"; + __unkeyed-2 = "Neotree toggle"; + desc = "NeoTree toggle"; + } + ]; + after = # lua + '' + function() + require("neo-tree").setup() + end + ''; + } + ]; + }; + }; + }; + + example-multiple-plugin = { + module = + { pkgs, lib, ... }: + { + extraPlugins = + with pkgs.vimPlugins; + [ onedarker-nvim ] + ++ (optionalPlugins [ + neo-tree-nvim + dial-nvim + vimtex + telescope-nvim + nvim-biscuits + crates-nvim + ]); + + plugins.treesitter.enable = true; + + plugins.lz-n = { + enable = true; + plugins = [ + # enabled, on keys + { + __unkeyed-1 = "neo-tree.nvim"; + enabled = '' + function() + return true + end + ''; + keys = [ + { + __unkeyed-1 = "ft"; + __unkeyed-2 = "Neotree toggle"; + desc = "NeoTree toggle"; + } + ]; + after = # lua + '' + function() + require("neo-tree").setup() + end + ''; + } + # on keys as list of str and rawLua + { + __unkeyed-1 = "dial.nvim"; + keys = [ + "" + { __raw = "{ ''; mode = 'n' }"; } + ]; + } + # beforeAll, before, on filetype + { + __unkeyed-1 = "vimtex"; + ft = [ "plaintex" ]; + beforeAll = # lua + '' + function() + vim.g.vimtex_compiler_method = "latexrun" + end + ''; + before = # lua + '' + function() + vim.g.vimtex_compiler_method = "latexmk" + end + ''; + } + # On event + { + __unkeyed-1 = "nvim-biscuits"; + event.__raw = "{ 'BufEnter *.lua' }"; + after.__raw = '' + function() + require('nvim-biscuits').setup({}) + end + ''; + } + # On command no setup function, priority + { + __unkeyed-1 = "telescope.nvim"; + cmd = [ "Telescope" ]; + priority = 500; + } + # On colorschme + { + __unkeyed-1 = "onedarker.nvim"; + colorscheme = [ "onedarker" ]; + } + # raw value + { + __raw = '' + { + "crates.nvim", + ft = "toml", + } + ''; + } + ]; + }; + }; + }; +}