fix: cancel visual/operator-pending mode instead of closing buffer
Problem: when close() is triggered from visual or operator-pending mode (e.g. pressing q after d in an oil buffer), the buffer closes instead of canceling the pending operation. This happens because keymaps without an explicit mode default to "" which covers normal, visual, select, and operator-pending modes. Solution: check the current mode at the top of close() and send <Esc> to cancel the mode instead of proceeding with the close. The check covers all visual modes (v, V, CTRL-V), select modes (s, S, CTRL-S), and operator-pending submodes (no, nov, noV, noCTRL-V). Based on: stevearc/oil.nvim#495
This commit is contained in:
parent
29239d56fb
commit
16f3d7bfa9
2 changed files with 54 additions and 0 deletions
|
|
@ -410,6 +410,11 @@ end
|
||||||
---@param opts? oil.CloseOpts
|
---@param opts? oil.CloseOpts
|
||||||
M.close = function(opts)
|
M.close = function(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
local mode = vim.api.nvim_get_mode().mode
|
||||||
|
if mode:match("^[vVsS\22\19]") or mode:match("^no") then
|
||||||
|
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<Esc>", true, true, true), "n", false)
|
||||||
|
return
|
||||||
|
end
|
||||||
-- If we're in a floating oil window, close it and try to restore focus to the original window
|
-- If we're in a floating oil window, close it and try to restore focus to the original window
|
||||||
if vim.w.is_oil_win then
|
if vim.w.is_oil_win then
|
||||||
local original_winid = vim.w.oil_original_win
|
local original_winid = vim.w.oil_original_win
|
||||||
|
|
|
||||||
49
tests/close_spec.lua
Normal file
49
tests/close_spec.lua
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
require("plenary.async").tests.add_to_env()
|
||||||
|
local oil = require("oil")
|
||||||
|
local test_util = require("tests.test_util")
|
||||||
|
|
||||||
|
a.describe("close", function()
|
||||||
|
a.before_each(function()
|
||||||
|
test_util.reset_editor()
|
||||||
|
end)
|
||||||
|
a.after_each(function()
|
||||||
|
test_util.reset_editor()
|
||||||
|
end)
|
||||||
|
|
||||||
|
a.it("does not close buffer from visual mode", function()
|
||||||
|
oil.open()
|
||||||
|
test_util.wait_for_autocmd({ "User", pattern = "OilEnter" })
|
||||||
|
assert.equals("oil", vim.bo.filetype)
|
||||||
|
test_util.feedkeys({ "V" }, 10)
|
||||||
|
oil.close()
|
||||||
|
assert.equals("oil", vim.bo.filetype)
|
||||||
|
test_util.feedkeys({ "<Esc>" }, 10)
|
||||||
|
end)
|
||||||
|
|
||||||
|
a.it("does not close buffer from operator-pending mode", function()
|
||||||
|
oil.open()
|
||||||
|
test_util.wait_for_autocmd({ "User", pattern = "OilEnter" })
|
||||||
|
assert.equals("oil", vim.bo.filetype)
|
||||||
|
vim.api.nvim_feedkeys("d", "n", false)
|
||||||
|
a.util.sleep(20)
|
||||||
|
local mode = vim.api.nvim_get_mode().mode
|
||||||
|
if mode:match("^no") then
|
||||||
|
oil.close()
|
||||||
|
assert.equals("oil", vim.bo.filetype)
|
||||||
|
end
|
||||||
|
vim.api.nvim_feedkeys(
|
||||||
|
vim.api.nvim_replace_termcodes("<Esc>", true, true, true),
|
||||||
|
"n",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
a.util.sleep(20)
|
||||||
|
end)
|
||||||
|
|
||||||
|
a.it("closes buffer from normal mode", function()
|
||||||
|
oil.open()
|
||||||
|
test_util.wait_for_autocmd({ "User", pattern = "OilEnter" })
|
||||||
|
assert.equals("oil", vim.bo.filetype)
|
||||||
|
oil.close()
|
||||||
|
assert.not_equals("oil", vim.bo.filetype)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue