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

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