-
-
Notifications
You must be signed in to change notification settings - Fork 77
feat(snacks): add snacks.picker action integration #152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(snacks): add snacks.picker action integration #152
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
| 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 |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| if entry ~= "" then | ||
| entries[#entries + 1] = entry | ||
| end | ||
| end |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If no items produce a non-empty entry, this will still call prompt("\n"), which appends an empty line to the TUI prompt. Consider returning early when #entries == 0 (or only adding the trailing newline when there is at least one entry).
| end | |
| end | |
| if #entries == 0 then | |
| return | |
| end |
|
Updated even though it is limiting the experience. But I think not to much if you don't know about it |
21bd1e5 to
ed2a936
Compare
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)