refactor: introduce backend concept and split out finders / sorters

We now have a concept of a 'backend' this is the same as the current
sorters and finders but with added info like the keymap so they can all
be registered as one. This will allow us to split our backends into
modues so we can better maintain then.
This commit is contained in:
Ade Attwood 2023-03-01 08:17:23 +00:00
parent 43d7e11c8b
commit 45068e759d
5 changed files with 119 additions and 60 deletions

12
lua/ivy/backends/ag.lua Normal file
View file

@ -0,0 +1,12 @@
local utils = require "ivy.utils"
local ag = {
name = "AG",
command = "IvyAg",
description = "Run ag to search for content in files",
keymap = "<leader>/",
items = utils.command_finder "ag",
callback = utils.vimgrep_action(),
}
return ag

View file

@ -0,0 +1,38 @@
local libivy = require "ivy.libivy"
local utils = require "ivy.utils"
local function items(input)
local list = {}
local buffers = vim.api.nvim_list_bufs()
for index = 1, #buffers do
local buffer = buffers[index]
-- Get the relative path from the current working directory. We need to
-- substring +2 to remove the `/` from the start of the path to give us a
-- true relative path
local buffer_name = vim.api.nvim_buf_get_name(buffer):sub(#vim.fn.getcwd() + 2, -1)
local file_type = vim.api.nvim_buf_get_option(buffer, "filetype")
if vim.api.nvim_buf_is_loaded(buffer) and file_type ~= "ivy" and #buffer_name > 0 then
local score = libivy.ivy_match(input, buffer_name)
if score > -200 or #input == 0 then
table.insert(list, { score = score, content = buffer_name })
end
end
end
table.sort(list, function(a, b)
return a.score < b.score
end)
return list
end
local buffers = {
name = "Buffers",
command = "IvyBuffers",
description = "List all of the current open buffers",
keymap = "<leader>b",
items = items,
callback = utils.file_action(),
}
return buffers

View file

@ -0,0 +1,17 @@
local libivy = require "ivy.libivy"
local utils = require "ivy.utils"
local function items(term)
return libivy.ivy_files(term, vim.fn.getcwd())
end
local files = {
name = "Files",
command = "IvyFd",
description = "Find files in the project",
keymap = "<leader>p",
items = items,
callback = utils.file_action(),
}
return files

View file

@ -0,0 +1,32 @@
local utils = require "ivy.utils"
local libivy = require "ivy.libivy"
local function items(input)
local list = {}
local lines = vim.api.nvim_buf_get_lines(vim.ivy.origin(), 0, -1, false)
for index = 1, #lines do
local line = lines[index]
local score = libivy.ivy_match(input, line)
if score > -200 then
local prefix = string.rep(" ", 4 - #tostring(index)) .. index .. ": "
table.insert(list, { score = score, content = prefix .. line })
end
end
table.sort(list, function(a, b)
return a.score < b.score
end)
return list
end
local lines = {
name = "Lines",
command = "IvyLines",
description = "Search though the lines in the current buffer",
items = items,
callback = utils.line_action(),
}
return lines

View file

@ -1,73 +1,33 @@
local controller = require "ivy.controller"
local utils = require "ivy.utils"
local libivy = require "ivy.libivy"
-- 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
vim.api.nvim_create_user_command("IvyAg", function()
vim.ivy.run("AG", utils.command_finder "ag", utils.vimgrep_action())
end, { bang = true, desc = "Run ag to search for content in files" })
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")
vim.api.nvim_create_user_command("IvyFd", function()
vim.ivy.run("Files", function(term)
return libivy.ivy_files(term, vim.fn.getcwd())
end, utils.file_action())
end, { bang = true, desc = "Find files in the project" })
local user_command_options = { bang = true }
if backend.description ~= nil then
user_command_options.desc = backend.description
end
vim.api.nvim_create_user_command("IvyBuffers", function()
vim.ivy.run("Buffers", function(input)
local list = {}
local buffers = vim.api.nvim_list_bufs()
for index = 1, #buffers do
local buffer = buffers[index]
-- Get the relative path from the current working directory. We need to
-- substring +2 to remove the `/` from the start of the path to give us a
-- true relative path
local buffer_name = vim.api.nvim_buf_get_name(buffer):sub(#vim.fn.getcwd() + 2, -1)
local file_type = vim.api.nvim_buf_get_option(buffer, "filetype")
if vim.api.nvim_buf_is_loaded(buffer) and file_type ~= "ivy" and #buffer_name > 0 then
local score = libivy.ivy_match(input, buffer_name)
if score > -200 or #input == 0 then
table.insert(list, { score = score, content = buffer_name })
end
end
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)
table.sort(list, function(a, b)
return a.score < b.score
end)
if backend.keymap ~= nil then
vim.api.nvim_set_keymap("n", backend.keymap, "<cmd>" .. backend.command .. "<CR>", { nowait = true, silent = true })
end
end
return list
end, utils.file_action())
end, { bang = true, desc = "List all of the current open buffers" })
vim.api.nvim_create_user_command("IvyLines", function()
vim.ivy.run("Lines", function(input)
local list = {}
local lines = vim.api.nvim_buf_get_lines(vim.ivy.origin(), 0, -1, false)
for index = 1, #lines do
local line = lines[index]
local score = libivy.ivy_match(input, line)
if score > -200 then
local prefix = string.rep(" ", 4 - #tostring(index)) .. index .. ": "
table.insert(list, { score = score, content = prefix .. line })
end
end
table.sort(list, function(a, b)
return a.score < b.score
end)
return list
end, utils.line_action())
end, { bang = true, desc = "List all of the current open buffers" })
vim.api.nvim_set_keymap("n", "<leader>b", "<cmd>IvyBuffers<CR>", { nowait = true, silent = true })
vim.api.nvim_set_keymap("n", "<leader>p", "<cmd>IvyFd<CR>", { nowait = true, silent = true })
vim.api.nvim_set_keymap("n", "<leader>/", "<cmd>IvyAg<CR>", { nowait = true, silent = true })
register_backend(require "ivy.backends.ag")
register_backend(require "ivy.backends.buffers")
register_backend(require "ivy.backends.files")
register_backend(require "ivy.backends.lines")
vim.cmd "highlight IvyMatch cterm=bold gui=bold"