aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-07 18:29:21 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-07 18:29:21 +0300
commitdcfe11a7588fcd42471159453810abc9b7720a57 (patch)
treec32a77266028e73ca2382b96c96f8438a5fcd621 /src
parent2dfed860103c4e4505ac7f25def9fe37da1e1e6a (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 'src')
-rw-r--r--src/ghostty/bindings.rs37
-rw-r--r--src/ghostty/mod.rs99
2 files changed, 96 insertions, 40 deletions
diff --git a/src/ghostty/bindings.rs b/src/ghostty/bindings.rs
index db2d412d..6e77288f 100644
--- a/src/ghostty/bindings.rs
+++ b/src/ghostty/bindings.rs
@@ -707,6 +707,28 @@ impl Default for GhosttyGridRef {
}
}
}
+#[doc = " A selection range defined by two grid references."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct GhosttySelection {
+ pub size: usize,
+ pub start: GhosttyGridRef,
+ pub end: GhosttyGridRef,
+ pub rectangle: bool,
+}
+#[allow(clippy::unnecessary_operation, clippy::identity_op)]
+const _: () = {
+ ["Size of GhosttySelection"][::std::mem::size_of::<GhosttySelection>() - 64usize];
+ ["Alignment of GhosttySelection"][::std::mem::align_of::<GhosttySelection>() - 8usize];
+ ["Offset of field: GhosttySelection::size"]
+ [::std::mem::offset_of!(GhosttySelection, size) - 0usize];
+ ["Offset of field: GhosttySelection::start"]
+ [::std::mem::offset_of!(GhosttySelection, start) - 8usize];
+ ["Offset of field: GhosttySelection::end"]
+ [::std::mem::offset_of!(GhosttySelection, end) - 32usize];
+ ["Offset of field: GhosttySelection::rectangle"]
+ [::std::mem::offset_of!(GhosttySelection, rectangle) - 56usize];
+};
unsafe extern "C" {
#[doc = " Get the cell from a grid reference.\n\n @param ref Pointer to the grid reference\n @param[out] out_cell On success, set to the cell at the ref's position (may be NULL)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's\n node is NULL\n\n @ingroup grid_ref"]
pub fn ghostty_grid_ref_cell(
@@ -731,6 +753,15 @@ unsafe extern "C" {
) -> GhosttyResult;
}
unsafe extern "C" {
+ #[doc = " Get the hyperlink URI for the cell at the grid reference's position."]
+ pub fn ghostty_grid_ref_hyperlink_uri(
+ ref_: *const GhosttyGridRef,
+ buf: *mut u8,
+ buf_len: usize,
+ out_len: *mut usize,
+ ) -> GhosttyResult;
+}
+unsafe extern "C" {
#[doc = " Get the style of the cell at the grid reference's position.\n\n @param ref Pointer to the grid reference\n @param[out] out_style On success, set to the cell's style (may be NULL)\n @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's\n node is NULL\n\n @ingroup grid_ref"]
pub fn ghostty_grid_ref_style(
ref_: *const GhosttyGridRef,
@@ -1250,11 +1281,13 @@ pub struct GhosttyFormatterTerminalOptions {
pub trim: bool,
#[doc = " Extra terminal state to include in styled output."]
pub extra: GhosttyFormatterTerminalExtra,
+ #[doc = " Optional selection to restrict output to a range."]
+ pub selection: *const GhosttySelection,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of GhosttyFormatterTerminalOptions"]
- [::std::mem::size_of::<GhosttyFormatterTerminalOptions>() - 48usize];
+ [::std::mem::size_of::<GhosttyFormatterTerminalOptions>() - 56usize];
["Alignment of GhosttyFormatterTerminalOptions"]
[::std::mem::align_of::<GhosttyFormatterTerminalOptions>() - 8usize];
["Offset of field: GhosttyFormatterTerminalOptions::size"]
@@ -1267,6 +1300,8 @@ const _: () = {
[::std::mem::offset_of!(GhosttyFormatterTerminalOptions, trim) - 13usize];
["Offset of field: GhosttyFormatterTerminalOptions::extra"]
[::std::mem::offset_of!(GhosttyFormatterTerminalOptions, extra) - 16usize];
+ ["Offset of field: GhosttyFormatterTerminalOptions::selection"]
+ [::std::mem::offset_of!(GhosttyFormatterTerminalOptions, selection) - 48usize];
};
impl Default for GhosttyFormatterTerminalOptions {
fn default() -> Self {
diff --git a/src/ghostty/mod.rs b/src/ghostty/mod.rs
index 99923789..5648e606 100644
--- a/src/ghostty/mod.rs
+++ b/src/ghostty/mod.rs
@@ -223,23 +223,6 @@ struct WritePtyCallbackState {
callback: Box<dyn FnMut(&[u8]) + Send>,
}
-#[repr(C)]
-struct GhosttyTerminalSelection {
- start: ffi::GhosttyPoint,
- end: ffi::GhosttyPoint,
- rectangle: bool,
-}
-
-unsafe extern "C" {
- fn ghostty_terminal_read_text(
- terminal: ffi::GhosttyTerminal_ptr,
- selection: GhosttyTerminalSelection,
- allocator: *const ffi::GhosttyAllocator,
- out_ptr: *mut *mut u8,
- out_len: *mut usize,
- ) -> ffi::GhosttyResult;
-}
-
unsafe extern "C" fn write_pty_trampoline(
_terminal: ffi::GhosttyTerminal_ptr,
userdata: *mut c_void,
@@ -461,11 +444,11 @@ impl Terminal {
end: (u16, u32),
rectangle: bool,
) -> Result<String, Error> {
- self.read_text_selection(GhosttyTerminalSelection {
- start: ghostty_viewport_point(start.0, start.1),
- end: ghostty_viewport_point(end.0, end.1),
+ self.read_text_selection(
+ ghostty_viewport_point(start.0, start.1),
+ ghostty_viewport_point(end.0, end.1),
rectangle,
- })
+ )
}
pub fn read_text_screen(
@@ -474,26 +457,68 @@ impl Terminal {
end: (u16, u32),
rectangle: bool,
) -> Result<String, Error> {
- self.read_text_selection(GhosttyTerminalSelection {
- start: ghostty_screen_point(start.0, start.1),
- end: ghostty_screen_point(end.0, end.1),
+ self.read_text_selection(
+ ghostty_screen_point(start.0, start.1),
+ ghostty_screen_point(end.0, end.1),
rectangle,
- })
+ )
}
- fn read_text_selection(&self, selection: GhosttyTerminalSelection) -> Result<String, Error> {
+ fn read_text_selection(
+ &self,
+ start: ffi::GhosttyPoint,
+ end: ffi::GhosttyPoint,
+ rectangle: bool,
+ ) -> Result<String, Error> {
+ let mut start_ref = ffi::GhosttyGridRef {
+ size: mem::size_of::<ffi::GhosttyGridRef>(),
+ ..Default::default()
+ };
+ let mut end_ref = ffi::GhosttyGridRef {
+ size: mem::size_of::<ffi::GhosttyGridRef>(),
+ ..Default::default()
+ };
+ unsafe {
+ ffi::ghostty_terminal_grid_ref(self.raw, start, &mut start_ref).into_result()?;
+ ffi::ghostty_terminal_grid_ref(self.raw, end, &mut end_ref).into_result()?;
+ }
+
+ let selection = ffi::GhosttySelection {
+ size: mem::size_of::<ffi::GhosttySelection>(),
+ start: start_ref,
+ end: end_ref,
+ rectangle,
+ };
+ let mut formatter: ffi::GhosttyFormatter_ptr = ptr::null_mut();
+ let options = ffi::GhosttyFormatterTerminalOptions {
+ size: mem::size_of::<ffi::GhosttyFormatterTerminalOptions>(),
+ emit: ffi::GhosttyFormatterFormat_GHOSTTY_FORMATTER_FORMAT_PLAIN,
+ unwrap: true,
+ trim: true,
+ extra: ffi::GhosttyFormatterTerminalExtra {
+ size: mem::size_of::<ffi::GhosttyFormatterTerminalExtra>(),
+ screen: ffi::GhosttyFormatterScreenExtra {
+ size: mem::size_of::<ffi::GhosttyFormatterScreenExtra>(),
+ ..Default::default()
+ },
+ ..Default::default()
+ },
+ selection: &selection,
+ };
+ unsafe {
+ ffi::ghostty_formatter_terminal_new(ptr::null(), &mut formatter, self.raw, options)
+ .into_result()?;
+ }
+
let mut out_ptr = ptr::null_mut();
let mut out_len = 0usize;
+ let result = unsafe {
+ ffi::ghostty_formatter_format_alloc(formatter, ptr::null(), &mut out_ptr, &mut out_len)
+ };
unsafe {
- ghostty_terminal_read_text(
- self.raw,
- selection,
- ptr::null(),
- &mut out_ptr,
- &mut out_len,
- )
- .into_result()?;
+ ffi::ghostty_formatter_free(formatter);
}
+ result.into_result()?;
let text = if out_len == 0 {
String::new()
@@ -1191,12 +1216,8 @@ mod tests {
let _simd = build_info_bool(ffi::GhosttyBuildInfo_GHOSTTY_BUILD_INFO_SIMD);
let _tmux_control_mode =
build_info_bool(ffi::GhosttyBuildInfo_GHOSTTY_BUILD_INFO_TMUX_CONTROL_MODE);
- let kitty_graphics =
+ let _kitty_graphics =
build_info_bool(ffi::GhosttyBuildInfo_GHOSTTY_BUILD_INFO_KITTY_GRAPHICS);
- assert!(
- !kitty_graphics,
- "current herdr vendor must keep Kitty graphics disabled until image handling is explicit"
- );
let optimize = build_info_optimize();
assert!(matches!(