diff options
| author | ThePrimeAgain <theprimeagain@theprimeagain.com> | 2026-01-15 11:22:01 -0700 |
|---|---|---|
| committer | ThePrimeAgain <theprimeagain@theprimeagain.com> | 2026-01-15 11:22:01 -0700 |
| commit | fc2ce13fcc6454fa12ee1015f921611cd2edc4fa (patch) | |
| tree | dc2cc7817d012eff49d8a902f8d083e73e98bf59 /lua | |
| parent | 4e24d093d50177e299823703759a5e276d198170 (diff) | |
| download | a4-fc2ce13fcc6454fa12ee1015f921611cd2edc4fa.tar.xz a4-fc2ce13fcc6454fa12ee1015f921611cd2edc4fa.zip | |
autocomplete appearing to work
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/99/extensions/agents/helpers.lua (renamed from lua/99/agents/helpers.lua) | 4 | ||||
| -rw-r--r-- | lua/99/extensions/agents/init.lua (renamed from lua/99/agents/init.lua) | 19 | ||||
| -rw-r--r-- | lua/99/extensions/cmp.lua | 76 | ||||
| -rw-r--r-- | lua/99/extensions/init.lua | 38 | ||||
| -rw-r--r-- | lua/99/init.lua | 75 | ||||
| -rw-r--r-- | lua/99/window/init.lua | 19 |
6 files changed, 161 insertions, 70 deletions
diff --git a/lua/99/agents/helpers.lua b/lua/99/extensions/agents/helpers.lua index a5000cb..1f4ed01 100644 --- a/lua/99/agents/helpers.lua +++ b/lua/99/extensions/agents/helpers.lua @@ -3,8 +3,8 @@ local M = {} --- @param dir string --- @return _99.Agents.Rule[] function M.ls(dir) - local cursor_rules_dir = vim.uv.cwd() .. dir - local files = vim.fn.glob(cursor_rules_dir .. "/*.{mdc,md}", false, true) + local cwd = vim.fs.joinpath(vim.uv.cwd(), dir) + local files = vim.fn.glob(cwd .. "/*.{mdc,md}", false, true) local rules = {} for _, file in ipairs(files) do diff --git a/lua/99/agents/init.lua b/lua/99/extensions/agents/init.lua index be43727..f594802 100644 --- a/lua/99/agents/init.lua +++ b/lua/99/extensions/agents/init.lua @@ -1,4 +1,4 @@ -local helpers = require("99.agents.helpers") +local helpers = require("99.extensions.agents.helpers") local M = {} --- @class _99.Agents.Rule @@ -17,7 +17,7 @@ local M = {} function M.rules(_99) local cursor = helpers.ls(".cursor/rules") local custom = {} - for _, path in ipairs(_99.custom_rules) do + for _, path in ipairs(_99.completion.custom_rules or {}) do local c = helpers.ls(path) table.insert(custom, c) end @@ -27,4 +27,19 @@ function M.rules(_99) } end +--- @param rules _99.Agents.Rules +--- @return _99.Agents.Rule[] +function M.rules_to_items(rules) + local items = {} + for _, rule in ipairs(rules.cursor or {}) do + table.insert(items, rule) + end + for _, custom_rules in ipairs(rules.custom or {}) do + for _, rule in ipairs(custom_rules) do + table.insert(items, rule) + end + end + return items +end + return M diff --git a/lua/99/extensions/cmp.lua b/lua/99/extensions/cmp.lua index e55ae36..30e5d2c 100644 --- a/lua/99/extensions/cmp.lua +++ b/lua/99/extensions/cmp.lua @@ -1,14 +1,24 @@ +local Agents = require("99.extensions.agents") +local SOURCE = "99" + +--- @param _99 _99.State +--- @return _99.Agents.Rule[] +local function rules(_99) + return Agents.rules_to_items(Agents.rules(_99)) +end + --- @class CmpSource --- @field _99 _99.State ---- @field items string[] +--- @field items _99.Agents.Rule[] local CmpSource = {} CmpSource.__index = CmpSource -local SOURCE = "99" - --- @param _99 _99.State function CmpSource.new(_99) - return setmetatable({}, CmpSource) + return setmetatable({ + _99 = _99, + items = rules(_99), + }, CmpSource) end function CmpSource:is_available() @@ -39,41 +49,39 @@ end -- true: I might return more if user types more -- false: this result set is complete function CmpSource:complete(params, callback) - local cmp = require("cmp") local before = params.context.cursor_before_line or "" - local prefix = before:match("(%w+)$") or "" - local items = {} --[[ @as CompletionItem[] ]] - print("complete: context", vim.inspect(params.context)) + if #before > 1 and before:sub(#before - 1) ~= " @" then + callback({ + items = {}, + isIncomplete = false, + }) + return + end + + for _, item in ipairs(self.items) do + table.insert(items, { + label = item.name, + insertText = item.path, + filterText = item.name, + kind = 17, -- file + -- documentation = "here is the documentation and everything associated with it", + -- detail = "detail: right side hint", + }) + end callback({ items = items, - isIncomplete = true, + isIncomplete = false, }) end --- resolve(completion_item, callback) (optional) --- Some sources return lightweight items first, then fill in heavy fields --- only when the user selects an item. --- --- For example: --- - fetch docs lazily --- - compute expensive detail text --- --- If you don’t need it, omit it. +--- TODO: Look into what this could be function CmpSource:resolve(completion_item, callback) - -- You can modify completion_item here. callback(completion_item) end --- execute(completion_item, callback) (optional) --- Called when the item is confirmed, if the item contains an "command" field --- or if your source wants to perform side-effects. --- --- Examples: --- - insert import statements (usually via additionalTextEdits instead) --- - open a snippet, run something, etc. function CmpSource:execute(completion_item, callback) callback(completion_item) end @@ -86,24 +94,32 @@ local function init_for_buffer(_99) local cmp = require("cmp") cmp.setup.buffer({ sources = { - { name = "my_source" }, + { name = SOURCE }, }, }) end --- @param _99 _99.State local function init(_99) - assert(source == nil, "the source must be nil when calling init on an completer") + assert( + source == nil, + "the source must be nil when calling init on an completer" + ) local cmp = require("cmp") source = CmpSource.new(_99) cmp.register_source(SOURCE, source) end -local function refresh_state(_99) end +--- @param _99 _99.State +local function refresh_state(_99) + source.items = rules(_99) +end -return { +--- @type _99.Extensions.Source +local source_wrapper = { init_for_buffer = init_for_buffer, init = init, refresh_state = refresh_state, } +return source_wrapper diff --git a/lua/99/extensions/init.lua b/lua/99/extensions/init.lua index 94190d6..ceb63a5 100644 --- a/lua/99/extensions/init.lua +++ b/lua/99/extensions/init.lua @@ -1,5 +1,37 @@ -local M = {} +local cmp = require("99.extensions.cmp") ---- @param _99 _99.State -function M.init_buffer(_99) +--- @class _99.Extensions.Source +--- @field init_for_buffer fun(_99: _99.State): nil +--- @field init fun(_99: _99.State): nil +--- @field refresh_state fun(_99: _99.State): nil + +--- @param completion _99.Completion | nil +--- @return _99.Extensions.Source | nil +local function get_source(completion) + if not completion or not completion.source then + return + end + local source = completion.source + if source == "cmp" then + return cmp + end end + +return { + --- @param _99 _99.State + init = function(_99) + local source = get_source(_99.completion) + if not source then + return + end + source.init(_99) + end, + + setup_buffer = function(_99) + local source = get_source(_99.completion) + if not source then + return + end + source.init_for_buffer(_99) + end, +} diff --git a/lua/99/init.lua b/lua/99/init.lua index 3faa6e2..a677d6b 100644 --- a/lua/99/init.lua +++ b/lua/99/init.lua @@ -6,6 +6,7 @@ local Window = require("99.window") local get_id = require("99.id") local RequestContext = require("99.request-context") local Range = require("99.geo").Range +local Extensions = require("99.extensions") --- @alias _99.Cleanup fun(): nil @@ -34,6 +35,10 @@ local function create_99_state() } end +--- @class _99.Completion +--- @field source "cmp" | nil +--- @field custom_rules string[] | nil + --- @class _99.Options --- @field logger _99.Logger.Options? --- @field model string? @@ -41,14 +46,14 @@ end --- @field provider _99.Provider? --- @field debug_log_prefix string? --- @field display_errors? boolean ---- @field custom_rules? string[] +--- @field completion _99.Completion? --- unanswered question -- will i need to queue messages one at a time or --- just send them all... So to prepare ill be sending around this state object --- @class _99.State +--- @field completion _99.Completion --- @field model string --- @field md_files string[] ---- @field custom_rules string[] --- @field prompts _99.Prompts --- @field ai_stdout_rows number --- @field languages string[] @@ -146,19 +151,25 @@ end function _99.fill_in_function_prompt() local context = get_context("fill-in-function-with-prompt") + context.logger:debug("start") - Window.capture_input(function(success, response) - context.logger:debug( - "capture_prompt", - "success", - success, - "response", - response - ) - if success then - ops.fill_in_function(context, response) - end - end, {}) + Window.capture_input({ + cb = function(success, response) + context.logger:debug( + "capture_prompt", + "success", + success, + "response", + response + ) + if success then + ops.fill_in_function(context, response) + end + end, + on_load = function() + Extensions.setup_buffer(_99_state) + end, + }) end function _99.fill_in_function() @@ -168,18 +179,23 @@ end function _99.visual_prompt() local context = get_context("over-range-with-prompt") context.logger:debug("start") - Window.capture_input(function(success, response) - context.logger:debug( - "capture_prompt", - "success", - success, - "response", - response - ) - if success then - _99.visual(response) - end - end, {}) + Window.capture_input({ + cb = function(success, response) + context.logger:debug( + "capture_prompt", + "success", + success, + "response", + response + ) + if success then + _99.visual(response) + end + end, + on_load = function() + Extensions.setup_buffer(_99_state) + end, + }) end --- @param prompt string? @@ -250,7 +266,11 @@ function _99.setup(opts) opts = opts or {} _99_state = _99_State.new() _99_state.provider_override = opts.provider - _99_state.custom_rules = opts.custom_rules or {} + _99_state.completion = opts.completion + or { + source = nil, + custom_rules = {}, + } vim.api.nvim_create_autocmd("VimLeavePre", { callback = function() @@ -275,6 +295,7 @@ function _99.setup(opts) _99_state.display_errors = opts.display_errors or false Languages.initialize(_99_state) + Extensions.init(_99_state) end --- @param md string diff --git a/lua/99/window/init.lua b/lua/99/window/init.lua index 8f45433..3475d5a 100644 --- a/lua/99/window/init.lua +++ b/lua/99/window/init.lua @@ -257,9 +257,12 @@ local function set_defaul_win_options(win, name) vim.bo[win.buf_id].swapfile = false end ---- @param cb fun(success: boolean, result: string): nil ---- @param opts {} -function M.capture_input(cb, opts) +--- @class _99.window.CaptureInputOpts +--- @field cb fun(success: boolean, result: string): nil +--- @field on_load? fun(): nil + +--- @param opts _99.window.CaptureInputOpts +function M.capture_input(opts) _ = opts M.clear_active_popups() @@ -299,7 +302,7 @@ function M.capture_input(cb, opts) local lines = vim.api.nvim_buf_get_lines(win.buf_id, 0, -1, false) local result = table.concat(lines, "\n") M.clear_active_popups() - cb(true, result) + opts.cb(true, result) end, }) @@ -322,14 +325,18 @@ function M.capture_input(cb, opts) return end M.clear_active_popups() - cb(false, "") + opts.cb(false, "") end, }) vim.keymap.set("n", "q", function() M.clear_active_popups() - cb(false, "") + opts.cb(false, "") end, { buffer = win.buf_id, nowait = true }) + + if opts.on_load then + vim.schedule(opts.on_load) + end end function M.clear_active_popups() |
