Skip to content

Commit 6940ea6

Browse files
sudo-teeCopilot
andauthored
refactor(code-references): remove reliance on system prompt (#196)
* refactor(code-references): remove reliance on system prompt - update the reference parser to be more generic instead of relying on a system prompt - add edit/read files to the references This should fix #194 * refactor: normalize file paths in formatter and test snapshots - Update formatter to show relative paths when inside cwd, basename when outside - Normalize file paths in replay test snapshots to be cwd-relative - Update expected test data to use relative paths instead of absolute paths * refactor(reference_picker): simplify and harden patterns * Update lua/opencode/ui/reference_picker.lua Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update lua/opencode/types.lua Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update lua/opencode/ui/reference_picker.lua Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 6524b8e commit 6940ea6

23 files changed

+977
-96
lines changed

AGENTS.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,32 @@
3232
- **Tests:** Place in `tests/minimal/`, `tests/unit/`, or `tests/replay/`. Manual/visual tests in `tests/manual/`.
3333

3434
_Agentic coding agents must follow these conventions strictly for consistency and reliability._
35+
36+
## File Reference Detection
37+
38+
The plugin automatically detects file references in LLM responses and makes them navigable via the reference picker (`<leader>or` or `:Opencode references`).
39+
40+
### Supported Formats
41+
42+
The reference picker recognizes these file reference patterns:
43+
44+
1. **Backtick-wrapped** (recommended by LLMs naturally):
45+
- `` `path/to/file.lua` ``
46+
- `` `path/to/file.lua:42` ``
47+
- `` `path/to/file.lua:42:10` `` (with column)
48+
- `` `path/to/file.lua:42-50` `` (line range)
49+
50+
2. **file:// URIs** (backward compatibility):
51+
- `file://path/to/file.lua`
52+
- `file://path/to/file.lua:42`
53+
- `file://path/to/file.lua:42-50`
54+
55+
3. **Plain paths** (natural format):
56+
- `path/to/file.lua`
57+
- `path/to/file.lua:42`
58+
- `./relative/path.lua:42`
59+
- `/absolute/path.lua:42`
60+
61+
All formats support both relative and absolute paths. Files must exist to be recognized (validation prevents false positives).
62+
63+
**No system prompt configuration is required** - the parser works with all LLM providers, including those without system prompt support.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ require('opencode').setup({
113113
preferred_completion = nil, -- 'blink', 'nvim-cmp','vim_complete' if nil, it will use the best available completion
114114
default_global_keymaps = true, -- If false, disables all default global keymaps
115115
default_mode = 'build', -- 'build' or 'plan' or any custom configured. @see [OpenCode Agents](https://opencode.ai/docs/modes/)
116+
default_system_prompt = nil, -- Custom system prompt to use for all sessions. If nil, uses the default built-in system prompt
116117
keymap_prefix = '<leader>o', -- Default keymap prefix for global keymaps change to your preferred prefix and it will be applied to all keymaps starting with <leader>o
117118
opencode_executable = 'opencode', -- Name of your opencode binary
118119
keymap = {

lua/opencode/config.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ M.defaults = {
1010
preferred_completion = nil,
1111
default_global_keymaps = true,
1212
default_mode = 'build',
13+
default_system_prompt = nil,
1314
legacy_commands = true,
1415
keymap_prefix = '<leader>o',
1516
opencode_executable = 'opencode',

lua/opencode/core.lua

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -173,22 +173,9 @@ M.send_message = Promise.async(function(prompt, opts)
173173
state.current_mode = opts.agent
174174
end
175175

176-
params.system = [[
177-
# Code References
178-
179-
**CRITICAL: Always use the file:// URI scheme when referencing files in responses AND wrap them in backticks.**
180-
181-
Format: `file://path/to/file.lua`, `file://path/to/file.lua:42`, or `file://path/to/file.lua:42-50`
182-
183-
Examples:
184-
- CORRECT: "The error is in `file://src/services/process.ts:712`"
185-
- INCORRECT: "The error is in file://src/services/process.ts:712"
186-
- INCORRECT: "The error is in src/services/process.ts:712"
187-
188-
This matches the file:// URI format that the reference picker already parses from your responses, enabling automatic navigation.
189-
]]
190-
191176
params.parts = context.format_message(prompt, opts.context):await()
177+
params.system = opts.system or config.default_system_prompt or nil
178+
192179
M.before_run(opts)
193180

194181
local session_id = state.active_session.id

lua/opencode/types.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@
195195
---@field preferred_completion 'blink' | 'nvim-cmp' | 'vim_complete' | nil -- Preferred completion strategy for mentons and commands
196196
---@field default_global_keymaps boolean
197197
---@field default_mode 'build' | 'plan' | string -- Default mode
198+
---@field default_system_prompt string | nil
198199
---@field keymap_prefix string
199200
---@field opencode_executable 'opencode' | string -- Command run for calling opencode
200201
---@field keymap OpencodeKeymap
@@ -373,6 +374,7 @@
373374
---@field model? string
374375
---@field agent? string
375376
---@field variant? string
377+
---@field system? string
376378

377379
---@class CompletionContext
378380
---@field trigger_char string The character that triggered completion

lua/opencode/ui/formatter.lua

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,18 @@ end
499499
---@param input FileToolInput data for the tool
500500
---@param metadata FileToolMetadata Metadata for the tool use
501501
function M._format_file_tool(output, tool_type, input, metadata)
502-
local file_name = input and vim.fn.fnamemodify(input.filePath, ':t') or ''
502+
local file_name = ''
503+
if input and input.filePath then
504+
local cwd = vim.fn.getcwd()
505+
local absolute = vim.fn.fnamemodify(input.filePath, ':p')
506+
507+
if vim.startswith(absolute, cwd .. '/') then
508+
file_name = absolute:sub(#cwd + 2)
509+
else
510+
file_name = absolute
511+
end
512+
end
513+
503514
local file_type = input and util.get_markdown_filetype(input.filePath) or ''
504515
local tool_action_icons = { read = icons.get('read'), edit = icons.get('edit'), write = icons.get('write') }
505516

0 commit comments

Comments
 (0)