summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThePrimeAgain <theprimeagain@theprimeagain.com>2025-12-01 16:01:40 -0700
committerThePrimeAgain <theprimeagain@theprimeagain.com>2025-12-01 16:01:40 -0700
commit7438d6024d57736ec2fe8e0cc8feeb4f5c817d33 (patch)
tree0e44b283b395817fae12934809dc8019ae0b15ed
parent00c5d9a9ca2d978641e7d30ab70bb34249011dec (diff)
downloada4-7438d6024d57736ec2fe8e0cc8feeb4f5c817d33.tar.xz
a4-7438d6024d57736ec2fe8e0cc8feeb4f5c817d33.zip
getting to the point of making this look pretty
-rw-r--r--AGENT.md2
-rw-r--r--lua/99/editor/location.lua17
-rw-r--r--lua/99/editor/lsp.lua2
-rw-r--r--lua/99/editor/treesitter.lua7
-rw-r--r--lua/99/init.lua16
-rw-r--r--lua/99/logger/logger.lua8
-rw-r--r--lua/99/ops/context.lua32
-rw-r--r--lua/99/ops/fill-in-function.lua36
-rw-r--r--lua/99/ops/implement-fn.lua31
-rw-r--r--scratch/refresh.lua1
10 files changed, 125 insertions, 27 deletions
diff --git a/AGENT.md b/AGENT.md
new file mode 100644
index 0000000..fc195c1
--- /dev/null
+++ b/AGENT.md
@@ -0,0 +1,2 @@
+always use vim functions
+never use lua std functions from io (when possible)
diff --git a/lua/99/editor/location.lua b/lua/99/editor/location.lua
index b4b3de8..fef40fb 100644
--- a/lua/99/editor/location.lua
+++ b/lua/99/editor/location.lua
@@ -1,8 +1,9 @@
-local Point = require("99.geo")
+local Range = require("99.geo").Range
--- @class _99.Location
--- @field full_path string
--- @field range Range
+--- @field node TSNode
--- @field buffer number
--- @field marks table<string, string>
local Location = {}
@@ -19,4 +20,18 @@ function Location.from_range(range)
}, Location)
end
+--- @param node TSNode
+--- @param range Range
+function Location.from_ts_node(node, range)
+ local full_path = vim.api.nvim_buf_get_name(range.buffer)
+
+ return setmetatable({
+ buffer = range.buffer,
+ full_path = full_path,
+ range = range,
+ node = node,
+ marks = {}
+ }, Location)
+end
+
return Location
diff --git a/lua/99/editor/lsp.lua b/lua/99/editor/lsp.lua
index ddb2486..590409b 100644
--- a/lua/99/editor/lsp.lua
+++ b/lua/99/editor/lsp.lua
@@ -41,7 +41,7 @@ local function get_lsp_definitions(buffer, position, cb)
end
--- @class Lsp
---- @field config _99Options
+--- @field config _99.Options
local Lsp = {}
Lsp.__index = Lsp
diff --git a/lua/99/editor/treesitter.lua b/lua/99/editor/treesitter.lua
index b76939d..7e0ddea 100644
--- a/lua/99/editor/treesitter.lua
+++ b/lua/99/editor/treesitter.lua
@@ -100,8 +100,13 @@ function Scope:has_scope()
return #self.range > 0
end
---- @return Range | nil
+--- @return TSNode | nil
function Scope:get_inner_scope()
+ return self.scope[#self.scope]
+end
+
+--- @return Range | nil
+function Scope:get_inner_range()
return self.range[#self.range]
end
diff --git a/lua/99/init.lua b/lua/99/init.lua
index f336f09..938fadc 100644
--- a/lua/99/init.lua
+++ b/lua/99/init.lua
@@ -2,9 +2,10 @@ local Logger = require("99.logger.logger")
local Level = require("99.logger.level")
local ops = require("99.ops")
---- @class _99Options
+--- @class _99.Options
--- @field logger _99.Logger.Options?
--- @field model string?
+--- @field md_files string[]
--- 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
@@ -12,12 +13,14 @@ local ops = require("99.ops")
--- @field model string
--- @field md_files string[]
--- @field prompts _99.Prompts
+--- @field ai_stdout_rows number
--- @type _99.State
local _99_state = {
model = "anthropic/claude-sonnet-4-5",
md_files = {},
prompts = require("99.prompt_settings"),
+ ai_stdout_rows = 3,
}
--- @class _99
@@ -39,15 +42,24 @@ function _99.fill_in_function()
fif:start()
end
---- @param opts _99Options?
+--- @param opts _99.Options?
function _99.setup(opts)
opts = opts or {}
+ print("configuring logger")
Logger:configure(opts.logger)
if opts.model then
+ assert(type(opts.model) == "string", "opts.model is not a string")
_99_state.model = opts.model
end
+
+ if opts.md_files then
+ assert(type(opts.md_files) == "table", "opts.md_files is not a table")
+ for _, md in ipairs(opts.md_files) do
+ _99.add_md_file(md)
+ end
+ end
end
--- @param md string
diff --git a/lua/99/logger/logger.lua b/lua/99/logger/logger.lua
index 8f03092..088a04f 100644
--- a/lua/99/logger/logger.lua
+++ b/lua/99/logger/logger.lua
@@ -132,17 +132,17 @@ function Logger:configure(opts)
end
if opts.level then
- Logger:set_level(opts.level)
+ self:set_level(opts.level)
end
if opts.path then
- Logger:file_sink(opts.path)
+ self:file_sink(opts.path)
else
- Logger:print_sink()
+ self:print_sink()
end
if opts.print_on_error then
- Logger:on_error_print_message()
+ self:on_error_print_message()
end
end
diff --git a/lua/99/ops/context.lua b/lua/99/ops/context.lua
index 0428671..1e14510 100644
--- a/lua/99/ops/context.lua
+++ b/lua/99/ops/context.lua
@@ -1,3 +1,5 @@
+local Logger = require("99.logger.logger")
+
--- TODO: some people change their current working directory as they open new
--- directories. if this is still the case in neovim land, then we will need
--- to make the _99_state have the project directory.
@@ -34,16 +36,38 @@ function Context:add_md_file_name(md_file_name)
return self
end
-function Context:_read_md_files()
- --- @ai use location's buffer's full path and walk back until we are at cwd
- --- @ai and read each of the md_file_names. if it exists then add it to
- --- @ai ai_context.
+--- @param location _99.Location
+function Context:_read_md_files(location)
+ local cwd = vim.uv.cwd()
+ local dir = vim.fn.fnamemodify(location.full_path, ":h")
+
+ Logger:info("_read_md_files", "cwd", cwd, "dir", dir)
+ while dir:find(cwd, 1, true) == 1 do
+ for _, md_file_name in ipairs(self.md_file_names) do
+ local md_path = dir .. "/" .. md_file_name
+ local file = io.open(md_path, "r")
+ Logger:info("_read_md_files#while#for", "md_path", md_path)
+ if file then
+ local content = file:read("*a")
+ file:close()
+ table.insert(self.ai_context, content)
+ end
+ end
+
+ if dir == cwd then
+ break
+ end
+
+ dir = vim.fn.fnamemodify(dir, ":h")
+ Logger:info("_read_md_files#while", "new dir selected", dir)
+ end
end
--- @param _99 _99.State
--- @param location _99.Location
--- @return self
function Context:finalize(_99, location)
+ self:_read_md_files(location)
table.insert(self.ai_context, _99.prompts.get_file_location(location))
table.insert(self.ai_context, _99.prompts.get_range_text(location.range))
table.insert(self.ai_context, _99.prompts.tmp_file_location(self.tmp_file))
diff --git a/lua/99/ops/fill-in-function.lua b/lua/99/ops/fill-in-function.lua
index ed28447..b222d1c 100644
--- a/lua/99/ops/fill-in-function.lua
+++ b/lua/99/ops/fill-in-function.lua
@@ -35,22 +35,50 @@ local function update_file_with_changes(res, location)
end
--- @param _99 _99.State
+--- @param location _99.Location
+local function add_space_in_function(_99, location)
+ if _99.ai_stdout_rows == 0 then
+ return
+ end
+
+ local buffer = location.buffer
+ local range = location.range
+ local function_end_row, _ = range.end_:to_vim()
+
+ local empty_lines = {}
+ for i = 1, _99.ai_stdout_rows do
+ empty_lines[i] = ""
+ end
+
+ vim.api.nvim_buf_set_lines(buffer, function_end_row, function_end_row, false, empty_lines)
+
+ location.marks.ai_stdout_start = marks(buffer, range)
+end
+
+local function print_hello_world()
+ print("Hello, World!")
+end
+
+--- @param _99 _99.State
--- @return _99.Request
local function fill_in_function(_99)
local ts = editor.treesitter
local cursor = Point:from_cursor()
local scopes = ts.function_scopes(cursor)
- local range = scopes:get_inner_scope()
+ local scope = scopes:get_inner_scope()
+ local range = scopes:get_inner_range()
- if not range then
+ if not range or not scope then
Logger:error("fill_in_function: unable to find any containing function")
error("you cannot call fill_in_function not in a function")
end
- local location = editor.Location.from_range(range)
+ local location = editor.Location.from_ts_node(scope, range)
local context = Context.new(_99):finalize(_99, location)
local request = Request.new({
model = _99.model,
+ on_stdout = function(line)
+ end,
on_complete = function(_, ok, response)
if not ok then
Logger:fatal("unable to fill in function, enable and check logger for more details")
@@ -64,6 +92,8 @@ local function fill_in_function(_99)
location.marks.function_location = marks(location.buffer, range)
request:add_prompt_content(_99.prompts.prompts.fill_in_function)
+ add_space_in_function(_99, location)
+
return request
end
diff --git a/lua/99/ops/implement-fn.lua b/lua/99/ops/implement-fn.lua
index ef28c10..3d445a7 100644
--- a/lua/99/ops/implement-fn.lua
+++ b/lua/99/ops/implement-fn.lua
@@ -1,32 +1,43 @@
+local Context = require("99.ops.context")
+local Location = require("99.editor.location")
local Logger = require("99.logger.logger")
local Request = require("99.request")
local editor = require("99.editor")
-local Range = require("99.geo").Range
+local geo = require("99.geo")
+local Range = geo.Range
+local Point = geo.Point
local function update_code(request, ok, res)
if not ok then
error("unable to implement function. check logger for more details")
end
- Logger:fatal("not implemented yet")
+ Logger:fatal("not implemented yet")
end
--- @param _99 _99.State
---- @return _99.Request?
+--- @return _99.Request
local function implement_fn(_99)
+ local ts = editor.treesitter
+ local cursor = Point:from_cursor()
+ local scopes = ts.function_scopes(cursor)
+
+ local range = scopes:get_inner_scope()
+
+ local context = Context.new(_99)
local request = Request.new({
- model = _99.model,
- md_files = _99.md_files,
on_complete = update_code,
+ model = _99.model,
+ context = context,
})
local ts = editor.treesitter
local ident = ts.identifier(request.buffer, request.cursor)
- print_ident(ident)
+ print_ident(ident)
- if not ident then
- Logger:error("implement_fn was called but cursor was not on a function call", "cursor", request.cursor)
- return nil
- end
+ if not ident then
+ Logger:error("implement_fn was called but cursor was not on a function call", "cursor", request.cursor)
+ return nil
+ end
Range:from_ts_node(ident, request.buffer)
diff --git a/scratch/refresh.lua b/scratch/refresh.lua
index c90f76f..3612efd 100644
--- a/scratch/refresh.lua
+++ b/scratch/refresh.lua
@@ -1,5 +1,4 @@
local function pick_a_number_that_is_42()
- return 42
end
function return_42()