filemanager-plugin
filemanager-plugin copied to clipboard
Replace current file in buffer instead of splitting into new pane
First of all, thank you for making this. Stellar plugin for a really great lightweight editor.
One thing I really wish I could do is open the selected file and replace the current buffer (and ideally maybe shift + click for new pane) instead of always splitting it into a new pane.
Maybe it is possible to do this already and I am just a bit slow.
Current design is to always open in a new buffer, so no it's not possible at the moment.
I suppose it's not the hardest thing, but I would need a way to do it non-destructively. I don't want it to just throw away whatever you have open. Maybe checking if the pane has changed since last save, then offering to save if needed before actually opening a file in its place.
I have a really hacked-together rough draft of something like this. It has a few bugs, namely that if you close a buffer for a file, and it was the last one you clicked, you need to click to open something else before you can open the original closed buffer again.
-- Tries to open the current index
-- If it's the top dir indicator, or separator, nothing happens
-- If it's ".." then it tries to go back a dir
-- If it's a dir then it moves into the dir and refreshes
-- If it's actually a file, open it in a new vsplit
-- THIS EXPECTS ZERO-BASED Y
-- Store a reference to the last opened file
last_opened_file = nil
local function try_open_at_y(y)
-- 2 is the zero-based index of ".."
if y == 2 then
go_back_dir()
elseif y > 2 and not scanlist_is_empty() then
-- -2 to conform to our scanlist "missing" first 3 indicies
y = y - 2
if scanlist[y].dirmsg ~= "" then
-- if passed path is a directory, update the current dir to be one deeper..
update_current_dir(scanlist[y].abspath)
-- If the targeted file is already open in the buffer, do not re-open
elseif last_opened_file == scanlist[y].abspath then
messenger:Error("File already open")
else
-- If it's a file, then open it
messenger:Message("Filemanager opened ", scanlist[y].abspath)
-- Opens the absolute path in new vertical view
CurView():VSplitIndex(NewBufferFromFile(scanlist[y].abspath), 1)
-- Resizes all views after opening a file
tabs[curTab + 1]:Resize()
-- Update the last opened file to be this one
last_opened_file = scanlist[y].abspath
end
else
messenger:Error("Can't open that")
end
end
Okay I got it.
I just store a table of opened files:
-- Store a reference to the last opened file
open_files ={}
And then in try_open_at_y() I handle adding new file entries into the table and preventing opening duplicate views of files:
if scanlist[y].dirmsg ~= "" then
-- if passed path is a directory, update the current dir to be one deeper..
update_current_dir(scanlist[y].abspath)
-- If the targeted file is already open in a buffer, do not re-open
elseif open_files[scanlist[y].abspath] then
messenger:Error("File already open")
else
-- If it's a file, then open it
messenger:Message("Filemanager opened ", scanlist[y].abspath)
-- Opens the absolute path in new vertical view
CurView():VSplitIndex(NewBufferFromFile(scanlist[y].abspath), 1)
-- Resizes all views after opening a file
tabs[curTab + 1]:Resize()
-- Add the file to the open files table
local filepath = scanlist[y].abspath
-- Set the value to true so we can just do a table lookup
-- Instead of a "pairs(table)" iteration to check for it
open_files[filepath] = true
end
In preQuit() hook, handle removal of table entries:
-- Close current
function preQuit(view)
-- Remove the current file from the open files table
open_files[view.Buf.path] = nil
if view == tree_view then
-- A fake quit function
close_tree()
-- Don't actually "quit", otherwise it closes everything without saving for some reason
return false
end
end
:+1:
It's not a bad idea, but this won't work if a file is opened in a way other than using the filemanager.
Sidenote: make open_files local to avoid conflicts with other plugins.
I personally don't care, but people might be annoyed at this type of change without it being behind an option. It's minor, but someone might open 1 file side-by-side, which this doesn't allow for.
@GavinRay97 do you have a fork somewhere available with this functionality? I'd love to pull it to play with it.
@lowski Hey, I would absolutely share the finished file with you but I've since re-installed my OS and have lost this =(
Sorry. Maybe you can copy-paste those customizations from the code snippets into the plugin lua (if they still work)?
@GavinRay97 thanks for the reply! Unfortunately, I don't think this code will work with micro 2. There is a separate repo for updated plugins.
I analyzed your code and I don't see a change to replace existing buffer - the line to open a file in a new buffer (CurView():VSplitIndex(NewBufferFromFile(scanlist[y].abspath), 1)) is still there. Am I missing something?