canola.nvim/lua/oil/lsp/helpers.lua
TheNordicMule 29a06fcc90
feat: add ability to alter lsp file operation timeout (#317)
* feat: add ability to alter lsp file operation timeout

* change default

* fix table

* add missing

* move inside table

* remove duplicate

* reuse default

* change message

* refactor: rename autosave config option

---------

Co-authored-by: Steven Arcangeli <stevearc@stevearc.com>
2024-03-02 09:02:42 -08:00

111 lines
3.7 KiB
Lua

local config = require("oil.config")
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))
if src_adapter.name == "files" and dest_adapter.name == "files" then
moves[src_path] = dest_path
end
elseif action.type == "create" then
local scheme, path = util.parse_url(action.url)
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)
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)
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