summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
authortheprimeagain <the.primeagen@gmail.com>2026-02-28 14:29:28 -0700
committertheprimeagain <the.primeagen@gmail.com>2026-02-28 14:29:49 -0700
commit78f39f61606597ca778ec01e2058a3e652000d7e (patch)
tree332ccb8a69a98d664854a7bbb99b297f6460d2d9 /lua
parentd485196b0a7956e9efb9f73eccfb126b95d113b3 (diff)
downloada4-78f39f61606597ca778ec01e2058a3e652000d7e.tar.xz
a4-78f39f61606597ca778ec01e2058a3e652000d7e.zip
selection works nicely now
Diffstat (limited to 'lua')
-rw-r--r--lua/99/init.lua39
-rw-r--r--lua/99/test/window_spec.lua38
-rw-r--r--lua/99/window/init.lua53
-rw-r--r--lua/99/window/select-window.lua30
4 files changed, 126 insertions, 34 deletions
diff --git a/lua/99/init.lua b/lua/99/init.lua
index 035ee16..72e4cc0 100644
--- a/lua/99/init.lua
+++ b/lua/99/init.lua
@@ -6,6 +6,7 @@ local Tracking = require("99.state.tracking")
local Level = require("99.logger.level")
local ops = require("99.ops")
local Window = require("99.window")
+local select_window = require("99.window.select-window")
local StatusWindow = require("99.window.status-window")
local Prompt = require("99.prompt")
local State = require("99.state")
@@ -216,39 +217,6 @@ local _99 = {
FATAL = Level.FATAL,
}
---- @param requests _99.Prompt[]
----@param cb fun(r: _99.Prompt): nil
-local function capture_request(requests, cb)
- local str_requests = Tracking.to_selectable_list(requests)
-
- Window.capture_select_input("99 Select Request", {
- content = str_requests,
- cb = function(success, result)
- if not success or result == "" then
- return
- end
-
- local idx = tonumber(vim.fn.matchstr(result, "^\\d\\+"))
- if idx == nil then
- return
- end
- local r = requests[idx]
- if not r then
- print(
- "request not found... potentially report bug: " .. vim.inspect(idx)
- )
- return
- end
- assert(
- r:valid(),
- "request is not valid... not sure how we got here. please report bug and this word: "
- .. vim.inspect(r.operation)
- )
- cb(r)
- end,
- })
-end
-
--- @param cb fun(context: _99.Prompt, o: _99.ops.Opts?): nil
--- @param name string
--- @param context _99.Prompt
@@ -318,7 +286,10 @@ end
function _99.open()
local requests = _99_state.tracking:successful()
- capture_request(requests, function(r)
+ local str_requests = Tracking.to_selectable_list(requests)
+ select_window(str_requests, function(idx)
+ local r = requests[idx]
+ assert(r:valid(), "encountered unexpected issue. malformated data")
if r.operation == "visual" then
--- TODO: this is its own work item for being able to have a global mark
--- section in which i keep track of marks for the lifetime of the
diff --git a/lua/99/test/window_spec.lua b/lua/99/test/window_spec.lua
new file mode 100644
index 0000000..c91c219
--- /dev/null
+++ b/lua/99/test/window_spec.lua
@@ -0,0 +1,38 @@
+-- luacheck: globals describe it assert before_each after_each
+local Window = require("99.window")
+local eq = assert.are.same
+
+describe("Window", function()
+ local previous_list_uis
+
+ before_each(function()
+ previous_list_uis = vim.api.nvim_list_uis
+ vim.api.nvim_list_uis = function()
+ return {
+ { width = 120, height = 40 },
+ }
+ end
+ end)
+
+ after_each(function()
+ vim.api.nvim_list_uis = previous_list_uis
+ Window.clear_active_popups()
+ end)
+
+ it("shows keymap legend window and applies keyoffset", function()
+ local win = Window.capture_input("Prompt", {
+ cb = function() end,
+ keymap = {
+ q = "cancel",
+ ["<CR>"] = "submit",
+ },
+ })
+
+ eq(2, #Window.active_windows)
+ eq(2, vim.wo[win.win_id].scrolloff)
+
+ local legend = Window.active_windows[2]
+ local lines = vim.api.nvim_buf_get_lines(legend.buf_id, 0, -1, false)
+ eq({ "<CR>=submit", "q=cancel" }, lines)
+ end)
+end)
diff --git a/lua/99/window/init.lua b/lua/99/window/init.lua
index a3a02bb..4cc44f4 100644
--- a/lua/99/window/init.lua
+++ b/lua/99/window/init.lua
@@ -3,6 +3,9 @@
local Agents = require("99.extensions.agents")
local Point = require("99.geo").Point
+local BASE = 100
+local LEGEND = 200
+
--- @class _99.window.Module
--- @field active_windows _99.window.Window[]
local M = {
@@ -355,11 +358,56 @@ local function highlight_rules_found(win, rules, group)
})
end
+--- @alias _99.window.KeyMap table<string, string>
--- @class _99.window.CaptureInputOpts
--- @field cb fun(success: boolean, result: string): nil
--- @field on_load? fun(): nil
--- @field content? string[]
--- @field rules? _99.Agents.Rules
+--- @field keymap? _99.window.KeyMap
+
+--- @param keymap _99.window.KeyMap
+--- @param width number
+--- @return string[]
+local function keymap_lines(keymap, width)
+ local keys = vim.tbl_keys(keymap)
+ table.sort(keys)
+
+ local lines = { "" }
+ for _, key in ipairs(keys) do
+ local current = lines[#lines]
+ local legend = string.format("%s=%s", key, keymap[key])
+ if #current + #legend + 1 > width then
+ table.insert(lines, legend)
+ else
+ lines[#lines] = string.format("%s %s", current, legend)
+ end
+ end
+
+ return lines
+end
+
+--- @param win _99.window.Window
+--- @param keymap _99.window.KeyMap
+local function create_window_legend(win, keymap)
+ local lines = keymap_lines(keymap, win.config.width - 2)
+ local keyoffset = #lines
+ local keymap_config = create_window_inside(win, keyoffset - 1)
+ keymap_config.height = keyoffset
+ keymap_config.zindex = LEGEND
+
+ local keymap_win = create_floating_window(keymap_config, "", false)
+ vim.bo[keymap_win.buf_id].buftype = "nofile"
+ vim.bo[keymap_win.buf_id].bufhidden = "wipe"
+ vim.bo[keymap_win.buf_id].swapfile = false
+ vim.bo[keymap_win.buf_id].modifiable = true
+ vim.bo[keymap_win.buf_id].readonly = false
+ vim.api.nvim_buf_set_lines(keymap_win.buf_id, 0, -1, false, lines)
+ vim.bo[keymap_win.buf_id].modifiable = false
+ vim.bo[keymap_win.buf_id].readonly = true
+
+ vim.wo[win.win_id].scrolloff = keyoffset
+end
--- @param name string
--- @param opts _99.window.CaptureInputOpts
@@ -374,6 +422,10 @@ function M.capture_input(name, opts)
set_defaul_win_options(win, "99-prompt")
vim.api.nvim_set_current_win(win.win_id)
+ opts.keymap = opts.keymap or {}
+ opts.keymap.q = "cancel"
+ create_window_legend(win, opts.keymap)
+
local group = vim.api.nvim_create_augroup(
"99_present_prompt_" .. win.buf_id,
{ clear = true }
@@ -458,6 +510,7 @@ function M.capture_select_input(name, opts)
win = M.capture_input(name, {
content = opts.content,
rules = opts.rules,
+ keymap = opts.keymap,
cb = function(success, result)
if not success then
opts.cb(false, result)
diff --git a/lua/99/window/select-window.lua b/lua/99/window/select-window.lua
new file mode 100644
index 0000000..3c90e0b
--- /dev/null
+++ b/lua/99/window/select-window.lua
@@ -0,0 +1,30 @@
+local Window = require("99.window")
+
+--- @param lines string[]
+---@param cb fun(idx: number): nil
+local function select_window(lines, cb)
+ Window.capture_select_input("Select", {
+ content = lines,
+ keymap = {
+ enter = "select",
+ },
+ cb = function(success, result)
+ if not success or result == "" then
+ return
+ end
+
+ local idx = tonumber(vim.fn.matchstr(result, "^\\d\\+"))
+ if idx == nil then
+ return
+ end
+ local r = lines[idx]
+ if not r then
+ return
+ end
+ cb(idx)
+ end,
+ })
+end
+
+
+return select_window