Skip to content

Commit

Permalink
feat: add keymap navigation
Browse files Browse the repository at this point in the history
functionality still isn't quite right because it's not working for
leader keymaps
  • Loading branch information
jokajak committed Jul 7, 2023
1 parent 58459b9 commit ec2ac37
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 47 deletions.
21 changes: 5 additions & 16 deletions dev.lua
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
local qwerty = require("keyseer.keyboard.qwerty")

local keyboard = qwerty:new()

print(vim.pretty_print(qwerty.get_lines))
print(vim.pretty_print(keyboard.get_lines))
local Display = require("keyseer.display")

local display = Display:new({
show_legend = true,
show_title = false,
keyboard = {
layout = "qwerty",
padding = { 0, 1, 0, 1 },
},
local KeySeer = require("keyseer").setup({
debug = true,
})
display:open()

local UI = require("keyseer.ui")
UI.show("home", "n")
37 changes: 35 additions & 2 deletions lua/keyseer/keymaps/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ local if_nil = vim.F.if_nil
---@class Keymaps
---@field root KeyMapTreeNode The root of the keymap treenode
---@field current_node KeyMapTreeNode The current node of the keymap tree
---@field previous_node KeyMapTreeNode The previous node of the keymap tree
---@field stack table<KeyMapTreeNode> The previous node of the keymap tree
local Keymaps = {}
Keymaps.__index = Keymaps

Expand All @@ -25,8 +25,8 @@ function Keymaps:new()
},
}, self)

this.stack = {}
this.current_node = this.root
this.previous_node = nil

return this
end
Expand Down Expand Up @@ -149,4 +149,37 @@ function Keymaps:get_current_keycaps(modifiers)
return ret
end

---Get the key presses for the current node
---@return table<KeyCapTreeNode>
function Keymaps:get_current_keypresses()
local ret = {}
for keypress, node in pairs(self.current_node.children) do
if next(node.children) ~= nil then
table.insert(ret, keypress)
end
end
return ret
end

---Update the current node
function Keymaps:push(keypress)
if vim.tbl_isempty(self.current_node.children) then
Utils.notify("Received a keypress for no children.", { level = vim.log.levels.ERROR })
return
end
if self.current_node.children[keypress] ~= nil then
table.insert(self.stack, self.current_node)
self.current_node = self.current_node.children[keypress]
else
Utils.notify(
"Received a keypress that isn't valid: " .. keypress,
{ level = vim.log.levels.ERROR }
)
vim.print(self.current_node.children[keypress])
end
end

function Keymaps:pop()
self.current_node = table.remove(self.stack)
end
return Keymaps
29 changes: 28 additions & 1 deletion lua/keyseer/ui/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@ local Popup = require("keyseer.ui.popup")
local Render = require("keyseer.ui.render")
local UIConfig = require("keyseer.ui.config")
local Utils = require("keyseer.utils")
local Config = require("keyseer").config
local Keymaps = require("keyseer.keymaps")

-- This section of code is copied from https://github.com/folke/lazy.nvim/
-- Mad props and respect go to folke

---@class KeySeerUIState
---@field pane string Which pane to show
---@field prev_pane string The previous pane shown
---@field keyboard Keyboard The associated keyboard object
---@field keyboard Keyboard The keyboard object
---@field keymaps Keymaps The keymaps
---@field current_keymaps table<string> The keymaps that have been added
---@field mode string The mode for displaying keymaps
---@field modifiers table{string,boolean} What modifier buttons are considered pressed
local default_state = {
pane = "home",
prev_pane = "",
mode = "n",
current_keymaps = {},
modifiers = {
ctrl = false,
shift = false,
Expand Down Expand Up @@ -74,6 +79,27 @@ function M.create()
self.state.pane = k
self:update()
end, v["desc"])

if not self.state.keyboard then
local keyboard_opts = Config.keyboard
local keyboard
local keyboard_options = vim.deepcopy(keyboard_opts)
keyboard_options.layout = nil

if type(keyboard_opts.layout) == "string" then
keyboard = require("keyseer.keyboard." .. keyboard_opts.layout):new(keyboard_options)
else
---@type Keyboard
local layout = keyboard_opts.layout
keyboard = layout:new(keyboard_options)
end

self.state.keyboard = keyboard
end
if not self.state.keymaps then
self.state.keymaps = Keymaps:new()
self.state.keymaps:process_keymaps()
end
end

-- open details for the keycap under the cursor
Expand All @@ -98,6 +124,7 @@ function M.create()
-- only makes sense on the home pane
if self.state.pane == "home" then
Utils.notify("Going back")
self.state.keymaps:pop()
self:update()
end
end)
Expand Down
49 changes: 21 additions & 28 deletions lua/keyseer/ui/panes/home.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,38 @@ local M = {
saved_keymaps = {},
}

function M.ensure_state(ui)
if not ui.state.keyboard then
local keyboard_opts = Config.keyboard
local keyboard
local keyboard_options = vim.deepcopy(keyboard_opts)
keyboard_options.layout = nil

if type(keyboard_opts.layout) == "string" then
keyboard = require("keyseer.keyboard." .. keyboard_opts.layout):new(keyboard_options)
else
---@type Keyboard
local layout = keyboard_opts.layout
keyboard = layout:new(keyboard_options)
end

ui.state.keyboard = keyboard
end
if not ui.state.keymaps then
ui.state.keymaps = Keymaps:new()
ui.state.keymaps:process_keymaps()
end
end

-- TODO: Populate main
function M.render(ui)
M.ensure_state(ui)
local current_keycaps = ui.state.keymaps:get_current_keycaps(ui.state.modifiers)
ui.state.keyboard:populate_lines(ui, current_keycaps)
for _, keypress in pairs(ui.state.current_keymaps) do
vim.keymap.del("n", "g" .. keypress, { buffer = ui.buf })
end
ui.state.current_keymaps = {}
for _, keypress in pairs(ui.state.keymaps:get_current_keypresses()) do
D.log("UI", "adding keymap for %s", keypress)
table.insert(ui.state.current_keymaps, keypress)
vim.keymap.set("n", "g" .. keypress, function()
ui.state.keymaps:push(keypress)
ui:update()
end, { buffer = ui.buf })
end
end

---Update keymaps when entering the pane
function M.on_enter(ui)
M.ensure_state(ui)
Utils.notify("Entering home")
for _, keypress in pairs(ui.state.current_keymaps) do
vim.keymap.set("n", "g" .. keypress, function()
ui.state.keymaps:push(keypress)
ui:update()
end, { buffer = ui.buf })
end
end

---Update keymaps when exiting the pane
function M.on_exit(ui)
Utils.notify("Exiting home")
for _, keypress in pairs(ui.state.current_keymaps) do
vim.keymap.del("n", "g" .. keypress, { buffer = ui.buf })
end
end

return M

0 comments on commit ec2ac37

Please sign in to comment.