Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: lazy keymap support #41

Merged
merged 7 commits into from
Dec 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ test:
--headless \
--noplugin \
-u ${TESTS_INIT} \
-c "PlenaryBustedDirectory ${TESTS_DIR} { minimal_init = '${TESTS_INIT}' }"
-c "PlenaryBustedDirectory ${TESTS_DIR} { minimal_init = '${TESTS_INIT}', sequential = true }"
11 changes: 4 additions & 7 deletions lua/hawtkeys/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ local M = {}
---@field homerow number
---@field powerFingers number[]
---@field keyboardLayout HawtKeySupportedKeyboardLayouts
---@field keyMapSet { [string] : TSKeyMapArgs | WhichKeyMapargs }
---@field customMaps { [string] : TSKeyMapArgs | WhichKeyMapargs } | nil
---@field keyMapSet { [string] : TSKeyMapArgs | WhichKeyMapargs | LazyKeyMapArgs }
---@field customMaps { [string] : TSKeyMapArgs | WhichKeyMapargs | LazyKeyMapArgs } | nil
---@field highlights HawtKeyHighlights
---@field lhsBlacklist string[]

Expand All @@ -26,11 +26,11 @@ local M = {}
---@field homerow number | nil
---@field powerFingers number[] | nil
---@field keyboardLayout HawtKeySupportedKeyboardLayouts | nil
---@field customMaps { [string] : TSKeyMapArgs | WhichKeyMapargs } | nil
---@field customMaps { [string] : TSKeyMapArgs | WhichKeyMapargs | LazyKeyMapArgs } | nil
---@field highlights HawtKeyHighlights | nil
---@field lhsBlacklist string[] | nil

---@type { [string] : TSKeyMapArgs | WhichKeyMapargs }---
---@type { [string] : TSKeyMapArgs | WhichKeyMapargs | LazyKeyMapArgs }
local _defaultSet = {
["vim.keymap.set"] = {
modeIndex = 1,
Expand All @@ -46,9 +46,6 @@ local _defaultSet = {
optsIndex = 4,
method = "dot_index_expression",
}, --method 2
["whichkey.register"] = {
method = "which_key",
}, -- method 6
}

---@type HawtKeyConfig
Expand Down
62 changes: 54 additions & 8 deletions lua/hawtkeys/ts.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ local tsQuery = require("nvim-treesitter.query")
---@alias VimModes 'n' | 'x' | 'v' | 'i'

---@alias WhichKeyMethods 'which_key'
---
---@alias TreeSitterMethods 'dot_index_expression' | 'function_call' | 'expression_list'
---

---@alias LazyMethods 'lazy'

---@alias TreeSitterMethods 'dot_index_expression' | 'function_call'

---@alias SetMethods WhichKeyMethods | TreeSitterMethods

---@class TSKeyMapArgs
Expand All @@ -24,6 +26,9 @@ local tsQuery = require("nvim-treesitter.query")
---@class WhichKeyMapargs
---@field method WhichKeyMethods

---@class LazyKeyMapArgs
---@field method LazyMethods

---@type table<string, boolean>
local scannedFiles = {}

Expand Down Expand Up @@ -130,7 +135,7 @@ local function find_maps_in_file(filePath)
local fileContent = Path:new(filePath):read()
local parser = vim.treesitter.get_string_parser(fileContent, "lua", {}) -- Get the Lua parser
local tree = parser:parse()[1]:root()
local tsKemaps = {}
local tsKeymaps = {}
-- TODO: This currently doesnt always work, as the options for helper functions are different,
-- need to use TS to resolve it back to a native keymap
local dotIndexExpressionQuery = ts.parse_query(
Expand Down Expand Up @@ -213,7 +218,7 @@ local function find_maps_in_file(filePath)
end
map.mode = table.concat(modes, ", ")
end
table.insert(tsKemaps, map)
table.insert(tsKeymaps, map)
end
end
end
Expand Down Expand Up @@ -301,7 +306,7 @@ local function find_maps_in_file(filePath)
end
map.mode = table.concat(modes, ", ")
end
table.insert(tsKemaps, map)
table.insert(tsKeymaps, map)
end
end
end
Expand Down Expand Up @@ -342,13 +347,43 @@ local function find_maps_in_file(filePath)
rhs = mapping.cmd,
from_file = filePath,
}
table.insert(tsKemaps, map)
table.insert(tsKeymaps, map)
end
end
end
end

return tsKemaps
return tsKeymaps
end

---@return table
local function get_keymaps_from_lazy()
local lazyKeyMaps = {}
for _, args in pairs(hawtkeys.config.keyMapSet) do
if args.method == "lazy" then
local ok, lazy = pcall(function()
return require("lazy").plugins()
end)
if not ok then
vim.print("Lazy Loading requires Lazy")
break
end
for _, v in ipairs(lazy) do
if v and v._ and v._.handlers and v._.handlers.keys then
for _, key in pairs(v._.handlers.keys) do
local map = {
lhs = key.lhs,
rhs = key.rhs,
mode = key.mode,
from_file = "Lazy Init:" .. tostring(v[1]),
}
table.insert(lazyKeyMaps, map)
end
end
end
end
end
return lazyKeyMaps
end

---@return table
Expand Down Expand Up @@ -420,6 +455,16 @@ function M.get_all_keymaps()
end
end

if
hawtkeys.config.keyMapSet.lazy
and hawtkeys.config.keyMapSet.lazy.method == "lazy"
then
local lazyKeyMaps = get_keymaps_from_lazy()
for _, keymap in ipairs(lazyKeyMaps) do
table.insert(keymaps, keymap)
end
end

local vimKeymaps = get_keymaps_from_vim()
returnKeymaps = utils.merge_tables(keymaps, vimKeymaps)
scannedFiles = {}
Expand All @@ -432,5 +477,6 @@ end

M.find_maps_in_file = find_maps_in_file
M.get_keymaps_from_vim = get_keymaps_from_vim
M.get_keymaps_from_lazy = get_keymaps_from_lazy

return M
120 changes: 111 additions & 9 deletions tests/hawtkeys/ts_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,53 @@ local eq = assert.are.same
---@diagnostic disable-next-line: undefined-field
local falsy = assert.falsy

describe("Uninstalled plugins", function()
before_each(function()
require("plenary.reload").reload_module("hawtkeys")
ts.reset_scanned_files()
hawtkeys.setup({
customMaps = {
["lazy"] = {
method = "lazy",
},
["whichkey.register"] = {
method = "which_key",
},
},
})
vim.cmd("messages clear")
end)
it("which key doesnt cause error", function()
local ok, _ = pcall(function()
return require("which-key")
end)
local keymapWhichKey = ts.find_maps_in_file(
"tests/hawtkeys/example_configs/which-key.register_keymap.lua"
)
local messages = vim.api.nvim_exec2("messages", { output = true })
eq(false, ok)
eq(0, #keymapWhichKey)
eq({
["output"] = "Which Key Mappings require which-key to be installed",
}, messages)
end)

it("Lazy doesnt cause error", function()
local ok, _ = pcall(function()
return require("lazy")
end)
local keymapLazy = ts.get_keymaps_from_lazy()
local messages = vim.api.nvim_exec2("messages", { output = true })
eq(false, ok)
eq(0, #keymapLazy)
eq({ ["output"] = "Lazy Loading requires Lazy" }, messages)
end)
end)

describe("Treesitter can extract keymaps", function()
before_each(function()
require("plenary.reload").reload_module("hawtkeys")
ts.reset_scanned_files()
hawtkeys.setup({})
end)
it("extract vim.api.nvim_set_keymap()", function()
Expand All @@ -28,15 +72,6 @@ describe("Treesitter can extract keymaps", function()
eq(':echo "hello"<CR>', keymap[1].rhs)
end)

it("extract whichkey.register() keymap", function()
local keymap = ts.find_maps_in_file(
"tests/hawtkeys/example_configs/which-key.register_keymap.lua"
)
eq("n", keymap[1].mode)
eq("<leader>3", keymap[1].lhs)
eq(':lua print("hello")<CR>', keymap[1].rhs)
end)

it("Extract short dot index aliasesd keymap", function()
hawtkeys.setup({
customMaps = {
Expand Down Expand Up @@ -95,3 +130,70 @@ describe("Treesitter can extract keymaps", function()
eq(beforeCount, finalCount)
end)
end)

describe("Which Key Managed Maps", function()
before_each(function()
require("plenary.reload").reload_module("hawtkeys")
require("tests.minimal_init").loadWhichKey()
ts.reset_scanned_files()
hawtkeys.setup({
customMaps = {
["whichkey.register"] = {
method = "which_key",
},
},
})
end)

it("extract whichkey.register() keymap", function()
local keymap = ts.find_maps_in_file(
"tests/hawtkeys/example_configs/which-key.register_keymap.lua"
)
eq("n", keymap[1].mode)
eq("<leader>3", keymap[1].lhs)
eq(':lua print("hello")<CR>', keymap[1].rhs)
end)
end)

describe("Lazy Managed Plugins", function()
before_each(function()
require("plenary.reload").reload_module("hawtkeys")
ts.reset_scanned_files()
hawtkeys.setup({
customMaps = {
["lazy"] = {
method = "lazy",
},
},
})
require("tests.minimal_init").loadLazy()
vim.g.lazy_did_setup = false
vim.go.loadplugins = true
for modname in pairs(package.loaded) do
if modname:find("lazy") == 1 then
package.loaded[modname] = nil
end
end
local lazy = require("lazy")
lazy.setup({
"ellisonleao/nvim-plugin-template",
keys = {
{
"<leader>1",
":lua print(1)<CR>",
desc = "Test Lazy Print 1",
},
},
})
end)
it("extract keys set in a Lazy init", function()
local lazyKeymaps = ts.get_keymaps_from_lazy()
eq("n", lazyKeymaps[1].mode)
eq("<leader>1", lazyKeymaps[1].lhs)
eq(":lua print(1)<CR>", lazyKeymaps[1].rhs)
eq(
"Lazy Init:ellisonleao/nvim-plugin-template",
lazyKeymaps[1].from_file
)
end)
end)
1 change: 1 addition & 0 deletions tests/hawtkeys/ui_spec.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---@diagnostic disable-next-line: undefined-field
local eq = assert.are.same

local MiniTest = require("mini.test")
Expand Down
2 changes: 1 addition & 1 deletion tests/hawtkeys/utils_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("utils functionality", function()
local keymaps = {
{ lhs = "a", rhs = "1" },
{ lhs = "a", rhs = "2" },
{ lhs = "b", rhs = "3"},
{ lhs = "b", rhs = "3" },
{ lhs = "b", rhs = "4" },
}
local duplicates = utils.find_duplicates(keymaps)
Expand Down
52 changes: 38 additions & 14 deletions tests/minimal_init.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
local M = {}

function M.loadLazy()
local lazy_dir = os.getenv("LAZY_DIR") or "/tmp/lazy.nvim"
if vim.fn.isdirectory(lazy_dir) == 0 then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazy_dir,
})
end
vim.opt.rtp:append(lazy_dir)
print("Installed Lazy to " .. lazy_dir)
end

function M.loadWhichKey()
local whichkey_dir = os.getenv("WHICHKEY_DIR") or "/tmp/which-key.nvim"
if vim.fn.isdirectory(whichkey_dir) == 0 then
vim.fn.system({
"git",
"clone",
"https://github.com/folke/which-key.nvim",
whichkey_dir,
})
end
vim.opt.rtp:append(whichkey_dir)
vim.cmd("runtime plugin/which-key.vim")
print("Installed WhichKey to " .. whichkey_dir)
require("which-key").setup({})
end

local plenary_dir = os.getenv("PLENARY_DIR") or "/tmp/plenary.nvim"
local treesitter_dir = os.getenv("TREESITTER_DIR") or "/tmp/nvim-treesitter"
local whichkey_dir = os.getenv("WHICHKEY_DIR") or "/tmp/which-key.nvim"
local mini_dir = os.getenv("MINI_DIR") or "/tmp/mini-test"
if vim.fn.isdirectory(plenary_dir) == 0 then
vim.fn.system({
Expand All @@ -18,14 +51,6 @@ if vim.fn.isdirectory(treesitter_dir) == 0 then
treesitter_dir,
})
end
if vim.fn.isdirectory(whichkey_dir) == 0 then
vim.fn.system({
"git",
"clone",
"https://github.com/folke/which-key.nvim",
whichkey_dir,
})
end
if vim.fn.isdirectory(mini_dir) == 0 then
vim.fn.system({
"git",
Expand All @@ -37,8 +62,9 @@ end
vim.opt.rtp:append(".")
vim.opt.rtp:append(plenary_dir)
vim.opt.rtp:append(treesitter_dir)
vim.opt.rtp:append(whichkey_dir)
vim.opt.rtp:append(mini_dir)
require("plenary.busted")
require("mini.test").setup()

vim.cmd("runtime plugin/plenary.vim")
vim.cmd("runtime plugin/treesitter.vim")
Expand All @@ -48,7 +74,5 @@ require("nvim-treesitter.configs").setup({
enable = true,
},
})
vim.cmd("runtime plugin/which-key.vim")
require("which-key").setup({})
require("plenary.busted")
require("mini.test").setup()

return M
Loading