From 91f1e5231132225c5b5551321b88d6ac3b4916ed Mon Sep 17 00:00:00 2001 From: Leon Lombar Date: Tue, 10 Nov 2026 19:00:08 +0100 Subject: [PATCH] fix(hover): properly format container fields Fixes the weird staircase effect, or whatever you want to call it, where each consecutive row would print all the previous fields as well. One issue is that this doesn't work recursively, which sounds like a disgusting can of worms I do NOT want to open, but it's still better than status quo. --- src/analysis.zig | 22 ++++++++++++++----- tests/lsp_features/hover.zig | 42 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index de98d7ba1..a382401dd 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -564,15 +564,27 @@ pub fn getVariableSignature( var members_source: std.ArrayList(u8) = .empty; for (container_decl.ast.members) |member| { - const member_line_start = offsets.lineLocUntilIndex(tree.source, tree.tokenStart(tree.firstToken(member))).start; - - const member_source_indented = switch (tree.nodeTag(member)) { + switch (tree.nodeTag(member)) { .container_field_init, .container_field_align, .container_field, - => tree.source[member_line_start..offsets.tokenToLoc(tree, ast.lastToken(tree, member)).end], + => {}, + else => continue, - }; + } + + const first_token = tree.firstToken(member); + const first_token_idx = tree.tokenStart(first_token); + const line_loc = offsets.lineLocUntilIndex(tree.source, first_token_idx); + + const member_source = offsets.nodeToSlice(tree, member); + const member_loc = offsets.nodeToLoc(tree, member); + + const prefix = tree.source[line_loc.start..member_loc.start]; + const indent = std.mem.findNone(u8, prefix, " \t") orelse prefix.len; + + const member_source_indented = try std.mem.concat(arena, u8, &.{ prefix[0..indent], member_source }); + try members_source.append(arena, '\n'); try members_source.appendSlice(arena, try trimCommonIndentation(arena, member_source_indented, 4)); try members_source.append(arena, ','); diff --git a/tests/lsp_features/hover.zig b/tests/lsp_features/hover.zig index 2a35e139e..0252d6eb5 100644 --- a/tests/lsp_features/hover.zig +++ b/tests/lsp_features/hover.zig @@ -588,6 +588,25 @@ test "enum" { \\(type) \\``` ); + + try testHover( + \\pub const MyEnum = enum { + \\ // zig fmt: off + \\ foo, bar, baz + \\ // zig fmt: on + \\}; + , + \\```zig + \\const MyEnum = enum { + \\ foo, + \\ bar, + \\ baz, + \\} + \\``` + \\```zig + \\(type) + \\``` + ); } test "union" { @@ -622,6 +641,29 @@ test "union" { \\(type) \\``` ); + + try testHover( + \\pub const MyUnion = union(enum) { + \\ // zig fmt: off + \\ foo, bar: u16, baz: struct { + \\ bam: u8 + \\ } + \\ // zig fmt: on + \\}; + , + \\```zig + \\const MyUnion = union(enum) { + \\ foo, + \\ bar: u16, + \\ baz: struct { + \\ bam: u8 + \\ }, + \\} + \\``` + \\```zig + \\(type) + \\``` + ); } test "enum member" {