| ... | ... | @@ -3302,6 +3302,26 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi |
| 3302 | 3302 | |
| 3303 | 3303 | /// Automatically inserts indentation of written data by keeping |
| 3304 | 3304 | /// track of the current indentation level |
| 3305 | /// |
| 3306 | /// We introduce a new indentation scope with pushIndent/popIndent whenever |
| 3307 | /// we potentially want to introduce an indent after the next newline. |
| 3308 | /// |
| 3309 | /// Indentation should only ever increment by one from one line to the next, |
| 3310 | /// no matter how many new indentation scopes are introduced. This is done by |
| 3311 | /// only realizing the indentation from the most recent scope. As an example: |
| 3312 | /// |
| 3313 | /// while (foo) if (bar) |
| 3314 | /// f(x); |
| 3315 | /// |
| 3316 | /// The body of `while` introduces a new indentation scope and the body of |
| 3317 | /// `if` also introduces a new indentation scope. When the newline is seen, |
| 3318 | /// only the indentation scope of the `if` is realized, and the `while` is |
| 3319 | /// not. |
| 3320 | /// |
| 3321 | /// As comments are rendered during space rendering, we need to keep track |
| 3322 | /// of the appropriate indentation level for them with pushSpace/popSpace. |
| 3323 | /// This should be done whenever a scope that ends in a .semicolon or a |
| 3324 | /// .comma is introduced. |
| 3305 | 3325 | fn AutoIndentingStream(comptime UnderlyingWriter: type) type { |
| 3306 | 3326 | return struct { |
| 3307 | 3327 | const Self = @This(); |
| ... | ... | @@ -3400,8 +3420,11 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type { |
| 3400 | 3420 | |
| 3401 | 3421 | fn resetLine(self: *Self) void { |
| 3402 | 3422 | self.current_line_empty = true; |
| 3423 | |
| 3403 | 3424 | if (self.disable_indent_committing > 0) return; |
| 3425 | |
| 3404 | 3426 | if (self.indent_stack.items.len > 0) { |
| 3427 | // By default, we realize the most recent indentation scope. |
| 3405 | 3428 | var to_realize = self.indent_stack.items.len - 1; |
| 3406 | 3429 | |
| 3407 | 3430 | if (self.indent_stack.items.len >= 2 and |
| ... | ... | @@ -3409,12 +3432,18 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type { |
| 3409 | 3432 | self.indent_stack.items[to_realize - 1].realized and |
| 3410 | 3433 | self.indent_stack.items[to_realize].indent_type == .binop) |
| 3411 | 3434 | { |
| 3412 | | // collapse one level of indentation in binop after equals sign |
| 3435 | // If we are in a .binop scope and our direct parent is .after_equals, don't indent. |
| 3436 | // This ensures correct indentation in the below example: |
| 3437 | // |
| 3438 | // const foo = |
| 3439 | // (x >= 'a' and x <= 'z') or //<-- we are here |
| 3440 | // (x >= 'A' and x <= 'Z'); |
| 3441 | // |
| 3413 | 3442 | return; |
| 3414 | 3443 | } |
| 3415 | 3444 | |
| 3416 | 3445 | if (self.indent_stack.items[to_realize].indent_type == .field_access) { |
| 3417 | | // only realize topmost field_access in a chain |
| 3446 | // Only realize the top-most field_access in a chain. |
| 3418 | 3447 | while (to_realize > 0 and self.indent_stack.items[to_realize - 1].indent_type == .field_access) |
| 3419 | 3448 | to_realize -= 1; |
| 3420 | 3449 | } |
| ... | ... | @@ -3425,6 +3454,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type { |
| 3425 | 3454 | } |
| 3426 | 3455 | } |
| 3427 | 3456 | |
| 3457 | /// Disables indentation level changes during the next newlines until re-enabled. |
| 3428 | 3458 | pub fn disableIndentCommitting(self: *Self) void { |
| 3429 | 3459 | self.disable_indent_committing += 1; |
| 3430 | 3460 | } |
| ... | ... | @@ -3442,6 +3472,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type { |
| 3442 | 3472 | _ = self.space_stack.pop(); |
| 3443 | 3473 | } |
| 3444 | 3474 | |
| 3475 | /// Sets current indentation level to be the same as that of the last pushSpace. |
| 3445 | 3476 | pub fn enableSpaceMode(self: *Self, space: Space) void { |
| 3446 | 3477 | if (self.space_stack.items.len == 0) return; |
| 3447 | 3478 | const curr = self.space_stack.getLast(); |
| ... | ... | @@ -3471,6 +3502,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type { |
| 3471 | 3502 | try self.indent_stack.append(.{ .indent_type = indent_type, .realized = false }); |
| 3472 | 3503 | } |
| 3473 | 3504 | |
| 3505 | /// Forces an indentation level to be realized. |
| 3474 | 3506 | pub fn forcePushIndent(self: *Self, indent_type: IndentType) !void { |
| 3475 | 3507 | try self.indent_stack.append(.{ .indent_type = indent_type, .realized = true }); |
| 3476 | 3508 | self.indent_count += 1; |