Add syntax highlighting for project symbol search#188
Add syntax highlighting for project symbol search#188tartarughina merged 4 commits intozed-extensions:mainfrom
Conversation
|
We require contributors to sign our Contributor License Agreement, and we don't have @da-r-k on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
@cla-bot check |
|
We require contributors to sign our Contributor License Agreement, and we don't have @da-r-k on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
Thanks for the PR. Please format the code with and push another commit |
|
@da-r-k I've tried the extension but it doesn't seem to be working as intended. For example, when searching for the symbol Media, see snippet below, I was just getting Media in the list without any of the additional information about it Are these changes depending on a change to the grammar? |
|
@da-r-k@da-r-k, I’ve been using the wrong branch. I assumed gh would have retrieved the correct one, but apparently, it wasn’t the case. Is fuzzy search something that the LSP needs to support to be used or is it up to us to enable it? |
|
@tartarughina Yes. JDTLS uses CamelCase fuzzy search. So if you search for |
|
@da-r-k interesting, I didn't know that it was using CamelCase fuzzy. Since that might be new to a lot, do you mind adding a small entry in the README explaining how project symbol works? The main points would be:
|
src/java.rs
Outdated
| SymbolKind::Class => { | ||
| // code: "class Name {}" → Tree-sitter: class_declaration | ||
| // display: "class Name" | ||
| let keyword = "class "; | ||
| let code = format!("{keyword}{name} {{}}"); | ||
|
|
||
| Some(CodeLabel { | ||
| spans: vec![CodeLabelSpan::code_range(0..keyword.len() + name.len())], | ||
| filter_range: (keyword.len()..keyword.len() + name.len()).into(), | ||
| code, | ||
| }) | ||
| } | ||
| SymbolKind::Interface => { | ||
| let keyword = "interface "; | ||
| let code = format!("{keyword}{name} {{}}"); | ||
|
|
||
| Some(CodeLabel { | ||
| spans: vec![CodeLabelSpan::code_range(0..keyword.len() + name.len())], | ||
| filter_range: (keyword.len()..keyword.len() + name.len()).into(), | ||
| code, | ||
| }) | ||
| } | ||
| SymbolKind::Enum => { | ||
| let keyword = "enum "; | ||
| let code = format!("{keyword}{name} {{}}"); | ||
|
|
||
| Some(CodeLabel { | ||
| spans: vec![CodeLabelSpan::code_range(0..keyword.len() + name.len())], | ||
| filter_range: (keyword.len()..keyword.len() + name.len()).into(), | ||
| code, | ||
| }) |
There was a problem hiding this comment.
This code is pretty much the same if not for the keyword, cannot we simplify it removing repeated code?
There was a problem hiding this comment.
Done — combined Class/Interface/Enum into a single match arm with an inner match for the keyword.
src/java.rs
Outdated
| }) | ||
| } else { | ||
| // No type info, just show the name | ||
| let class_open = "class _ { int "; |
There was a problem hiding this comment.
Why does it default to int?
src/java.rs
Outdated
| } | ||
| SymbolKind::Constant => { | ||
| // Wrap in class; ALL_CAPS names get @constant from highlights.scm regex | ||
| let class_open = "class _ { static final int "; |
src/java.rs
Outdated
| }) | ||
| } | ||
| SymbolKind::Variable => { | ||
| let class_open = "class _ { int "; |
There was a problem hiding this comment.
Same comment as above regarding int usage
|
@tartarughina We do not get a type info from the LSP. That's why I used int. Anyways, JDTLS does not support variables in the workspace/symbols call. It only supports methods and classes afaik |
|
@da-r-k if the type is not returned then let's avoid defaulting to int. Also, if the LSP only supports methods and classes let's clean up unused code |
Implement `label_for_symbol` to provide syntax-highlighted labels in the
project symbol picker (cmd-t). Without this, Java symbols appear as
plain grey text.
Each symbol kind generates a Tree-sitter-parseable code snippet wrapped
in the appropriate context (e.g. methods/fields inside `class _ { }`)
so the Java grammar can produce correct AST nodes for highlighting.
Supported symbols:
- Class, Interface, Enum: keyword prefix + name
- Method/Function: return type + name + params (Java declaration order)
- Constructor: name + params
- Field/Property: type + name (Java declaration order)
- Constant, EnumMember, Variable: highlighted name
- Package/Module/Namespace: keyword prefix + name
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove handlers for symbol kinds that JDTLS workspace/symbol never returns (Constructor, Field, Constant, EnumMember, Variable, Package). Deduplicate Class/Interface/Enum into a single match arm. Add README section documenting project symbol search and CamelCase fuzzy matching. JDTLS WorkspaceSymbolHandler only searches type names (Class, Interface, Enum, Annotation) and optionally method names when includeSourceMethodDeclarations is enabled: https://github.com/eclipse-jdtls/eclipse.jdt.ls/blob/main/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/WorkspaceSymbolHandler.java Zed only calls label_for_symbol for workspace/symbol results, not textDocument/documentSymbol: https://github.com/zed-industries/zed/blob/main/crates/language_extension/src/extension_lsp_adapter.rs
195b59e to
6c04d33
Compare
|
We require contributors to sign our Contributor License Agreement, and we don't have @gitbutler-client on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
6c04d33 to
48c4a51
Compare
Remove handlers for symbol kinds that JDTLS workspace/symbol never returns (Constructor, Field, Constant, EnumMember, Variable, Package). Deduplicate Class/Interface/Enum into a single match arm. Add README section documenting project symbol search and CamelCase fuzzy matching. JDTLS WorkspaceSymbolHandler only searches type names (Class, Interface, Enum, Annotation) and optionally method names when includeSourceMethodDeclarations is enabled: https://github.com/eclipse-jdtls/eclipse.jdt.ls/blob/main/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/WorkspaceSymbolHandler.java Zed only calls label_for_symbol for workspace/symbol results, not textDocument/documentSymbol: https://github.com/zed-industries/zed/blob/main/crates/language_extension/src/extension_lsp_adapter.rs
|
@tartarughina cleaned up the code to only include supported symbols. The last commit message has code references for all the symbols that are supported. |
tartarughina
left a comment
There was a problem hiding this comment.
Thanks a lot for the changes and for updating the README. Looks good to me

Summary
Implements
label_for_symbolto provide syntax-highlighted labels in the project symbol picker (cmd-t). Currently, Java symbols appear as plain grey text with no highlighting, unlike Rust and other languages that already implement this.Ref: zed-industries/zed#36383, zed-industries/zed#37176
Changes
label_for_symbolto theExtension for JavaimplSymbolandSymbolKindfrom the extension APIclass _ { }since Java's Tree-sitter grammar requires class context for these declarationsvoid doWork(String, int),String fieldNameclass,interface,enum,packageSupported symbol kinds
class MyClassclass MyClass {}interface Runnableinterface Runnable {}enum Statusenum Status {}MyClass(String, int)class MyClass { MyClass() {} }void doWork(String, int)class _ { void doWork() {} }String nameclass _ { String name; }MAX_SIZEclass _ { static final int MAX_SIZE; }ACTIVEenum _ { ACTIVE }countclass _ { int count; }package com.examplepackage com.example;Screenshot: