u.nvim/lua/tt/repeat.lua
2024-09-01 14:09:07 -06:00

67 lines
1.6 KiB
Lua

local M = {}
local function _normal(cmd) vim.cmd.normal { cmd = 'normal', args = { cmd }, bang = true } end
local function _feedkeys(keys, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), mode or 'nx', true)
end
M.native_repeat = function() _feedkeys '.' end
M.native_undo = function() _feedkeys '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