2024-10-27 09:19:50 +00:00
|
|
|
local config = require "ivy.config"
|
|
|
|
|
|
2022-07-10 20:07:33 +00:00
|
|
|
-- Constent options that will be used for the keymaps
|
|
|
|
|
local opts = { noremap = true, silent = true, nowait = true }
|
|
|
|
|
|
|
|
|
|
-- All of the base chars that will be used for an "input" operation on the
|
|
|
|
|
-- prompt
|
|
|
|
|
-- stylua: ignore
|
|
|
|
|
local chars = {
|
|
|
|
|
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
|
|
|
|
|
"X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
|
|
|
|
|
"u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<", ">", "`", "@", "#", "~", "!",
|
|
|
|
|
"\"", "$", "%", "^", "&", "/", "(", ")", "=", "+", "*", "-", "_", ".", ",", ";", ":", "?", "\\", "|", "'", "{", "}",
|
|
|
|
|
"[", "]", " ",
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-23 07:49:45 +00:00
|
|
|
local function string_to_table(lines)
|
2022-09-02 19:48:30 +00:00
|
|
|
local matches = {}
|
2022-07-10 20:07:33 +00:00
|
|
|
for line in lines:gmatch "[^\r\n]+" do
|
2022-09-02 19:48:30 +00:00
|
|
|
table.insert(matches, { content = line })
|
2022-07-10 20:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
2022-09-02 19:48:30 +00:00
|
|
|
return matches
|
2022-07-10 20:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
2023-10-22 17:02:50 +00:00
|
|
|
local function get_items_length(items)
|
|
|
|
|
local mt = getmetatable(items)
|
|
|
|
|
if mt ~= nil and mt.__len ~= nil then
|
|
|
|
|
return mt.__len(items)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return #items
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function call_gc(items)
|
|
|
|
|
local mt = getmetatable(items)
|
|
|
|
|
if mt ~= nil and mt.__gc ~= nil then
|
|
|
|
|
return mt.__gc(items)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-27 09:19:50 +00:00
|
|
|
local callbacks = {
|
|
|
|
|
destroy = "<cmd>lua vim.ivy.destroy()<CR>",
|
|
|
|
|
clear = "<cmd>lua vim.ivy.search('')<CR>",
|
|
|
|
|
next = "<cmd>lua vim.ivy.next()<CR>",
|
|
|
|
|
previous = "<cmd>lua vim.ivy.previous()<CR>",
|
|
|
|
|
next_checkpoint = "<cmd>lua vim.ivy.next(); vim.ivy.checkpoint()<CR>",
|
|
|
|
|
previous_checkpoint = "<cmd>lua vim.ivy.previous(); vim.ivy.checkpoint()<CR>",
|
|
|
|
|
|
|
|
|
|
complete = "<cmd>lua vim.ivy.complete(vim.ivy.action.EDIT)<CR>",
|
|
|
|
|
vsplit = "<cmd>lua vim.ivy.complete(vim.ivy.action.VSPLIT)<CR>",
|
|
|
|
|
split = "<cmd>lua vim.ivy.complete(vim.ivy.action.SPLIT)<CR>",
|
|
|
|
|
|
|
|
|
|
backspace = "<cmd>lua vim.ivy.input('BACKSPACE')<CR>",
|
|
|
|
|
left = "<cmd>lua vim.ivy.input('LEFT')<CR>",
|
|
|
|
|
right = "<cmd>lua vim.ivy.input('RIGHT')<CR>",
|
|
|
|
|
delete_word = "<cmd>lua vim.ivy.input('DELETE_WORD')<CR>",
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-10 20:07:33 +00:00
|
|
|
local window = {}
|
|
|
|
|
|
|
|
|
|
window.index = 0
|
2022-07-23 19:17:31 +00:00
|
|
|
window.origin = nil
|
2022-07-10 20:07:33 +00:00
|
|
|
window.window = nil
|
|
|
|
|
window.buffer = nil
|
2023-03-01 08:23:07 +00:00
|
|
|
window.origin_buffer = nil
|
2022-07-10 20:07:33 +00:00
|
|
|
|
|
|
|
|
window.initialize = function()
|
|
|
|
|
window.make_buffer()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
window.make_buffer = function()
|
2022-07-23 19:17:31 +00:00
|
|
|
window.origin = vim.api.nvim_get_current_win()
|
2023-03-01 08:23:07 +00:00
|
|
|
window.origin_buffer = vim.api.nvim_win_get_buf(0)
|
2022-07-10 20:07:33 +00:00
|
|
|
|
|
|
|
|
vim.api.nvim_command "botright split new"
|
|
|
|
|
window.buffer = vim.api.nvim_win_get_buf(0)
|
|
|
|
|
window.window = vim.api.nvim_get_current_win()
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_win_set_option(window.window, "number", false)
|
|
|
|
|
vim.api.nvim_win_set_option(window.window, "relativenumber", false)
|
|
|
|
|
vim.api.nvim_win_set_option(window.window, "signcolumn", "no")
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_buf_set_option(window.buffer, "filetype", "ivy")
|
|
|
|
|
vim.api.nvim_buf_set_var(window.buffer, "bufftype", "nofile")
|
|
|
|
|
|
|
|
|
|
for index = 1, #chars do
|
|
|
|
|
local char = chars[index]
|
|
|
|
|
if char == "'" then
|
|
|
|
|
char = "\\'"
|
|
|
|
|
end
|
|
|
|
|
if char == "\\" then
|
|
|
|
|
char = "\\\\\\\\"
|
|
|
|
|
end
|
|
|
|
|
vim.api.nvim_buf_set_keymap(window.buffer, "n", chars[index], "<cmd>lua vim.ivy.input('" .. char .. "')<CR>", opts)
|
|
|
|
|
end
|
|
|
|
|
|
2024-10-27 09:19:50 +00:00
|
|
|
local mappings = config:get { "mappings" }
|
|
|
|
|
assert(mappings, "The mappings key is missing from the config, something has gone horribly wrong")
|
|
|
|
|
for key, value in pairs(mappings) do
|
|
|
|
|
if callbacks[value] == nil then
|
|
|
|
|
error("The mapping '" .. value .. "' is not a valid ivy callback")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_buf_set_keymap(window.buffer, "n", key, callbacks[value], opts)
|
|
|
|
|
end
|
2022-07-10 20:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
window.get_current_selection = function()
|
|
|
|
|
local line = vim.api.nvim_buf_get_lines(window.buffer, window.index, window.index + 1, true)
|
|
|
|
|
if line == nil then
|
|
|
|
|
line = { "" }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return line[1]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
window.get_buffer = function()
|
|
|
|
|
if window.buffer == nil then
|
|
|
|
|
window.make_buffer()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return window.buffer
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
window.update = function()
|
|
|
|
|
vim.api.nvim_win_set_cursor(window.window, { window.index + 1, 0 })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
window.set_items = function(items)
|
2022-09-02 19:48:30 +00:00
|
|
|
if type(items) == "string" then
|
|
|
|
|
items = string_to_table(items)
|
|
|
|
|
end
|
|
|
|
|
|
2023-10-22 17:02:50 +00:00
|
|
|
local items_length = get_items_length(items)
|
|
|
|
|
|
2022-09-02 19:48:30 +00:00
|
|
|
-- TODO(ade): Validate the items are in the correct format. This also need to
|
|
|
|
|
-- come with some descriptive messages and possible help.
|
|
|
|
|
|
|
|
|
|
-- Display no items text if there are no items to dispaly
|
2023-10-22 17:02:50 +00:00
|
|
|
if items_length == 0 then
|
|
|
|
|
items_length = 1
|
2022-09-04 15:13:02 +00:00
|
|
|
items = { { content = "-- No Items --" } }
|
2022-09-02 19:48:30 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
window.index = items_length - 1
|
|
|
|
|
|
|
|
|
|
for index = 1, items_length do
|
|
|
|
|
vim.api.nvim_buf_set_lines(window.buffer, index - 1, -1, false, { items[index].content })
|
2022-07-10 20:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
2022-09-02 19:48:30 +00:00
|
|
|
-- Limit the results window size to 10 so when there are lots of results the
|
|
|
|
|
-- window does not take up the hole terminal
|
2022-09-02 20:30:32 +00:00
|
|
|
local line_count = items_length
|
2022-07-10 20:07:33 +00:00
|
|
|
if line_count > 10 then
|
|
|
|
|
line_count = 10
|
|
|
|
|
end
|
|
|
|
|
|
2022-07-23 07:49:45 +00:00
|
|
|
vim.api.nvim_win_set_height(window.window, line_count)
|
2022-07-10 20:07:33 +00:00
|
|
|
window.update()
|
2023-10-22 17:02:50 +00:00
|
|
|
|
|
|
|
|
call_gc(items)
|
2022-07-10 20:07:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
window.destroy = function()
|
|
|
|
|
if type(window.buffer) == "number" then
|
|
|
|
|
vim.api.nvim_buf_delete(window.buffer, { force = true })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
window.buffer = nil
|
|
|
|
|
window.window = nil
|
2022-07-23 19:17:31 +00:00
|
|
|
window.origin = nil
|
2023-03-01 08:23:07 +00:00
|
|
|
window.origin_buffer = nil
|
2022-07-10 20:07:33 +00:00
|
|
|
window.index = 0
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return window
|