Skip to content

Commit c596965

Browse files
committed
feat(neovim): reintroduce trigger.lua
1 parent baf1d5f commit c596965

File tree

5 files changed

+124
-17
lines changed

5 files changed

+124
-17
lines changed

home/.config/nvim/lua/defer.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,12 @@ function M.call(method, ...)
211211
end
212212
end
213213

214+
---@alias Defer.Lazy<T> fun(...): T
215+
---
214216
--- Memoizes a function result.
215217
---@generic T
216218
---@param fn fun(...): T
217-
---@return fun(...): T
219+
---@return Defer.Lazy<T>
218220
function M.lazy(fn)
219221
local value
220222
local ran = false

home/.config/nvim/lua/trigger.lua

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
local lazy = require('defer').lazy
2+
local M = {}
3+
4+
--- @type Defer.Lazy<uv.uv_timer_t>
5+
local timer = lazy(function()
6+
return vim.uv.new_timer()
7+
end)
8+
local cache = {} -- Stores original mappings keyed by the repeat_key
9+
10+
---Restores the original mapping for a specific key
11+
---@param key string
12+
local function restore(key)
13+
local map = cache[key]
14+
if map == nil then
15+
return
16+
end
17+
18+
if map ~= false then
19+
local opts = {
20+
silent = map.silent == 1,
21+
expr = map.expr == 1,
22+
nowait = map.nowait == 1,
23+
noremap = map.noremap == 1,
24+
desc = map.desc,
25+
buffer = map.buffer,
26+
}
27+
if map.callback then
28+
vim.keymap.set('n', key, map.callback, opts)
29+
else
30+
vim.keymap.set('n', key, map.rhs, opts)
31+
end
32+
else
33+
pcall(vim.keymap.del, 'n', key)
34+
end
35+
cache[key] = nil
36+
end
37+
38+
---Activates the sticky repeat for the primary key
39+
---@param key string
40+
---@param action function
41+
---@param timeout number
42+
local function activate_sticky(key, action, timeout)
43+
timer():stop()
44+
45+
-- 1. Cache current mapping if we haven't already
46+
if cache[key] == nil then
47+
local arg = vim.fn.maparg(key, 'n', false, true)
48+
if next(arg) ~= nil then
49+
cache[key] = arg
50+
else
51+
cache[key] = false
52+
end
53+
end
54+
55+
-- 2. Create the temporary override
56+
vim.keymap.set('n', key, function()
57+
action()
58+
activate_sticky(key, action, timeout)
59+
end, { silent = true, nowait = true, desc = 'Sticky repeat: ' .. key })
60+
61+
-- 3. Set timer to restore original state
62+
timer():start(
63+
timeout,
64+
0,
65+
vim.schedule_wrap(function()
66+
restore(key)
67+
end)
68+
)
69+
end
70+
71+
---Wraps actions to trigger sticky repetition
72+
---@param key string The key to override (e.g., 'b')
73+
---@param action_prev function
74+
---@param action_next function
75+
---@param timeout? number Defaults to 1000ms
76+
---@return function action_prev, function action_next
77+
function M.trigger(key, action_prev, action_next, timeout)
78+
timeout = timeout or 1000
79+
80+
local wrapped_prev = function()
81+
local res = action_prev()
82+
activate_sticky(key, action_prev, timeout)
83+
return res
84+
end
85+
86+
local wrapped_next = function()
87+
local res = action_next()
88+
activate_sticky(key, action_next, timeout)
89+
return res
90+
end
91+
92+
return wrapped_prev, wrapped_next
93+
end
94+
95+
return M

home/.config/nvim/plugin/diagnostic.lua

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ defer.very_lazy(function()
1717
map('<leader>q', 'setloclist')
1818

1919
local next_move = require('nvim-next.move')
20+
local trigger = require('trigger').trigger
2021

21-
local prev_diag, next_diag = next_move.make_repeatable_pair(function()
22-
vim.diagnostic.jump({ count = -vim.v.count1 })
23-
end, function()
24-
vim.diagnostic.jump({ count = vim.v.count1 })
25-
end)
22+
local prev_diag, next_diag = trigger(
23+
'd',
24+
next_move.make_repeatable_pair(function()
25+
vim.diagnostic.jump({ count = -vim.v.count1 })
26+
end, function()
27+
vim.diagnostic.jump({ count = vim.v.count1 })
28+
end)
29+
)
2630
require('map').map('n', '[d', prev_diag, 'Go to previous diagnostic')
2731
require('map').map('n', ']d', next_diag, 'Go to next diagnostic')
2832

home/.config/nvim/plugin/gitsigns.lua

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ defer.on_load('gitsigns', function()
1313
local next_integrations = require('nvim-next.integrations')
1414
local nngs = next_integrations.gitsigns(gs)
1515

16-
-- Navigation
17-
map('n', ']c', function()
16+
local trigger = require('trigger').trigger
17+
local prev_hunk, next_hunk = trigger('c', function()
1818
if vim.wo.diff then
1919
return ']c'
2020
end
@@ -23,17 +23,19 @@ defer.on_load('gitsigns', function()
2323
nngs.next_hunk()
2424
end)
2525
return '<Ignore>'
26-
end, { expr = true, desc = 'next_hunk' })
27-
28-
map('n', '[c', function()
26+
end, function()
2927
if vim.wo.diff then
3028
return '[c'
3129
end
3230
vim.schedule(function()
3331
nngs.prev_hunk()
3432
end)
3533
return '<Ignore>'
36-
end, { expr = true, desc = 'prev_hunk' })
34+
end)
35+
36+
-- Navigation
37+
map('n', ']c', prev_hunk, { expr = true, desc = 'next_hunk' })
38+
map('n', '[c', next_hunk, { expr = true, desc = 'prev_hunk' })
3739

3840
-- Actions
3941
map('n', '<leader>hs', gs.stage_hunk, 'stage_hunk')

home/.config/nvim/plugin/unimpaired.lua

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ defer.very_lazy(function()
44
vim.cmd.packadd('vim-unimpaired')
55

66
local next_move = require('nvim-next.move')
7+
local trigger = require('trigger').trigger
78

89
-- buffers
9-
local prev_buffers, next_buffers = next_move.make_repeatable_pair(function()
10-
vim.cmd('bprevious')
11-
end, function()
12-
vim.cmd('bnext')
13-
end)
10+
local prev_buffers, next_buffers = trigger(
11+
'b',
12+
next_move.make_repeatable_pair(function()
13+
vim.cmd('bprevious')
14+
end, function()
15+
vim.cmd('bnext')
16+
end)
17+
)
1418

1519
map('n', '[b', prev_buffers, 'Go to previous buffer')
1620
map('n', ']b', next_buffers, 'Go to next buffer')

0 commit comments

Comments
 (0)