NAME
    Term::Ghostty - Headless terminal emulator built on Ghostty's
    libghostty-vt

SYNOPSIS
        use Term::Ghostty;

        my $term = Term::Ghostty->new(
            cols         => 80,
            rows         => 24,
            on_pty_write => sub {
                my ($term, $bytes) = @_;
                syswrite $pty, $bytes;    # answers to terminal queries
            },
            on_title_changed => sub {
                my ($term, $title) = @_;
                print "title: $title\n";
            },
        );

        $term->feed($bytes_read_from_a_pty);
        $term->feed("Hello \e[31mGhostty\e[0m!\r\n");

        my $text = $term->get_text;                     # visible screen
        my $all  = $term->get_text(scrollback => 1);    # with history
        my $vt   = $term->get_vt(cursor => 1, style => 1);
        my $html = $term->get_html;

        my ($col, $row) = $term->cursor_pos;
        my $fullscreen  = $term->active_screen eq 'alternate';

        $term->resize(100, 30);

DESCRIPTION
    Term::Ghostty feeds a byte stream through the terminal emulation core of
    the Ghostty <https://ghostty.org/> terminal, "libghostty-vt", and lets
    you read back the resulting screen: its text, cursor and modes, or the
    screen re-encoded as plain text, VT sequences or HTML. There is no
    display; use it to drive or test programs running in a pseudo-terminal,
    to scrape their output, or to render captured terminal output.

    The library comes from Alien::ghostty. When that module builds it, which
    is the default, it is linked statically.

CONSTRUCTOR
  new
        my $term = Term::Ghostty->new(%options);

    Options:

    cols, rows
        Size in cells, 1 to 65535. Default 80 x 24.

    cell_width_px, cell_height_px
        Size of one cell in pixels, used only to answer pixel-size queries
        ("CSI 14 t") and in-band resize reports (mode 2048). Default 0.

    max_scrollback
        Roughly how many rows of history to keep. The library keeps and
        frees history in whole pages of a few hundred rows, so the number
        kept can be off by a page either way, and rows are counted at the
        current width. 0 disables the scrollback; undef keeps the default of
        about one page. Setting it also lifts the library's default memory
        cap, so memory use grows with the content.

    title, pwd
        Initial window title and working directory.

    on_pty_write, on_title_changed, on_bell, on_pwd_changed
        Callbacks, see "CALLBACKS".

    It croaks on an unknown option, an odd number of arguments, an
    out-of-range size, or a callback that is not a code reference.

METHODS
  feed
        $term->feed($data);

    Runs $data through the VT parser. A byte string is processed as raw
    bytes, which is what you read from a pseudo-terminal; a character string
    (one with the UTF-8 flag) is processed as its UTF-8 encoding. Escape
    sequences and multi-byte characters may be split across calls. Malformed
    UTF-8 shows up as U+FFFD.

    The emulator does not turn "\n" into "\r\n"; a pseudo-terminal's line
    discipline normally does that. When feeding text from a file or a pipe,
    convert the line endings yourself or enable linefeed mode with "\e[20h".

  write
    Same as "feed".

  write_until_ground
        my ($consumed, $at_ground) = $term->write_until_ground($data);
        my $consumed = $term->write_until_ground($data);

    Feeds only the shortest prefix of $data that brings the parser back to
    its ground state, the point between sequences where it is safe to inject
    your own output. $consumed is the number of bytes processed (of the
    UTF-8 encoding, for a character string, so split byte strings rather
    than character strings with it); the rest of $data is not processed, so
    feed it yourself. If the parser is already at ground, nothing is
    consumed. $at_ground is false when all of $data was consumed and the
    parser is still inside a sequence.

  format
        my $out = $term->format(%options);

    Returns the screen as a character string. Rows are joined with "\n"
    ("\r\n" for VT output); rows below the last one written to are omitted
    and rows are not padded to the terminal width.

    format => 'plain' | 'vt' | 'html'
        Plain text (the default), text with the VT sequences needed to
        reproduce its colours and attributes, or HTML. See "HTML OUTPUT".

    scrollback => 0 | 1
        Include the scrollback history before the visible screen. Default 0.

    trim => 0 | 1
        Remove trailing spaces from each row of plain output. Default 1.

    unwrap => 0 | 1
        Join rows that were soft-wrapped at the right margin. Default 0.

    palette => 0 | 1
        Include the colour palette: a "<style>" block for HTML (default 1),
        OSC 4 sequences for VT (default 0).

    The following options add terminal state to VT output, so that replaying
    it into a fresh terminal restores more than the text. They all default
    to 0: "cursor" (cursor position), "style" (the current SGR attributes),
    "modes", "scrolling_region", "tabstops", "pwd", "keyboard", "hyperlink",
    "protection", "kitty_keyboard" and "charsets".

    It croaks on an unknown option or an odd number of arguments.

  get_text
        my $text = $term->get_text(%options);

    Same as "format(%options, format => 'plain')".

  get_vt
    Same as "format(%options, format => 'vt')".

  get_html
    Same as "format(%options, format => 'html')".

  cols
    The terminal width in cells.

  rows
    The terminal height in cells.

  cursor_x
    The cursor column, counted from 0.

  cursor_y
    The cursor row, counted from 0 at the top of the visible screen.

  cursor_pos
        my ($col, $row) = $term->cursor_pos;
        my $pos = $term->cursor_pos;    # [$col, $row]

  cursor_visible
    True unless the cursor was hidden (DEC mode 25).

  cursor_pending_wrap
    True if the cursor is in the last column and the next character will
    wrap.

  title
        my $title = $term->title;

    The window title, set by OSC 0 or OSC 2 or by "set_title". An empty
    string when there is none.

  set_title
        $term->set_title($title);

    Sets the title; "undef" clears it. Does not call "on_title_changed".

  pwd
        my $url = $term->pwd;

    The working directory as reported by the program, usually through OSC 7.
    This is the raw value from the escape sequence, normally a URL such as
    "file://host/home/me/My%20Dir", not a decoded path. An empty string when
    there is none.

  set_pwd
        $term->set_pwd($url);

    Sets the working directory; "undef" clears it. Does not call
    "on_pwd_changed".

  resize
        $term->resize($cols, $rows);
        $term->resize($cols, $rows, $cell_width_px, $cell_height_px);

    Changes the size. Text on the primary screen is reflowed. The cell pixel
    size is kept when not given. If the program enabled in-band resize
    reports (mode 2048), the report is sent through "on_pty_write" during
    this call.

  reset
    Full reset (RIS): clears both screens and the scrollback, and restores
    the default modes, attributes, title and working directory. Callbacks
    and the size are kept.

  mode
        my $on = $term->mode(25);      # DEC private mode 25
        my $on = $term->mode(4, 1);    # ANSI mode 4

    Whether a mode is set. Returns undef for a mode the terminal does not
    know, and croaks if the number is not between 0 and 32767.

  active_screen
    'primary' or 'alternate'. Full-screen programs such as editors and
    pagers normally switch to the alternate screen.

  mouse_tracking
    True if the program enabled any mouse reporting mode.

  scrollback_rows
    Number of rows in the scrollback history.

  lib_version
        my $version = Term::Ghostty->lib_version;

    The version of the linked libghostty-vt.

  on_pty_write
        my $old = $term->on_pty_write(sub { ... });
        $term->on_pty_write(undef);
        my $cb = $term->on_pty_write;

    Gets or replaces the callback; with an argument, returns the previous
    one. See "CALLBACKS".

  on_title_changed
    Like "on_pty_write", for the title callback.

  on_bell
    Like "on_pty_write", for the bell callback.

  on_pwd_changed
    Like "on_pty_write", for the working directory callback.

CALLBACKS
    on_pty_write($term, $bytes)
        Bytes the terminal sends back to the program: answers to status
        queries, mode reports and so on. Write them to the pseudo-terminal.
        $bytes is a byte string.

    on_title_changed($term, $title)
        The title was changed by OSC 0 or OSC 2.

    on_bell($term)
        A BEL character (0x07) outside an escape sequence.

    on_pwd_changed($term, $url)
        The working directory was reported by OSC 7, OSC 9;9 or OSC 1337
        CurrentDir. See "pwd" for the format.

    Callbacks run synchronously inside "feed", "write", "write_until_ground"
    and "resize". Inside a callback the terminal can be read, and callbacks
    can be replaced, but methods that change it ("feed", "write",
    "write_until_ground", "resize", "reset", "set_title", "set_pwd") croak.

    If a callback dies, the rest of the input is still processed, the
    remaining callbacks of that call are skipped, and the method rethrows
    the first error once the library has returned.

    Use the terminal passed as the first argument instead of closing over
    the variable that holds it; a closure over that variable creates a
    reference cycle and the terminal is never freed.

QUERIES
    With "on_pty_write" set, the terminal answers device attribute queries
    (primary as a VT220 with ANSI colour, "CSI ? 62 ; 22 c", secondary and
    tertiary), device status and cursor position reports, mode and setting
    queries (DECRQM, DECRQSS), palette colour queries (OSC 4), XTVERSION,
    the Kitty keyboard query, window size queries ("CSI 14 t", "CSI 16 t",
    "CSI 18 t"; pixel sizes are 0 unless a cell size was given) and in-band
    resize reports. Default colour queries (OSC 10 and 11), clipboard reads
    (OSC 52), ENQ and the colour scheme query ("CSI ? 996 n") are not
    answered.

ENCODING
    "feed" takes bytes or characters as described above. "format" and its
    wrappers, "title" and "pwd" return character strings; malformed UTF-8
    coming from the program is replaced by U+FFFD. "on_pty_write" receives
    bytes.

HTML OUTPUT
    HTML output is a "<div>" with inline styles. Palette colours refer to
    the CSS variables "--vt-palette-0" to "--vt-palette-255", which the
    "<style>" block emitted by default defines on ":root"; pass "palette =>
    0" to define them yourself. Text is HTML-escaped. Hyperlinks (OSC 8)
    become "<a href>"; links whose URL does not start with "http://",
    "https://", "ftp://", "mailto:" or "file://" are emitted without the
    "href", so a program cannot plant "javascript:" links in the page.

THREADS
    A terminal belongs to the thread that created it. New threads get an
    unusable copy; create a separate terminal in each thread. Terminals
    cannot be serialized or cloned with Storable.

EXAMPLES
    The examples directory of the distribution has scripts that drive
    programs in a pseudo-terminal, convert ANSI output to HTML, replay
    asciinema recordings and more.

SEE ALSO
    Alien::ghostty, Term::VTerm, Ghostty <https://ghostty.org/>

AUTHOR
    vividsnow

COPYRIGHT AND LICENSE
    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

    libghostty-vt, which is linked into this module, is copyright Mitchell
    Hashimoto and the Ghostty contributors and is distributed under the MIT
    license. It includes third-party code, such as simdutf, Highway and
    Wuffs, under their own permissive licenses; see its source for the
    texts.

