feat: prompt user to save changes before editing moved file/dir (#93)

This commit is contained in:
Steven Arcangeli 2023-05-06 22:48:37 -07:00
parent 3cbebc2b0c
commit 6b05c2e913
7 changed files with 39 additions and 10 deletions

View file

@ -154,6 +154,8 @@ require("oil").setup({
skip_confirm_for_simple_edits = false,
-- Deleted files will be removed with the `trash-put` command.
delete_to_trash = false,
-- Selecting a new/moved/renamed file or directory will prompt you to save changes first
prompt_save_on_select_new_entry = true,
-- Keymaps in oil buffer. Can be any value that `vim.keymap.set` accepts OR a table of keymap
-- options with a `callback` (e.g. { callback = function() ... end, desc = "", nowait = true })
-- Additionally, if it is a string that matches "actions.<name>",

View file

@ -45,6 +45,8 @@ OPTIONS *oil-option
skip_confirm_for_simple_edits = false,
-- Deleted files will be removed with the `trash-put` command.
delete_to_trash = false,
-- Selecting a new/moved/renamed file or directory will prompt you to save changes first
prompt_save_on_select_new_entry = true,
-- Keymaps in oil buffer. Can be any value that `vim.keymap.set` accepts OR a table of keymap
-- options with a `callback` (e.g. { callback = function() ... end, desc = "", nowait = true })
-- Additionally, if it is a string that matches "actions.<name>",

View file

@ -30,6 +30,8 @@ local default_config = {
skip_confirm_for_simple_edits = false,
-- Deleted files will be removed with the `trash-put` command.
delete_to_trash = false,
-- Selecting a new/moved/renamed file or directory will prompt you to save changes first
prompt_save_on_select_new_entry = true,
-- Keymaps in oil buffer. Can be any value that `vim.keymap.set` accepts OR a table of keymap
-- options with a `callback` (e.g. { callback = function() ... end, desc = "", nowait = true })
-- Additionally, if it is a string that matches "actions.<name>",

View file

@ -6,6 +6,7 @@ local M = {}
---@field name string
---@field type oil.EntryType
---@field id nil|integer Will be nil if it hasn't been persisted to disk yet
---@field parsed_name nil|string
---@alias oil.EntryType "file"|"directory"|"socket"|"link"
---@alias oil.TextChunk string|string[]
@ -47,11 +48,14 @@ M.get_entry_on_line = function(bufnr, lnum)
local result = parser.parse_line(adapter, line, column_defs)
if result then
if result.entry then
return util.export_entry(result.entry)
local entry = util.export_entry(result.entry)
entry.parsed_name = result.data.name
return entry
else
return {
name = result.data.name,
type = result.data._type,
parsed_name = result.data.name,
}
end
end
@ -70,6 +74,7 @@ M.get_entry_on_line = function(bufnr, lnum)
return {
name = name,
type = entry_type,
parsed_name = name,
}
end
end
@ -399,6 +404,7 @@ end
--- tab boolean Open the buffer in a new tab
M.select = function(opts)
local cache = require("oil.cache")
local config = require("oil.config")
opts = vim.tbl_extend("keep", opts or {}, {})
if opts.horizontal or opts.vertical or opts.preview then
opts.split = opts.split or "belowright"
@ -451,12 +457,34 @@ M.select = function(opts)
vim.notify("Cannot preview multiple entries", vim.log.levels.WARN)
entries = { entries[1] }
end
-- Check if any of these entries are moved from their original location
local bufname = vim.api.nvim_buf_get_name(0)
local any_moved = false
for _, entry in ipairs(entries) do
local is_new_entry = entry.id == nil
local is_moved_from_dir = entry.id and cache.get_parent_url(entry.id) ~= bufname
local is_renamed = entry.parsed_name ~= entry.name
if is_new_entry or is_moved_from_dir or is_renamed then
any_moved = true
break
end
end
if any_moved and not opts.preview and config.prompt_save_on_select_new_entry then
local ok, choice = pcall(vim.fn.confirm, "Save changes?", "Yes\nNo", 1)
if not ok then
return
elseif choice == 1 then
M.save()
return
end
end
-- Close the preview window if we're not previewing the selection
local preview_win = util.get_preview_win()
if not opts.preview and preview_win then
vim.api.nvim_win_close(preview_win, true)
end
local bufname = vim.api.nvim_buf_get_name(0)
local prev_win = vim.api.nvim_get_current_win()
for _, entry in ipairs(entries) do
local scheme, dir = util.parse_url(bufname)

View file

@ -528,7 +528,7 @@ M.try_write_changes = function(confirm)
-- get the entry under the cursor and make sure the cursor stays on it
view.set_last_cursor(
vim.api.nvim_buf_get_name(0),
vim.split(current_entry.name, "/")[1]
vim.split(current_entry.parsed_name or current_entry.name, "/")[1]
)
end
view.rerender_all_oil_buffers({ preserve_undo = M.trash })

View file

@ -2,10 +2,4 @@ vim.cmd([[set runtimepath+=.]])
vim.o.swapfile = false
vim.bo.swapfile = false
require("oil").setup({
columms = {},
adapters = {
["oil-test://"] = "test",
},
silence_disclaimer = true,
})
require("tests.test_util").reset_editor()

View file

@ -9,6 +9,7 @@ M.reset_editor = function()
["oil-test://"] = "test",
},
silence_disclaimer = true,
prompt_save_on_select_new_entry = false,
})
vim.cmd.tabonly({ mods = { silent = true } })
for i, winid in ipairs(vim.api.nvim_tabpage_list_wins(0)) do