From 2ac18ee9441fcd31bd0f6fe38d753b21e1913359 Mon Sep 17 00:00:00 2001 From: Jack Tubbenhauer Date: Wed, 8 Nov 2023 09:41:56 +1100 Subject: [PATCH 1/5] save buffers changed by will_rename_files --- lua/oil/lsp_helpers.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lua/oil/lsp_helpers.lua b/lua/oil/lsp_helpers.lua index e6a8d2d9..7f0f72c0 100644 --- a/lua/oil/lsp_helpers.lua +++ b/lua/oil/lsp_helpers.lua @@ -89,6 +89,13 @@ M.will_rename_files = function(actions) }, function(_, result) if result then vim.lsp.util.apply_workspace_edit(result, client.offset_encoding) + for uri, _ in pairs(result.changes) do + local bufnr = vim.uri_to_bufnr(uri) + vim.api.nvim_buf_call(bufnr, function() + vim.cmd("w") + end) + vim.api.nvim_buf_delete(bufnr, { force = true }) -- This line will close the buffer + end end end) end From e1e45969038b8104d3b2dd69009ddb1d5e1b7a01 Mon Sep 17 00:00:00 2001 From: Jack Tubbenhauer Date: Wed, 8 Nov 2023 10:27:53 +1100 Subject: [PATCH 2/5] prevent closing already open buffers --- lua/oil/lsp_helpers.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lua/oil/lsp_helpers.lua b/lua/oil/lsp_helpers.lua index 7f0f72c0..9713ede0 100644 --- a/lua/oil/lsp_helpers.lua +++ b/lua/oil/lsp_helpers.lua @@ -77,15 +77,21 @@ 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 + local open_buffers = vim.api.nvim_list_bufs() + local is_open = {} + for _, bufnr in ipairs(open_buffers) do + is_open[bufnr] = true + end + 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 vim.lsp.util.apply_workspace_edit(result, client.offset_encoding) @@ -94,7 +100,9 @@ M.will_rename_files = function(actions) vim.api.nvim_buf_call(bufnr, function() vim.cmd("w") end) - vim.api.nvim_buf_delete(bufnr, { force = true }) -- This line will close the buffer + if not is_open[bufnr] then + vim.api.nvim_buf_delete(bufnr, { force = true }) + end end end end) From f34ac4acf1e551358bfc909fe110487a3e2918c6 Mon Sep 17 00:00:00 2001 From: Jack Tubbenhauer Date: Sun, 17 Dec 2023 21:37:06 +1100 Subject: [PATCH 3/5] chore: move to config option --- README.md | 3 +++ doc/oil.txt | 3 +++ lua/oil/config.lua | 3 +++ lua/oil/lsp_helpers.lua | 46 ++++++++++++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1e90cd6b..a2512f10 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 91f478b8..ce54284e 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 789df88f..7b04d933 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 4ffa3c46..3525f45c 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,30 @@ local function get_matching_paths(client, path_pairs) end end +---@param bufnr number +---@return boolean +local function should_save_buffer(bufnr) + local autosave = config.lsp_rename_autosave + if autosave == "unmodified" then + local is_modified = vim.api.nvim_buf_get_option_value("modified", { buf = bufnr }) + return not is_modified + end + if type(autosave) ~= "boolean" then + return false + end + return autosave +end + +---@return table +local function get_open_buffers() + local is_open = {} + local buffers = vim.api.nvim_list_bufs() + for _, bufnr in ipairs(buffers) do + is_open[bufnr] = true + end + return is_open +end + ---Process LSP rename in the background ---@param actions oil.MoveAction[] M.will_rename_files = function(actions) @@ -89,12 +114,6 @@ M.will_rename_files = function(actions) for _, client in ipairs(clients) do local matching_paths = get_matching_paths(client, path_pairs) if matching_paths then - local open_buffers = vim.api.nvim_list_bufs() - local is_open = {} - for _, bufnr in ipairs(open_buffers) do - is_open[bufnr] = true - end - client.request("workspace/willRenameFiles", { files = vim.tbl_map(function(pair) return { @@ -105,12 +124,19 @@ M.will_rename_files = function(actions) }, function(_, result) if result then vim.lsp.util.apply_workspace_edit(result, client.offset_encoding) + if config.lsp_rename_autosave == false then + return + end + + local open_buffers = get_open_buffers() for uri, _ in pairs(result.changes) do local bufnr = vim.uri_to_bufnr(uri) - vim.api.nvim_buf_call(bufnr, function() - vim.cmd("w") - end) - if not is_open[bufnr] then + if should_save_buffer(bufnr) then + vim.api.nvim_buf_call(bufnr, function() + vim.cmd("update") + end) + end + if not open_buffers[bufnr] then vim.api.nvim_buf_delete(bufnr, { force = true }) end end From 4174be184ce7765d9452fc5149cf4174b214624c Mon Sep 17 00:00:00 2001 From: Jack Tubbenhauer Date: Sun, 17 Dec 2023 22:45:04 +1100 Subject: [PATCH 4/5] chore: fixes --- lua/oil/lsp_helpers.lua | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/lua/oil/lsp_helpers.lua b/lua/oil/lsp_helpers.lua index 3525f45c..f9e4e5c5 100644 --- a/lua/oil/lsp_helpers.lua +++ b/lua/oil/lsp_helpers.lua @@ -72,28 +72,17 @@ local function get_matching_paths(client, path_pairs) end end ----@param bufnr number ----@return boolean -local function should_save_buffer(bufnr) - local autosave = config.lsp_rename_autosave - if autosave == "unmodified" then - local is_modified = vim.api.nvim_buf_get_option_value("modified", { buf = bufnr }) - return not is_modified - end - if type(autosave) ~= "boolean" then - return false - end - return autosave -end - ----@return table -local function get_open_buffers() - local is_open = {} +---@return table +local function get_buffers_status() + local buffers_status = {} local buffers = vim.api.nvim_list_bufs() for _, bufnr in ipairs(buffers) do - is_open[bufnr] = true + buffers_status[bufnr] = { + is_open = true, + is_modified = vim.api.nvim_get_option_value("modified", { buf = bufnr }), + } end - return is_open + return buffers_status end ---Process LSP rename in the background @@ -123,20 +112,23 @@ M.will_rename_files = function(actions) end, matching_paths), }, function(_, result) if result then + local buffers_status = get_buffers_status() vim.lsp.util.apply_workspace_edit(result, client.offset_encoding) - if config.lsp_rename_autosave == false then + local autosave = config.lsp_rename_autosave + if autosave == false then return end - local open_buffers = get_open_buffers() for uri, _ in pairs(result.changes) do local bufnr = vim.uri_to_bufnr(uri) - if should_save_buffer(bufnr) then + local is_modified = buffers_status[bufnr] 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) end - if not open_buffers[bufnr] then + if not buffers_status[bufnr].is_open then vim.api.nvim_buf_delete(bufnr, { force = true }) end end From 24281dfa1c3b7316121d2d6eda65fe9a38e9e6d0 Mon Sep 17 00:00:00 2001 From: Steven Arcangeli <506791+stevearc@users.noreply.github.com> Date: Sat, 23 Dec 2023 07:47:20 -0800 Subject: [PATCH 5/5] fix: a crash and some formatting --- lua/oil/lsp_helpers.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lua/oil/lsp_helpers.lua b/lua/oil/lsp_helpers.lua index f9e4e5c5..b78a2575 100644 --- a/lua/oil/lsp_helpers.lua +++ b/lua/oil/lsp_helpers.lua @@ -78,8 +78,7 @@ local function get_buffers_status() local buffers = vim.api.nvim_list_bufs() for _, bufnr in ipairs(buffers) do buffers_status[bufnr] = { - is_open = true, - is_modified = vim.api.nvim_get_option_value("modified", { buf = bufnr }), + is_modified = vim.bo[bufnr].modified, } end return buffers_status @@ -119,17 +118,18 @@ M.will_rename_files = function(actions) return end - for uri, _ in pairs(result.changes) do + for uri in pairs(result.changes) do local bufnr = vim.uri_to_bufnr(uri) - local is_modified = buffers_status[bufnr] and buffers_status[bufnr].is_modified + 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") + vim.cmd.update() end) - end - if not buffers_status[bufnr].is_open then - vim.api.nvim_buf_delete(bufnr, { force = true }) + if not is_open then + vim.api.nvim_buf_delete(bufnr, { force = true }) + end end end end