diff --git a/README.md b/README.md index 1e90cd6..a2512f1 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,9 @@ require("oil").setup({ -- You can set the delay to false to disable cleanup entirely -- Note that the cleanup process only starts when none of the oil buffers are currently displayed cleanup_delay_ms = 2000, + -- Set to true to autosave buffers that are updated with LSP willRenameFiles + -- Set to "unmodified" to only save unmodified buffers + lsp_rename_autosave = false, -- 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 = "", mode = "n" }) -- Additionally, if it is a string that matches "actions.", diff --git a/doc/oil.txt b/doc/oil.txt index 91f478b..ce54284 100644 --- a/doc/oil.txt +++ b/doc/oil.txt @@ -52,6 +52,9 @@ OPTIONS *oil-option -- You can set the delay to false to disable cleanup entirely -- Note that the cleanup process only starts when none of the oil buffers are currently displayed cleanup_delay_ms = 2000, + -- Set to true to autosave buffers that are updated with LSP willRenameFiles + -- Set to "unmodified" to only save unmodified buffers + lsp_rename_autosave = false, -- 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 = "", mode = "n" }) -- Additionally, if it is a string that matches "actions.", diff --git a/lua/oil/config.lua b/lua/oil/config.lua index 789df88..7b04d93 100644 --- a/lua/oil/config.lua +++ b/lua/oil/config.lua @@ -38,6 +38,9 @@ local default_config = { -- You can set the delay to false to disable cleanup entirely -- Note that the cleanup process only starts when none of the oil buffers are currently displayed cleanup_delay_ms = 2000, + -- Set to true to autosave buffers that are updated with LSP willRenameFiles + -- Set to "unmodified" to only save unmodified buffers + lsp_rename_autosave = false, -- 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 = "", mode = "n" }) -- Additionally, if it is a string that matches "actions.", diff --git a/lua/oil/lsp_helpers.lua b/lua/oil/lsp_helpers.lua index 70b0f2c..b78a257 100644 --- a/lua/oil/lsp_helpers.lua +++ b/lua/oil/lsp_helpers.lua @@ -1,3 +1,4 @@ +local config = require("oil.config") local fs = require("oil.fs") local util = require("oil.util") @@ -71,6 +72,18 @@ local function get_matching_paths(client, path_pairs) end end +---@return table +local function get_buffers_status() + local buffers_status = {} + local buffers = vim.api.nvim_list_bufs() + for _, bufnr in ipairs(buffers) do + buffers_status[bufnr] = { + is_modified = vim.bo[bufnr].modified, + } + end + return buffers_status +end + ---Process LSP rename in the background ---@param actions oil.MoveAction[] M.will_rename_files = function(actions) @@ -87,18 +100,38 @@ M.will_rename_files = function(actions) local clients = vim.lsp.get_active_clients() for _, client in ipairs(clients) do - local pairs = get_matching_paths(client, path_pairs) - if pairs then + local matching_paths = get_matching_paths(client, path_pairs) + if matching_paths then client.request("workspace/willRenameFiles", { files = vim.tbl_map(function(pair) return { oldUri = vim.uri_from_fname(pair.src), newUri = vim.uri_from_fname(pair.dest), } - end, pairs), + end, matching_paths), }, function(_, result) if result then + local buffers_status = get_buffers_status() vim.lsp.util.apply_workspace_edit(result, client.offset_encoding) + local autosave = config.lsp_rename_autosave + if autosave == false then + return + end + + for uri in pairs(result.changes) do + local bufnr = vim.uri_to_bufnr(uri) + local is_open = buffers_status[bufnr] ~= nil + local is_modified = is_open and buffers_status[bufnr].is_modified + local should_save = autosave == true or (autosave == "unmodified" and not is_modified) + if should_save then + vim.api.nvim_buf_call(bufnr, function() + vim.cmd.update() + end) + if not is_open then + vim.api.nvim_buf_delete(bufnr, { force = true }) + end + end + end end end) end