aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-09-23 21:55:03 +0200
committerDanielGavin <danielgavin5@hotmail.com>2025-09-23 21:55:03 +0200
commit487158b00d62ea80bf1205ad59a6a67fe1804650 (patch)
tree1212044824a9706e373bc1fd6f430c2cccdd26ce
parent1009de179a717c8b355acb8b1268fedc9b2d089c (diff)
Add proper support for ranged semantic tokens.semantic_tokens_range
-rw-r--r--src/server/file_resolve.odin39
-rw-r--r--src/server/requests.odin10
-rw-r--r--src/server/semantic_tokens.odin5
3 files changed, 47 insertions, 7 deletions
diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin
index 53fda8f..22d2d63 100644
--- a/src/server/file_resolve.odin
+++ b/src/server/file_resolve.odin
@@ -36,6 +36,45 @@ reset_position_context :: proc(position_context: ^DocumentPositionContext) {
position_context.index = nil
}
+resolve_ranged_file :: proc(
+ document: ^Document,
+ range: common.Range,
+ allocator := context.allocator,
+) -> map[uintptr]SymbolAndNode {
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ allocator,
+ )
+
+ position_context: DocumentPositionContext
+
+ get_globals(document.ast, &ast_context)
+
+ ast_context.current_package = ast_context.document_package
+
+ symbols := make(map[uintptr]SymbolAndNode, 10000, allocator)
+
+ margin := 20
+
+ for decl in document.ast.decls {
+ if _, is_value := decl.derived.(^ast.Value_Decl); !is_value {
+ continue
+ }
+
+ //Look for declarations that overlap with range
+ if range.start.line - margin <= decl.end.line && decl.pos.line <= range.end.line + margin {
+ resolve_decl(&position_context, &ast_context, document, decl, &symbols, .None, allocator)
+ clear(&ast_context.locals)
+ }
+ }
+
+ return symbols
+}
+
resolve_entire_file :: proc(
document: ^Document,
flag := ResolveReferenceFlag.None,
diff --git a/src/server/requests.odin b/src/server/requests.odin
index 0cbcd99..17597be 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -717,7 +717,7 @@ request_initialize :: proc(
},
semanticTokensProvider = SemanticTokensOptions {
range = config.enable_semantic_tokens,
- full = config.enable_semantic_tokens,
+ full = false,
legend = SemanticTokensLegend {
tokenTypes = semantic_token_type_names,
tokenModifiers = semantic_token_modifier_names,
@@ -1205,12 +1205,10 @@ request_semantic_token_range :: proc(
tokens_params: SemanticTokensResponseParams
if config.enable_semantic_tokens {
- resolve_entire_file_cached(document)
+ symbols := resolve_ranged_file(document, semantic_params.range, context.temp_allocator)
- if file, ok := file_resolve_cache.files[document.uri.uri]; ok {
- tokens := get_semantic_tokens(document, semantic_params.range, file.symbols)
- tokens_params = semantic_tokens_to_response_params(tokens)
- }
+ tokens := get_semantic_tokens(document, semantic_params.range, symbols)
+ tokens_params = semantic_tokens_to_response_params(tokens)
}
response := make_response_message(params = tokens_params, id = id)
diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin
index 60042cd..669ff99 100644
--- a/src/server/semantic_tokens.odin
+++ b/src/server/semantic_tokens.odin
@@ -143,8 +143,11 @@ get_semantic_tokens :: proc(
src = ast_context.file.src,
}
+ margin := 20
+
for decl in document.ast.decls {
- if range.start.line <= decl.pos.line && decl.end.line <= range.end.line {
+ //Look for declarations that overlap with range
+ if range.start.line - margin <= decl.end.line && decl.pos.line <= range.end.line + margin {
visit_node(decl, &builder)
}
}