fix: spurious exits from faulty :wq detection (#221)
The previous mechanism used histget() to get the last command or expression to detect if the user issued a `:wq` or similar. This had the issue where if a user issued a `:wq`, started vim again, then entered oil and saved via some mechanism that is _not_ a command (e.g. a keymap), we would incorrectly detect that `:wq` and exit after saving. The new mechanism tracks all keypresses and may end up with false negatives (e.g. ":wqaff<backspace><backspace>ll"), but those are less frustrating than false positives.
This commit is contained in:
parent
18dfd2458d
commit
e045ee3b4e
2 changed files with 52 additions and 4 deletions
|
|
@ -926,9 +926,11 @@ local function close_preview_window_if_not_in_oil()
|
|||
pcall(vim.api.nvim_win_close, preview_win_id, true)
|
||||
end
|
||||
|
||||
local _on_key_ns = 0
|
||||
---Initialize oil
|
||||
---@param opts nil|table
|
||||
M.setup = function(opts)
|
||||
local Ringbuf = require("oil.ringbuf")
|
||||
local config = require("oil.config")
|
||||
|
||||
config.setup(opts)
|
||||
|
|
@ -999,6 +1001,12 @@ M.setup = function(opts)
|
|||
pattern = filetype_patterns,
|
||||
})
|
||||
|
||||
local keybuf = Ringbuf.new(7)
|
||||
if _on_key_ns == 0 then
|
||||
_on_key_ns = vim.on_key(function(char)
|
||||
keybuf:push(char)
|
||||
end, _on_key_ns)
|
||||
end
|
||||
vim.api.nvim_create_autocmd("ColorScheme", {
|
||||
desc = "Set default oil highlights",
|
||||
group = aug,
|
||||
|
|
@ -1018,12 +1026,15 @@ M.setup = function(opts)
|
|||
pattern = scheme_pattern,
|
||||
nested = true,
|
||||
callback = function(params)
|
||||
local last_keys = keybuf:as_str()
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
local last_cmd = vim.fn.histget("cmd", -1)
|
||||
local last_expr = vim.fn.histget("expr", -1)
|
||||
-- If the user issued a :wq or similar, we should quit after saving
|
||||
local quit_after_save = last_cmd == "wq" or last_cmd == "x" or last_expr == "ZZ"
|
||||
local quit_all = last_cmd:match("^wqal*$")
|
||||
local quit_after_save = vim.endswith(last_keys, ":wq\r")
|
||||
or vim.endswith(last_keys, ":x\r")
|
||||
or vim.endswith(last_keys, "ZZ")
|
||||
local quit_all = vim.endswith(last_keys, ":wqa\r")
|
||||
or vim.endswith(last_keys, ":wqal\r")
|
||||
or vim.endswith(last_keys, ":wqall\r")
|
||||
local bufname = vim.api.nvim_buf_get_name(params.buf)
|
||||
if vim.endswith(bufname, "/") then
|
||||
vim.cmd.doautocmd({ args = { "BufWritePre", params.file }, mods = { silent = true } })
|
||||
|
|
|
|||
37
lua/oil/ringbuf.lua
Normal file
37
lua/oil/ringbuf.lua
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
---@class oil.Ringbuf
|
||||
---@field private size integer
|
||||
---@field private tail integer
|
||||
---@field private buf string[]
|
||||
local Ringbuf = {}
|
||||
function Ringbuf.new(size)
|
||||
local self = setmetatable({
|
||||
size = size,
|
||||
buf = {},
|
||||
tail = 0,
|
||||
}, { __index = Ringbuf })
|
||||
return self
|
||||
end
|
||||
|
||||
---@param val string
|
||||
function Ringbuf:push(val)
|
||||
self.tail = self.tail + 1
|
||||
if self.tail > self.size then
|
||||
self.tail = 1
|
||||
end
|
||||
self.buf[self.tail] = val
|
||||
end
|
||||
|
||||
---@return string
|
||||
function Ringbuf:as_str()
|
||||
local postfix = ""
|
||||
for i = 1, self.tail, 1 do
|
||||
postfix = postfix .. self.buf[i]
|
||||
end
|
||||
local prefix = ""
|
||||
for i = self.tail + 1, #self.buf, 1 do
|
||||
prefix = prefix .. self.buf[i]
|
||||
end
|
||||
return prefix .. postfix
|
||||
end
|
||||
|
||||
return Ringbuf
|
||||
Loading…
Add table
Add a link
Reference in a new issue