| ... | @@ -35,6 +35,9 @@ initial_delay_ns: u64, | ... | @@ -35,6 +35,9 @@ initial_delay_ns: u64, |
| 35 | | 35 | |
| 36 | rows: u16, | 36 | rows: u16, |
| 37 | cols: u16, | 37 | cols: u16, |
| | 38 | /// Needed because terminal escape codes require one to take scrolling into |
| | 39 | /// account. |
| | 40 | newline_count: u16, |
| 38 | | 41 | |
| 39 | /// Accessed only by the update thread. | 42 | /// Accessed only by the update thread. |
| 40 | draw_buffer: []u8, | 43 | draw_buffer: []u8, |
| ... | @@ -240,6 +243,7 @@ var global_progress: Progress = .{ | ... | @@ -240,6 +243,7 @@ var global_progress: Progress = .{ |
| 240 | .initial_delay_ns = undefined, | 243 | .initial_delay_ns = undefined, |
| 241 | .rows = 0, | 244 | .rows = 0, |
| 242 | .cols = 0, | 245 | .cols = 0, |
| | 246 | .newline_count = 0, |
| 243 | .draw_buffer = undefined, | 247 | .draw_buffer = undefined, |
| 244 | .done = false, | 248 | .done = false, |
| 245 | | 249 | |
| ... | @@ -346,6 +350,7 @@ fn updateThreadRun() void { | ... | @@ -346,6 +350,7 @@ fn updateThreadRun() void { |
| 346 | } | 350 | } |
| 347 | | 351 | |
| 348 | const start_sync = "\x1b[?2026h"; | 352 | const start_sync = "\x1b[?2026h"; |
| | 353 | const up_one_line = "\x1bM"; |
| 349 | const clear = "\x1b[J"; | 354 | const clear = "\x1b[J"; |
| 350 | const save = "\x1b7"; | 355 | const save = "\x1b7"; |
| 351 | const restore = "\x1b8"; | 356 | const restore = "\x1b8"; |
| ... | @@ -431,22 +436,32 @@ fn computeRedraw() []u8 { | ... | @@ -431,22 +436,32 @@ fn computeRedraw() []u8 { |
| 431 | } | 436 | } |
| 432 | | 437 | |
| 433 | // The strategy is: keep the cursor at the beginning, and then with every redraw: | 438 | // The strategy is: keep the cursor at the beginning, and then with every redraw: |
| 434 | // erase, save, write, restore | 439 | // erase to end of screen, write, move cursor to beginning of line, move cursor up N lines |
| 435 | | 440 | |
| 436 | var i: usize = 0; | 441 | var i: usize = 0; |
| 437 | const buf = global_progress.draw_buffer; | 442 | const buf = global_progress.draw_buffer; |
| 438 | | 443 | |
| 439 | const prefix = start_sync ++ clear ++ save; | 444 | buf[i..][0..start_sync.len].* = start_sync.*; |
| 440 | const suffix = restore ++ finish_sync; | 445 | i += start_sync.len; |
| 441 | | 446 | |
| 442 | buf[0..prefix.len].* = prefix.*; | 447 | buf[0..clear.len].* = clear.*; |
| 443 | i = prefix.len; | 448 | i = clear.len; |
| 444 | | 449 | |
| 445 | const root_node_index: Node.Index = @enumFromInt(0); | 450 | const root_node_index: Node.Index = @enumFromInt(0); |
| 446 | i = computeNode(buf, i, serialized_node_storage, serialized_node_parents, children, root_node_index); | 451 | i = computeNode(buf, i, serialized_node_storage, serialized_node_parents, children, root_node_index); |
| 447 | | 452 | |
| 448 | buf[i..][0..suffix.len].* = suffix.*; | 453 | if (buf[i - 1] == '\n') { |
| 449 | i += suffix.len; | 454 | buf[i - 1] = '\r'; |
| | 455 | const prev_nl_n = global_progress.newline_count - 1; |
| | 456 | global_progress.newline_count = 0; |
| | 457 | for (0..prev_nl_n) |_| { |
| | 458 | buf[i..][0..up_one_line.len].* = up_one_line.*; |
| | 459 | i += up_one_line.len; |
| | 460 | } |
| | 461 | } |
| | 462 | |
| | 463 | buf[i..][0..finish_sync.len].* = finish_sync.*; |
| | 464 | i += finish_sync.len; |
| 450 | | 465 | |
| 451 | return buf[0..i]; | 466 | return buf[0..i]; |
| 452 | } | 467 | } |
| ... | @@ -514,6 +529,7 @@ fn computeNode( | ... | @@ -514,6 +529,7 @@ fn computeNode( |
| 514 | i = @min(global_progress.cols + start_i, i); | 529 | i = @min(global_progress.cols + start_i, i); |
| 515 | buf[i] = '\n'; | 530 | buf[i] = '\n'; |
| 516 | i += 1; | 531 | i += 1; |
| | 532 | global_progress.newline_count += 1; |
| 517 | | 533 | |
| 518 | if (children[@intFromEnum(node_index)].child.unwrap()) |child| { | 534 | if (children[@intFromEnum(node_index)].child.unwrap()) |child| { |
| 519 | i = computeNode(buf, i, serialized_node_storage, serialized_node_parents, children, child); | 535 | i = computeNode(buf, i, serialized_node_storage, serialized_node_parents, children, child); |