Skip to content

Commit

Permalink
feat(api): ability to filter plugin searches by handlers (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcjkb authored Aug 22, 2024
1 parent 8d06940 commit 33a8b19
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 17 deletions.
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,12 +389,12 @@ require("lz.n").register_handler(handler)
#### `lz.n.Handler`

<!-- markdownlint-disable MD013 -->
| Property | Type | Description |
| --- | --- | --- |
| spec_field | `string` | the `lz.n.PluginSpec` field used to configure the handler |
| add | `fun(plugin: lz.n.Plugin)` | adds a plugin to the handler |
| del | `fun(name: string)` | removes a plugin from the handler by name |
| lookup | `fun(name: string):lz.n.Plugin?` | lookup a plugin managed by this handler by name |
| Property | Type | Description |
| --- | --- | --- |
| spec_field | `string` | the `lz.n.PluginSpec` field used to configure the handler |
| add | `fun(plugin: lz.n.Plugin)` | adds a plugin to the handler |
| del | `fun(name: string)` | removes a plugin from the handler by name |
| lookup | `fun(name: string` | lookup a plugin managed by this handler by name |
<!-- markdownlint-enable MD013 -->

> [!TIP]
Expand All @@ -419,7 +419,8 @@ You can manually load a plugin (and run the hooks from the spec)
with the following function:

```lua
---@type fun(plugins: string | string[] | lz.n.Plugin | lz.n.Plugin[])
---@overload fun(plugin: lz.n.Plugin | lz.n.Plugin[])
---@overload fun(plugin: string | string[], opts: lz.n.lookup.Opts)
require('lz.n').trigger_load
```

Expand Down Expand Up @@ -454,10 +455,21 @@ As a result, calling `trigger_load` with a plugin name is idempotent.
To lookup a plugin that is pending to be loaded by name, use:

```lua
---@type fun(name: string):lz.n.Plugin?
---@type fun(name: string, opts: lz.n.lookup.Opts):lz.n.Plugin?
require('lz.n').lookup
```

The lookup, as well as `trigger_load(string|string[])` can be
fine-tuned with a `lz.n.lookup.Opts` table:

```lua
--- The handlers to include in the search (filtered by `spec_field`)
--- In case of multiple filters, the order of the filter list
--- determines the order in which handlers' `lookup` functions are called.
---@field filter string | string[]
---@class lz.n.lookup.Opts
```

## :green_heart: Contributing

All contributions are welcome!
Expand Down
21 changes: 18 additions & 3 deletions lua/lz/n/handler/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,27 @@ local handlers = {
}

---@param name string
---@param opts? lz.n.lookup.Opts
---@return lz.n.Plugin?
function M.lookup(name)
function M.lookup(name, opts)
---@type string | string[] | nil
local filter = opts and vim.tbl_get(opts, "filter")
if type(filter) == "string" then
filter = { filter }
end
---@type lz.n.Handler[]
local handler_list = filter
and vim.iter(filter)
:map(function(key)
return handlers[key]
end)
:totable()
or vim.tbl_values(handlers)
---@cast filter string[] | nil
return vim
.iter(handlers)
.iter(handler_list)
---@param handler lz.n.Handler
:map(function(_, handler)
:map(function(handler)
return handler.lookup(name)
end)
---@param result lz.n.Plugin?
Expand Down
22 changes: 16 additions & 6 deletions lua/lz/n/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ end
--- Once a plugin has been loaded, it will be removed from all handlers (via `del`).
--- As a result, calling `trigger_load` with a plugin name is stateful and idempotent.
---@overload fun(plugins: lz.n.Plugin | string[] | lz.n.Plugin[] | table<unknown, lz.n.Plugin>)
---@overload fun(plugins: string | string[])
M.trigger_load = function(plugins)
require("lz.n.loader").load(plugins, M.lookup)
---@overload fun(plugins: string | string[], opts: lz.n.lookup.Opts)
M.trigger_load = function(plugins, opts)
require("lz.n.loader").load(plugins, function(name)
return M.lookup(name, opts)
end)
end

---@overload fun(spec: lz.n.Spec)
Expand Down Expand Up @@ -63,11 +65,19 @@ function M.load(spec)
end
end

---Lookup a plugin that is pending to be loaded by name.
--- Lookup a plugin that is pending to be loaded by name.
---@param name string
---@param opts? lz.n.lookup.Opts
---@return lz.n.Plugin?
function M.lookup(name)
return require("lz.n.handler").lookup(name)
function M.lookup(name, opts)
return require("lz.n.handler").lookup(name, opts)
end

---@class lz.n.lookup.Opts
---
--- The handlers to include in the search (filtered by `spec_field`)
--- In case of multiple filters, the order of the filter list
--- determines the order in which handlers' `lookup` functions are called.
---@field filter string | string[]

return M
33 changes: 33 additions & 0 deletions spec/lookup_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
vim.g.lz_n = {
load = function() end,
}
local lz = require("lz.n")

---@type lz.n.PluginSpec
local cmd_testplugin = {
"lookup_testplugin",
cmd = "Telescope",
}
lz.load(cmd_testplugin)

---@type lz.n.PluginSpec
local colorscheme_testplugin = {
"lookup_testplugin",
colorscheme = "sweetie",
}
lz.load(colorscheme_testplugin)

describe("lookup", function()
it("can influence which handlers to search", function()
local result = lz.lookup("lookup_testplugin", { filter = "cmd" })
assert.is_not_nil(result and result.cmd)
result = lz.lookup("lookup_testplugin", { filter = "colorscheme" })
assert.is_not_nil(result and result.colorscheme)
end)
it("can influence the order in which handlers are searched", function()
local result = lz.lookup("lookup_testplugin", { filter = { "cmd", "colorscheme" } })
assert.is_not_nil(result and result.cmd)
result = lz.lookup("lookup_testplugin", { filter = { "colorscheme", "cmd" } })
assert.is_not_nil(result and result.colorscheme)
end)
end)

0 comments on commit 33a8b19

Please sign in to comment.