feat: remove history command (#2063)
* feat: remove history command * Address code review Co-authored-by: Michael Bøcker-Larsen <247048+mblarsen@users.noreply.github.com> --------- Co-authored-by: Michael Bøcker-Larsen <247048+mblarsen@users.noreply.github.com>
This commit is contained in:
@@ -31,13 +31,15 @@ function M.open(bufnr, cb)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if #selector_items == 0 then
|
if #selector_items == 0 then
|
||||||
Utils.warn("No models available in config")
|
Utils.warn("No history items found.")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local selector = Selector:new({
|
local current_selector -- To be able to close it from the keymap
|
||||||
provider = Config.selector.provider,
|
|
||||||
title = "Select Avante History",
|
current_selector = Selector:new({
|
||||||
|
provider = Config.selector.provider, -- This should be 'native' for the current setup
|
||||||
|
title = "Avante History (Select, then choose action)", -- Updated title
|
||||||
items = vim
|
items = vim
|
||||||
.iter(selector_items)
|
.iter(selector_items)
|
||||||
:map(
|
:map(
|
||||||
@@ -60,8 +62,21 @@ function M.open(bufnr, cb)
|
|||||||
local content = Sidebar.render_history_content(history)
|
local content = Sidebar.render_history_content(history)
|
||||||
return content, "markdown"
|
return content, "markdown"
|
||||||
end,
|
end,
|
||||||
|
on_delete_item = function(item_id_to_delete)
|
||||||
|
if not item_id_to_delete then
|
||||||
|
Utils.warn("No item ID provided for deletion.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
Path.history.delete(bufnr, item_id_to_delete) -- bufnr from M.open's scope
|
||||||
|
-- The native provider handles the UI flow; we just need to refresh.
|
||||||
|
M.open(bufnr, cb) -- Re-open the selector to refresh the list
|
||||||
|
end,
|
||||||
|
on_action_cancel = function()
|
||||||
|
-- If the user cancels the open/delete prompt, re-open the history selector.
|
||||||
|
M.open(bufnr, cb)
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
selector:open()
|
current_selector:open()
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ end
|
|||||||
---@return avante.ChatHistory
|
---@return avante.ChatHistory
|
||||||
function History.load(bufnr, filename)
|
function History.load(bufnr, filename)
|
||||||
local history_filepath = filename and History.get_filepath(bufnr, filename)
|
local history_filepath = filename and History.get_filepath(bufnr, filename)
|
||||||
or History.get_latest_filepath(bufnr, false)
|
or History.get_latest_filepath(bufnr, false)
|
||||||
if history_filepath:exists() then
|
if history_filepath:exists() then
|
||||||
local content = history_filepath:read()
|
local content = history_filepath:read()
|
||||||
if content ~= nil then
|
if content ~= nil then
|
||||||
@@ -154,6 +154,35 @@ History.save = function(bufnr, history)
|
|||||||
History.save_latest_filename(bufnr, history.filename)
|
History.save_latest_filename(bufnr, history.filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Deletes a specific chat history file.
|
||||||
|
---@param bufnr integer
|
||||||
|
---@param filename string
|
||||||
|
function History.delete(bufnr, filename)
|
||||||
|
local history_filepath = History.get_filepath(bufnr, filename)
|
||||||
|
if history_filepath:exists() then
|
||||||
|
local was_latest = (filename == History.get_latest_filename(bufnr, false))
|
||||||
|
history_filepath:rm()
|
||||||
|
|
||||||
|
if was_latest then
|
||||||
|
local remaining_histories = History.list(bufnr) -- This list is sorted by recency
|
||||||
|
if #remaining_histories > 0 then
|
||||||
|
History.save_latest_filename(bufnr, remaining_histories[1].filename)
|
||||||
|
else
|
||||||
|
-- No histories left, clear the latest_filename from metadata
|
||||||
|
local metadata_filepath = History.get_metadata_filepath(bufnr)
|
||||||
|
if metadata_filepath:exists() then
|
||||||
|
local metadata_content = metadata_filepath:read()
|
||||||
|
local metadata = vim.json.decode(metadata_content)
|
||||||
|
metadata.latest_filename = nil -- Or "", depending on desired behavior for an empty latest
|
||||||
|
metadata_filepath:write(vim.json.encode(metadata), "w")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Utils.warn("History file not found: " .. tostring(history_filepath))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
P.history = History
|
P.history = History
|
||||||
|
|
||||||
-- Prompt path
|
-- Prompt path
|
||||||
@@ -210,7 +239,7 @@ function Prompt.get_templates_dir(project_root)
|
|||||||
end
|
end
|
||||||
|
|
||||||
Path:new(debug.getinfo(1).source:match("@?(.*/)"):gsub("/lua/avante/path.lua$", "") .. "templates")
|
Path:new(debug.getinfo(1).source:match("@?(.*/)"):gsub("/lua/avante/path.lua$", "") .. "templates")
|
||||||
:copy({ destination = cache_prompt_dir, recursive = true })
|
:copy({ destination = cache_prompt_dir, recursive = true })
|
||||||
|
|
||||||
vim.iter(Prompt.custom_prompts_contents):filter(function(_, v) return v ~= nil end):each(function(k, v)
|
vim.iter(Prompt.custom_prompts_contents):filter(function(_, v) return v ~= nil end):each(function(k, v)
|
||||||
local orig_file = cache_prompt_dir:joinpath(Prompt.get_builtin_prompts_filepath(k))
|
local orig_file = cache_prompt_dir:joinpath(Prompt.get_builtin_prompts_filepath(k))
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ local Utils = require("avante.utils")
|
|||||||
---@field provider_opts table | nil
|
---@field provider_opts table | nil
|
||||||
---@field on_select fun(item_ids: string[] | nil)
|
---@field on_select fun(item_ids: string[] | nil)
|
||||||
---@field get_preview_content fun(item_id: string): (string, string) | nil
|
---@field get_preview_content fun(item_id: string): (string, string) | nil
|
||||||
|
---@field on_delete_item fun(item_id: string): (nil) | nil
|
||||||
|
---@field on_action_cancel fun(): (nil) | nil
|
||||||
|
|
||||||
---@class avante.ui.Selector
|
---@class avante.ui.Selector
|
||||||
---@field provider avante.SelectorProvider
|
---@field provider avante.SelectorProvider
|
||||||
@@ -23,6 +25,8 @@ local Utils = require("avante.utils")
|
|||||||
---@field on_select fun(item_ids: string[] | nil)
|
---@field on_select fun(item_ids: string[] | nil)
|
||||||
---@field selected_item_ids string[] | nil
|
---@field selected_item_ids string[] | nil
|
||||||
---@field get_preview_content fun(item_id: string): (string, string) | nil
|
---@field get_preview_content fun(item_id: string): (string, string) | nil
|
||||||
|
---@field on_delete_item fun(item_id: string): (nil) | nil
|
||||||
|
---@field on_action_cancel fun(): (nil) | nil
|
||||||
local Selector = {}
|
local Selector = {}
|
||||||
Selector.__index = Selector
|
Selector.__index = Selector
|
||||||
|
|
||||||
@@ -45,6 +49,8 @@ function Selector:new(opts)
|
|||||||
o.on_select = opts.on_select
|
o.on_select = opts.on_select
|
||||||
o.selected_item_ids = opts.selected_item_ids or {}
|
o.selected_item_ids = opts.selected_item_ids or {}
|
||||||
o.get_preview_content = opts.get_preview_content
|
o.get_preview_content = opts.get_preview_content
|
||||||
|
o.on_delete_item = opts.on_delete_item
|
||||||
|
o.on_action_cancel = opts.on_action_cancel
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,39 @@ function M.show(selector)
|
|||||||
prompt = selector.title,
|
prompt = selector.title,
|
||||||
format_item = function(item) return item.title end,
|
format_item = function(item) return item.title end,
|
||||||
}, function(item)
|
}, function(item)
|
||||||
if item then
|
if not item then
|
||||||
selector.on_select({ item.id })
|
|
||||||
else
|
|
||||||
selector.on_select(nil)
|
selector.on_select(nil)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If on_delete_item callback is provided, prompt for action
|
||||||
|
if type(selector.on_delete_item) == "function" then
|
||||||
|
vim.ui.input(
|
||||||
|
{ prompt = "Action for '" .. item.title .. "': (o)pen, (d)elete, (c)ancel?", default = "" },
|
||||||
|
function(input)
|
||||||
|
if not input then -- User cancelled input
|
||||||
|
selector.on_select(nil) -- Treat as cancellation of selection
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local choice = input:lower()
|
||||||
|
if choice == "d" or choice == "delete" then
|
||||||
|
selector.on_delete_item(item.id)
|
||||||
|
elseif choice == "" or choice == "o" or choice == "open" then
|
||||||
|
selector.on_select({ item.id })
|
||||||
|
elseif choice == "c" or choice == "cancel" then
|
||||||
|
if type(selector.on_action_cancel) == "function" then
|
||||||
|
selector.on_action_cancel()
|
||||||
|
else
|
||||||
|
selector.on_select(nil) -- Fallback if on_action_cancel is not defined
|
||||||
|
end
|
||||||
|
else -- c or any other input, treat as cancel
|
||||||
|
selector.on_select(nil) -- Fallback if on_action_cancel is not defined
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
else
|
||||||
|
-- Default behavior: directly select the item
|
||||||
|
selector.on_select({ item.id })
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user