diff --git a/src/Workspace.zig b/src/Workspace.zig index 4db7ffd..17130ce 100644 --- a/src/Workspace.zig +++ b/src/Workspace.zig @@ -156,14 +156,16 @@ fn builtinCompletions(arena: std.mem.Allocator, spec: *const Spec) ![]lsp.Comple } for (spec.variables) |variable| { - var signature = std.ArrayList(u8).init(arena); - try signature.writer().print("{}", .{variable.modifiers}); - try signature.appendSlice(" "); - try signature.appendSlice(variable.type); + var anonymous_signature = std.ArrayList(u8).init(arena); + try writeVariableSignature(variable, anonymous_signature.writer(), .{ .names = false }); + + var named_signature = std.ArrayList(u8).init(arena); + try writeVariableSignature(variable, named_signature.writer(), .{ .names = true }); try completions.append(.{ .label = variable.name, - .labelDetails = .{ .detail = signature.items }, + .labelDetails = .{ .detail = anonymous_signature.items }, + .detail = named_signature.items, .kind = .variable, .documentation = try itemDocumentation(arena, variable), }); @@ -207,6 +209,31 @@ fn itemDocumentation(arena: std.mem.Allocator, item: anytype) !lsp.MarkupContent return .{ .kind = .markdown, .value = try documentation.toOwnedSlice() }; } +fn writeVariableSignature( + variable: Spec.Variable, + writer: anytype, + options: struct { names: bool }, +) !void { + if (!std.meta.eql(variable.modifiers, .{ .in = true })) { + try writer.print("{}", .{variable.modifiers}); + try writer.writeAll(" "); + } + + try writer.writeAll(variable.type); + + if (options.names) { + try writer.writeAll(" "); + try writer.writeAll(variable.name); + + if (variable.default_value) |value| { + try writer.writeAll(" = "); + try writer.writeAll(value); + } + + try writer.writeAll(";"); + } +} + fn writeFunctionSignature( function: Spec.Function, writer: anytype, diff --git a/src/format.zig b/src/format.zig index 7e15cdc..6897021 100644 --- a/src/format.zig +++ b/src/format.zig @@ -314,6 +314,7 @@ fn formatNode(tree: parse.Tree, current: usize, writer: anytype) !void { .array, .array_specifier, .selection, + .parenthized, => { const children = tree.children(current); for (children.start..children.end) |child| { @@ -321,6 +322,14 @@ fn formatNode(tree: parse.Tree, current: usize, writer: anytype) !void { } }, + .conditional => { + const children = tree.children(current); + for (children.start..children.end) |child| { + if (child != children.start) writer.writeSpace(); + try formatNode(tree, child, writer); + } + }, + // emit tokens separated by spaces inline else => |tag| { const operators = comptime parse.assignment_operators.unionWith(parse.infix_operators); @@ -362,7 +371,6 @@ fn needsLeadingSpace(tag: parse.Tag) bool { .@",", .parameter_list, .array, - .array_specifier, => false, else => true, }; @@ -573,6 +581,42 @@ test "format field selection" { ); } +test "format ternary condition" { + try expectIsFormatted( + \\void main() { + \\ int foo = a ? b : c; + \\} + \\ + ); +} + +test "format parenthized" { + try expectIsFormatted( + \\void main() { + \\ int foo = (1 + 1); + \\} + \\ + ); +} + +test "format assign array" { + try expectIsFormatted( + \\void main() { + \\ int foo = bar[123]; + \\} + \\ + ); +} + +test "format array declaration" { + try expectIsFormatted( + \\void main() { + \\ int[2] foo[123]; + \\} + \\ + ); +} + fn expectIsFormatted(source: []const u8) !void { try expectFormat(source, source); }