mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-08-05 15:18:40 +00:00
terminal: print repeated characters through printSlice
While doing some work on my tmux fork I noticed multiple parts of libghostty-vt was slower than tmux equivalents(isolated). Turns out they do some smart stuff there. printRepeat called print() once per repeat, so something like \x1b[2000b ran grapheme checks, width lookups, wrap handling, etc etc 2000 times. printSlice is already documented as semantically identical to calling print per codepoint, so this just feeds the repeated codepoint through it in 4096-entry stack chunks. Simple runs take the batched fast path, and anything that needs care falls back to the previous behaviour.
This commit is contained in:
@@ -490,9 +490,19 @@ pub fn printString(self: *Terminal, str: []const u8) !void {
|
||||
|
||||
/// Print the previous printed character a repeated amount of times.
|
||||
pub fn printRepeat(self: *Terminal, count_req: usize) !void {
|
||||
if (self.previous_char) |c| {
|
||||
const count = @max(count_req, 1);
|
||||
for (0..count) |_| try self.print(c);
|
||||
const c = self.previous_char orelse return;
|
||||
var remaining = @max(count_req, 1);
|
||||
|
||||
// Print the repeated codepoint in slices so that eligible runs
|
||||
// take the batched printSlice fast path. printSlice is semantically
|
||||
// identical to calling print per codepoint: ineligible characters
|
||||
// or terminal states (insert mode, grapheme clustering, hyperlinks,
|
||||
// etc.) fall back to the per-codepoint print() path internally.
|
||||
var buf: [4096]u32 = @splat(c);
|
||||
while (remaining > 0) {
|
||||
const n = @min(remaining, buf.len);
|
||||
try self.printSlice(buf[0..n]);
|
||||
remaining -= n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user