feat(snacks): add snacks.picker action integration#152
feat(snacks): add snacks.picker action integration#152naowalrahman wants to merge 4 commits intonickjvandyke:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a snacks.picker action integration that sends the currently selected (or fallback) picker items into the opencode prompt.
Changes:
- Introduces
opencode_send(picker)action forsnacks.picker. - Builds a newline-delimited list of selected picker entries and appends it to the opencode prompt.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| local entries = {} | ||
| for _, item in ipairs(picker:selected({ fallback = true })) do | ||
| local entry = "" | ||
| if item.text and item.text ~= "" then -- Includes file reference | ||
| entry = item.text | ||
| end | ||
| -- Append line numbers if available | ||
| if item.file and item.pos then | ||
| local line_ref = ("L%d"):format(item.pos[1]) | ||
| if item.end_pos and item.end_pos[1] ~= item.pos[1] then | ||
| line_ref = line_ref .. ("-L%d"):format(item.end_pos[1]) | ||
| end | ||
| entry = entry .. " " .. line_ref | ||
| end | ||
| if entry ~= "" then |
There was a problem hiding this comment.
entry is only populated from item.text. For items where item.file/item.pos exist but item.text is empty (common for many picker items), the code will end up sending just a line ref (e.g. " L10") or dropping the item entirely, which is not a valid opencode file reference. Consider using opencode.context.Context.format({ path = item.file, start_line = ..., start_col = ... }) (and optionally appending item.text as a label) so the output always includes the required @path prefix when a file is available.
| local entries = {} | |
| for _, item in ipairs(picker:selected({ fallback = true })) do | |
| local entry = "" | |
| if item.text and item.text ~= "" then -- Includes file reference | |
| entry = item.text | |
| end | |
| -- Append line numbers if available | |
| if item.file and item.pos then | |
| local line_ref = ("L%d"):format(item.pos[1]) | |
| if item.end_pos and item.end_pos[1] ~= item.pos[1] then | |
| line_ref = line_ref .. ("-L%d"):format(item.end_pos[1]) | |
| end | |
| entry = entry .. " " .. line_ref | |
| end | |
| if entry ~= "" then | |
| local Context = require("opencode.context").Context | |
| local entries = {} | |
| for _, item in ipairs(picker:selected({ fallback = true })) do | |
| local entry | |
| -- Prefer constructing a proper opencode context when file and position are available | |
| if item.file and item.pos then | |
| local start_line = item.pos[1] | |
| local start_col = item.pos[2] | |
| local ctx = Context.format({ | |
| path = item.file, | |
| start_line = start_line, | |
| start_col = start_col, | |
| }) | |
| if item.text and item.text ~= "" then | |
| entry = ctx .. " " .. item.text | |
| else | |
| entry = ctx | |
| end | |
| -- Fallback: no file info, just use the text if present | |
| elseif item.text and item.text ~= "" then | |
| entry = item.text | |
| end | |
| if entry and entry ~= "" then |
There was a problem hiding this comment.
This is wrong because item.text is never empty in my experience. Tested on file picker, grep, diagnostics, etc.
| if item.file and item.pos then | ||
| local line_ref = ("L%d"):format(item.pos[1]) | ||
| if item.end_pos and item.end_pos[1] ~= item.pos[1] then | ||
| line_ref = line_ref .. ("-L%d"):format(item.end_pos[1]) | ||
| end | ||
| entry = entry .. " " .. line_ref | ||
| end |
There was a problem hiding this comment.
This reimplements location formatting manually and only includes line numbers. The project already has Context.format (lua/opencode/context.lua) which handles required spacing for @path references and supports line/column ranges. Reusing it here will avoid subtle formatting bugs and keep location formatting consistent across integrations.
There was a problem hiding this comment.
@path references for the plugin were removed in a recent commit because opencode doesn't parse them unless you use the native TUI picker and press tab
There was a problem hiding this comment.
I think we can still re-use Context.format here though right? Assuming we have the necessary fields on item
|
Updated even though it is limiting the experience. But I think not to much if you don't know about it |
de5f1cc to
5de2380
Compare
@dmtrKovalenko what do you mean? |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@nickjvandyke addressed copilot's comments, sorry for taking a while 😅. The LuaLS diagnostic check failing seems to be unrelated to the PR, because this PR doesn't change |
|
I think @dmtrKovalenko meant to comment in #151 No worries on the wait, I know all too well that there's not always time for FOSS 😂 Thanks for addressing, I will take a look ASAP! |
|
Can you merge |
|
@nickjvandyke should be good now hopefully! |
Description
Adds a function under
lua/opencode/integrations/picker/snacks.luathat can be used to set up a snacks.picker action that sends the selected/current items to opencode via a keybind.Note
Line number, if available, is appended to the end of the reference because diagnostic text content usually doesn't have the line number. This is redundant for grep/file references, because the text content for those items do have the line number already, but for the sake of simplicity it is better to just have the line number at the end anyway.
Integration looks like this:
Related Issue(s)