Skip to content

feat: jump to symbols from assistant outputFeat/reference scoped symbol navigation#437

Merged
sudo-tee merged 9 commits into
sudo-tee:mainfrom
jensenojs:feat/reference-scoped-symbol-navigation
Jul 6, 2026
Merged

feat: jump to symbols from assistant outputFeat/reference scoped symbol navigation#437
sudo-tee merged 9 commits into
sudo-tee:mainfrom
jensenojs:feat/reference-scoped-symbol-navigation

Conversation

@jensenojs

@jensenojs jensenojs commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

I really like this feature, lol

Summary

  • add reference-scoped symbol navigation for assistant output
  • highlight jumpable symbols from files already referenced in the conversation
  • make <CR> jump to symbol definitions when file/diff targets do not match
  • keep gf limited to file/diff targets
  • highlight assistant file references with a lighter path color

Notes

This uses Tree-sitter over the current conversation's Code References. It does not add LSP, workspace-wide symbol search, or a persistent symbol index.

iShot_2026-06-30_16 04 14_compressed

Tests: ./run_tests.sh

@jensenojs
jensenojs force-pushed the feat/reference-scoped-symbol-navigation branch from 41d36e7 to 3be36d8 Compare June 30, 2026 11:24
@jensenojs

jensenojs commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator Author

Design note for review:

This is deliberately not a workspace symbol search. The feature only looks at files already referenced in the current conversation.

Render path:

assistant text
-> file references get OpencodeReference
-> conversation Code References are collected
-> Tree-sitter reads definitions from those referenced files only
-> matching output tokens get OpencodeSymbolReference

Keypress path:

<CR>
-> existing file/path/diff target first
-> if no target, collect current conversation refs
-> read current Tree-sitter definitions from those referenced files
-> jump/pick matching symbol definitions

The render highlight is only a hint. It does not store jump targets. This avoids stale extmarks becoming navigation authority.

No LSP, no workspace-wide search, no persistent index, no edit-event subscriptions. gf remains file/diff-only; only gets the symbol fallback.

@sudo-tee

Copy link
Copy Markdown
Owner

I love the feature and find it really useful.

But I noticed a big performance hit in snapshot collection

image

A semi large session will cause a couple of seconds delay before displaying in the output buffer.

@jensenojs
jensenojs marked this pull request as draft July 1, 2026 09:51
@jensenojs

jensenojs commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator Author

Because performance issues exposed some oversights in my vibe-coding process, I took some time to reflect and clean up the code, which is why it took a bit longer. However, we can see where the problems were from the previous comments. A simpler conceptual approach should look something like this:

iShot_2026-07-02_16 54 09_under10M

The GIF might have been compressed a bit too much, so the color differences might not be very noticeable. But generally speaking, the "symbol" and "file" jumps will update according to our changes. You can try commenting them out or uncommenting them to test it.

The durable fact is the current conversation’s reference-file set. Session load rebuilds it from messages; message updates and file lifecycle events refresh it and dirty rendered assistant text parts. Render reads that file set plus current Tree-sitter definitions, then writes visual affordances and RenderState targets. Keypress does not rediscover refs from screen text; it only executes the current RenderState target, resolving symbol targets against that target’s candidate files at press time.

So extmarks are no longer navigation authority. They are just the visual projection of RenderState targets.

After this PR and the other one(#439) are merged, my first instinct when opening opencode might no longer be the TUI, there are (currently) no interaction methods in the TUI that opencode.nvim cannot easily handle; conversely, we can do many things that the TUI simply cannot.

I think having some reasonable interactions in the output window is a good thing. When I have time later, I might tinker with the input window as well. Better delivery methods are all low-hanging fruit, and these can likely be showcased in the README. I doubt the other opencode.nvim plugin has this functionality, hhh.

However, I may not be able to dedicate as much energy to this project in the next month or two as I am now. I will likely still assist with some bug fixes or PR reviews, as I need to spend some time preparing for my next job. But please trust that I have laid a solid foundation for your agent to take over this feature. The ui/AGENTS directory maintains the minimal mental model of this feature; it should be relatively "cheap" for the agent to understand what each part of the code is doing right or wrong (which, in my view, is more important in a sense).

@jensenojs
jensenojs marked this pull request as ready for review July 2, 2026 09:08
@jensenojs
jensenojs requested a review from sudo-tee July 2, 2026 09:11
@jensenojs

Copy link
Copy Markdown
Collaborator Author

One direction I'm interested in for the future is automatic prompt injection/enhancement. My GPT has been too stupid lately, and manual fine-tuning is too exhausting. I want to create an automatic prompt injection/enhancement system to save my time for those high-quality conversations that I don't dare reply to lightly. If it could achieve over 80% accuracy compared to my usual prompt responses, that would be a very good thing.

This job isn't very difficult; I've already started the refactoring over there, but there's still quite a bit of work to do lol

@sudo-tee

sudo-tee commented Jul 2, 2026

Copy link
Copy Markdown
Owner

I am not sure about updating the AGENTS. As it adds way more tokens than it's worth. Many you could transform this into a skill?

@jensenojs

jensenojs commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator Author

I am not sure about updating the AGENTS. As it adds way more tokens than it's worth. Many you could transform this into a skill?

Okay, I'll withdraw them all for now and consider adding them back later when they are worth formalizing as skills

@sudo-tee

sudo-tee commented Jul 2, 2026

Copy link
Copy Markdown
Owner

With this PR I lost the ability to gf on a file path like this one

image

sudo-tee and others added 2 commits July 2, 2026 09:24
…ed-symbol-navigation

# Conflicts:
#	lua/opencode/ui/message_actions.lua
#	lua/opencode/ui/renderer/buffer.lua
@sudo-tee

sudo-tee commented Jul 6, 2026

Copy link
Copy Markdown
Owner

@jensenojs

Did you had a chance to look at the regression I identified where I can not navigate to file from lines like this

image

@jensenojs

Copy link
Copy Markdown
Collaborator Author

If those paths were not in the current reference-file list, that would explain the behavior. Even so, it is a regression.

The intended change was to use the current reference-file list for symbol navigation, so Enter does not rebuild that list from the conversation every time it resolves a symbol; that was the performance fix. In the refactor, I reused the same gate for plain file-path targets. That gate makes sense for symbols, but it is too strict for files: file targets only need to resolve to an existing file. If such a file is opened, we can then add it to the reference-file list and trigger the same local re-render, so symbols from that file can become available too. I’ll take another look when I have time. @sudo-tee

@sudo-tee

sudo-tee commented Jul 6, 2026

Copy link
Copy Markdown
Owner

I just added a simple add_target in my last commit, and it adds what I need there, no need to complexify things :)

@sudo-tee

sudo-tee commented Jul 6, 2026

Copy link
Copy Markdown
Owner

I did some test and everything seems smooth now. I really like the feature,

I don't know if you wanted to add other stuff, but if not it should be ready to merge

@jensenojs

Copy link
Copy Markdown
Collaborator Author

Thanks, that makes sense. For tool-output file paths, adding the file target during render is the simpler fix.

The only remaining corner case is for symbols: symbol targets are still scoped to the current reference-file list. If a symbol appears in the output but its defining file is not in that list, it won’t become a jump target. That’s separate from this fix, and I can handle it later if needed.

If the current behavior works for you, I’m happy for this to be merged.

@sudo-tee
sudo-tee merged commit eebda20 into sudo-tee:main Jul 6, 2026
5 checks passed
@jensenojs
jensenojs deleted the feat/reference-scoped-symbol-navigation branch July 6, 2026 14:11
disrupted pushed a commit to disrupted/opencode-native.nvim that referenced this pull request Jul 23, 2026
…ol navigation (sudo-tee#437)

* feat: add reference-scoped symbol navigation

* feat: highlight assistant file references

* Refine reference target lifecycle

* Stabilize timer restart test

* Remove AGENTS prompt additions

* fix: pass through left mouse click on non-message areas in output window

* feat(output): add file navigation targets to tool output

---------

Co-authored-by: Francis Belanger <francis.belanger@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants