diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-07 18:29:21 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-07 18:29:21 +0300 |
| commit | dcfe11a7588fcd42471159453810abc9b7720a57 (patch) | |
| tree | c32a77266028e73ca2382b96c96f8438a5fcd621 /vendor/libghostty-vt/src/terminal/Terminal.zig | |
| parent | 2dfed860103c4e4505ac7f25def9fe37da1e1e6a (diff) | |
build: update libghostty-vt vendor
vendor ghostty 063ac3e and remove the musl libc++ link workaround.
expose the new selection formatter and hyperlink uri apis for follow-up rendering work.
add manual artifact validation for static linux builds.
Diffstat (limited to 'vendor/libghostty-vt/src/terminal/Terminal.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/terminal/Terminal.zig | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/vendor/libghostty-vt/src/terminal/Terminal.zig b/vendor/libghostty-vt/src/terminal/Terminal.zig index 99536e7a..6740a93e 100644 --- a/vendor/libghostty-vt/src/terminal/Terminal.zig +++ b/vendor/libghostty-vt/src/terminal/Terminal.zig @@ -191,6 +191,26 @@ pub const Options = struct { /// The default mode state. When the terminal gets a reset, it /// will revert back to this state. default_modes: modespkg.ModePacked = .{}, + + /// The total storage limit for Kitty images in bytes. Has no effect + /// if kitty images are disabled at build-time. + kitty_image_storage_limit: usize = switch (build_options.artifact) { + .ghostty => 320 * 1000 * 1000, // 320MB + + // libghostty we start with a much lower limit since this is an + // embedded library and we want to be more conservative with memory + // usage by default. + .lib => 10 * 1000 * 1000, // 10MB + }, + + /// The limits for what medium types are allowed for Kitty image loading. + /// Has no effect if kitty images are disabled otherwise. For example, + // if no `sys.decode_png` hook is specified, png formats are disabled + // no matter what. + kitty_image_loading_limits: if (build_options.kitty_graphics) + kitty.graphics.LoadingImage.Limits + else + void = if (build_options.kitty_graphics) .direct else {}, }; /// Initialize a new terminal. @@ -205,6 +225,8 @@ pub fn init( .cols = cols, .rows = rows, .max_scrollback = opts.max_scrollback, + .kitty_image_storage_limit = opts.kitty_image_storage_limit, + .kitty_image_loading_limits = opts.kitty_image_loading_limits, }); errdefer screen_set.deinit(alloc); @@ -551,20 +573,25 @@ pub fn print(self: *Terminal, c: u21) !void { // it. if (self.modes.get(.grapheme_cluster)) return; - // If we're at cell zero, then this is malformed data and we don't - // print anything or even store this. Zero-width characters are ALWAYS - // attached to some other non-zero-width character at the time of - // writing. - if (self.screens.active.cursor.x == 0) { + // If we have wraparound enabled and a pending wrap, the character + // we're attaching to is still under the cursor. Otherwise, it's the + // cell to the left. + const left: size.CellCountInt = if (self.modes.get(.wraparound) and self.screens.active.cursor.pending_wrap) 0 else 1; + + // If we're at cell zero and not pending a wrap, then this is malformed + // data and we don't print anything or even store this. Zero-width + // characters are ALWAYS attached to some other non-zero-width + // character at the time of writing. + if (self.screens.active.cursor.x == 0 and left == 1) { log.warn("zero-width character with no prior character, ignoring", .{}); return; } // Find our previous cell const prev = prev: { - const immediate = self.screens.active.cursorCellLeft(1); + const immediate = self.screens.active.cursorCellLeft(left); if (immediate.wide != .spacer_tail) break :prev immediate; - break :prev self.screens.active.cursorCellLeft(2); + break :prev self.screens.active.cursorCellLeft(left + 1); }; // If our previous cell has no text, just ignore the zero-width character @@ -2693,6 +2720,34 @@ pub fn kittyGraphics( return kitty.graphics.execute(alloc, self, cmd); } +/// Set the storage size limit for Kitty graphics across all screens. +pub fn setKittyGraphicsSizeLimit( + self: *Terminal, + alloc: Allocator, + limit: usize, +) !void { + if (comptime !build_options.kitty_graphics) return; + var it = self.screens.all.iterator(); + while (it.next()) |entry| { + const screen: *Screen = entry.value.*; + try screen.kitty_images.setLimit(alloc, screen, limit); + } +} + +/// Set the allowed medium types for Kitty graphics image loading +/// across all screens. +pub fn setKittyGraphicsLoadingLimits( + self: *Terminal, + limits: kitty.graphics.LoadingImage.Limits, +) void { + if (comptime !build_options.kitty_graphics) return; + var it = self.screens.all.iterator(); + while (it.next()) |entry| { + const screen: *Screen = entry.value.*; + screen.kitty_images.image_limits = limits; + } +} + /// Set a style attribute. pub fn setAttribute(self: *Terminal, attr: sgr.Attribute) !void { try self.screens.active.setAttribute(attr); @@ -2941,12 +2996,15 @@ pub fn switchScreen(self: *Terminal, key: ScreenSet.Key) !?*Screen { .alternate => 0, }, - // Inherit our Kitty image storage limit from the primary + // Inherit our Kitty image settings from the primary // screen if we have to initialize. .kitty_image_storage_limit = if (comptime build_options.kitty_graphics) primary.kitty_images.total_limit else 0, + .kitty_image_loading_limits = if (comptime build_options.kitty_graphics) + primary.kitty_images.image_limits + else {}, }, ); }; @@ -3260,6 +3318,23 @@ test "Terminal: zero-width character at start" { try testing.expect(!t.isDirty(.{ .screen = .{ .x = 0, .y = 0 } })); } +// https://github.com/ghostty-org/ghostty/issues/12581 +test "Terminal: zero-width character attaches to pending wrap cell" { + var t = try init(testing.allocator, .{ .cols = 2, .rows = 2 }); + defer t.deinit(testing.allocator); + + // Disable grapheme clustering to exercise the fallback path. + t.modes.set(.grapheme_cluster, false); + + try t.print('x'); + try t.print('å'); + try t.print(0x0332); // Combining low line. + + const str = try t.plainString(testing.allocator); + defer testing.allocator.free(str); + try testing.expectEqualStrings("xå̲", str); +} + // https://github.com/mitchellh/ghostty/issues/1400 test "Terminal: print single very long line" { var t = try init(testing.allocator, .{ .rows = 5, .cols = 5 }); |
