You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
6.1 KiB
249 lines
6.1 KiB
local M = require('module'):new()
|
|
|
|
local map = require('lib/map')
|
|
|
|
function M:initialize(config)
|
|
self.plugins = nukevim.modules:get('plugins')
|
|
self.keymap = {}
|
|
end
|
|
|
|
function M:register()
|
|
if (self.config.ui.enable) then
|
|
self.plugins:add('folke/which-key.nvim', { branch = "main" }, {
|
|
{ mode = 'n', key = { '?', '?', '?' }, map = ":lua nukevim.modules:get('keymap'):show()<CR>", hidden = true },
|
|
{ mode = 'i', key = { '?', '?', '?' }, map = "<cmd> lua nukevim.modules:get('keymap'):show()<CR>", hidden = true },
|
|
{ mode = 'v', key = { '?', '?', '?' }, map = "<cmd> lua nukevim.modules:get('keymap'):show()<CR>", hidden = true },
|
|
})
|
|
end
|
|
|
|
if (self.config.keys ~= nil) then
|
|
for idx, key in ipairs(self.config.keys) do
|
|
self:add(key)
|
|
end
|
|
end
|
|
end
|
|
|
|
function M:show()
|
|
mode = vim.fn.mode()
|
|
buffer = vim.fn.expand('%')
|
|
-- n, i, v/V
|
|
|
|
show_buffer_keys = false
|
|
for i=1,#self.keymap do
|
|
if (self.keymap[i].buffer ~= nil and self.keymap[i].buffer == buffer) then
|
|
show_buffer_keys = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if (show_buffer_keys and false) then
|
|
|
|
-- buf = vim.api.nvim_create_buf(false, true)
|
|
-- win = vim.api.nvim_open_win(buf, false, {
|
|
-- relative = "editor",
|
|
-- height = 6,
|
|
-- focusable = false,
|
|
-- anchor = "SW",
|
|
-- style = "minimal",
|
|
-- row = vim.o.lines,
|
|
-- col = 0,
|
|
-- width = vim.o.columns
|
|
-- })
|
|
-- vim.api.nvim_buf_set_option(buf, "filetype", "WhichKey")
|
|
-- vim.api.nvim_buf_set_option(buf, "buftype", "nofile")
|
|
-- vim.api.nvim_win_set_option(win, "winhighlight", "NormalFloat:WhichKeyFloat")
|
|
-- vim.api.nvim_win_set_option(win, "foldmethod", "manual")
|
|
-- -- vim.api.nvim_win_set_option(win, "winblend", true)
|
|
-- vim.cmd([[autocmd! WinClosed <buffer> lua nukevim.modules:get('keymap'):closed()]])
|
|
|
|
-- vim.api.nvim_buf_set_lines(buf, 0, -1, false, {
|
|
-- "hello, world!",
|
|
-- "this is a window"
|
|
-- })
|
|
else
|
|
require('which-key').show('', { mode = mode })
|
|
end
|
|
end
|
|
|
|
function M:registerBufferLocal()
|
|
filetype = vim.bo.filetype
|
|
|
|
local_binds = {}
|
|
|
|
for i=1,#self.keymap do
|
|
if (self.keymap[i].filetype ~= nil and self.keymap[i].filetype == filetype) then
|
|
table.insert(local_binds, self.keymap[i])
|
|
end
|
|
end
|
|
|
|
self:registerWithWhichKey(local_binds, { buffer = 0 })
|
|
|
|
end
|
|
|
|
function M:map(mode, key, map, options)
|
|
M:add({
|
|
mode = mode,
|
|
key = key,
|
|
map = map,
|
|
options = options or { noremap = true }
|
|
})
|
|
end
|
|
|
|
function M:add(keymap)
|
|
-- todo: validate
|
|
keymap.mode = keymap.mode or nil
|
|
keymap.key = keymap.key or nil
|
|
if (type(keymap.key) == "string") then
|
|
parts = {}
|
|
for part in string.gmatch(keymap.key, '.') do
|
|
table.insert(parts, part)
|
|
end
|
|
keymap.key = parts
|
|
end
|
|
keymap.map = keymap.map or nil
|
|
keymap.options = keymap.options or { noremap = true }
|
|
keymap.label = keymap.label or nil
|
|
keymap.virtual = keymap.virtual or false
|
|
keymap.hidden = keymap.hidden or false
|
|
keymap.group = keymap.group or false
|
|
keymap.with = keymap.with or {}
|
|
keymap.without = keymap.without or {}
|
|
table.insert(self.keymap, keymap)
|
|
end
|
|
|
|
function M:commit()
|
|
if (self.plugins:has('folke/which-key.nvim') and self.config.ui.enable) then
|
|
self:commitWithWhichKey()
|
|
else
|
|
self:commitWithNative()
|
|
end
|
|
end
|
|
|
|
function M:commitWithWhichKey()
|
|
-- Set up whichkey
|
|
whichkey = require('which-key')
|
|
whichkey.setup({
|
|
ignore_missing = true,
|
|
plugins = {
|
|
marks = true,
|
|
registers = true,
|
|
spelling = {
|
|
enabled = true,
|
|
suggestions = 20
|
|
},
|
|
presets = {
|
|
operators = self.config.ui.show_builtin,
|
|
motions = self.config.ui.show_builtin,
|
|
text_objects = self.config.ui.show_builtin,
|
|
windows = self.config.ui.show_builtin,
|
|
nav = self.config.ui.show_builtin,
|
|
z = self.config.ui.show_builtin,
|
|
g = self.config.ui.show_builtin,
|
|
}
|
|
}
|
|
})
|
|
|
|
-- Build tree of key binds
|
|
self:registerWithWhichKey(self.keymap)
|
|
|
|
end
|
|
|
|
function M:registerWithWhichKey(keys, opts)
|
|
opts = opts or {}
|
|
tree = {}
|
|
node = nil
|
|
|
|
for idx, keymap in ipairs(keys) do
|
|
if (keymap.hidden) then
|
|
if (keymap.label ~= nil) then
|
|
keymap.options.desc = keymap.label
|
|
end
|
|
map(keymap.mode, table.concat(keymap.key, ""), keymap.map, keymap.options)
|
|
-- TODO: Hack-y hack.
|
|
elseif (keymap.filetype ~= nil and opts.buffer == nil) then
|
|
-- this only applies to a specific filetype, register() will register
|
|
-- it buffer-local when it's opened
|
|
else
|
|
if (tree[keymap.mode] == nil) then
|
|
tree[keymap.mode] = {}
|
|
end
|
|
|
|
node = tree[keymap.mode]
|
|
|
|
for i = 1, #keymap.key - 1 do
|
|
if (node[keymap.key[i]] == nil) then
|
|
node[keymap.key[i]] = {}
|
|
end
|
|
node = node[keymap.key[i]]
|
|
end
|
|
|
|
last = keymap.key[#keymap.key]
|
|
|
|
have_all_with = true
|
|
for idx,plugin in ipairs(keymap.with) do
|
|
have_all_with = have_all_with and self.plugins:has(plugin)
|
|
end
|
|
have_any_without = false
|
|
for idx,plugin in ipairs(keymap.without) do
|
|
have_any_without = have_any_without or self.plugins:has(plugin)
|
|
end
|
|
|
|
if (have_all_with and not have_any_without) then
|
|
if (keymap.group) then
|
|
node[last] = node[last] or {}
|
|
node[last]['name'] = keymap.label
|
|
elseif (keymap.virtual) then
|
|
node[last] = { keymap.label }
|
|
else
|
|
node[last] = { keymap.map, keymap.label or nil }
|
|
if (keymap.options.noremap) then
|
|
node[last].noremap = true
|
|
end
|
|
if (keymap.options.silent) then
|
|
node[last].silent = true
|
|
end
|
|
if (keymap.options.nowait) then
|
|
node[last].nowait = true
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
for mode, node in pairs(tree) do
|
|
local_opts = {}
|
|
for k, v in pairs(opts) do
|
|
local_opts[k] = v
|
|
end
|
|
local_opts['mode'] = mode
|
|
whichkey.register(node, local_opts)
|
|
end
|
|
|
|
end
|
|
|
|
function M:commitWithNative()
|
|
for idx, keymap in ipairs(self.keymap) do
|
|
if (keymap.label ~= nil) then
|
|
keymap.options.desc = keymap.label
|
|
end
|
|
|
|
if (keymap.virtual ~= true) then
|
|
|
|
have_all_with = true
|
|
for plugin in ipairs(keymap.with) do
|
|
have_all_with = have_all_with and self.plugins:has(plugin)
|
|
end
|
|
have_any_without = false
|
|
for plugin in ipairs(keymap.without) do
|
|
have_any_without = have_any_without or self.plugins:has(plugin)
|
|
end
|
|
|
|
if (have_all_with and not have_any_without) then
|
|
map(keymap.mode, table.concat(keymap.key, ''), keymap.map, keymap.options)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return M
|
|
|