Move code related to converting history messages into UI representation
from utils into history/render.lua for better code organization and
clean up the implementation.
Code dealing with scanning history messages and extracting some data or
state belongs to avante/history/ so move it there. Along with the move
update the implementation to make use of get_tool_use_data() and
get_tool_result_data() helpers to simplify it.
Also rename the function to History.get_pending_tools() to better
reflect its purpose: "uncalled" means something that was done without
request, unsolicited, not something that has not completed yet.
Simplify the code locating viewed files as well as code locating last
completion attempt by using these new helpers.
Also avoid using "goto" in simple loops.
Tool results are not useful without their "use" messages, so delete them
when deleting "use" ones.
Makes use of the new get_tool_use_data() and get_tool_result_data()
helpers.
There are many places in the code that wants to work with content of
"tool use" and "tool result" messages. Currently such code uses
is_tool_use_message() and is_tool_result() message to check if message
is of right kind, and then pokes into message internals. This is not
very efficient.
Introduce get_tool_use_data() and get_tool_result_data() that would
return contents of the message if it is of right kind, or nil otherwise.
Also introduce get_tool_result() that attempts to locate result of a
tool execution by its invocation ID.
The utils module has grown too big and contains unrelated functionality.
Start moving code related to managing history messages comprising chat
history into lua/avante/history module to keep the code more manageable.
Sorting function in FileSelector:get_filepaths() is not very efficient
since it has to hit the filesystem each time it is called to determine
if it is dealing with a directory or not.
Optimize performance by figuring this data in get_project_filepaths()
and returning a list of structures containing paths and directory flags,
and use this data in get_filepaths(). Do the absolute->relative
conversion once.
Also use vim.fn.isdirectory() instead of vim.loop.fs_stat() everywhere
in the file.
The FileSelector:get_filepaths() function incorrectly filters selected
files due to a mismatch in path formats (relative vs. absolute).
Fix the issue by converting relative file paths to absolute paths before
doing the comparison. Use a set instead of re-scanning the table when
filtering out duplicates.
get_project_filepath() converts candidate file paths to relative form
twice, once in the first iterator, and then in vim.tbl_map() call while.
It also iterates the same list twice for no apparent reason.
Combine both scans into one and use dedicated vim.fn.isdirectory().