aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-30 19:44:58 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-30 19:46:57 -0400
commit0583fbd35b14e32b848972d1a0d916f7bf9185a3 (patch)
tree85e75b68924d1b27c8c2bbeaa2f624ee5dde1840
parentaae20c2190e619715b9f9a55e757d50c2d517cd7 (diff)
Show struct and bitfield fields with workspace and document symbols
-rw-r--r--src/server/document_symbols.odin27
-rw-r--r--src/server/indexer.odin4
-rw-r--r--src/server/memory_index.odin36
-rw-r--r--src/server/symbol.odin4
-rw-r--r--src/server/workspace_symbols.odin2
5 files changed, 70 insertions, 3 deletions
diff --git a/src/server/document_symbols.odin b/src/server/document_symbols.odin
index 3c9b651..d146e6a 100644
--- a/src/server/document_symbols.odin
+++ b/src/server/document_symbols.odin
@@ -44,6 +44,33 @@ get_document_symbols :: proc(document: ^Document) -> []DocumentSymbol {
#partial switch v in global.expr.derived {
case ^ast.Struct_Type, ^ast.Bit_Field_Type:
+ // TODO: this only does the top level fields, we may want to travers all the way down in the future
+ if s, ok := resolve_type_expression(&ast_context, global.expr); ok {
+ #partial switch v in s.value {
+ case SymbolStructValue:
+ children := make([dynamic]DocumentSymbol, context.temp_allocator)
+ for name, i in v.names {
+ child: DocumentSymbol
+ child.range = v.ranges[i]
+ child.selectionRange = v.ranges[i]
+ child.name = name
+ child.kind = .Field
+ append(&children, child)
+ }
+ symbol.children = children[:]
+ case SymbolBitFieldValue:
+ children := make([dynamic]DocumentSymbol, context.temp_allocator)
+ for name, i in v.names {
+ child: DocumentSymbol
+ child.range = v.ranges[i]
+ child.selectionRange = v.ranges[i]
+ child.name = name
+ child.kind = .Field
+ append(&children, child)
+ }
+ symbol.children = children[:]
+ }
+ }
symbol.kind = .Struct
case ^ast.Proc_Lit, ^ast.Proc_Group:
symbol.kind = .Function
diff --git a/src/server/indexer.odin b/src/server/indexer.odin
index 89817d2..793f621 100644
--- a/src/server/indexer.odin
+++ b/src/server/indexer.odin
@@ -63,8 +63,8 @@ lookup :: proc(name: string, pkg: string, current_file: string, loc := #caller_l
return {}, false
}
-fuzzy_search :: proc(name: string, pkgs: []string, current_file: string) -> ([]FuzzyResult, bool) {
- results, ok := memory_index_fuzzy_search(&indexer.index, name, pkgs, current_file)
+fuzzy_search :: proc(name: string, pkgs: []string, current_file: string, resolve_fields := false) -> ([]FuzzyResult, bool) {
+ results, ok := memory_index_fuzzy_search(&indexer.index, name, pkgs, current_file, resolve_fields)
result := make([dynamic]FuzzyResult, context.temp_allocator)
if !ok {
diff --git a/src/server/memory_index.odin b/src/server/memory_index.odin
index da55f44..7853203 100644
--- a/src/server/memory_index.odin
+++ b/src/server/memory_index.odin
@@ -45,6 +45,7 @@ memory_index_fuzzy_search :: proc(
name: string,
pkgs: []string,
current_file: string,
+ resolve_fields := false,
) -> (
[]FuzzyResult,
bool,
@@ -61,6 +62,41 @@ memory_index_fuzzy_search :: proc(
if should_skip_private_symbol(symbol, current_file) {
continue
}
+ if resolve_fields {
+ // TODO: this only does the top level fields, we may want to travers all the way down in the future
+ #partial switch v in symbol.value {
+ case SymbolStructValue:
+ for name, i in v.names {
+ full_name := fmt.tprintf("%s.%s", symbol.name, name)
+ if score, ok := common.fuzzy_match(fuzzy_matcher, full_name); ok == 1 {
+ s := symbol
+ construct_struct_field_symbol(&s, symbol.name, v, i)
+ s.name = full_name
+ result := FuzzyResult {
+ symbol = s,
+ score = score,
+ }
+
+ append(&symbols, result)
+ }
+ }
+ case SymbolBitFieldValue:
+ for name, i in v.names {
+ full_name := fmt.tprintf("%s.%s", symbol.name, name)
+ if score, ok := common.fuzzy_match(fuzzy_matcher, full_name); ok == 1 {
+ s := symbol
+ construct_bit_field_field_symbol(&s, symbol.name, v, i)
+ s.name = full_name
+ result := FuzzyResult {
+ symbol = s,
+ score = score,
+ }
+
+ append(&symbols, result)
+ }
+ }
+ }
+ }
if score, ok := common.fuzzy_match(fuzzy_matcher, symbol.name); ok == 1 {
result := FuzzyResult {
symbol = symbol,
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 7fab60c..3a4b7c6 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -772,6 +772,8 @@ symbol_kind_to_type :: proc(type: SymbolType) -> SymbolKind {
return .Enum
case .Keyword:
return .Key
+ case .Field:
+ return .Field
case:
return .Null
}
@@ -851,6 +853,7 @@ construct_struct_field_symbol :: proc(symbol: ^Symbol, parent_name: string, valu
symbol.parent_name = parent_name
symbol.doc = get_doc(value.types[index], value.docs[index], context.temp_allocator)
symbol.comment = get_comment(value.comments[index])
+ symbol.range = value.ranges[index]
}
construct_bit_field_field_symbol :: proc(
@@ -865,6 +868,7 @@ construct_bit_field_field_symbol :: proc(
symbol.doc = get_doc(value.types[index], value.docs[index], context.temp_allocator)
symbol.comment = get_comment(value.comments[index])
symbol.signature = get_bit_field_field_signature(value, index)
+ symbol.range = value.ranges[index]
}
construct_enum_field_symbol :: proc(symbol: ^Symbol, value: SymbolEnumValue, index: int) {
diff --git a/src/server/workspace_symbols.odin b/src/server/workspace_symbols.odin
index e5aff20..a45fba5 100644
--- a/src/server/workspace_symbols.odin
+++ b/src/server/workspace_symbols.odin
@@ -65,7 +65,7 @@ get_workspace_symbols :: proc(query: string) -> (workspace_symbols: []WorkspaceS
try_build_package(pkg)
- if results, ok := fuzzy_search(query, {pkg}, ""); ok {
+ if results, ok := fuzzy_search(query, {pkg}, "", resolve_fields = true); ok {
for result in results {
symbol := WorkspaceSymbol {
name = result.symbol.name,