///|
/// Terminal output command.
///
/// A `Command` is inert data. It only writes bytes when passed to
/// `Tty::execute`.
pub(all) enum Command {
Print(StringView)
EnterAltScreen
LeaveAltScreen
BeginSynchronizedUpdate
EndSynchronizedUpdate
EnableBracketedPaste
DisableBracketedPaste
EnableFocusTracking
DisableFocusTracking
EnableAutoWrap
DisableAutoWrap
PushKeyboardEnhancementFlags(KeyboardEnhancementFlags)
PopKeyboardEnhancementFlags
HideCursor
ShowCursor
CursorUp(Int)
CursorDown(Int)
CursorForward(Int)
CursorBack(Int)
CursorNextLine(Int)
CursorPrevLine(Int)
CursorHorizontalAbsolute(Int)
CursorPosition(Int, Int)
EraseLineAll
EraseLineLeft
EraseLineRight
EraseDisplay
EraseScrollback
SetTopBottomMargins(Int, Int)
ResetTopBottomMargins
ReverseIndex
SetForeground(@color.Color)
SetBackground(@color.Color)
ResetForeground
ResetBackground
SetBold
ResetBold
SetItalic
ResetItalic
SetUnderline
ResetUnderline
SetReverse
ResetReverse
ResetStyle
}
///|
fn Command::write_to(self : Command, buf : @buffer.Buffer) -> Unit {
match self {
Print(text) => buf.write_string_utf8(text)
EnterAltScreen => buf.write_bytes(@vt.enter_alt_screen)
LeaveAltScreen => buf.write_bytes(@vt.leave_alt_screen)
BeginSynchronizedUpdate => buf.write_bytes(@vt.begin_synchronized_update)
EndSynchronizedUpdate => buf.write_bytes(@vt.end_synchronized_update)
EnableBracketedPaste => buf.write_bytes(@vt.enable_bracketed_paste)
DisableBracketedPaste => buf.write_bytes(@vt.disable_bracketed_paste)
EnableFocusTracking => buf.write_bytes(@vt.enable_focus_tracking)
DisableFocusTracking => buf.write_bytes(@vt.disable_focus_tracking)
EnableAutoWrap => buf.write_bytes(@vt.enable_auto_wrap)
DisableAutoWrap => buf.write_bytes(@vt.disable_auto_wrap)
PushKeyboardEnhancementFlags(flags) =>
@vt.write_push_keyboard_enhancement_flags(buf, flags.bits())
PopKeyboardEnhancementFlags =>
buf.write_bytes(@vt.pop_keyboard_enhancement_flags)
HideCursor => buf.write_bytes(@vt.hide_cursor)
ShowCursor => buf.write_bytes(@vt.show_cursor)
CursorUp(n) => @vt.write_cursor_up(buf, n)
CursorDown(n) => @vt.write_cursor_down(buf, n)
CursorForward(n) => @vt.write_cursor_forward(buf, n)
CursorBack(n) => @vt.write_cursor_back(buf, n)
CursorNextLine(n) => @vt.write_cursor_next_line(buf, n)
CursorPrevLine(n) => @vt.write_cursor_prev_line(buf, n)
CursorHorizontalAbsolute(n) => @vt.write_cursor_horizontal_absolute(buf, n)
CursorPosition(row, col) => @vt.write_cursor_position(buf, row, col)
EraseLineAll => buf.write_bytes(@vt.erase_line_all)
EraseLineLeft => buf.write_bytes(@vt.erase_line_left)
EraseLineRight => buf.write_bytes(@vt.erase_line_right)
EraseDisplay => buf.write_bytes(@vt.erase_display)
EraseScrollback => buf.write_bytes(@vt.erase_scrollback)
SetTopBottomMargins(top, bottom) =>
@vt.write_set_top_bottom_margins(buf, top, bottom)
ResetTopBottomMargins => buf.write_bytes(@vt.reset_top_bottom_margins)
ReverseIndex => buf.write_bytes(@vt.reverse_index)
SetForeground(color) => @vt.write_set_foreground(buf, color)
SetBackground(color) => @vt.write_set_background(buf, color)
ResetForeground => buf.write_bytes(@vt.reset_foreground)
ResetBackground => buf.write_bytes(@vt.reset_background)
SetBold => buf.write_bytes(@vt.bold)
ResetBold => buf.write_bytes(@vt.reset_bold)
SetItalic => buf.write_bytes(@vt.italic)
ResetItalic => buf.write_bytes(@vt.reset_italic)
SetUnderline => buf.write_bytes(@vt.underline)
ResetUnderline => buf.write_bytes(@vt.reset_underline)
SetReverse => buf.write_bytes(@vt.reverse)
ResetReverse => buf.write_bytes(@vt.reset_reverse)
ResetStyle => buf.write_bytes(@vt.reset_style)
}
}
///|
/// Execute terminal output commands with one serialized write.
pub async fn Tty::execute(self : Self, commands : Array[Command]) -> Unit {
if commands.length() == 0 {
return
}
let buf = @buffer.Buffer()
for command in commands {
command.write_to(buf)
}
self.write(buf.to_bytes())
}