pub struct Engine { /* private fields */ }Expand description
The terminal engine: pairs the vte parser with our state model.
Parser and Term are kept as separate fields because Parser::advance
borrows both the parser and the performer mutably at once — a single struct
owning both could not satisfy the borrow checker.
Implementations§
Source§impl Engine
impl Engine
Sourcepub fn new(cols: usize, rows: usize) -> Self
pub fn new(cols: usize, rows: usize) -> Self
A blank engine with a cols × rows screen and a default scrollback cap.
Sourcepub fn with_scrollback(
cols: usize,
rows: usize,
scrollback_limit: usize,
) -> Self
pub fn with_scrollback( cols: usize, rows: usize, scrollback_limit: usize, ) -> Self
Like Engine::new but with an explicit scrollback line limit.
Sourcepub fn feed(&mut self, bytes: &[u8])
pub fn feed(&mut self, bytes: &[u8])
Push a slice of VT bytes. The caller owns the PTY/SSH/socket I/O — the engine only consumes the bytes it is handed.
Sourcepub fn resize(&mut self, cols: usize, rows: usize)
pub fn resize(&mut self, cols: usize, rows: usize)
Resize the screen to cols x rows. Rows that scroll off the top enter
scrollback; the whole screen is damaged. (Soft-wrap reflow lands in #7.)
Sourcepub fn bracketed_paste(&self) -> bool
pub fn bracketed_paste(&self) -> bool
Whether bracketed-paste mode (DEC ?2004) is enabled. A consumer’s input encoder reads this to decide whether to wrap pasted text in markers.
Sourcepub fn encode_key(&self, ev: KeyEvent) -> Option<Vec<u8>>
pub fn encode_key(&self, ev: KeyEvent) -> Option<Vec<u8>>
Encode a key event to the bytes an application expects, honouring the
engine’s cursor-key mode (DECCKM). The inverse of Engine::feed — the
consumer hands a decoded key event and writes the bytes to its PTY.
Returns None for a key with no defined encoding.
Sourcepub fn encode_mouse(&self, ev: MouseEvent) -> Option<Vec<u8>>
pub fn encode_mouse(&self, ev: MouseEvent) -> Option<Vec<u8>>
Encode a mouse event using the engine’s active tracking mode + encoding.
Returns None when mouse reporting is off, or when the event is filtered
out by the mode (e.g. a bare move while only ?1000 is set).
Sourcepub fn encode_paste(&self, text: &str) -> Vec<u8> ⓘ
pub fn encode_paste(&self, text: &str) -> Vec<u8> ⓘ
Encode pasted text — wrapped in bracketed-paste markers when ?2004 is on, raw otherwise.
Sourcepub fn encode_focus(&self, focused: bool) -> Option<Vec<u8>>
pub fn encode_focus(&self, focused: bool) -> Option<Vec<u8>>
Encode a focus change (CSI I on focus-in, CSI O on focus-out), or
None when focus reporting (?1004) is off.
Sourcepub fn drain_events(&mut self) -> Vec<TermEvent>
pub fn drain_events(&mut self) -> Vec<TermEvent>
Take the consumer events accumulated since the last drain (title / bell /
cwd — see TermEvent), emptying the queue. The pull counterpart to a
callback: poll this alongside Engine::frame.
Sourcepub fn drain_replies(&mut self) -> Vec<u8> ⓘ
pub fn drain_replies(&mut self) -> Vec<u8> ⓘ
Take the reply bytes the engine produced for app queries (DA / DSR /
DECRQM) since the last drain — the consumer writes them straight back to
the PTY. The inbound-query counterpart to Engine::drain_events.
Sourcepub fn link_at(&self, row: usize, col: usize) -> Option<NonZeroU32>
pub fn link_at(&self, row: usize, col: usize) -> Option<NonZeroU32>
The OSC 8 hyperlink index at screen (row, col) — the live grid, same
coordinates as Engine::grid’s cell(row, col) — or None. Combining
and links no longer ride on the Cell (#45/#46); read the
index here, then resolve it with Engine::hyperlink.
Sourcepub fn underline_color_at(&self, row: usize, col: usize) -> Color
pub fn underline_color_at(&self, row: usize, col: usize) -> Color
The underline colour (SGR 58, #520) at screen (row, col) — same
coordinates as Engine::grid’s cell(row, col). A theme-agnostic
Color reference; Color::Default means the underline follows the
glyph’s foreground (the common case, and what a cell with no SGR 58 returns).
Like the hyperlink, the colour rides a per-row side table, not the 12-byte
Cell (#520).
Sourcepub fn viewport_link_at(&self, row: usize, col: usize) -> Option<NonZeroU32>
pub fn viewport_link_at(&self, row: usize, col: usize) -> Option<NonZeroU32>
The OSC 8 hyperlink index at viewport (row, col) — the visible
window including scrollback at the current scroll, same coordinates as
Engine::viewport_line — or None.
Sourcepub fn hyperlink(&self, link: NonZeroU32) -> Option<&str>
pub fn hyperlink(&self, link: NonZeroU32) -> Option<&str>
Resolve a hyperlink index (from Engine::link_at /
Engine::viewport_link_at, or a decoded Span’s links) to its URI,
to make a cell clickable.
Sourcepub fn scrollback_len(&self) -> usize
pub fn scrollback_len(&self) -> usize
Number of lines currently held in scrollback history.
Sourcepub fn synchronized_output(&self) -> bool
pub fn synchronized_output(&self) -> bool
Whether the app has an open synchronized-output block (DEC ?2026):
it has asked that the next frame of output be painted atomically. The
engine only reports this — the consumer owns the paint-hold and the
spec-mandated timeout (a buggy app that never closes the block must not
freeze the screen forever, and the engine has no clock). Poll this after
feed; while it is true, defer applying frames, and apply once it
clears (or your own timeout fires). (#73)
Sourcepub fn color_scheme_updates(&self) -> bool
pub fn color_scheme_updates(&self) -> bool
Whether the app enabled color-scheme-update notifications (DEC ?2031).
The engine is theme-agnostic — it never knows the scheme. The consumer
answers a TermEvent::ColorSchemeQuery (from ?996) and, when its
scheme changes and this is true, sends an unsolicited notification, in
both cases by calling Engine::report_color_scheme (#85).
Sourcepub fn report_color_scheme(&mut self, dark: bool)
pub fn report_color_scheme(&mut self, dark: bool)
Report the current light/dark color scheme to the app as CSI ? 997 ; 1 n
(dark) / ; 2 n (light), drained via Engine::drain_replies. Call this
to answer a TermEvent::ColorSchemeQuery, or — guarded by
Engine::color_scheme_updates — when the scheme changes. The engine only
formats the bit you pass; it stores no scheme (#85).
Sourcepub fn report_background(&mut self, spec: &str)
pub fn report_background(&mut self, spec: &str)
Answer an OSC 11 QueryBackground event (#122): the consumer hands back
the current background spec (it owns the palette) and the engine queues
the OSC 11 reply for drain_replies. Theme-agnostic — the engine never
knows the colour, only formats the envelope.
Sourcepub fn report_foreground(&mut self, spec: &str)
pub fn report_foreground(&mut self, spec: &str)
Answer an OSC 10 QueryForeground event (#122): queue the OSC 10 reply
from the consumer-supplied spec. Theme-agnostic envelope-only.
Sourcepub fn report_palette_color(&mut self, index: u8, spec: &str)
pub fn report_palette_color(&mut self, index: u8, spec: &str)
Answer an OSC 4 QueryPaletteColor event (#122): queue the OSC 4 reply for
index from the consumer-supplied spec. Theme-agnostic envelope-only.
Sourcepub fn win32_input_mode(&self) -> bool
pub fn win32_input_mode(&self) -> bool
Whether the app enabled win32-input-mode (DEC ?9001): it asked for
keys as raw Windows key-records. The engine only tracks the flag — encoding
the records (CSI Vk;Sc;Uc;Kd;Cs;Rc _) is a non-goal (raw passthrough, no
semantic conversion), so Engine::encode_key is unchanged. A ConPTY
consumer reads this to decide whether to emit the records itself (#86).
Sourcepub fn damage(&self) -> TermDamage
pub fn damage(&self) -> TermDamage
What changed since the last Engine::reset_damage — line ranges each
with a changed column span (see ADR-0003).
Sourcepub fn frame(&self) -> Frame
pub fn frame(&self) -> Frame
Build a serializable Frame of the current diff — the damaged spans
(or every row, when Full), the recorded scroll op, and a frame-local
grapheme side-table. Pass it to encode for the wire (see #6). Reading
a frame does not clear damage; call Engine::reset_damage on ack.
Sourcepub fn reset_damage(&mut self)
pub fn reset_damage(&mut self)
Clear accumulated damage after a frame is applied (the consumer’s ack).
Sourcepub fn mark_fully_damaged(&mut self)
pub fn mark_fully_damaged(&mut self)
Force the next Engine::frame to be a Full frame (every row), even if
little changed. The use case is reattach / late subscribe: a renderer
that connects after output has already been parsed needs the whole current
viewport once, then incremental diffs. Marks the screen fully damaged; the
next frame() reports FrameKind::Full.
Sourcepub fn scroll_delta(&self) -> Option<ScrollOp>
pub fn scroll_delta(&self) -> Option<ScrollOp>
The first-class scroll recorded since the last Engine::reset_damage,
if any — lets the renderer shift rows instead of redrawing them.
Sourcepub fn viewport_line(&self, i: usize) -> &[Cell]
pub fn viewport_line(&self, i: usize) -> &[Cell]
The cells of visible row i (0..rows) at the current scroll position.
Sourcepub fn scroll_up(&mut self, n: usize)
pub fn scroll_up(&mut self, n: usize)
Scroll the viewport up by n lines into scrollback history.
Sourcepub fn scroll_down(&mut self, n: usize)
pub fn scroll_down(&mut self, n: usize)
Scroll the viewport down by n lines toward the live screen.
Sourcepub fn scroll_to_bottom(&mut self)
pub fn scroll_to_bottom(&mut self)
Jump the viewport back to the live screen (follow the bottom).
Sourcepub fn selection_begin(
&mut self,
row: usize,
col: usize,
side: Side,
ty: SelectionType,
)
pub fn selection_begin( &mut self, row: usize, col: usize, side: Side, ty: SelectionType, )
Begin a selection of ty at viewport cell (row, col), on side of the
cell. Coordinates are viewport-relative (what a mouse event carries).
Sourcepub fn selection_extend(&mut self, row: usize, col: usize, side: Side)
pub fn selection_extend(&mut self, row: usize, col: usize, side: Side)
Extend the live selection to viewport cell (row, col), on side.
Sourcepub fn selection_clear(&mut self)
pub fn selection_clear(&mut self)
Clear the selection.
Sourcepub fn selection_range(&self) -> Vec<SelectionSpan>
pub fn selection_range(&self) -> Vec<SelectionSpan>
The selection projected onto the viewport: one inclusive-column span per visible row, for the renderer to highlight. Empty when nothing is selected or the selection is fully scrolled off-screen.
Sourcepub fn selection_text(&self) -> Option<String>
pub fn selection_text(&self) -> Option<String>
The selected text for copy (respects scrollback), or None if no
selection.
Sourcepub fn search(&self, query: &str) -> Vec<Match>
pub fn search(&self, query: &str) -> Vec<Match>
Literal search over the grid + scrollback, returning every match in
absolute buffer coordinates (top-to-bottom). Smart-case: a query with no
uppercase matches case-insensitively. The consumer drives next/prev by
walking the returned Vec and calling Engine::scroll_to_match.
Sourcepub fn search_with(&self, query: &str, opts: SearchOptions) -> Vec<Match>
pub fn search_with(&self, query: &str, opts: SearchOptions) -> Vec<Match>
Search with explicit SearchOptions — regex, whole-word, and a case-sensitivity override
beyond the literal + smart-case search (#314).
Sourcepub fn viewport_logical_lines(&self) -> Vec<LogicalLine>
pub fn viewport_logical_lines(&self) -> Vec<LogicalLine>
The viewport’s logical lines (#113/ADR-0017): each soft-wrap-joined line’s
text plus a per-char map to its viewport (row, col). The buffer-wide
mechanism for consumer-side URL detection — the consumer runs its own
regex / new URL() over the text and maps matches back through cells.
Also serves the a11y mirror (#119).
Sourcepub fn accessible_text(&self) -> String
pub fn accessible_text(&self) -> String
The whole buffer (scrollback + screen) as one text document for a
screen-reader accessible view (#150) — soft-wrap-joined, wide-spacers
skipped, trailing blanks trimmed at the logical end, \n between logical
lines. A query seam the consumer summons (frame mode: over IPC, like
selection_text); no wire-format change. On the
alt screen only the alt buffer is shown.
Sourcepub fn scroll_to_match(&mut self, m: &Match)
pub fn scroll_to_match(&mut self, m: &Match)
Scroll the viewport so m is visible (next/prev navigation: the consumer
picks the match, the engine scrolls to it).
Sourcepub fn match_spans(&self, m: &Match) -> Vec<SelectionSpan>
pub fn match_spans(&self, m: &Match) -> Vec<SelectionSpan>
The match projected onto the viewport as inclusive-column spans per visible row, for the renderer to highlight.
Sourcepub fn set_search_highlights(&mut self, matches: Vec<Match>)
pub fn set_search_highlights(&mut self, matches: Vec<Match>)
Set the search highlights the frame should carry (#108). The
consumer owns match navigation, so it hands the set to highlight back
here; Engine::frame then projects them onto the viewport overlay
alongside the selection. An empty vec clears the highlights.
Sourcepub fn set_active_search_highlight(&mut self, index: Option<usize>)
pub fn set_active_search_highlight(&mut self, index: Option<usize>)
Designate which member of the held highlight set is the active match
(#428) — the one next/prev navigation currently points at (that choice is
the consumer’s policy). Engine::frame projects it into the overlay’s
active_match group; it also stays in matches, and the renderer’s
highlight ranking resolves the overlap (#424). None or an out-of-range
index projects nothing. Passing a new set to
set_search_highlights resets the
designation, so re-designate after every hand-over.
Sourcepub fn set_active_search_match(&mut self, m: Option<Match>)
pub fn set_active_search_match(&mut self, m: Option<Match>)
Designate the active match by its absolute span (#436), independent of
the held highlight set — the past-cap path. A backend that caps its
hand-over (the documented 1000, xterm’s highlightLimit) can still give
the current match its active emphasis: xterm builds its active
decoration from the found result outside the capped list, and this is
that model. The span projects through the same wrap-aware viewport math
as any match; past the cap it paints the ACTIVE colour only (no plain
highlight underneath — honest about the cap). None clears. Same
lifecycle as the index form: reset on every
set_search_highlights hand-over and on
any coordinate-shifting invalidation (eviction, region scroll, reflow,
alt-screen swaps), so re-designate after each hand-over.
Sourcepub fn add_marker(&mut self, row: usize) -> MarkerId
pub fn add_marker(&mut self, row: usize) -> MarkerId
Register a decoration marker at viewport row, returning its stable id
(#118). The marker anchors the content currently on that row and tracks
it through scroll/eviction/reflow; Engine::frame reports its viewport
position while visible. Use the id to remove it or to match the
TermEvent::MarkerDisposed fired when its line leaves the buffer.
Sourcepub fn remove_marker(&mut self, id: MarkerId)
pub fn remove_marker(&mut self, id: MarkerId)
Remove a marker by id (#118), firing TermEvent::MarkerDisposed. A no-op
for an unknown or already-disposed id.
Sourcepub fn command_marks(&self) -> Vec<(MarkerId, usize, MarkerKind)>
pub fn command_marks(&self) -> Vec<(MarkerId, usize, MarkerKind)>
The OSC 133 shell-integration command marks in buffer order — (id, absolute line, kind) (#158). Excludes plain add_marker decorations.
The consumer pairs prompt/command/finished marks to drive prompt-to-prompt
navigation and command/exit announcements (#160); the engine only parses
the 133;A/B/C/D sequences and anchors the marks.
Sourcepub fn command_lines(&self) -> Vec<CommandLine>
pub fn command_lines(&self) -> Vec<CommandLine>
The executed shell commands recovered from OSC-133 marks, in buffer order
(#166) — the query behind screen-reader command navigation. Each
CommandLine carries the typed command text (prompt/output excluded via
the captured columns), its jump line (CommandStart), and the exit code.
This is a full-buffer query, wired to the frame-mode consumer over IPC like
Engine::accessible_text; the web side has no scrollback cells to derive
it (ADR-0017 — buffer-wide text is core’s).