diff --git a/README.md b/README.md index 98b03b6..ff2d3bd 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ A [neovim] plugin and configuration management plugin, highly inspired by [lazy] - [X] Lazy load your plugins - [X] on command - [X] on filetype - - [ ] on event + - [X] on event - [ ] on keybinding - [X] load plugins in order (via plugin `dependencies` property) - [X] Have a `:Sloth` command to load or query your plugins @@ -164,8 +164,9 @@ The Plugin configuration object accepts the following properties: | `config` | `null` | Lua code (as string of path) to call after loading the plugin | | `dependencies` | `[]` | The plugin dependencies³ | | `lazy` | `false` | Should the plugin be loaded lazily | -| `cmd` | `[]` | Command to put as place_holder to lazy load the plugin⁴ | -| `ft` | `[]` | Filetype to watch to lazy load the plugin⁴ | +| `cmd` | `[]` | Command to put as place_holder to load the lazy plugin⁴ | +| `ft` | `[]` | Filetype to watch to load the lazy plugin⁴ | +| `events` | `[]` | Events to watch to load the lazy plugin⁴⁵ | > ² The plugin can be either a nix package or an object with only `name` and > `src` as properties. The latter will be used to create a nix package of your @@ -178,6 +179,17 @@ The Plugin configuration object accepts the following properties: > ⁴ Setting this property implicitly set `lazy` to `true`. +> ⁵ Events can be a string, an Event object or a list of either. You can +> represent a simple event name and pattern with the following string format : +> "BufRead *.md". + +The Event configuration object accepts the following properties: + +| name | default | description | +|-----------|---------|----------------------------------------------------------------| +| `name` | N/A | The name of the event as string or list of string **REQUIRED** | +| `pattern` | `null` | Pattern (as string or list of string) associated to the event | + ### neovim (lua) #### Using default `init.lua` diff --git a/lib/deps.nix b/lib/deps.nix index 73d5773..33bda61 100644 --- a/lib/deps.nix +++ b/lib/deps.nix @@ -6,14 +6,19 @@ types, ... }: let - inherit (builtins) isPath foldl'; + inherit (builtins) foldl' isPath isList isString mapAttrs match elemAt; inherit (lib.attrsets) attrNames optionalAttrs; inherit (lib.lists) concatMap; - inherit (lib.strings) fileContents; + inherit (lib.strings) fileContents splitString; lua = callPackage ./lua.nix {}; - callPackage = lib.callPackageWith (pkgs // dependenciesExtraArgs); + hasMatch = pattern: str: isList (match pattern str); + wrapArray = value: + if isList value + then value + else [value]; + defaultPlugin = { enabled = true; init = null; @@ -22,6 +27,7 @@ lazy = false; cmd = []; ft = []; + events = []; }; remotePluginToNeovimPlugin = p: @@ -30,6 +36,26 @@ pname = name; }; + normalizeEvent = event: let + value = + if ! isString event + then event + else + if ! hasMatch ".* .*" event + then {name = event;} + else let + part = elemAt (splitString " " event); + in { + name = part 0; + pattern = part 1; + }; + in + mapAttrs (_: wrapArray) value; + normalizeEvents = events: + if isList events + then map normalizeEvent events + else [(normalizeEvent events)]; + withPluginDefaults = dep: defaultPlugin // dep; normalizePlugin = d: let dep = types.dependency d; @@ -48,7 +74,9 @@ // rec { hasCommands = p.cmd != []; hasFileTypes = p.ft != []; - lazy = p.lazy || hasCommands || hasFileTypes; + events = normalizeEvents p.events; + hasEvents = p.events != []; + lazy = p.lazy || hasCommands || hasFileTypes || hasEvents; optional = lazy || p.init != null; }; @@ -137,6 +165,9 @@ }) // (optionalAttrs plugin.hasFileTypes { inherit (plugin) ft; + }) + // (optionalAttrs plugin.hasEvents { + inherit (plugin) events; }); }; pluginsLuaDef = plugins: diff --git a/lib/types.nix b/lib/types.nix index 9ad29cb..de8bd55 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -22,6 +22,12 @@ src = any; }; + eventType = with yants; + struct "event" { + name = either string stringList; + pattern = either string stringList; + }; + # The plugin type of dependencies pluginType = with yants; let stringList = list string; @@ -49,7 +55,7 @@ lazy = option bool; # List of events on which the plugin should be loaded - # events = option stringList; + events = option (eitherN [string eventType (list (either string eventType))]); # List of commands on which the plugin should be loaded cmd = option stringList; diff --git a/lua/sloth-flake/dep.lua b/lua/sloth-flake/dep.lua index 1550cbb..d3a12ee 100644 --- a/lua/sloth-flake/dep.lua +++ b/lua/sloth-flake/dep.lua @@ -28,15 +28,29 @@ function M.new(values) end end - if self.ft then + if self.has_events then local group_id = vim.api.nvim_create_augroup(self.augroup_name, { clear = true, }) - vim.api.nvim_create_autocmd('FileType', { - group = group_id, - pattern = self.ft, - callback = self:lazy_load_ft() - }) + + if self.ft then + vim.api.nvim_create_autocmd('FileType', { + group = group_id, + pattern = self.ft, + callback = self:lazy_load_event('FileType') + }) + end + + if self.events then + for _, event in ipairs(self.events) do + -- print("register event", event.name, "for pattern", event.pattern) + vim.api.nvim_create_autocmd(event.name, { + group = group_id, + pattern = event.pattern, + callback = self:lazy_load_event(event.name) + }) + end + end end end, [State.Inited] = function() @@ -73,7 +87,7 @@ function M.new(values) end end - if self.ft then + if self.has_events then vim.api.nvim_del_augroup_by_name(self.augroup_name) end end, @@ -134,6 +148,10 @@ function M:get_ft() return self.values.ft end +function M:get_events() + return self.values.events +end + function M:get_is_lazy() return self.values.lazy or false end @@ -150,6 +168,10 @@ function M:get_is_loaded() return self.state >= State.Loaded end +function M:get_has_events() + return self.ft or self.events +end + function M:get_augroup_name() return "Sloth-plugin-" .. self.name end @@ -187,10 +209,10 @@ function M:lazy_load_cmd(cmd) end end -function M:lazy_load_ft() +function M:lazy_load_event(name) return function(param) self:load() - vim.api.nvim_exec_autocmds('FileType', { + vim.api.nvim_exec_autocmds(name, { pattern = param.match, }) end