136 lines
4.9 KiB
Lua
136 lines
4.9 KiB
Lua
local Utils = require("avante.utils")
|
|
|
|
local M = {}
|
|
|
|
---@param selector avante.ui.Selector
|
|
function M.show(selector)
|
|
local success, _ = pcall(require, "telescope")
|
|
if not success then
|
|
Utils.error("telescope is not installed. Please install telescope to use it as a file selector.")
|
|
return
|
|
end
|
|
|
|
local pickers = require("telescope.pickers")
|
|
local finders = require("telescope.finders")
|
|
local conf = require("telescope.config").values
|
|
local actions = require("telescope.actions")
|
|
local action_state = require("telescope.actions.state")
|
|
local previewers = require("telescope.previewers")
|
|
|
|
local items = {}
|
|
for _, item in ipairs(selector.items) do
|
|
if not vim.list_contains(selector.selected_item_ids, item.id) then table.insert(items, item) end
|
|
end
|
|
|
|
pickers
|
|
.new(
|
|
{},
|
|
vim.tbl_extend("force", {
|
|
prompt_title = selector.title,
|
|
finder = finders.new_table({
|
|
results = items,
|
|
entry_maker = function(entry)
|
|
return {
|
|
value = entry.id,
|
|
display = entry.title,
|
|
ordinal = entry.title,
|
|
}
|
|
end,
|
|
}),
|
|
sorter = conf.file_sorter(),
|
|
previewer = selector.get_preview_content and previewers.new_buffer_previewer({
|
|
title = "Preview",
|
|
define_preview = function(self, entry)
|
|
if not entry then return end
|
|
local content, filetype = selector.get_preview_content(entry.value)
|
|
local lines = vim.split(content or "", "\n")
|
|
-- Ensure the buffer exists and is valid before setting lines
|
|
if vim.api.nvim_buf_is_valid(self.state.bufnr) then
|
|
vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines)
|
|
-- Set filetype after content is loaded
|
|
vim.api.nvim_set_option_value("filetype", filetype, { buf = self.state.bufnr })
|
|
-- Ensure cursor is within bounds
|
|
vim.schedule(function()
|
|
if vim.api.nvim_buf_is_valid(self.state.bufnr) then
|
|
local row = math.min(vim.api.nvim_buf_line_count(self.state.bufnr), 1)
|
|
pcall(vim.api.nvim_win_set_cursor, self.state.winnr, { row, 0 })
|
|
end
|
|
end)
|
|
end
|
|
end,
|
|
}),
|
|
attach_mappings = function(prompt_bufnr, map)
|
|
map("i", "<esc>", require("telescope.actions").close)
|
|
map("i", "<c-del>", function()
|
|
local picker = action_state.get_current_picker(prompt_bufnr)
|
|
|
|
local selections
|
|
local multi_selection = picker:get_multi_selection()
|
|
if #multi_selection ~= 0 then
|
|
selections = multi_selection
|
|
else
|
|
selections = action_state.get_selected_entry()
|
|
selections = vim.islist(selections) and selections or { selections }
|
|
end
|
|
|
|
local selected_item_ids = vim
|
|
.iter(selections)
|
|
:map(function(selection) return selection.value end)
|
|
:totable()
|
|
|
|
vim.ui.input({ prompt = "Remove·selection?·(" .. #selected_item_ids .. " items) [y/N]" }, function(input)
|
|
if input and input:lower() == "y" then
|
|
for _, item_id in ipairs(selected_item_ids) do
|
|
selector.on_delete_item(item_id)
|
|
end
|
|
|
|
local new_items = {}
|
|
for _, item in ipairs(items) do
|
|
if not vim.list_contains(selected_item_ids, item.id) then table.insert(new_items, item) end
|
|
end
|
|
|
|
local new_finder = finders.new_table({
|
|
results = new_items,
|
|
entry_maker = function(entry)
|
|
return {
|
|
value = entry.id,
|
|
display = entry.title,
|
|
ordinal = entry.title,
|
|
}
|
|
end,
|
|
})
|
|
|
|
picker:refresh(new_finder, { reset_prompt = true })
|
|
end
|
|
end)
|
|
end, { desc = "delete_selection" })
|
|
actions.select_default:replace(function()
|
|
local picker = action_state.get_current_picker(prompt_bufnr)
|
|
|
|
local selections
|
|
local multi_selection = picker:get_multi_selection()
|
|
if #multi_selection ~= 0 then
|
|
selections = multi_selection
|
|
else
|
|
selections = action_state.get_selected_entry()
|
|
selections = vim.islist(selections) and selections or { selections }
|
|
end
|
|
|
|
local selected_item_ids = vim
|
|
.iter(selections)
|
|
:map(function(selection) return selection.value end)
|
|
:totable()
|
|
|
|
selector.on_select(selected_item_ids)
|
|
|
|
pcall(actions.close, prompt_bufnr)
|
|
end)
|
|
return true
|
|
end,
|
|
}, selector.provider_opts)
|
|
)
|
|
:find()
|
|
end
|
|
|
|
return M
|