-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathasync.lua
More file actions
122 lines (111 loc) · 3.31 KB
/
Copy pathasync.lua
File metadata and controls
122 lines (111 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
local config = require 'term-edit.config'
local coord = require 'term-edit.coord'
---@diagnostic disable: unused-local
local M = {
callbacks = {},
}
---delay function f with vim.defer_fn by delay milliseconds
---@param f function
---@param delay? integer
function M.schedule(f, delay)
---@diagnostic disable-next-line: param-type-mismatch
vim.defer_fn(f, delay or 0)
end
local callback_index = 0
---@param callback function
---@param defer_more function? will keep defering callback if this returns true
local function register_callback(callback, defer_more)
callback_index = (callback_index + 1) % 1000
defer_more = defer_more or function()
return false
end
M.callbacks[callback_index] = function()
local start_time = os.clock()
local event_loop_elapsed = 0
local function schedule_callback()
if os.clock() > start_time + 10 then
vim.notify(
'feedkeys callbacks leak' .. vim.inspect(M.callbacks),
vim.log.levels.ERROR
)
M.callbacks = {}
end
if event_loop_elapsed < config.opts.feedkeys_delay then
event_loop_elapsed = event_loop_elapsed + 1
M.schedule(schedule_callback)
elseif defer_more() then
event_loop_elapsed = 0
M.schedule(schedule_callback)
else
callback()
end
end
schedule_callback()
end
end
local function call_callback()
return 'lua require("term-edit.async").callbacks[' .. callback_index .. ']()'
end
---feedkeys and run callback after
---Assume start in terminal mode, will execute callback in terminal mode
---@param keys string
---@param callback function? called after the keys are fed
---@param opts? { moves?: boolean, start_normal: boolean, callback_normal: boolean }
function M.feedkeys(keys, callback, opts)
opts = opts or {}
if callback then
local old
register_callback(callback, function()
if not opts.moves then
return false
end
local current = coord.get_coord '.'
local moved = not coord.equals(current, old)
old = current
-- wait till it doesn't move if the keys moves
return moved
end)
if not opts.start_normal then
keys = keys .. '<C-\\><C-n>' -- exit terminal mode
end
keys = keys .. '<cmd>' -- enter command mode
if not opts.callback_normal then
keys = keys .. 'startinsert | ' -- get back to terminal mode
end
keys = keys .. call_callback() .. '<CR>'
end
local keys = vim.api.nvim_replace_termcodes(keys, true, false, true)
vim.api.nvim_feedkeys(keys, "n", false)
end
---quit insert (terminal) mode
---@param callback? function
function M.quit_insert(callback)
local keys = '<C-\\><C-n>' -- exit terminal mode
if callback then
register_callback(callback)
keys = keys .. '<cmd>' .. call_callback() .. '<CR>'
end
vim.api.nvim_input(keys)
end
---paste register content
---@param register string
function M.put(register)
vim.api.nvim_put(
---@diagnostic disable-next-line: param-type-mismatch
vim.fn.getreg(register, nil, true),
vim.fn.getregtype(register),
false,
false
)
end
---execute command and then maybe call callback
---@param cmd string
---@param callback? function
function M.vim_cmd(cmd, callback)
if callback then
register_callback(callback)
cmd = cmd .. '\n' .. call_callback()
end
vim.cmd(cmd)
end
return M