stevearc / oil.nvim

Neovim file explorer: edit your filesystem like a buffer
MIT License
3.5k stars 99 forks source link

Using rename to move an existing file to a subdirectory #442

Open timtatt opened 1 month ago

timtatt commented 1 month ago

Previously an oil window with

foo.txt

changing to:

bar/foo.txt

would result in the following error "Filename cannot contain path separator"

With this code change, running the above Oil change will create a subdirectory bar if it doesn't exist and will move foo.txt inside

stevearc commented 1 month ago

This currently has the same problems as #400 and #305

mkdir foo
touch foo/a.txt
touch a.txt

Then nvim . and edit the buffer to look like this:

foo/
foo/a.txt    // renamed from a.txt

When you save, it moves a.txt to foo/a.txt, obliterating the pre-existing file.

The reason this feature does not exist yet is because of the difficulty in ensuring that these operations are safe and cannot produce unexpected data loss.

timtatt commented 1 month ago

This currently has the same problems as #400 and #305

mkdir foo
touch foo/a.txt
touch a.txt

Then nvim . and edit the buffer to look like this:

foo/
foo/a.txt    // renamed from a.txt

When you save, it moves a.txt to foo/a.txt, obliterating the pre-existing file.

The reason this feature does not exist yet is because of the difficulty in ensuring that these operations are safe and cannot produce unexpected data loss.

Great points @stevearc, I've pushed a couple ideas to resolve this. Added a file_exists method to the adapter which can be used in the parse phase. Currently only implemented for 'files' adapter due to complexity with async for SSH (open to ideas here).

Below are the use cases I've identified, let me know if I'm missing any. If you're happy with the approach I'll add some tests to tie it up.

  1. When foo/bar.txt exists AND bar.txt is renamed to foo/bar.txt
mkdir foo
touch foo/bar.txt
foo/
foo/bar.txt // renamed from bar.txt

Current Behaviour:

image

New Behaviour:

image
  1. When foo/bar.txt exists AND bar.txt is renamed to bar/bar.txt AND foo/ is renamed to bar/
    • Expect to throw an error that you cannot create a file in a subdirectory while renaming the same directory
mkdir foo
touch foo/bar.txt
touch bar.txt
bar/ // renamed from foo/
bar/bar.txt // renamed from bar.txt
  1. When foo/bar.txt exists AND bar/bar.txt is created AND foo/ is renamed to bar/

3a. bar/bar.txt is below bar/

mkdir foo
touch foo/bar.txt
bar/ // renamed from foo/
bar/bar.txt // added

Previous Behaviour: No actions, the bar/bar.txt file is ignored

New Behaviour:

image

3b. bar/bar.txt is above bar/

mkdir foo
touch foo/bar.txt
bar/bar.txt // added
bar/ // renamed from foo/

Previous Behaviour: If bar/bar.txt is before bar/ in the buffer, it will result in:

image

New Behaviour: Not 100% happy with the error message here, it is using the existing dedup functionality

image
timtatt commented 3 weeks ago

@stevearc what do you think this solution?