Commit 4e1f3a9ba3

Timon Kruiper <timonkruiper@gmail.com>
2019-05-30 00:11:16
Correct formatting for multiline string in arrays
1 parent 7bfae39
Changed files (2)
std/zig/parser_test.zig
@@ -2209,6 +2209,25 @@ test "zig fmt: inline asm parameter alignment" {
     );
 }
 
+test "zig fmt: multiline string in array" {
+    try testCanonical(
+        \\const Foo = [][]const u8{
+        \\    \\aaa
+        \\,
+        \\    \\bbb
+        \\};
+        \\
+        \\fn bar() void {
+        \\    const Foo = [][]const u8{
+        \\        \\aaa
+        \\    ,
+        \\        \\bbb
+        \\    };
+        \\}
+        \\
+    );
+}
+
 const std = @import("std");
 const mem = std.mem;
 const warn = std.debug.warn;
std/zig/render.zig
@@ -726,15 +726,21 @@ fn renderExpression(
                             expr_widths[i] = width;
                         }
 
-                        const new_indent = indent + indent_delta;
+                        var new_indent = indent + indent_delta;
                         try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
-                        try stream.writeByteNTimes(' ', new_indent);
+
+                        if (tree.tokens.at(lbrace + 1).id != Token.Id.MultilineStringLiteralLine) {
+                            try stream.writeByteNTimes(' ', new_indent);
+                        }
 
                         it.set(0);
                         i = 0;
                         var col: usize = 1;
                         while (it.next()) |expr| : (i += 1) {
                             if (it.peek()) |next_expr| {
+                                if (expr.*.id == ast.Node.Id.MultilineStringLiteral) {
+                                    new_indent -= indent_delta;
+                                }
                                 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.None);
 
                                 const comma = tree.nextToken(expr.*.lastToken());
@@ -753,12 +759,17 @@ fn renderExpression(
                                 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,
 
                                 try renderExtraNewline(tree, stream, start_col, next_expr.*);
-                                try stream.writeByteNTimes(' ', new_indent);
+                                if (next_expr.*.id != ast.Node.Id.MultilineStringLiteral) {
+                                    try stream.writeByteNTimes(' ', new_indent);
+                                }
                             } else {
                                 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // ,
                             }
                         }
-                        try stream.writeByteNTimes(' ', indent);
+                        const last_node = it.prev() orelse unreachable;
+                        if (last_node.*.id != ast.Node.Id.MultilineStringLiteral) {
+                            try stream.writeByteNTimes(' ', indent);
+                        }
                         return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
                     } else {
                         try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
@@ -1039,6 +1050,8 @@ fn renderExpression(
         },
 
         ast.Node.Id.MultilineStringLiteral => {
+            // TODO: Don't indent in this function, but let the caller indent.
+            // If this has been implemented, a lot of hacky solutions in i.e. ArrayInit and FunctionCall can be removed
             const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);
 
             var skip_first_indent = true;