64 lines
1.4 KiB
Lua
64 lines
1.4 KiB
Lua
local M = {}
|
|
|
|
local function _normal(cmd) vim.cmd.normal { cmd = 'normal', args = { cmd }, bang = true } end
|
|
|
|
M.native_repeat = function() _normal '.' end
|
|
M.native_undo = function() _normal 'u' end
|
|
|
|
---@param cmd? string|fun():unknown
|
|
function M.set(cmd)
|
|
local ts = vim.b.changedtick
|
|
vim.b.tt_changedtick = ts
|
|
if cmd ~= nil then vim.b.tt_repeatcmd = cmd end
|
|
end
|
|
|
|
---@generic T
|
|
---@param cmd string|fun():T
|
|
---@return T
|
|
function M.run(cmd)
|
|
M.set(cmd)
|
|
local result = cmd()
|
|
M.set()
|
|
return result
|
|
end
|
|
|
|
function M.do_repeat()
|
|
local ts, tt_ts, tt_cmd = vim.b.changedtick, vim.b.tt_changedtick, vim.b.tt_repeatcmd
|
|
if
|
|
-- (force formatter break)
|
|
tt_ts == nil
|
|
or tt_cmd == nil
|
|
-- has the buffer been modified after we last modified it?
|
|
or ts > tt_ts
|
|
or (type(tt_cmd) ~= 'function' and type(tt_cmd) ~= 'string')
|
|
then
|
|
return M.native_repeat()
|
|
end
|
|
|
|
-- execute the cached command:
|
|
local count = vim.api.nvim_get_vvar 'count1'
|
|
if type(tt_cmd) == 'string' then
|
|
_normal(count .. tt_cmd --[[@as string]])
|
|
else
|
|
local last_return
|
|
for _ = 1, count do
|
|
last_return = M.run(tt_cmd --[[@as fun():any]])
|
|
end
|
|
return last_return
|
|
end
|
|
end
|
|
|
|
function M.undo()
|
|
M.native_undo()
|
|
-- Update the current TS on the next event tick,
|
|
-- to make sure we get the latest
|
|
vim.schedule(M.set)
|
|
end
|
|
|
|
function M.setup()
|
|
vim.keymap.set('n', '.', M.do_repeat)
|
|
vim.keymap.set('n', 'u', M.undo)
|
|
end
|
|
|
|
return M
|