From ca75a50858774f7ae36dfc1afd66f4b5701432b1 Mon Sep 17 00:00:00 2001 From: Marco S Hyman Date: Mon, 5 Jan 2026 00:49:45 -0800 Subject: [PATCH] feat: Terminal buffer keymap help (#64) This sets up a base where the keymap g? shows a help buffer displaying the normal mode keymaps available. --- lua/jj/ui/terminal.lua | 73 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/lua/jj/ui/terminal.lua b/lua/jj/ui/terminal.lua index 1c00538..33113e2 100644 --- a/lua/jj/ui/terminal.lua +++ b/lua/jj/ui/terminal.lua @@ -50,6 +50,78 @@ function M.setup(user_opts) opts = vim.tbl_deep_extend("force", opts, user_opts or {}) end +--- Help for terminal buffer +function M.keymap_help() + -- get the normal mode keys defined for the current buffer + local keys = vim.api.nvim_buf_get_keymap(0, "n") + + -- sort the keys table by desc + table.sort(keys, function(a, b) return (a.desc or "") < (b.desc or "") end) + + -- Figure out the width of the longest key for later formatting + -- Ignore keys for entries without a desc + local max_key_width = 0 + for _, mapping in ipairs(keys) do + local desc = mapping["desc"] + if desc ~= nil then + local key = mapping["lhs"] + local key_width = vim.api.nvim_strwidth(key) + if key_width > max_key_width then + max_key_width = key_width + end + end + end + + -- create a buffer and floating window to show the key mappings + local buf, win = buffer.create_float({ + title = " Key mappings ", + title_pos = "left", + enter = true, + bufhidden = "hide", + win_options = { + wrap = true, + number = false, + relativenumber = false, + cursorline = false, + signcolumn = "no", + }, + }) + + -- helper function to pad a given key with spaces if necessary such that + -- its size will match max_key_width calculated above. + local function space_pad(key) + local key_width = vim.api.nvim_strwidth(key) + local delta = max_key_width - key_width + if delta > 0 then + return key .. string.rep(" ", delta) + end + return key + end + + -- create formated entries for items with a non-nil desc + local lines = {} + for _, entry in ipairs(keys) do + if entry["desc"] ~= nil then + local line = string.format(" %s %s", + space_pad(entry["lhs"]), + entry["desc"]) + table.insert(lines, line) + end + + end + + -- add some helper text at the end + table.insert(lines, "") + table.insert(lines, ' Use "q" or ESC to close this window') + + -- add the formatted lines to the buffer + vim.api.nvim_buf_set_lines(buf, 3, -1, false, lines) + + -- Use q or ESC to close the buffer + vim.keymap.set("n", "q", "close", { buffer = buf }) + vim.keymap.set("n", "", "close", { buffer = buf }) +end + --- Close the current terminal buffer if it exists function M.close_terminal_buffer() buffer.close(state.buf) @@ -338,6 +410,7 @@ function M.run(cmd, keymaps) -- Set base keymaps only if they haven't been set for this buffer yet if not vim.b[state.buf].jj_keymaps_set then buffer.set_keymaps(state.buf, { + { modes = { "n" }, lhs = "g?", rhs = M.keymap_help }, -- Disable insert, command and append modes { modes = { "n", "v" }, lhs = "i", rhs = function() end }, { modes = { "n", "v" }, lhs = "c", rhs = function() end },