Skip to content
34 changes: 34 additions & 0 deletions lua/opencode/integrations/picker/snacks.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---@module 'snacks'

---Snacks picker integration for opencode.
---@class opencode.integrations.picker.snacks
local M = {}

---Send selected picker items to opencode prompt.
---@param picker snacks.Picker
function M.opencode_send(picker)
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
Comment thread
nickjvandyke marked this conversation as resolved.
Outdated
if entry ~= "" then

Copilot AI Jan 29, 2026

Copy link

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.

Suggested change
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

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong because item.text is never empty in my experience. Tested on file picker, grep, diagnostics, etc.

entries[#entries + 1] = entry
end
end
Comment thread
naowalrahman marked this conversation as resolved.
Outdated
if #entries == 0 then
return
end
require("opencode").prompt(table.concat(entries, "\n") .. "\n")
end

return M
Loading