Skip to content

Add semantic tokens support (textDocument/semanticTokens/full and /range)#450

Merged
Schottkyc137 merged 4 commits intoVHDL-LS:masterfrom
axlegrinder1:feature/semantic-tokens
Apr 23, 2026
Merged

Add semantic tokens support (textDocument/semanticTokens/full and /range)#450
Schottkyc137 merged 4 commits intoVHDL-LS:masterfrom
axlegrinder1:feature/semantic-tokens

Conversation

@axlegrinder1
Copy link
Copy Markdown
Contributor

Expose VHDL entity classification to the editor via LSP semantic tokens, enabling context-aware coloring for signals, variables, constants, types, functions, ports, generics, and other VHDL constructs.

Uses standard LSP token types (variable, parameter, function, type, etc.) for out-of-the-box theme compatibility. Constants and generics are distinguished via the readonly modifier.

Results are cached per file and invalidated on change.

Closes #314

I built this functionality pretty quickly alongside Claude Opus4.6, so I would consider this a conceptual implementation which likely has room for improvement, but the results are very promising. I have added a set of tests within the vhdl_server.rs module and run this functionality in vscode + teroshdl across several large projects (200-500 source files) with good results.

With the feature, once the server is running, the code editor has a lot more visibility within the files, giving valuable context that was previously missing, such as being able to colour valid constants/enums in line with code, not just at declaration.

This is currently working cleanly as a separate module utilising the searcher infrastructure, but a tighter integration into the analysis pass could eliminate the redundant walk and guarantee consistency but would be a far more involved change within vhdl_lang.

…nge)

Expose VHDL entity classification to the editor via LSP semantic tokens,
enabling context-aware coloring for signals, variables, constants, types,
functions, ports, generics, and other VHDL constructs.

Uses standard LSP token types (variable, parameter, function, type, etc.)
for out-of-the-box theme compatibility. Constants and generics are
distinguished via the readonly modifier.

Results are cached per file and invalidated on change.

Closes VHDL-LS#314
Copy link
Copy Markdown
Contributor

@Schottkyc137 Schottkyc137 left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this!
Implementation looks overall like a good starting point. I have left a few comments.
Concerning more involved changes of vhdl_lang: I have nothing against that if there is real advantage. Just please make sure to structure this, e.g., by opening multiple PRs such that it's easier to review.

Comment thread vhdl_ls/src/vhdl_server.rs Outdated
Comment thread vhdl_ls/src/vhdl_server/text_document.rs
Comment thread vhdl_ls/src/vhdl_server/semantic_tokens.rs Outdated
Comment thread vhdl_ls/src/vhdl_server/semantic_tokens.rs Outdated
Comment on lines +91 to +95
/// Check if a token overlaps the filter range by line.
/// Character-level precision is not needed as clients request full-line ranges.
fn in_range(token_range: &vhdl_lang::Range, filter: &vhdl_lang::Range) -> bool {
token_range.start.line <= filter.end.line && token_range.end.line >= filter.start.line
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If this kind of utility doesn't exist in vhdl_lang::Range already I suggest to move it there

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.

I've moved the function to the Range::overlaps_lines

Comment thread vhdl_ls/src/vhdl_server/semantic_tokens.rs Outdated
Comment thread vhdl_ls/src/vhdl_server/semantic_tokens.rs Outdated
Comment thread vhdl_lang/src/project.rs Outdated
Comment thread vhdl_lang/src/ast/search.rs
- Replace bare (u32, u32) tuples with TokenClassification and
CachedToken structs
- Replace DecodedToken test tuple with named struct
- Add define_token_types! macro to keep index constants and legend in
sync
- Use SrcPos::cmp for sorting instead of manual line/character
comparison
- Move in_range to Range::overlaps_lines in vhdl_lang
- Rename Project::semantic_tokens to find_all_entity_references
- Add source file filter in search_decl to guard against cross-file
decl_pos
- Match ExternalObjectClass directly instead of converting to
ObjectClass
- Skip multi-line tokens in encode instead of computing wrong length
@axlegrinder1 axlegrinder1 force-pushed the feature/semantic-tokens branch from 42100a1 to bb77ba1 Compare April 7, 2026 12:36
@axlegrinder1
Copy link
Copy Markdown
Contributor Author

@Schottkyc137 Your comments have been addressed, is there any more that you want to see in this feature or is it just in the backlog now? I'm eager to go further with development of this if needed, but else I'm very happy with the result and would appreciate feedback :) I have been using this build day-to-day and it has been very stable in my own use-case.

Comment thread vhdl_lang/src/ast/search.rs
@Schottkyc137
Copy link
Copy Markdown
Contributor

Hi
Sorry for the long delay. All looks good with this implementation, I'll merge this in a bit.

@Schottkyc137 Schottkyc137 force-pushed the feature/semantic-tokens branch from 9806e1e to 148a369 Compare April 23, 2026 23:04
@Schottkyc137 Schottkyc137 merged commit c486d8a into VHDL-LS:master Apr 23, 2026
19 checks passed
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.

[FEATURE] Semantic Tokens

2 participants