Components / content
Terminal builder
A terminal grid.
A builder is RenderOnce. Construct and mount it in one expression.
use gpui_kit::content::Terminal;
Reviewed in terminal.
Construct
new(ident: impl Into<Ident>) -> Self
Options
Chain onto the value.
state(state: TerminalState) -> Self
grid(grid: impl Fn(GridGeometry, &mut App) -> Option<GridSnapshot> + 'static) -> Self
focused(focused: bool) -> Self
scrollback(scrollback: bool) -> Self
on_event(handler: impl Fn(TerminalEvent, &mut Window, &mut App) + 'static) -> Self
Reports
The variants of the event it emits. It never applies the change itself.
- SelectionStarted
- SelectionUpdated
- SelectionCleared
- Scrolled
Example · terminal
fn terminal(_window: &mut Window, cx: &mut App) -> AnyElement {
/// A session's worth of output, chosen so every branch of the painter has
/// something to paint.
const SESSION: &[u8] = concat!(
"\x1b[32m>\x1b[0m cargo run -p xtask -- gate\r\n",
"\x1b[1mCompiling\x1b[0m gpui-box-kit v0.1.2\r\n",
"\x1b[2m dim text stays legible and stays dim\x1b[0m\r\n",
"\x1b[4munderlined\x1b[0m \x1b[7minverse\x1b[0m \x1b[44;97m on a background \x1b[0m\r\n",
"\x1b[30m0\x1b[31m1\x1b[32m2\x1b[33m3\x1b[34m4\x1b[35m5\x1b[36m6\x1b[37m7",
"\x1b[90m8\x1b[91m9\x1b[92ma\x1b[93mb\x1b[94mc\x1b[95md\x1b[96me\x1b[97mf\x1b[0m\r\n",
"\x1b[38;5;208m256-colour cube\x1b[0m and \x1b[38;2;120;200;255mtruecolour\x1b[0m\r\n",
"\x1b[32m>\x1b[0m ",
)
.as_bytes();
let theme = cx.theme().clone();
let panel = |ident: &'static str, state: TerminalState| {
div()
.w(px(400.0))
.h(px(180.0))
.child(Terminal::new(ident).state(state))
};
stack(&theme)
.child(
div().w(px(400.0)).h(px(180.0)).child(
Terminal::new("scene.terminal.ready")
.focused(true)
.grid(|geometry, _| {
let mut emulator = Emulator::new(geometry.cols, geometry.rows);
emulator.feed(SESSION);
// A selection over the middle of a coloured row, so the
// achromatic wash is reviewable against sixteen hues at
// once rather than against one.
emulator.start_selection(
SelectionKind::Drag,
emulator.grid_point(4, 0),
CellSide::Left,
);
emulator.update_selection(emulator.grid_point(4, 15), CellSide::Right);
Some(GridSnapshot {
lines: emulator.lines(),
cursor: emulator.cursor(),
})
})
.on_event(|_, _, _| {}),
),
)
.child(
row(&theme)
.items_start()
.child(panel("scene.terminal.starting", TerminalState::Loading))
.child(panel(
"scene.terminal.unavailable",
TerminalState::Unavailable("No shell is configured for this workspace.".into()),
)),
)
.child(
div().w(px(400.0)).h(px(180.0)).child(
Terminal::new("scene.terminal.ended")
.state(TerminalState::Error("The process exited with status 130.".into()))
.grid(|geometry, _| {
let mut emulator = Emulator::new(geometry.cols, geometry.rows);
emulator.feed(b"\x1b[32m>\x1b[0m tail -f build.log\r\n\x1b[31merror\x1b[0m: interrupted\r\n");
Some(GridSnapshot {
lines: emulator.lines(),
// Nothing is reading this grid any more, so there
// is no insertion point in it: a caret drawn under
// an exited process invites a keystroke that has
// nowhere to go.
cursor: None,
})
}),
),
)
.into_any_element()
}