Problem: the canola rename creates unnecessary friction for users
migrating from stevearc/oil.nvim — every `require('oil')` call and
config reference must change.
Solution: revert all module paths, URL schemes, autocmd groups,
highlight groups, and filetype names back to `oil`. The repo stays
`canola.nvim` for identity; the code is a drop-in replacement.
121 lines
4.2 KiB
Lua
121 lines
4.2 KiB
Lua
local config = require('oil.config')
|
|
local fs = require('oil.fs')
|
|
local util = require('oil.util')
|
|
local workspace = require('oil.lsp.workspace')
|
|
|
|
local M = {}
|
|
|
|
---@param actions oil.Action[]
|
|
---@return fun() did_perform Call this function when the file operations have been completed
|
|
M.will_perform_file_operations = function(actions)
|
|
local moves = {}
|
|
local creates = {}
|
|
local deletes = {}
|
|
for _, action in ipairs(actions) do
|
|
if action.type == 'move' then
|
|
local src_scheme, src_path = util.parse_url(action.src_url)
|
|
assert(src_path)
|
|
local src_adapter = assert(config.get_adapter_by_scheme(src_scheme))
|
|
local dest_scheme, dest_path = util.parse_url(action.dest_url)
|
|
local dest_adapter = assert(config.get_adapter_by_scheme(dest_scheme))
|
|
src_path = fs.posix_to_os_path(src_path)
|
|
dest_path = fs.posix_to_os_path(assert(dest_path))
|
|
if src_adapter.name == 'files' and dest_adapter.name == 'files' then
|
|
moves[src_path] = dest_path
|
|
elseif src_adapter.name == 'files' then
|
|
table.insert(deletes, src_path)
|
|
elseif dest_adapter.name == 'files' then
|
|
table.insert(creates, src_path)
|
|
end
|
|
elseif action.type == 'create' then
|
|
local scheme, path = util.parse_url(action.url)
|
|
path = fs.posix_to_os_path(assert(path))
|
|
local adapter = assert(config.get_adapter_by_scheme(scheme))
|
|
if adapter.name == 'files' then
|
|
table.insert(creates, path)
|
|
end
|
|
elseif action.type == 'delete' then
|
|
local scheme, path = util.parse_url(action.url)
|
|
path = fs.posix_to_os_path(assert(path))
|
|
local adapter = assert(config.get_adapter_by_scheme(scheme))
|
|
if adapter.name == 'files' then
|
|
table.insert(deletes, path)
|
|
end
|
|
elseif action.type == 'copy' then
|
|
local scheme, path = util.parse_url(action.dest_url)
|
|
path = fs.posix_to_os_path(assert(path))
|
|
local adapter = assert(config.get_adapter_by_scheme(scheme))
|
|
if adapter.name == 'files' then
|
|
table.insert(creates, path)
|
|
end
|
|
end
|
|
end
|
|
|
|
local buf_was_modified = {}
|
|
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
|
buf_was_modified[bufnr] = vim.bo[bufnr].modified
|
|
end
|
|
|
|
local edited_uris = {}
|
|
local final_err = nil
|
|
---@param edits nil|{edit: lsp.WorkspaceEdit, client_offset: string}[]
|
|
local function accum(edits, err)
|
|
final_err = final_err or err
|
|
if edits then
|
|
for _, edit in ipairs(edits) do
|
|
if edit.edit.changes then
|
|
for uri in pairs(edit.edit.changes) do
|
|
edited_uris[uri] = true
|
|
end
|
|
end
|
|
if edit.edit.documentChanges then
|
|
for _, change in ipairs(edit.edit.documentChanges) do
|
|
if change.textDocument then
|
|
edited_uris[change.textDocument.uri] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local timeout_ms = config.lsp_file_methods.timeout_ms
|
|
accum(workspace.will_create_files(creates, { timeout_ms = timeout_ms }))
|
|
accum(workspace.will_delete_files(deletes, { timeout_ms = timeout_ms }))
|
|
accum(workspace.will_rename_files(moves, { timeout_ms = timeout_ms }))
|
|
if final_err then
|
|
vim.notify(
|
|
string.format('[lsp] file operation error: %s', vim.inspect(final_err)),
|
|
vim.log.levels.WARN
|
|
)
|
|
end
|
|
|
|
return function()
|
|
workspace.did_create_files(creates)
|
|
workspace.did_delete_files(deletes)
|
|
workspace.did_rename_files(moves)
|
|
|
|
local autosave = config.lsp_file_methods.autosave_changes
|
|
if autosave == false then
|
|
return
|
|
end
|
|
for uri, _ in pairs(edited_uris) do
|
|
local bufnr = vim.uri_to_bufnr(uri)
|
|
local was_open = buf_was_modified[bufnr] ~= nil
|
|
local was_modified = buf_was_modified[bufnr]
|
|
local should_save = autosave == true or (autosave == 'unmodified' and not was_modified)
|
|
-- Autosave changed buffers if they were not modified before
|
|
if should_save then
|
|
vim.api.nvim_buf_call(bufnr, function()
|
|
vim.cmd.update({ mods = { emsg_silent = true, noautocmd = true } })
|
|
end)
|
|
|
|
-- Delete buffers that weren't open before
|
|
if not was_open then
|
|
vim.api.nvim_buf_delete(bufnr, { force = true })
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return M
|