-
-
Notifications
You must be signed in to change notification settings - Fork 190
/
Copy pathkeymaps.lua
101 lines (91 loc) · 2.73 KB
/
keymaps.lua
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
-- Taken from:
-- https://github.com/stevearc/oil.nvim/blob/master/lua/oil/keymap_util.lua
---@class CodeCompanion.Keymaps
---@field bufnr number The buffer number to apply the keymaps to
---@field callbacks table The callbacks to execute for each keymap
---@field data table The CodeCompanion class
---@field keymaps table The keymaps from the user's config
---Get the current position of the cursor when the keymap was triggered
---@return table
local function get_position_info()
local cursor = vim.api.nvim_win_get_cursor(0)
return {
line = vim.api.nvim_get_current_line(),
row = cursor[1],
col = cursor[2] + 1,
}
end
---@class CodeCompanion.Keymaps
local Keymaps = {}
---@param args table
function Keymaps.new(args)
return setmetatable({
bufnr = args.bufnr,
callbacks = args.callbacks,
data = args.data,
keymaps = args.keymaps,
}, { __index = Keymaps })
end
---Resolve the callback for each keymap
---@param rhs string|table|fun()
---@return string|fun(table)|boolean rhs
---@return table opts
---@return string|nil mode
function Keymaps:resolve(rhs)
if type(rhs) == "string" and vim.startswith(rhs, "keymaps.") then
return self:resolve(self.callbacks[vim.split(rhs, ".", { plain = true })[2]])
elseif type(rhs) == "string" then
return self.callbacks()[rhs], {}
elseif type(rhs) == "function" then
return rhs, {}
elseif type(rhs) == "table" then
local opts = vim.deepcopy(rhs)
local callback = opts.callback
local mode = opts.mode
if type(rhs.callback) == "string" then
local action_opts, action_mode
callback, action_opts, action_mode = self:resolve(rhs.callback)
opts = vim.tbl_extend("keep", opts, action_opts)
mode = mode or action_mode
end
opts.callback = nil
opts.mode = nil
return callback, opts, mode
else
return rhs, {}
end
end
---Set the keymaps
---@return nil
function Keymaps:set()
for _, map in pairs(self.keymaps) do
local callback
local rhs, action_opts = self:resolve(map.callback)
if type(map.condition) == "function" and not map.condition() then
goto continue
end
local opts = { desc = map.description or action_opts.desc, buffer = self.bufnr }
if type(rhs) == "function" then
callback = function()
self.data = self.data or {}
self.data.position = get_position_info()
rhs(self.data)
end
else
callback = rhs
end
for mode, key in pairs(map.modes) do
if mode ~= "" then
if type(key) == "table" then
for _, v in ipairs(key) do
vim.keymap.set(mode, v, callback, opts)
end
else
vim.keymap.set(mode, key, callback, opts)
end
end
end
::continue::
end
end
return Keymaps