diff --git a/src/features/document_symbol.zig b/src/features/document_symbol.zig index f0a35f0ca..b987ebffa 100644 --- a/src/features/document_symbol.zig +++ b/src/features/document_symbol.zig @@ -203,8 +203,11 @@ fn convertSymbolsInternal( const to: []types.DocumentSymbol = symbol_buffer.items[prev_len..]; for (from, to) |symbol, *out| { + // LSP spec requires that a symbol name is not empty or consisting only of whitespace + const name_is_empty = symbol.name.len == 0 or + std.mem.indexOfNone(u8, symbol.name, &std.ascii.whitespace) == null; out.* = .{ - .name = symbol.name, + .name = if (name_is_empty) "" else symbol.name, .detail = symbol.detail, .kind = symbol.kind, // will be set later through the mapping below diff --git a/tests/lsp_features/document_symbol.zig b/tests/lsp_features/document_symbol.zig index abee529fa..bb204c6a8 100644 --- a/tests/lsp_features/document_symbol.zig +++ b/tests/lsp_features/document_symbol.zig @@ -93,6 +93,20 @@ test "nested struct with self" { ); } +test "empty decl names return non-empty document symbol" { + try testDocumentSymbol( + \\test "" {} + \\test " " {} + \\const @"" = 0; + \\const @" " = 0; + , + \\Method + \\Method + \\Constant + \\Constant + ); +} + fn testDocumentSymbol(source: []const u8, expected: []const u8) !void { var ctx: Context = try .init(); defer ctx.deinit();