silk.system.terminal.

Read the size of a terminal, and switch it between its normal mode and raw mode.

When to use#

Use Terminal for a program that draws on the terminal or reads keys one at a time, such as an editor, a prompt, or the REPL of a JavaScript runtime. Read the mode with Terminal.mode before you change it, and give it back with Terminal.setMode before the program ends.

Details#

The functions take a raw descriptor of a terminal, such as 0 for standard input. They never open, close, or wait on the descriptor. A TerminalMode is a copy of the terminal settings (struct termios); TerminalMode.raw returns the same settings in raw mode, as libuv and Node.js define it: no line editing, no echo, no signals from keys such as Control-C, and reads that return each byte at once.

Errors#

Each function fails with TerminalError: the native error code, such as 25 (ENOTTY) for a descriptor that is not a terminal.

Gotchas#

  • A raw terminal stays raw after the program ends. Give back the earlier mode first.

  • Listen for SIGWINCH with silk.system.signal_watch to learn when the size changes.

  • The module is empty on targets other than Darwin on x86_64 or aarch64, and Linux with GNU libc on x86_64 or aarch64.

Examples#

Ask a descriptor that is not a terminal#

silk
import silk.core.effect { Effect }
import silk.mem.pointer { Pointer }
import silk.core.result { Result }
import silk.system.terminal { Terminal, TerminalError, WindowSize }

@foreign(noCapture: .("fds"))
unsafe extern "C" fn pipe(fds: ?[*]mut i32) -> i32

pub effect fn main() -> i32 {
  let mut fds: [i32; 2] = [-1, -1]
  if unsafe pipe(Pointer.fromMutSlice<i32>(&mut fds)) != 0 { return 1 }
  if Terminal.isTerminal(fds[0]) { return 1 }
  return match run Effect.result(Terminal.windowSize(fds[0])) {
    Result<WindowSize, TerminalError>.Success { .. } => 1
    // ENOTTY is 25 on Linux and Darwin.
    Result<WindowSize, TerminalError>.Failure { error } => if error.code == 25 { 0 } else { 1 }
  }
}

Import as Terminal with import silk.system.terminal { Terminal }.

Public declarations: 4.

TerminalError#

silk
pub struct TerminalError

A failed terminal operation, with the native error code.

Details#

code is the errno value of the failed system call, such as 25 (ENOTTY) for a descriptor that is not a terminal, or 9 (EBADF) for one that is not open.

Field code#

silk
pub code: i32

The native error code.

WindowSize#

silk
pub struct WindowSize

The size of a terminal in character cells.

Field columns#

silk
pub columns: u16

The number of columns.

Field rows#

silk
pub rows: u16

The number of rows.

Implementation Copy for WindowSize#

silk
impl Copy for WindowSize

TerminalMode#

silk
pub struct TerminalMode

A copy of the settings of a terminal, from Terminal.mode.

Details#

Keep the mode that you read first, and give it back with Terminal.setMode. Make a raw copy with TerminalMode.raw.

Implementation Copy for TerminalMode#

silk
impl Copy for TerminalMode

Implementation TerminalMode#

silk
impl TerminalMode

Method raw#

silk
pub fn raw(self: &Self) -> TerminalMode

Returns these settings in raw mode, as libuv and Node.js define it.

Details#

Raw mode turns off line editing, echo, the signals from keys such as Control-C and Control-Z, the translation of a carriage return to a newline on input, flow control with Control-S and Control-Q, and parity checks. Characters are 8 bits, and a read returns as soon as one byte is there. Output still turns a newline into a carriage return and a newline.

Terminal#

silk
pub struct Terminal

Functions on a terminal descriptor.

Implementation Terminal#

silk
impl Terminal

Associated function isTerminal#

silk
pub fn isTerminal(fd: i32) -> bool

Returns whether fd is an open descriptor of a terminal.

Associated function windowSize#

silk
pub effect fn windowSize(fd: i32) -> WindowSize ! TerminalError

Returns the size of the terminal fd in character cells.

Errors#

TerminalError with code 25 (ENOTTY) if fd is not a terminal, or 9 (EBADF) if it is not open.

Associated function mode#

silk
pub effect fn mode(fd: i32) -> TerminalMode ! TerminalError

Returns the current settings of the terminal fd.

Errors#

TerminalError with code 25 (ENOTTY) if fd is not a terminal, or 9 (EBADF) if it is not open.

Associated function setMode#

silk
pub effect fn setMode(fd: i32, mode: &TerminalMode) -> () ! TerminalError

Applies mode to the terminal fd, after the output that was written to it is sent.

Errors#

TerminalError with code 25 (ENOTTY) if fd is not a terminal, 9 (EBADF) if it is not open, or 5 (EIO) if the process is in the background of the terminal.

Category: System.

Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, x86_64-unknown-linux-gnu.

View the source of this page