mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 08:16:13 +03:00
fix(terminal): properly lookup hyperlinks when cloning rows across pages
Before this we were doing bad things with the memory, looking at `PageEntry`s for links not actually in the page we were reading the strings from.
This commit is contained in:
@ -194,14 +194,24 @@ pub const Set = RefCountedSet(
|
|||||||
Id,
|
Id,
|
||||||
size.CellCountInt,
|
size.CellCountInt,
|
||||||
struct {
|
struct {
|
||||||
|
/// The page which holds the strings for items in this set.
|
||||||
page: ?*Page = null,
|
page: ?*Page = null,
|
||||||
|
|
||||||
|
/// The page which holds the strings for items
|
||||||
|
/// looked up with, e.g., `add` or `lookup`,
|
||||||
|
/// if different from the destination page.
|
||||||
|
src_page: ?*const Page = null,
|
||||||
|
|
||||||
pub fn hash(self: *const @This(), link: PageEntry) u64 {
|
pub fn hash(self: *const @This(), link: PageEntry) u64 {
|
||||||
return link.hash(self.page.?.memory);
|
return link.hash((self.src_page orelse self.page.?).memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eql(self: *const @This(), a: PageEntry, b: PageEntry) bool {
|
pub fn eql(self: *const @This(), a: PageEntry, b: PageEntry) bool {
|
||||||
return a.eql(self.page.?.memory, &b, self.page.?.memory);
|
return a.eql(
|
||||||
|
(self.src_page orelse self.page.?).memory,
|
||||||
|
&b,
|
||||||
|
self.page.?.memory,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deleted(self: *const @This(), link: PageEntry) void {
|
pub fn deleted(self: *const @This(), link: PageEntry) void {
|
||||||
|
@ -821,11 +821,7 @@ pub const Page = struct {
|
|||||||
if (self.hyperlink_set.lookupContext(
|
if (self.hyperlink_set.lookupContext(
|
||||||
self.memory,
|
self.memory,
|
||||||
other_link.*,
|
other_link.*,
|
||||||
|
.{ .page = self, .src_page = @constCast(other) },
|
||||||
// `lookupContext` uses the context for hashing, and
|
|
||||||
// that doesn't write to the page, so this constCast
|
|
||||||
// is completely safe.
|
|
||||||
.{ .page = @constCast(other) },
|
|
||||||
)) |i| {
|
)) |i| {
|
||||||
self.hyperlink_set.use(self.memory, i);
|
self.hyperlink_set.use(self.memory, i);
|
||||||
break :dst_id i;
|
break :dst_id i;
|
||||||
|
@ -38,8 +38,14 @@ const fastmem = @import("../fastmem.zig");
|
|||||||
///
|
///
|
||||||
/// `Context`
|
/// `Context`
|
||||||
/// A type containing methods to define behaviors.
|
/// A type containing methods to define behaviors.
|
||||||
|
///
|
||||||
/// - `fn hash(*Context, T) u64` - Return a hash for an item.
|
/// - `fn hash(*Context, T) u64` - Return a hash for an item.
|
||||||
|
///
|
||||||
/// - `fn eql(*Context, T, T) bool` - Check two items for equality.
|
/// - `fn eql(*Context, T, T) bool` - Check two items for equality.
|
||||||
|
/// The first of the two items passed in is guaranteed to be from
|
||||||
|
/// a value passed in to an `add` or `lookup` function, the second
|
||||||
|
/// is guaranteed to be a value already resident in the set.
|
||||||
|
///
|
||||||
/// - `fn deleted(*Context, T) void` - [OPTIONAL] Deletion callback.
|
/// - `fn deleted(*Context, T) void` - [OPTIONAL] Deletion callback.
|
||||||
/// If present, called whenever an item is finally deleted.
|
/// If present, called whenever an item is finally deleted.
|
||||||
/// Useful if the item has memory that needs to be freed.
|
/// Useful if the item has memory that needs to be freed.
|
||||||
|
Reference in New Issue
Block a user