Skip to main content

Terminal

Struct Terminal 

Source
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>

Source

pub fn new(opts: Options) -> Result<Self>

Create a new terminal instance.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn scroll_viewport(&mut self, scroll: ScrollViewport)

Scroll the terminal viewport.

Source

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.

Source

pub fn mode(&self, mode: Mode) -> Result<bool>

Get the current value of a terminal mode.

Source

pub fn set_mode(&mut self, mode: Mode, value: bool) -> Result<()>

Set the value of a terminal mode.

Source

pub fn cols(&self) -> Result<u16>

Get the terminal width in cells.

Source

pub fn rows(&self) -> Result<u16>

Get the terminal height in cells.

Source

pub fn cursor_x(&self) -> Result<u16>

Get the cursor column position (inner-indexed).

Source

pub fn cursor_y(&self) -> Result<u16>

Get the cursor row position within the active area (inner-indexed).

Source

pub fn is_cursor_pending_wrap(&self) -> Result<bool>

Get whether the cursor has a pending wrap (next print will soft-wrap).

Source

pub fn is_cursor_visible(&self) -> Result<bool>

Get whether the cursor is visible (DEC mode 25).

Source

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.

Source

pub fn kitty_keyboard_flags(&self) -> Result<KittyKeyFlags>

Get the current Kitty keyboard protocol flags.

Source

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.

Source

pub fn active_screen(&self) -> Result<GhosttyTerminalScreen>

Get the currently active screen.

Source

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.

Source

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.

Source

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.

Source

pub fn total_rows(&self) -> Result<usize>

The total number of rows in the active screen including scrollback.

Source

pub fn scrollback_rows(&self) -> Result<usize>

The number of scrollback rows (total rows minus viewport rows).

Source§

impl<'alloc, 'cb> Terminal<'alloc, 'cb>

Source

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).

Source

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).

Source

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).

Source

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”).

Source

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.

Source

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).

Source

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.

Source

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.

Trait Implementations§

Source§

impl<'alloc: 'cb, 'cb> Debug for Terminal<'alloc, 'cb>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for Terminal<'_, '_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'alloc, 'cb> Freeze for Terminal<'alloc, 'cb>

§

impl<'alloc, 'cb> !RefUnwindSafe for Terminal<'alloc, 'cb>

§

impl<'alloc, 'cb> !Send for Terminal<'alloc, 'cb>

§

impl<'alloc, 'cb> !Sync for Terminal<'alloc, 'cb>

§

impl<'alloc, 'cb> Unpin for Terminal<'alloc, 'cb>

§

impl<'alloc, 'cb> UnsafeUnpin for Terminal<'alloc, 'cb>

§

impl<'alloc, 'cb> !UnwindSafe for Terminal<'alloc, 'cb>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.