Skip to content

Commit 97dd5a6

Browse files
committed
feat(nvim): add a new QueryCallback that uses :changes. Implement #45.
1 parent 6863fd8 commit 97dd5a6

File tree

3 files changed

+103
-4
lines changed

3 files changed

+103
-4
lines changed

doc/VectorCode.txt

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*VectorCode.txt* For Last change: 2025 March 28
1+
*VectorCode.txt* For Last change: 2025 March 29
22

33
==============================================================================
44
Table of Contents *VectorCode-table-of-contents*
@@ -40,6 +40,7 @@ Table of Contents *VectorCode-table-of-contents*
4040
- |VectorCode-`cacher_backend.buf_is_enabled(bufnr?)`|
4141
- |VectorCode-`cacher_backend.buf_job_count(bufnr?)`|
4242
- |VectorCode-`cacher_backend.make_prompt_component(bufnr?,-component_cb?)`|
43+
- |VectorCode-built-in-query-callbacks|
4344

4445

4546
INSTALLATION *VectorCode-neovim-plugin-installation*
@@ -383,8 +384,9 @@ documents. Default: `1`; - `debounce`: debounce time in milliseconds. Default:
383384
`10`; - `notify`: whether to show notifications when a query is completed.
384385
Default: `false`; - `query_cb`: a callback function that accepts the buffer ID
385386
and returns the query message(s). Default:
386-
`require("vectorcode.utils").make_surrounding_lines_cb(-1)`; - `events`: list
387-
of autocommand events that triggers the query. Default: `{"BufWritePost",
387+
`require("vectorcode.utils").make_surrounding_lines_cb(-1)`. See
388+
|VectorCode-this-section| for a list of built-in query callbacks; - `events`:
389+
list of autocommand events that triggers the query. Default: `{"BufWritePost",
388390
"InsertEnter", "BufReadPost"}`; - `run_on_register`: whether to run the query
389391
when the buffer is registered. Default: `false`; - `single_job`: boolean. If
390392
this is set to `true`, there will only be one running job for each buffer, and
@@ -472,6 +474,27 @@ etc. for the component. The default is the following:
472474
retrieved documents; - `content`: The retrieval results concatenated together
473475
into a string. Each result is formatted by `component_cb`.
474476

477+
478+
BUILT-IN QUERY CALLBACKS
479+
480+
When using async cache, the query message is constructed by a function that
481+
takes the buffer ID as the only parameter, and return a string or a list of
482+
strings. The `vectorcode.utils` module provides the following callback
483+
constructor for you to play around with it, but you can easily build your own!
484+
485+
- `require("vectorcode.utils").make_surrounding_lines_cb(line_count)`: returns a
486+
callback that uses `line_count` lines around the cursor as the query. When
487+
`line_count` is negative, it uses the full buffer;
488+
- `require("vectorcode.utils").make_lsp_document_symbol_cb()`: returns a
489+
callback which uses the `textDocument/documentSymbol` method to retrieve a
490+
list of symbols in the current document. This will fallback to
491+
`make_surrounding_lines_cb(-1)` when there’s no LSP that supports the
492+
`documentSymbol` method;
493+
- `require("vectorcode.utils").make_changes_cb(max_num)`: returns a callback
494+
that fetches `max_num` unique items from the `:changes` list. This will also
495+
fallback to `make_surrounding_lines_cb(-1)`. The default value for `max_num`
496+
is 50.
497+
475498
Generated by panvimdoc <https://github.com/kdheepak/panvimdoc>
476499

477500
vim:tw=78:ts=8:noet:ft=help:norl:

docs/neovim.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* [`cacher_backend.buf_is_enabled(bufnr?)`](#cacher_backendbuf_is_enabledbufnr)
3232
* [`cacher_backend.buf_job_count(bufnr?)`](#cacher_backendbuf_job_countbufnr)
3333
* [`cacher_backend.make_prompt_component(bufnr?, component_cb?)`](#cacher_backendmake_prompt_componentbufnr-component_cb)
34+
* [Built-in Query Callbacks](#built-in-query-callbacks)
3435

3536
<!-- mtoc-end -->
3637

@@ -341,7 +342,9 @@ The following are the available options for this function:
341342
- `n_query`: number of retrieved documents. Default: `1`;
342343
- `debounce`: debounce time in milliseconds. Default: `10`;
343344
- `notify`: whether to show notifications when a query is completed. Default: `false`;
344-
- `query_cb`: a callback function that accepts the buffer ID and returns the query message(s). Default: `require("vectorcode.utils").make_surrounding_lines_cb(-1)`;
345+
- `query_cb`: a callback function that accepts the buffer ID and returns the query message(s).
346+
Default: `require("vectorcode.utils").make_surrounding_lines_cb(-1)`. See
347+
[this section](#built-in-query-callbacks) for a list of built-in query callbacks;
345348
- `events`: list of autocommand events that triggers the query. Default: `{"BufWritePost", "InsertEnter", "BufReadPost"}`;
346349
- `run_on_register`: whether to run the query when the buffer is registered.
347350
Default: `false`;
@@ -419,3 +422,23 @@ end
419422
- `count`: number of retrieved documents;
420423
- `content`: The retrieval results concatenated together into a string. Each
421424
result is formatted by `component_cb`.
425+
426+
#### Built-in Query Callbacks
427+
428+
When using async cache, the query message is constructed by a function that
429+
takes the buffer ID as the only parameter, and return a string or a list of
430+
strings. The `vectorcode.utils` module provides the following callback
431+
constructor for you to play around with it, but you can easily build your own!
432+
433+
- `require("vectorcode.utils").make_surrounding_lines_cb(line_count)`: returns a
434+
callback that uses `line_count` lines around the cursor as the query. When
435+
`line_count` is negative, it uses the full buffer;
436+
- `require("vectorcode.utils").make_lsp_document_symbol_cb()`: returns a
437+
callback which uses the `textDocument/documentSymbol` method to retrieve a
438+
list of symbols in the current document. This will fallback to
439+
`make_surrounding_lines_cb(-1)` when there's no LSP that supports the
440+
`documentSymbol` method;
441+
- `require("vectorcode.utils").make_changes_cb(max_num)`: returns a callback
442+
that fetches `max_num` unique items from the `:changes` list. This will also
443+
fallback to `make_surrounding_lines_cb(-1)`. The default value for `max_num`
444+
is 50.

lua/vectorcode/utils.lua

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,57 @@ function M.find_root(path)
100100
return vim.fs.root(path, ".vectorcode") or vim.fs.root(path, ".git")
101101
end
102102

103+
---@param str string
104+
---@param sep string?
105+
---@return string[]
106+
local function split(str, sep)
107+
if sep == nil then
108+
sep = " "
109+
end
110+
local result = {}
111+
local pattern = "([^" .. sep .. "]+)"
112+
for part in string.gmatch(str, pattern) do
113+
table.insert(result, part)
114+
end
115+
return result
116+
end
117+
118+
--- This function build a `VectorCode.QueryCallback` by extracting recent changes from the `:changes` command.
119+
---@param max_num integer? Default is 50
120+
---@return VectorCode.QueryCallback
121+
function M.make_changes_cb(max_num)
122+
if max_num == nil then
123+
max_num = 50
124+
end
125+
return function(bufnr)
126+
---@type string?
127+
local raw_changes = vim.api.nvim_exec2("changes", { output = true }).output
128+
if raw_changes == nil then
129+
-- fallback to other cb
130+
return M.make_surrounding_lines_cb(-1)(bufnr)
131+
end
132+
local lines = vim.tbl_map(function(s)
133+
local res = string.gsub(s, "^[%d%s]+", "")
134+
return res
135+
end, split(raw_changes, "\n"))
136+
local results = {}
137+
local seen = {} -- deduplicate
138+
for i = #lines - 1, 2, -1 do
139+
if #results <= max_num then
140+
if not seen[lines[i]] then
141+
table.insert(results, lines[i])
142+
seen[lines[i]] = true
143+
end
144+
else
145+
break
146+
end
147+
end
148+
if #results == 0 then
149+
-- fallback to other cb
150+
return M.make_surrounding_lines_cb(-1)(bufnr)
151+
end
152+
return results
153+
end
154+
end
155+
103156
return M

0 commit comments

Comments
 (0)