diff options
| author | theprimeagain <the.primeagen@gmail.com> | 2026-02-25 15:14:48 -0700 |
|---|---|---|
| committer | theprimeagain <the.primeagen@gmail.com> | 2026-02-25 15:14:48 -0700 |
| commit | 9be01a1a50a61635ea7169e01c85fab41638ad66 (patch) | |
| tree | a4d50311770e1eed49bf330dd0596db19fc7cea3 /lua | |
| parent | ba72babb9d606f021ef0697a572ced10d5ff0d48 (diff) | |
| download | a4-9be01a1a50a61635ea7169e01c85fab41638ad66.tar.xz a4-9be01a1a50a61635ea7169e01c85fab41638ad66.zip | |
the vibe stuff is sort of there. I genuinely dislike what it is, moving
on
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/99/extensions/work/worker.lua | 9 | ||||
| -rw-r--r-- | lua/99/init.lua | 119 | ||||
| -rw-r--r-- | lua/99/ops/search.lua | 4 | ||||
| -rw-r--r-- | lua/99/ops/vibe.lua | 4 | ||||
| -rw-r--r-- | lua/99/prompt.lua | 6 | ||||
| -rw-r--r-- | lua/99/state.lua | 5 | ||||
| -rw-r--r-- | lua/99/test/qfix_navigation_spec.lua | 70 |
7 files changed, 191 insertions, 26 deletions
diff --git a/lua/99/extensions/work/worker.lua b/lua/99/extensions/work/worker.lua index a967b4c..7bc65d9 100644 --- a/lua/99/extensions/work/worker.lua +++ b/lua/99/extensions/work/worker.lua @@ -155,13 +155,4 @@ function M.search() }) end -function M.last_search_results() - if M.last_work_search == nil then - print("no previous search results") - return - end - - require("99").qfix(M.last_work_search) -end - return M diff --git a/lua/99/init.lua b/lua/99/init.lua index 17eeb06..52ba23b 100644 --- a/lua/99/init.lua +++ b/lua/99/init.lua @@ -188,6 +188,7 @@ local _99_state --- locations with notes that will be put into your quick fix list. --- @field vibe_search fun(opts?: _99.ops.Opts): _99.TraceID | nil --- Select a previous search, edit it, then pass it to vibe. +--- @field vibe fun(opts?: _99.ops.Opts): _99.TraceID | nil --- @field visual fun(opts: _99.ops.Opts): _99.TraceID --- takes your current selection and sends that along with the prompt provided and replaces --- your visual selection with the results @@ -356,10 +357,7 @@ function _99.vibe_search(opts) local o = process_opts(opts) local lines = {} for i, context in ipairs(searches) do - table.insert( - lines, - string.format("%d: %s", i, context:summary()) - ) + table.insert(lines, string.format("%d: %s", i, context:summary())) end Window.capture_select_input("Select Search", { @@ -454,6 +452,61 @@ end --- @field col number --- @field text string +--- @class _99.QFixOpts +--- @field operation? "search" | "vibe" + +--- @param opts? _99.QFixOpts +--- @return "search" | "vibe" +local function qfix_operation(opts) + local operation = (opts and opts.operation) or "search" + assert( + operation == "search" or operation == "vibe", + "opts.operation must be either 'search' or 'vibe'" + ) + return operation +end + +--- @param operation "search" | "vibe" +--- @return _99.Prompt[] +local function qfix_requests(operation) + local out = {} --[[ @as _99.Prompt[] ]] + for _, request in ipairs(_99_state.__request_history) do + if request.operation == operation then + local ok, items = pcall(request.qfix_data, request) + if ok and #items > 0 then + table.insert(out, request) + end + end + end + return out +end + +--- @param operation "search" | "vibe" +--- @param index number +--- @return _99.Prompt | nil +local function qfix_request_at(operation, index) + local requests = qfix_requests(operation) + if #requests == 0 then + return nil + end + + local idx = math.max(1, math.min(index, #requests)) + _99_state.__qfix_history_idx[operation] = idx + return requests[idx] +end + +--- @param request _99.Prompt +local function open_qfix_request(request) + local items = request:qfix_data() + if #items == 0 then + print("there are no quickfix items to show") + return + end + + vim.fn.setqflist({}, "r", { title = "99 Results", items = items }) + vim.cmd("copen") +end + function _99.stop_all_requests() for _, c in pairs(_99_state.__request_by_id) do if c.state == "requesting" then @@ -469,16 +522,56 @@ function _99.clear_all_marks() _99_state.__active_marks = {} end ---- @param xid number -function _99.qfix(xid) - --- @type _99.Prompt - local entry = _99_state.__request_by_id[xid] - assert(entry, "qfix_search_results could not find id: " .. xid) +--- @param opts? _99.QFixOpts +function _99.qfix_top(opts) + local operation = qfix_operation(opts) + local requests = qfix_requests(operation) + if #requests == 0 then + print("there are no quickfix items to show") + return + end - local items = entry:qfix_data() - Logger:set_id(xid):debug("qfix items retrieved", "items", items) - vim.fn.setqflist({}, "r", { title = "99 Results", items = items }) - vim.cmd("copen") + local request = qfix_request_at(operation, #requests) + assert(request, "failed to retrieve qfix request") + open_qfix_request(request) +end + +--- @param opts? _99.QFixOpts +function _99.qfix_older(opts) + local operation = qfix_operation(opts) + local requests = qfix_requests(operation) + if #requests == 0 then + print("there are no quickfix items to show") + return + end + + local current = _99_state.__qfix_history_idx[operation] + if current == 0 then + current = #requests + end + + local request = qfix_request_at(operation, current - 1) + assert(request, "failed to retrieve older qfix request") + open_qfix_request(request) +end + +--- @param opts? _99.QFixOpts +function _99.qfix_newer(opts) + local operation = qfix_operation(opts) + local requests = qfix_requests(operation) + if #requests == 0 then + print("there are no quickfix items to show") + return + end + + local current = _99_state.__qfix_history_idx[operation] + if current == 0 then + current = #requests + end + + local request = qfix_request_at(operation, current + 1) + assert(request, "failed to retrieve newer qfix request") + open_qfix_request(request) end function _99.clear_previous_requests() diff --git a/lua/99/ops/search.lua b/lua/99/ops/search.lua index 0619f47..dc7520f 100644 --- a/lua/99/ops/search.lua +++ b/lua/99/ops/search.lua @@ -17,7 +17,9 @@ local function create_search_locations(context, response) } if #qf_list > 0 then - require("99").qfix(context.xid) + require("99").qfix_top({ + operation = "search", + }) else vim.notify("No search results found", vim.log.levels.INFO) end diff --git a/lua/99/ops/vibe.lua b/lua/99/ops/vibe.lua index 9a64b78..3ba15c5 100644 --- a/lua/99/ops/vibe.lua +++ b/lua/99/ops/vibe.lua @@ -17,7 +17,9 @@ local function finish_vibe(context, response) } if #qf_list > 0 then - require("99").qfix(context.xid) + require("99").qfix_top({ + operation = "vibe", + }) else vim.notify("No search results found", vim.log.levels.INFO) end diff --git a/lua/99/prompt.lua b/lua/99/prompt.lua index 384dbde..fbb8265 100644 --- a/lua/99/prompt.lua +++ b/lua/99/prompt.lua @@ -23,6 +23,7 @@ local filetype_map = { -- luacheck: ignore --- @alias _99.Prompt.Data _99.Prompt.Data.Search | _99.Prompt.Data.Tutorial | _99.Prompt.Data.Visual | _99.Prompt.Data.Vibe --- @alias _99.Prompt.Operation "visual" | "tutorial" | "search" | "vibe" +--- @alias _99.Prompt.QFixOperation "search" | "vibe" --- @alias _99.Prompt.EndingState "failed" | "success" | "cancelled" --- @alias _99.Prompt.State "ready" | "requesting" | _99.Prompt.EndingState --- @alias _99.Prompt.Cleanup fun(): nil @@ -35,7 +36,7 @@ local filetype_map = { --- @class _99.Prompt.Data.Vibe --- @field type "vibe" --- @field response string ---- @field xfix_items _99.Search.Result[] +--- @field qfix_items _99.Search.Result[] --- @class _99.Prompt.Data.Visual --- @field type "visual" @@ -193,6 +194,7 @@ function Prompt.search(_99) context.data = { type = "search", qfix_items = {}, + response = "", } context.logger:debug("99 Request", "method", "search") @@ -332,7 +334,7 @@ function Prompt:qfix_data() self.data.type == "search" or self.data.type == "vibe", "data type is not search or vibe: " .. self.data.type ) - return self.data.xfix_items + return self.data.qfix_items end function Prompt:stop() diff --git a/lua/99/state.lua b/lua/99/state.lua index ae7fc8c..397e30f 100644 --- a/lua/99/state.lua +++ b/lua/99/state.lua @@ -38,6 +38,7 @@ end --- @field __request_by_id table<number, _99.Prompt> --- @field __active_marks _99.Mark[] --- @field __tmp_dir string | nil +--- @field __qfix_history_idx table<"search" | "vibe", number> local State = {} State.__index = State @@ -55,6 +56,10 @@ local function create() __view_log_idx = 1, __request_history = {}, __request_by_id = {}, + __qfix_history_idx = { + search = 0, + vibe = 0, + }, tmp_dir = nil, } end diff --git a/lua/99/test/qfix_navigation_spec.lua b/lua/99/test/qfix_navigation_spec.lua new file mode 100644 index 0000000..f079a9e --- /dev/null +++ b/lua/99/test/qfix_navigation_spec.lua @@ -0,0 +1,70 @@ +-- luacheck: globals describe it assert before_each +local _99 = require("99") +local test_utils = require("99.test.test_utils") +local eq = assert.are.same + +local content = { + "local value = 1", + "return value", +} + +local function qfix_first_text() + local items = vim.fn.getqflist() + local first = items[1] + assert(first, "expected a quickfix item") + return first.text +end + +describe("qfix navigation", function() + local provider + local results = {} + + before_each(function() + provider = test_utils.test_setup(content, 1, 0) + end) + + it("navigates older and newer search quickfix results", function() + _99.search({ additional_prompt = "search one" }) + provider:resolve("success", "/tmp/one.lua:1:1,1,first search") + test_utils.next_frame() + + _99.search({ additional_prompt = "search two" }) + provider:resolve("success", "/tmp/two.lua:1:1,1,second search") + test_utils.next_frame() + + _99.search({ additional_prompt = "search three" }) + provider:resolve("success", "/tmp/three.lua:1:1,1,third search") + test_utils.next_frame() + + _99.qfix_older({ operation = "search" }) + eq("second search", qfix_first_text()) + + _99.qfix_older({ operation = "search" }) + eq("first search", qfix_first_text()) + + _99.qfix_newer({ operation = "search" }) + eq("second search", qfix_first_text()) + + _99.qfix_top({ operation = "search" }) + eq("third search", qfix_first_text()) + end) + + it("navigates vibe quickfix history through vibe results", function() + _99.vibe({ additional_prompt = "vibe one" }) + provider:resolve("success", "/tmp/a.lua:1:1,1,first vibe") + test_utils.next_frame() + + _99.vibe({ additional_prompt = "vibe two" }) + provider:resolve("success", "/tmp/b.lua:1:1,1,second vibe") + test_utils.next_frame() + + _99.qfix_top({ operation = "vibe" }) + eq("second vibe", qfix_first_text()) + + _99.qfix_older({ operation = "vibe" }) + eq("first vibe", qfix_first_text()) + + _99.qfix_newer({ operation = "vibe" }) + eq("second vibe", qfix_first_text()) + end) +end) |
