feat: split out register backend so it can be used as an external API
Summary:
Split out the register backend function from being a private function. A
backend is a table that will define all of the attributes for a run function.
The attributes are as follows:
- **command** The name of the command that will be registered as a vim user command.
- **items** The callback function that will be passed to the run function that will gather the items for selection
- **callback** The callback function run when an item is selected
The following are optional:
- **keymap** The string passed to `nvim_set_keymap`, this will always be registered in normal mode
- **description** The text description that will be used in the user command
- **name** The name of the backend, this will fallback to the command if its not set
It will also allow to register a backend in a couple of different ways:
- With a backend module table
- With a backend module name
- With a backend module name and override options
This will look for for a lua module `ivy.backends.files`. The module will be
required and registered as a backend.
```lua
register_backend "ivy.backends.files"
```
This will do the same with the module string however, before the backend is
registered the keymap will be overridden
```lua
register_backend({ "ivy.backends.file", { keymap = "<C-p>" } })
```
Test Plan:
CI / Manual testing locally
This commit is contained in:
parent
4803045d4e
commit
91b6db9d76
3 changed files with 132 additions and 26 deletions
54
lua/ivy/register_backend.lua
Normal file
54
lua/ivy/register_backend.lua
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
---@class IvyBackend
|
||||
---@field command string The command this backend will have
|
||||
---@field items fun(input: string): { content: string }[] | string The callback function to get the items to select from
|
||||
---@field callback fun(result: string, action: string) The callback function to run when a item is selected
|
||||
---@field description string? The description of the backend, this will be used in the keymaps
|
||||
---@field name string? The name of the backend, this will fallback to the command if its not set
|
||||
---@field keymap string? The keymap to trigger this backend
|
||||
|
||||
---@class IvyBackendOptions
|
||||
---@field command string The command this backend will have
|
||||
---@field keymap string? The keymap to trigger this backend
|
||||
|
||||
---Register a new backend
|
||||
---
|
||||
---This will create all the commands and set all the keymaps for the backend
|
||||
---@param backend IvyBackend
|
||||
local register_backend_class = function(backend)
|
||||
local user_command_options = { bang = true }
|
||||
if backend.description ~= nil then
|
||||
user_command_options.desc = backend.description
|
||||
end
|
||||
|
||||
local name = backend.name or backend.command
|
||||
vim.api.nvim_create_user_command(backend.command, function()
|
||||
vim.ivy.run(name, backend.items, backend.callback)
|
||||
end, user_command_options)
|
||||
|
||||
if backend.keymap ~= nil then
|
||||
vim.api.nvim_set_keymap("n", backend.keymap, "<cmd>" .. backend.command .. "<CR>", { nowait = true, silent = true })
|
||||
end
|
||||
end
|
||||
|
||||
---@param backend IvyBackend | { ["1"]: string, ["2"]: IvyBackendOptions} | string The backend or backend module
|
||||
---@param options IvyBackendOptions? The options for the backend, that will be merged with the backend
|
||||
local register_backend = function(backend, options)
|
||||
if type(backend[1]) == "string" then
|
||||
options = backend[2]
|
||||
backend = require(backend[1])
|
||||
end
|
||||
|
||||
if type(backend) == "string" then
|
||||
backend = require(backend)
|
||||
end
|
||||
|
||||
if options then
|
||||
for key, value in pairs(options) do
|
||||
backend[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
register_backend_class(backend)
|
||||
end
|
||||
|
||||
return register_backend
|
||||
71
lua/ivy/register_backend_spec.lua
Normal file
71
lua/ivy/register_backend_spec.lua
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
local register_backend = require "ivy.register_backend"
|
||||
|
||||
local function get_command(name)
|
||||
local command_iter = vim.api.nvim_get_commands {}
|
||||
|
||||
for _, cmd in pairs(command_iter) do
|
||||
if cmd.name == name then
|
||||
return cmd
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function get_keymap(mode, rhs)
|
||||
local keymap_iter = vim.api.nvim_get_keymap(mode)
|
||||
for _, keymap in pairs(keymap_iter) do
|
||||
if keymap.rhs == rhs then
|
||||
return keymap
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
describe("register_backend", function()
|
||||
after_each(function()
|
||||
vim.api.nvim_del_user_command "IvyFd"
|
||||
|
||||
local keymap = get_keymap("n", "<Cmd>IvyFd<CR>")
|
||||
if keymap then
|
||||
vim.api.nvim_del_keymap("n", keymap.lhs)
|
||||
end
|
||||
end)
|
||||
|
||||
it("registers a backend from a string with the default options", function()
|
||||
register_backend "ivy.backends.files"
|
||||
|
||||
local command = get_command "IvyFd"
|
||||
assert.is_not_nil(command)
|
||||
|
||||
local keymap = get_keymap("n", "<Cmd>IvyFd<CR>")
|
||||
assert.is_not_nil(keymap)
|
||||
end)
|
||||
|
||||
it("allows you to override the keymap", function()
|
||||
register_backend("ivy.backends.files", { keymap = "<C-p>" })
|
||||
|
||||
local keymap = get_keymap("n", "<Cmd>IvyFd<CR>")
|
||||
assert(keymap ~= nil)
|
||||
assert.are.equal("<C-P>", keymap.lhs)
|
||||
end)
|
||||
|
||||
it("allows you to pass in a hole backend module", function()
|
||||
register_backend(require "ivy.backends.files")
|
||||
|
||||
local command = get_command "IvyFd"
|
||||
assert.is_not_nil(command)
|
||||
|
||||
local keymap = get_keymap("n", "<Cmd>IvyFd<CR>")
|
||||
assert.is_not_nil(keymap)
|
||||
end)
|
||||
|
||||
it("allows you to pass in a hole backend module", function()
|
||||
register_backend { "ivy.backends.files", { keymap = "<C-p>" } }
|
||||
|
||||
local keymap = get_keymap("n", "<Cmd>IvyFd<CR>")
|
||||
assert(keymap ~= nil)
|
||||
assert.are.equal("<C-P>", keymap.lhs)
|
||||
end)
|
||||
end)
|
||||
|
|
@ -1,30 +1,11 @@
|
|||
local controller = require "ivy.controller"
|
||||
local register_backend = require "ivy.register_backend"
|
||||
|
||||
-- Put the controller in to the vim global so we can access it in mappings
|
||||
-- better without requires. You can call controller commands like `vim.ivy.xxx`.
|
||||
-- luacheck: ignore
|
||||
vim.ivy = controller
|
||||
|
||||
local register_backend = function(backend)
|
||||
assert(backend.command, "The backend must have a command")
|
||||
assert(backend.items, "The backend must have a items function")
|
||||
assert(backend.callback, "The backend must have a callback function")
|
||||
|
||||
local user_command_options = { bang = true }
|
||||
if backend.description ~= nil then
|
||||
user_command_options.desc = backend.description
|
||||
end
|
||||
|
||||
local name = backend.name or backend.command
|
||||
vim.api.nvim_create_user_command(backend.command, function()
|
||||
vim.ivy.run(name, backend.items, backend.callback)
|
||||
end, user_command_options)
|
||||
|
||||
if backend.keymap ~= nil then
|
||||
vim.api.nvim_set_keymap("n", backend.keymap, "<cmd>" .. backend.command .. "<CR>", { nowait = true, silent = true })
|
||||
end
|
||||
end
|
||||
|
||||
vim.paste = (function(overridden)
|
||||
return function(lines, phase)
|
||||
local file_type = vim.api.nvim_buf_get_option(0, "filetype")
|
||||
|
|
@ -36,15 +17,15 @@ vim.paste = (function(overridden)
|
|||
end
|
||||
end)(vim.paste)
|
||||
|
||||
register_backend(require "ivy.backends.buffers")
|
||||
register_backend(require "ivy.backends.files")
|
||||
register_backend(require "ivy.backends.lines")
|
||||
register_backend(require "ivy.backends.lsp-workspace-symbols")
|
||||
register_backend "ivy.backends.buffers"
|
||||
register_backend "ivy.backends.files"
|
||||
register_backend "ivy.backends.lines"
|
||||
register_backend "ivy.backends.lsp-workspace-symbols"
|
||||
|
||||
if vim.fn.executable "rg" then
|
||||
register_backend(require "ivy.backends.rg")
|
||||
register_backend "ivy.backends.rg"
|
||||
elseif vim.fn.executable "ag" then
|
||||
register_backend(require "ivy.backends.ag")
|
||||
register_backend "ivy.backends.ag"
|
||||
end
|
||||
|
||||
vim.cmd "highlight IvyMatch cterm=bold gui=bold"
|
||||
|
|
|
|||
Loading…
Reference in a new issue