feat(clipboard): pasting from system clipboard can delete original (cut) (#649)
* feat: cut_from_system_clipboard * refactor: shuffle some code around --------- Co-authored-by: Steven Arcangeli <stevearc@stevearc.com>
This commit is contained in:
parent
64dbcaa91d
commit
f55ebb0079
3 changed files with 51 additions and 6 deletions
|
|
@ -575,6 +575,9 @@ parent *actions.paren
|
||||||
paste_from_system_clipboard *actions.paste_from_system_clipboard*
|
paste_from_system_clipboard *actions.paste_from_system_clipboard*
|
||||||
Paste the system clipboard into the current oil directory
|
Paste the system clipboard into the current oil directory
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
{delete_original} `boolean` Delete the original file after copying
|
||||||
|
|
||||||
preview *actions.preview*
|
preview *actions.preview*
|
||||||
Open the entry under the cursor in a preview window, or close the preview
|
Open the entry under the cursor in a preview window, or close the preview
|
||||||
window if already open
|
window if already open
|
||||||
|
|
|
||||||
|
|
@ -438,9 +438,15 @@ M.copy_to_system_clipboard = {
|
||||||
|
|
||||||
M.paste_from_system_clipboard = {
|
M.paste_from_system_clipboard = {
|
||||||
desc = "Paste the system clipboard into the current oil directory",
|
desc = "Paste the system clipboard into the current oil directory",
|
||||||
callback = function()
|
callback = function(opts)
|
||||||
require("oil.clipboard").paste_from_system_clipboard()
|
require("oil.clipboard").paste_from_system_clipboard(opts and opts.delete_original)
|
||||||
end,
|
end,
|
||||||
|
parameters = {
|
||||||
|
delete_original = {
|
||||||
|
type = "boolean",
|
||||||
|
desc = "Delete the original file after copying",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
M.open_cmdline_dir = {
|
M.open_cmdline_dir = {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ local columns = require("oil.columns")
|
||||||
local config = require("oil.config")
|
local config = require("oil.config")
|
||||||
local fs = require("oil.fs")
|
local fs = require("oil.fs")
|
||||||
local oil = require("oil")
|
local oil = require("oil")
|
||||||
|
local parser = require("oil.mutator.parser")
|
||||||
local util = require("oil.util")
|
local util = require("oil.util")
|
||||||
local view = require("oil.view")
|
local view = require("oil.view")
|
||||||
|
|
||||||
|
|
@ -50,8 +51,31 @@ local function write_pasted(winid, entry, column_defs, adapter, bufnr)
|
||||||
vim.api.nvim_buf_set_lines(bufnr, pos[1], pos[1], true, lines)
|
vim.api.nvim_buf_set_lines(bufnr, pos[1], pos[1], true, lines)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param parent_url string
|
||||||
|
---@param entry oil.InternalEntry
|
||||||
|
local function remove_entry_from_parent_buffer(parent_url, entry)
|
||||||
|
local bufnr = vim.fn.bufadd(parent_url)
|
||||||
|
assert(vim.api.nvim_buf_is_loaded(bufnr), "Expected parent buffer to be loaded during paste")
|
||||||
|
local adapter = assert(util.get_adapter(bufnr))
|
||||||
|
local column_defs = columns.get_supported_columns(adapter)
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||||
|
for i, line in ipairs(lines) do
|
||||||
|
local result = parser.parse_line(adapter, line, column_defs)
|
||||||
|
if result and result.entry == entry then
|
||||||
|
vim.api.nvim_buf_set_lines(bufnr, i - 1, i, false, {})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local exported = util.export_entry(entry)
|
||||||
|
vim.notify(
|
||||||
|
string.format("Error: could not delete original file '%s'", exported.name),
|
||||||
|
vim.log.levels.ERROR
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
---@param paths string[]
|
---@param paths string[]
|
||||||
local function paste_paths(paths)
|
---@param delete_original? boolean
|
||||||
|
local function paste_paths(paths, delete_original)
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
local scheme = "oil://"
|
local scheme = "oil://"
|
||||||
local adapter = assert(config.get_adapter_by_scheme(scheme))
|
local adapter = assert(config.get_adapter_by_scheme(scheme))
|
||||||
|
|
@ -61,6 +85,7 @@ local function paste_paths(paths)
|
||||||
local parent_urls = {}
|
local parent_urls = {}
|
||||||
local pending_paths = {}
|
local pending_paths = {}
|
||||||
|
|
||||||
|
-- Handle as many paths synchronously as possible
|
||||||
for _, path in ipairs(paths) do
|
for _, path in ipairs(paths) do
|
||||||
-- Trim the trailing slash off directories
|
-- Trim the trailing slash off directories
|
||||||
if vim.endswith(path, "/") then
|
if vim.endswith(path, "/") then
|
||||||
|
|
@ -68,18 +93,24 @@ local function paste_paths(paths)
|
||||||
end
|
end
|
||||||
|
|
||||||
local ori_entry = cache.get_entry_by_url(scheme .. path)
|
local ori_entry = cache.get_entry_by_url(scheme .. path)
|
||||||
|
local parent_url = util.addslash(scheme .. vim.fs.dirname(path))
|
||||||
if ori_entry then
|
if ori_entry then
|
||||||
write_pasted(winid, ori_entry, column_defs, adapter, bufnr)
|
write_pasted(winid, ori_entry, column_defs, adapter, bufnr)
|
||||||
|
if delete_original then
|
||||||
|
remove_entry_from_parent_buffer(parent_url, ori_entry)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
local parent_url = scheme .. vim.fs.dirname(path)
|
|
||||||
parent_urls[parent_url] = true
|
parent_urls[parent_url] = true
|
||||||
table.insert(pending_paths, path)
|
table.insert(pending_paths, path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- If all paths could be handled synchronously, we're done
|
||||||
if #pending_paths == 0 then
|
if #pending_paths == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Process the remaining paths by asynchronously loading them
|
||||||
local cursor = vim.api.nvim_win_get_cursor(winid)
|
local cursor = vim.api.nvim_win_get_cursor(winid)
|
||||||
local complete_loading = util.cb_collect(#vim.tbl_keys(parent_urls), function(err)
|
local complete_loading = util.cb_collect(#vim.tbl_keys(parent_urls), function(err)
|
||||||
if err then
|
if err then
|
||||||
|
|
@ -92,6 +123,10 @@ local function paste_paths(paths)
|
||||||
local ori_entry = cache.get_entry_by_url(scheme .. path)
|
local ori_entry = cache.get_entry_by_url(scheme .. path)
|
||||||
if ori_entry then
|
if ori_entry then
|
||||||
write_pasted(winid, ori_entry, column_defs, adapter, bufnr)
|
write_pasted(winid, ori_entry, column_defs, adapter, bufnr)
|
||||||
|
if delete_original then
|
||||||
|
local parent_url = util.addslash(scheme .. vim.fs.dirname(path))
|
||||||
|
remove_entry_from_parent_buffer(parent_url, ori_entry)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
vim.notify(
|
vim.notify(
|
||||||
string.format("The pasted file '%s' could not be found", path),
|
string.format("The pasted file '%s' could not be found", path),
|
||||||
|
|
@ -261,7 +296,8 @@ local function handle_paste_output_linux(lines)
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
M.paste_from_system_clipboard = function()
|
---@param delete_original? boolean Delete the source file after pasting
|
||||||
|
M.paste_from_system_clipboard = function(delete_original)
|
||||||
local dir = oil.get_current_dir()
|
local dir = oil.get_current_dir()
|
||||||
if not dir then
|
if not dir then
|
||||||
return
|
return
|
||||||
|
|
@ -324,7 +360,7 @@ M.paste_from_system_clipboard = function()
|
||||||
elseif #paths == 0 then
|
elseif #paths == 0 then
|
||||||
vim.notify("No valid files found in system clipboard", vim.log.levels.WARN)
|
vim.notify("No valid files found in system clipboard", vim.log.levels.WARN)
|
||||||
else
|
else
|
||||||
paste_paths(paths)
|
paste_paths(paths, delete_original)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue