-
Notifications
You must be signed in to change notification settings - Fork 24
/
init.lua
156 lines (126 loc) · 3.67 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
local u = require('model.store.util')
local M = {}
---@class FunctionItem
---@field content string
---@field filepath string
---@field name string
---@class Item
---@field content string
---@field id string
---@field meta? table
local function get_git_root()
return vim.fn.systemlist('git rev-parse --show-toplevel')[1]
end
function M.load(opts, force)
if M.store_did_init == true and not force then
return
end
local store_root_dir = (opts or {}).store_root_dir or get_git_root()
M.store_root_dir = store_root_dir
vim.cmd([[
py import json
py import store
py s = store.load_or_initialize_store(']] .. M.store_root_dir .. [[')
]])
local store_items_count = vim.fn.pyeval("len(s['items'])")
local store_location = vim.fn.pyeval("s['abs_path']")
vim.notify(
'Loaded '
.. store_items_count
.. ' items in store.json at '
.. store_location
)
M.store_did_init = true
end
function M.get_known_ids()
return vim.fn.pyeval("[ i['id'] for i in s['items'] ]")
end
---@return { id: string, content: string, similarity: number }[]
function M.query_store(prompt, count, similarity)
if similarity == nil then
return vim.fn.py3eval(
[[store.query_store(]]
.. u.escape_quotes(prompt)
.. [[, ]]
.. count
.. [[, s)]]
)
else
local filter = [[lambda item, similarity: similarity > ]] .. similarity
return vim.fn.py3eval(
[[store.query_store(]]
.. u.escape_quotes(prompt)
.. [[, ]]
.. count
.. [[, s, filter=]]
.. filter
.. [[)]]
)
end
end
local ts_source = require('model.store.sources.treesitter')
---@param function_item FunctionItem
local function normalize_function_item_filepath_to_store(function_item)
local store_rel_path = vim.fn.pyeval(
'store.path_relative_to_store(r"' .. function_item.filepath .. '", s)'
)
return {
id = store_rel_path .. ':' .. function_item.name,
content = function_item.content,
}
end
--- Add items to the git-local vector store. Expects store to be initialized.
--- Item content will be embedded with openai ada. Items that match existing id and content
--- won't be embedded again.
---@param items Item[] items
function M.add_items(items)
vim.cmd([[py store.update_store_and_save(]] .. u.to_python(items) .. [[,s)]])
end
function M.add_files(root_path)
vim.cmd(
[[py store.update_with_files_and_save(s, files_root=']]
.. root_path
.. [[')]]
)
end
function M.add_lua_functions(glob)
if glob == nil then
glob = vim.fn.expand('%')
end
-- Extracts lua functions as items
local function to_lua_functions(file)
return vim.tbl_map(
normalize_function_item_filepath_to_store,
ts_source.lang.lua.functions(file)
)
end
---@param glob_ string glob pattern to search for files, starting from current directory
---@param to_items function converts each filepath to a list of items
local function glob_to_items(glob_, to_items)
local filepaths = vim.fn.glob(glob_, nil, true)
local results = {}
for _, filepath in ipairs(filepaths) do
-- show(filepath)
local file = ts_source.ingest_file(filepath)
local items = to_items(file)
for _, item in ipairs(items) do
table.insert(results, item)
end
end
return results
end
M.add_items(glob_to_items(glob, to_lua_functions))
end
M.prompt = {}
function M.prompt.query_store(input, count, similarity)
M.load()
local context_results = M.query_store(input, count, similarity)
local context = table.concat(
vim.tbl_map(function(x)
return '```' .. x.id .. '\n' .. x.content .. '\n```'
end, context_results),
'\n'
)
return context
end
return M