pub struct Terminal<'alloc: 'cb, 'cb> { /* private fields */ }Expand description
Complete terminal emulator state and rendering.
A terminal instance manages the full emulator state including the screen, scrollback, cursor, styles, modes, and VT stream processing.
Once a terminal session is up and running, you can configure a key encoder
to write keyboard input via key::Encoder::set_options_from_terminal.
§Effects
By default, the terminal sequence processing with Terminal::vt_write
only process sequences that directly affect terminal state and ignores
sequences that have side effect behavior or require responses. These
sequences include things like bell characters, title changes, device
attributes queries, and more. To handle these sequences, the user
must configure “effects.”
Effects are callbacks that the terminal invokes in response to VT sequences
processed during Terminal::vt_write. They let the embedding application
react to terminal-initiated events such as bell characters, title changes,
device status report responses, and more.
Each effect is registered with its corresponding Terminal::on_<effect>
function, which accepts a closure with access to the terminal state and
possibly other parameters. Some examples include Terminal::on_bell
and Terminal::on_pty_write.
All callbacks are invoked synchronously during Terminal::vt_write.
Callbacks must be very careful to not block for too long or perform
expensive operations, since they are blocking further IO processing.
§Shared state
Unlike the C API, you cannot specify arbitrary user data that’s shared between all callbacks, mainly because a safe, idiomatic Rust equivalent of this pattern is very difficult to implement and use due to Rust’s much stricter safety guarantees. In turn, we use the user data internally for callback dispatch purposes.
You should instead use idiomatic Rust mechanisms like Rcs
to hold common, mutable state between callbacks (which is perfectly safe,
since everything is run on a single thread within a single vt_write call),
or with some other type with interior mutability.
§Example: Registering effects and processing VT data
use std::{cell::Cell, rc::Rc};
use libghostty_vt::{Terminal, TerminalOptions};
let mut terminal = Terminal::new(TerminalOptions {
cols: 80,
rows: 24,
max_scrollback: 0,
})?;
// Set up a simple bell counter
let bell_count = Rc::new(Cell::new(0usize));
terminal
.on_pty_write(|_term, data| {
println!("Replying {} bytes to the PTY", data.len());
})?
.on_bell({
let bell_count = bell_count.clone();
move |_term| {
bell_count.update(|v| v + 1);
println!("Bell! (count = {})", bell_count.get())
}
})?
.on_title_changed(|term| {
// Query the cursor position to confirm the terminal processed the
// title change (the title itself is tracked by the embedder via the
// OSC parser or its own state).
let col = term.cursor_x().unwrap();
println!("Title changed! (cursor at col {col})");
})?;
// Feed VT data that triggers effects:
// 1. Bell (BEL = 0x07)
terminal.vt_write(b"\x07");
// 2. Title change (OSC 2 ; <title> ST)
terminal.vt_write(b"\x1b]2;Hello Effects\x1b\\");
// 3. Device status report (DECRQM for wraparound mode ?7)
// triggers write_pty with the response
terminal.vt_write(b"\x1B[?7$p");
// 4. Another bell to show the counter increments
terminal.vt_write(b"\x07");
assert_eq!(bell_count.get(), 2);Implementations§
Source§impl<'alloc: 'cb, 'cb> Terminal<'alloc, 'cb>
impl<'alloc: 'cb, 'cb> Terminal<'alloc, 'cb>
Sourcepub fn new_with_alloc<'ctx: 'alloc, Ctx>(
alloc: &'alloc Allocator<'ctx, Ctx>,
opts: Options,
) -> Result<Self>
pub fn new_with_alloc<'ctx: 'alloc, Ctx>( alloc: &'alloc Allocator<'ctx, Ctx>, opts: Options, ) -> Result<Self>
Create a new terminal instance with a custom allocator.
See the crate-level documentation regarding custom memory management and lifetimes.
Sourcepub fn vt_write(&mut self, data: &[u8])
pub fn vt_write(&mut self, data: &[u8])
Write VT-encoded data to the terminal for processing.
Feeds raw bytes through the terminal’s VT stream parser, updating
terminal state accordingly. By default, sequences that require output
(queries, device status reports) are silently ignored.
Use Terminal::on_pty_write to install a callback that receives
response data.
This never fails. Any erroneous input or errors in processing the input are logged internally but do not cause this function to fail because this input is assumed to be untrusted and from an external source; so the primary goal is to keep the terminal state consistent and not allow malformed input to corrupt or crash.
Sourcepub fn resize(
&mut self,
cols: u16,
rows: u16,
cell_width_px: u32,
cell_height_px: u32,
) -> Result<()>
pub fn resize( &mut self, cols: u16, rows: u16, cell_width_px: u32, cell_height_px: u32, ) -> Result<()>
Resize the terminal to the given dimensions.
Changes the number of columns and rows in the terminal. The primary screen will reflow content if wraparound mode is enabled; the alternate screen does not reflow. If the dimensions are unchanged, this is a no-op.
This also updates the terminal’s pixel dimensions (used for image protocols and size reports), disables synchronized output mode (allowed by the spec so that resize results are shown immediately), and sends an in-band size report if mode 2048 is enabled.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Perform a full reset of the terminal (RIS).
Resets all terminal state back to its initial configuration, including modes, scrollback, scrolling region, and screen contents. The terminal dimensions are preserved.
Sourcepub fn scroll_viewport(&mut self, scroll: ScrollViewport)
pub fn scroll_viewport(&mut self, scroll: ScrollViewport)
Scroll the terminal viewport.
Sourcepub fn grid_ref(&self, point: Point) -> Result<GridRef<'_>>
pub fn grid_ref(&self, point: Point) -> Result<GridRef<'_>>
Resolve a point in the terminal grid to a grid reference.
Resolves the given point (which can be in active, viewport, screen,
or history coordinates) to a grid reference for that location. Use
GridRef::cell and GridRef::row to extract the cell and row.
Lookups in the active region and viewport are fast. Lookups in the screen and history may require traversing the full scrollback page list to resolve the y coordinate, so they can be expensive for large scrollback buffers.
This function isn’t meant to be used as the core of render loop. It isn’t built to sustain the framerates needed for rendering large screens. Use the render state API for that. This API is instead meant for less strictly performance-sensitive use cases.
Sourcepub fn set_mode(&mut self, mode: Mode, value: bool) -> Result<()>
pub fn set_mode(&mut self, mode: Mode, value: bool) -> Result<()>
Set the value of a terminal mode.
Sourcepub fn cursor_y(&self) -> Result<u16>
pub fn cursor_y(&self) -> Result<u16>
Get the cursor row position within the active area (inner-indexed).
Sourcepub fn is_cursor_pending_wrap(&self) -> Result<bool>
pub fn is_cursor_pending_wrap(&self) -> Result<bool>
Get whether the cursor has a pending wrap (next print will soft-wrap).
Sourcepub fn is_cursor_visible(&self) -> Result<bool>
pub fn is_cursor_visible(&self) -> Result<bool>
Get whether the cursor is visible (DEC mode 25).
Sourcepub fn cursor_style(&self) -> Result<Style>
pub fn cursor_style(&self) -> Result<Style>
Get the current SGR style of the cursor.
This is the style that will be applied to newly printed characters.
Sourcepub fn kitty_keyboard_flags(&self) -> Result<KittyKeyFlags>
pub fn kitty_keyboard_flags(&self) -> Result<KittyKeyFlags>
Get the current Kitty keyboard protocol flags.
Sourcepub fn scrollbar(&self) -> Result<GhosttyTerminalScrollbar>
pub fn scrollbar(&self) -> Result<GhosttyTerminalScrollbar>
Get the scrollbar state for the terminal viewport.
This may be expensive to calculate depending on where the viewport is (arbitrary pins are expensive). The caller should take care to only call this as needed and not too frequently.
Sourcepub fn active_screen(&self) -> Result<GhosttyTerminalScreen>
pub fn active_screen(&self) -> Result<GhosttyTerminalScreen>
Get the currently active screen.
Sourcepub fn is_mouse_tracking(&self) -> Result<bool>
pub fn is_mouse_tracking(&self) -> Result<bool>
Get whether any mouse tracking mode is active.
Returns true if any of the mouse tracking modes (X1inner, normal, button, or any-event) are enabled.
Sourcepub fn title(&self) -> Result<&str>
pub fn title(&self) -> Result<&str>
Get the terminal title as set by escape sequences (e.g. OSC inner/2).
Returns a borrowed string, valid until the next call to
Terminal::vt_write or Terminal::reset. An empty string is
returned when no title has been set.
Sourcepub fn pwd(&self) -> Result<&str>
pub fn pwd(&self) -> Result<&str>
Get the current working directory as set by escape sequences (e.g. OSC 7).
Returns a borrowed string, valid until the next call to
Terminal::vt_write or Terminal::reset. An empty string is
returned when no title has been set.
Sourcepub fn total_rows(&self) -> Result<usize>
pub fn total_rows(&self) -> Result<usize>
The total number of rows in the active screen including scrollback.
Sourcepub fn scrollback_rows(&self) -> Result<usize>
pub fn scrollback_rows(&self) -> Result<usize>
The number of scrollback rows (total rows minus viewport rows).
Source§impl<'alloc, 'cb> Terminal<'alloc, 'cb>
impl<'alloc, 'cb> Terminal<'alloc, 'cb>
Sourcepub fn on_pty_write(
&mut self,
f: impl PtyWriteFn<'alloc, 'cb>,
) -> Result<&mut Self>
pub fn on_pty_write( &mut self, f: impl PtyWriteFn<'alloc, 'cb>, ) -> Result<&mut Self>
Call the given function when the terminal needs to write data back to the pty (e.g. in response to a DECRQM query or device status report).
Sourcepub fn on_bell(&mut self, f: impl BellFn<'alloc, 'cb>) -> Result<&mut Self>
pub fn on_bell(&mut self, f: impl BellFn<'alloc, 'cb>) -> Result<&mut Self>
Call the given function when the terminal receives a BEL character (0x07).
Sourcepub fn on_enquiry(
&mut self,
f: impl EnquiryFn<'alloc, 'cb>,
) -> Result<&mut Self>
pub fn on_enquiry( &mut self, f: impl EnquiryFn<'alloc, 'cb>, ) -> Result<&mut Self>
Call the given function when the terminal receives an ENQ character (0x05).
Sourcepub fn on_xtversion(
&mut self,
f: impl XtversionFn<'alloc, 'cb>,
) -> Result<&mut Self>
pub fn on_xtversion( &mut self, f: impl XtversionFn<'alloc, 'cb>, ) -> Result<&mut Self>
Call the given function when the terminal receives an XTVERSION query (CSI > q), and respond with the resulting version string (e.g. “myterm 1.0”).
Sourcepub fn on_title_changed(
&mut self,
f: impl TitleChanged<'alloc, 'cb>,
) -> Result<&mut Self>
pub fn on_title_changed( &mut self, f: impl TitleChanged<'alloc, 'cb>, ) -> Result<&mut Self>
Call the given function when the terminal title changes via escape sequences (e.g. OSC 0 or OSC 2).
The new title can be queried from the terminal after the callback returns.
Sourcepub fn on_size(&mut self, f: impl SizeFn<'alloc, 'cb>) -> Result<&mut Self>
pub fn on_size(&mut self, f: impl SizeFn<'alloc, 'cb>) -> Result<&mut Self>
Call the given function in response to XTWINOPS size queries (CSI 14/16/18 t).
Sourcepub fn on_color_scheme(
&mut self,
f: impl ColorSchemeFn<'alloc, 'cb>,
) -> Result<&mut Self>
pub fn on_color_scheme( &mut self, f: impl ColorSchemeFn<'alloc, 'cb>, ) -> Result<&mut Self>
Call the given function in response to a color scheme device status report query (CSI ? 996 n).
Return Some to report the current color scheme,
or return None to silently ignore.
Sourcepub fn on_device_attributes(
&mut self,
f: impl DeviceAttributesFn<'alloc, 'cb>,
) -> Result<&mut Self>
pub fn on_device_attributes( &mut self, f: impl DeviceAttributesFn<'alloc, 'cb>, ) -> Result<&mut Self>
Call the given function in response to a device attributes query (CSI c, CSI > c, or CSI = c).
Return Some with the response data,
or return None to silently ignore.