Terminal
A program run from a terminal may want to colour its output, draw to the size of the window, read single keypresses or set the window title. This module tells it whether a terminal is there, how many colours it can show and how big it is, and lets it switch stdin into raw mode, set the title and hear about resizes.
A terminal here is a standard stream connected to a terminal device rather
than to a file or a pipe. configuration and setTitle act on stdout, and
setStdinRawMode on stdin: configuration gives Nothing and the other two
do nothing when that stream is not a terminal. There is therefore no setup
step, and none of the tasks can fail. configuration is how a program finds
out whether stdout is a terminal.
On the native backend on Windows, running any of these tasks, or subscribing
with onResize, stops the program with a fatal error saying it is not
supported there yet.
Configuration
type alias Configuration =
{ colorDepth : Int, columns : Int, rows : Int }configuration : Task x (Maybe Configuration)Gets the configuration of the terminal on stdout, or Nothing when stdout
is not a terminal, as when the output is redirected to a file or a pipe.
It reads the terminal again each time it is run, so a later run reports the current size.
Commands
setStdinRawMode : Bool -> Task x ()Switches stdin into raw mode with True, and back to its original mode with
False. It does nothing when stdin is not a terminal.
In its original mode a terminal usually hands input over a line at a time,
once the user presses enter. In raw mode every keypress is sent over the stdin
stream as it happens, and is not echoed. Key combinations such as Ctrl-C arrive
as input too, rather than raising a signal, so System.onSignalInterrupt does
not see them.
The original mode is the one stdin had when this was first run. It is restored
when the process exits, but on the native backend not when a fatal error stops
the program. It is also restored when the program is ended by an interrupt
(SIGINT) or terminate (SIGTERM) signal it does not subscribe to, unless,
on the native backend, the program is embedded in a host application, which
keeps its own signal handling; any other signal that ends the program leaves
raw mode on. While the program subscribes to that signal
with System.onSignalInterrupt or System.onSignalTerminate, the signal does
not end it and raw mode stays on.
setTitle : String -> Task x ()Sets the title of the terminal window, as shown in the title bar or tab of a terminal emulator.
It writes the title escape sequence (OSC 2) to stdout when stdout is a
terminal, and does nothing otherwise, so the sequence never ends up in a
redirected file or pipe. ASCII control characters, DEL included, are removed
from title first, so that none of them (BEL or ESC in particular) can end
the sequence early. Whether the title changes is up to the terminal, and a
failure to write is ignored.
Subscriptions
onResize : (Size -> msg) -> Sub msgCreates a subscription to changes in the size of the terminal, with the new size.
A size arrives each time the program receives SIGWINCH, the signal the
operating system sends when a terminal's window is resized, and may equal the
previous one. It is read as configuration reads its size, falling back to
the other standard streams also when stdout is not a terminal, and nothing
arrives when no standard stream reports one, or, on the native backend, when
the program is embedded in a host application. The subscription does not keep
the program running.
What is known about the terminal on stdout: how many colours it can show, and the size of its window in character cells.
colorDepthis a number of bits per colour:1for no colour,4for 16 colours,8for 256 colours and24for true colour. It is not asked of the terminal but guessed from the environment, by the first of these rules that applies:NO_COLOR, orTERM=dumb, gives1;FORCE_COLORset to exactly0,1,2or3gives1,4,8or24;COLORTERMset totruecoloror24bitgives24;TERMending in256colorgives8;4.The size is the one stdout reports or, when stdout reports a width of zero, the one another standard stream that is a terminal reports (stdin, then stderr, on the native backend; stderr on the JS backend).
columnsandrowsare both0when none can be read.