Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
- Basic data types
- Cursor movement by character
- Cursor movement by line
- Directly changing cursor position
- Saving, restoring and reporting cursor position
- Clearing parts of the screen
- Scrolling the screen
- Using screen buffers
- Reporting the background or foreground colors
- Select Graphic Rendition mode: colors and other whizzy stuff
- Cursor visibilty changes
- Hyperlinks
- Changing the title
- Checking if handle supports ANSI (not portable: GHC only)
- Getting the cursor position
- Getting the terminal size
- Getting the background or foreground colors
Introduction
Through this module, this library provides platform-independent support for control character sequences following the 'ANSI' standards (see further below) for terminal software that supports those sequences, running on a Unix-like operating system or on Windows (see further below).
The sequences of control characters (also referred to as 'escape' sequences or codes) provide a rich range of functionality for terminal control, which includes:
- Colored text output, with control over both foreground and background colors
- Clearing parts of a line or the screen
- Hiding or showing the cursor
- Moving the cursor around
- Reporting the position of the cursor
- Scrolling the screen up or down
- Switching between the Alternate and Normal Screen Buffers
- Clickable hyperlinks to URIs
- Changing the title of the terminal
A terminal that supports control character sequences acts on them when they
are flushed from the output buffer (with a newline character "\n"
or, for
the standard output channel, hFlush stdout
).
'ANSI' standards
The 'ANSI' standards refer to (1) standard ECMA-48 `Control Functions for Coded Character Sets' (5th edition, 1991); (2) extensions in ITU-T Recommendation (previously CCITT Recommendation) T.416 (03/93) 'Information Technology – Open Document Architecture (ODA) and Interchange Format: Character Content Architectures` (also published as ISO/IEC International Standard 8613-6); and (3) further extensions used by 'XTerm', a terminal emulator for the X Window System. The escape codes are described in a Wikipedia article at http://en.wikipedia.org/wiki/ANSI_escape_code and those codes supported on current versions of Windows at https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences.
The whole of the 'ANSI' standards are not supported by this library but most (if not all) of the parts that are popular and well-supported by terminal software are supported (see further below).
Cursor positions
The functions moving the cursor to an absolute position are 0-based (the
top-left corner is considered to be at row 0 column 0) (see setCursorPosition
)
and so is getCursorPosition
. The 'ANSI' standards themselves are 1-based
(that is, the top-left corner is considered to be at row 1 column 1) and some
functions reporting the position of the cursor are too (see
reportCursorPosition
).
Windows and control character sequences
The native terminal software on Windows has developed over time. Before Windows 10 version 1511 (known as the 'November [2015] Update' or 'Threshold 2') that software did not support control character sequences. For that software, this library also provides support for such sequences by using emulation based on the Windows Console API. From 2018, Microsoft introduced the Windows Pseudo Console ('ConPTY') API and then Windows Terminal, with the objective of replacing most of the Windows Console API with the use of control character sequences and retiring the historical user-interface role of Windows Console Host ('ConHost').
Terminal software other than the native software exists for Windows. One example is the 'mintty' terminal emulator for 'Cygwin', 'MSYS' or 'MSYS2', and dervied projects, and for 'WSL' (Windows Subsystem for Linux).
GHC's management of input and output (IO) on Windows has also developed over
time. If they are supported by the terminal software, some control character
sequences cause data to be emitted into the console input stream. For GHC's
historical and default IO manager, the function hGetBufNonBlocking
in module
System.IO does not work on Windows. This has been attributed to the lack of
non-blocking primatives in the operating system (see the GHC bug report #806 at
https://ghc.haskell.org/trac/ghc/ticket/806). GHC's native IO manager on
Windows ('WinIO'), introduced as a preview in
GHC 9.0.1,
has not yet provided a solution. On Windows, this library uses emulation based
on the Windows Console API to try to read data emitted into the console input
stream. Functions that use that emulation are not supported on consoles, such
as mintty, that are not based on that API.
Function variants provided
Every function exported by this module comes in three variants, namely:
- A variant that has an
IO ()
type and doesn't take aHandle
(for example,clearScreen :: IO ()
). This variant just outputs the `ANSI` command directly to the standard output channel (stdout
) and any terminal corresponding to it. Commands issued like this should work as you expect on both Unix-like operating systems and Windows (unless exceptions on Windows are stated). - An '
h
...' variant that has anIO ()
type but takes aHandle
(for example,hClearScreen :: Handle -> IO ()
). This variant outputs the `ANSI` command to the supplied handle and any terminal corresponding to it. Commands issued like this should also work as you expect on both Unix-like operating systems and Windows (unless exceptions on Windows are stated). - A '...
Code
' variant that has aString
type (for example,clearScreenCode :: String
). This variant outputs the sequence of control characters as aString
, which can be added to any other bit of text before being output. If a high degree of backwards compatability is rewuired, the use of these codes is discouraged because they will not work on legacy versions of Windows where the terminal in use is not ANSI-enabled (see further above). On Windows, where emulation has been necessary, these variants will always output the empty string. That is done so that it is possible to use them portably; for example, coloring console output on the understanding that you will see colors only if you are running on a Unix-like operating system or a version of Windows where emulation has not been necessary. If the control characters are always required, see module System.Console.ANSI.Codes.
Examples of use
A simple example is below:
module Main where import System.Console.ANSI -- Set colors and write some text in those colors. main :: IO () main = do setSGR [SetColor Foreground Vivid Red] setSGR [SetColor Background Vivid Blue] putStrLn "Red-On-Blue" setSGR [Reset] -- Reset to default colour scheme putStrLn "Default colors."
Another example is below:
module Main where import System.IO (hFlush, stdout) import System.Console.ANSI main :: IO () main = do setSGR [SetColor Foreground Dull Blue] putStr "Enter your name: " setSGR [SetColor Foreground Dull Yellow] hFlush stdout -- flush the output buffer before getLine name <- getLine setSGR [SetColor Foreground Dull Blue] putStrLn $ "Hello, " ++ name ++ "!" setSGR [Reset] -- reset to default colour scheme
For many more examples, see the project's extensive Example.hs file.
Synopsis
- module System.Console.ANSI.Types
- cursorUp :: Int -> IO ()
- cursorDown :: Int -> IO ()
- cursorForward :: Int -> IO ()
- cursorBackward :: Int -> IO ()
- hCursorUp :: Handle -> Int -> IO ()
- hCursorDown :: Handle -> Int -> IO ()
- hCursorForward :: Handle -> Int -> IO ()
- hCursorBackward :: Handle -> Int -> IO ()
- cursorUpCode :: Int -> String
- cursorDownCode :: Int -> String
- cursorForwardCode :: Int -> String
- cursorBackwardCode :: Int -> String
- cursorUpLine :: Int -> IO ()
- cursorDownLine :: Int -> IO ()
- hCursorUpLine :: Handle -> Int -> IO ()
- hCursorDownLine :: Handle -> Int -> IO ()
- cursorUpLineCode :: Int -> String
- cursorDownLineCode :: Int -> String
- setCursorColumn :: Int -> IO ()
- setCursorPosition :: Int -> Int -> IO ()
- hSetCursorColumn :: Handle -> Int -> IO ()
- hSetCursorPosition :: Handle -> Int -> Int -> IO ()
- setCursorColumnCode :: Int -> String
- setCursorPositionCode :: Int -> Int -> String
- saveCursor :: IO ()
- restoreCursor :: IO ()
- reportCursorPosition :: IO ()
- hSaveCursor :: Handle -> IO ()
- hRestoreCursor :: Handle -> IO ()
- hReportCursorPosition :: Handle -> IO ()
- saveCursorCode :: String
- restoreCursorCode :: String
- reportCursorPositionCode :: String
- clearFromCursorToScreenEnd :: IO ()
- clearFromCursorToScreenBeginning :: IO ()
- clearScreen :: IO ()
- clearFromCursorToLineEnd :: IO ()
- clearFromCursorToLineBeginning :: IO ()
- clearLine :: IO ()
- hClearFromCursorToScreenEnd :: Handle -> IO ()
- hClearFromCursorToScreenBeginning :: Handle -> IO ()
- hClearScreen :: Handle -> IO ()
- hClearFromCursorToLineEnd :: Handle -> IO ()
- hClearFromCursorToLineBeginning :: Handle -> IO ()
- hClearLine :: Handle -> IO ()
- clearFromCursorToScreenEndCode :: String
- clearFromCursorToScreenBeginningCode :: String
- clearScreenCode :: String
- clearFromCursorToLineEndCode :: String
- clearFromCursorToLineBeginningCode :: String
- clearLineCode :: String
- scrollPageUp :: Int -> IO ()
- scrollPageDown :: Int -> IO ()
- hScrollPageUp :: Handle -> Int -> IO ()
- hScrollPageDown :: Handle -> Int -> IO ()
- scrollPageUpCode :: Int -> String
- scrollPageDownCode :: Int -> String
- useAlternateScreenBuffer :: IO ()
- useNormalScreenBuffer :: IO ()
- hUseAlternateScreenBuffer :: Handle -> IO ()
- hUseNormalScreenBuffer :: Handle -> IO ()
- useAlternateScreenBufferCode :: String
- useNormalScreenBufferCode :: String
- reportLayerColor :: ConsoleLayer -> IO ()
- hReportLayerColor :: Handle -> ConsoleLayer -> IO ()
- reportLayerColorCode :: ConsoleLayer -> String
- setSGR :: [SGR] -> IO ()
- hSetSGR :: Handle -> [SGR] -> IO ()
- setSGRCode :: [SGR] -> String
- hideCursor :: IO ()
- showCursor :: IO ()
- hHideCursor :: Handle -> IO ()
- hShowCursor :: Handle -> IO ()
- hideCursorCode :: String
- showCursorCode :: String
- hyperlink :: String -> String -> IO ()
- hyperlinkWithId :: String -> String -> String -> IO ()
- hyperlinkWithParams :: [(String, String)] -> String -> String -> IO ()
- hHyperlink :: Handle -> String -> String -> IO ()
- hHyperlinkWithId :: Handle -> String -> String -> String -> IO ()
- hHyperlinkWithParams :: Handle -> [(String, String)] -> String -> String -> IO ()
- hyperlinkCode :: String -> String -> String
- hyperlinkWithIdCode :: String -> String -> String -> String
- hyperlinkWithParamsCode :: [(String, String)] -> String -> String -> String
- setTitle :: String -> IO ()
- hSetTitle :: Handle -> String -> IO ()
- setTitleCode :: String -> String
- hSupportsANSI :: Handle -> IO Bool
- hSupportsANSIColor :: Handle -> IO Bool
- hSupportsANSIWithoutEmulation :: Handle -> IO (Maybe Bool)
- getCursorPosition :: IO (Maybe (Int, Int))
- hGetCursorPosition :: Handle -> IO (Maybe (Int, Int))
- getReportedCursorPosition :: IO String
- cursorPosition :: ReadP (Int, Int)
- getTerminalSize :: IO (Maybe (Int, Int))
- hGetTerminalSize :: Handle -> IO (Maybe (Int, Int))
- getLayerColor :: ConsoleLayer -> IO (Maybe (RGB Word16))
- hGetLayerColor :: Handle -> ConsoleLayer -> IO (Maybe (RGB Word16))
- getReportedLayerColor :: ConsoleLayer -> IO String
- layerColor :: ConsoleLayer -> ReadP (RGB Word16)
Basic data types
module System.Console.ANSI.Types
Cursor movement by character
'h...' variants
'...Code' variants
Cursor movement by line
The difference between movements "by character" and "by line" is
that *Line
functions additionally move the cursor to the start of the
line, while functions like cursorUp
and cursorDown
keep the column
the same.
'h...' variants
'...Code' variants
Directly changing cursor position
Move the cursor to the specified column. The column numbering is 0-based (that is, the left-most column is numbered 0).
Move the cursor to the specified position (row and column). The position is 0-based (that is, the top-left corner is at row 0 column 0).
'h...' variants
'...Code' variants
Code to move the cursor to the specified column. The column numbering is 0-based (that is, the left-most column is numbered 0).
setCursorPositionCode Source #
Code to move the cursor to the specified position (row and column). The position is 0-based (that is, the top-left corner is at row 0 column 0).
Saving, restoring and reporting cursor position
saveCursor :: IO () Source #
Save the cursor position in memory. The only way to access the saved value
is with the restoreCursor
command.
Since: 0.7.1
restoreCursor :: IO () Source #
Restore the cursor position from memory. There will be no value saved in
memory until the first use of the saveCursor
command.
Since: 0.7.1
reportCursorPosition :: IO () Source #
Looking for a way to get the cursors position? See
getCursorPosition
.
Emit the cursor position into the console input stream, immediately after
being recognised on the output stream, as:
ESC [ <cursor row> ; <cursor column> R
Note that the information that is emitted is 1-based (the top-left corner is
at row 1 column 1) but setCursorColumn
and setCursorPosition
are
0-based.
In isolation of getReportedCursorPosition
or getCursorPosition
, this
function may be of limited use on Windows operating systems because of
difficulties in obtaining the data emitted into the console input stream.
Since: 0.7.1
'h...' variants
hSaveCursor :: Handle -> IO () Source #
hRestoreCursor :: Handle -> IO () Source #
hReportCursorPosition :: Handle -> IO () Source #
'...Code' variants
saveCursorCode :: String Source #
Since: 0.7.1
restoreCursorCode :: String Source #
Since: 0.7.1
reportCursorPositionCode :: String Source #
Code to emit the cursor position into the console input stream, immediately
after being recognised on the output stream, as:
ESC [ <cursor row> ; <cursor column> R
Note that the information that is emitted is 1-based (the top-left corner is
at row 1 column 1) but setCursorPositionCode
is 0-based.
In isolation of getReportedCursorPosition
or
getCursorPosition
, this function may be of limited use
on Windows operating systems because of difficulties in obtaining the data
emitted into the console input stream.
Since: 0.7.1
Clearing parts of the screen
Note that these functions only clear parts of the screen. They do not move the cursor. Some functions are based on the whole screen and others are based on the line in which the cursor is located.
clearFromCursorToScreenEnd :: IO () Source #
clearScreen :: IO () Source #
clearFromCursorToLineEnd :: IO () Source #
'h...' variants
hClearFromCursorToScreenEnd :: Handle -> IO () Source #
hClearFromCursorToScreenBeginning :: Handle -> IO () Source #
hClearScreen :: Handle -> IO () Source #
hClearFromCursorToLineEnd :: Handle -> IO () Source #
hClearFromCursorToLineBeginning :: Handle -> IO () Source #
hClearLine :: Handle -> IO () Source #
'...Code' variants
Scrolling the screen
Scroll the displayed information up or down the terminal: not widely supported
Scroll the displayed information up or down the terminal: not widely supported
'h...' variants
'...Code' variants
Using screen buffers
On Windows, if emulation is required, switching between alternate and normal screen buffers is not emulated.
useAlternateScreenBuffer :: IO () Source #
Use the Alternate Screen Buffer. If currently using the Normal Screen Buffer, it will save the cursor position and switch to the Alternate Screen Buffer. It will always clear the Alternate Screen Buffer. The Alternate Screen Buffer has no scroll back facility.
It is an application's responsibility to ensure that it switches back to the
Normal Screen Buffer if an exception is raised while the Alternate Screen
Buffer is being used. For example, by using bracket_
:
bracket_ useAlternateScreenBuffer useNormalScreenBuffer action
Since: 0.11.4
useNormalScreenBuffer :: IO () Source #
Use the Normal Screen Buffer. If currently using the Alternate Screen Buffer, it will clear the Alternate Screen Buffer, and switch to the Normal Screen Buffer. It will always restore the saved cursor position.
Since: 0.11.4
'h...' variants
hUseAlternateScreenBuffer :: Handle -> IO () Source #
hUseNormalScreenBuffer :: Handle -> IO () Source #
'...Code' variants
Reporting the background or foreground colors
reportLayerColor :: ConsoleLayer -> IO () Source #
Looking for a way to get layer colors? See getLayerColor
.
Emit the layerColor into the console input stream, immediately after
being recognised on the output stream, as:
ESC ] <Ps> ; rgb: <red> ; <green> ; <blue> <ST>
where <Ps>
is 10
for Foreground
and 11
for Background
; <red>
,
<green>
and <blue>
are the color channel values in hexadecimal (4, 8,
12 and 16 bit values are possible, although 16 bit values are most common);
and <ST>
is the STRING TERMINATOR (ST). ST depends on the terminal
software and may be the BEL
character or ESC \
characters.
This function may be of limited, or no, use on Windows operating systems because (1) the function is not supported on native terminals and is emulated, but the emulation does not work on Windows Terminal and (2) of difficulties in obtaining the data emitted into the console input stream.
Since: 0.11.4
hReportLayerColor :: Handle -> ConsoleLayer -> IO () Source #
reportLayerColorCode :: ConsoleLayer -> String Source #
Code to emit the layer color into the console input stream, immediately
after being recognised on the output stream, as:
ESC ] <Ps> ; rgb: <red> ; <green> ; <blue> <ST>
where <Ps>
is 10
for Foreground
and 11
for Background
; <red>
,
<green>
and <blue>
are the color channel values in hexadecimal (4, 8,
12 and 16 bit values are possible, although 16 bit values are most common);
and <ST>
is the STRING TERMINATOR (ST). ST depends on the terminal
software and may be the BEL
character or ESC \
characters.
This function may be of limited, or no, use on Windows operating systems
because (1) the control character sequence is not supported on native
terminals (2) of difficulties in obtaining the data emitted into the
console input stream. See getReportedLayerColor
.
Since: 0.11.4
Select Graphic Rendition mode: colors and other whizzy stuff
:: [SGR] | Commands: these will typically be applied on top of the
current console SGR mode. An empty list of commands is
equivalent to the list |
-> IO () |
Set the Select Graphic Rendition mode
Cursor visibilty changes
hideCursor :: IO () Source #
showCursor :: IO () Source #
'h...' variants
hHideCursor :: Handle -> IO () Source #
hShowCursor :: Handle -> IO () Source #
'...Code' variants
Hyperlinks
Some, but not all, terminals support hyperlinks - that is, clickable text that points to a URI. On Windows, if emulation is required, hyperlinks are not emulated.
Introduce a hyperlink with an identifier for the link. Some terminals support an identifier, so that hyperlinks with the same identifier are treated as connected.
Since: 0.11.3
Introduce a hyperlink with (key, value) parameters. Some terminals support
an id
parameter key, so that hyperlinks with the same id
value are
treated as connected.
Since: 0.11.3
'h...' variants
'...Code' variants
Code to introduce a hyperlink.
Since: 0.11.3
Code to introduce a hyperlink with an identifier for the link. Some terminals support an identifier, so that hyperlinks with the same identifier are treated as connected.
Since: 0.11.3
hyperlinkWithParamsCode Source #
Code to introduce a hyperlink with (key, value) parameters. Some terminals
support an id
parameter key, so that hyperlinks with the same id
value
are treated as connected.
Since: 0.11.3
Changing the title
Set the terminal window title and icon name (that is, the text for the window in the Start bar, or similar).
Code to set the terminal window title and the icon name (that is, the text for the window in the Start bar, or similar).
Checking if handle supports ANSI (not portable: GHC only)
hSupportsANSI :: Handle -> IO Bool Source #
Use heuristics to determine whether the functions defined in this
package will work with a given handle. This function assumes that the handle
is writable (that is, it manages output - see hIsWritable
).
For Unix-like operating systems, the current implementation checks
that: (1) the handle is a terminal; and (2) a TERM
environment variable is not set to dumb
(which is what the GNU Emacs text
editor sets for its integrated terminal).
For Windows, the current implementation performs the same checks as for
Unix-like operating systems and, as an alternative, checks whether the
handle is connected to a 'mintty' terminal. (That is because the function
hIsTerminalDevice
is used to check if the handle is a
terminal. However, where a non-native Windows terminal (such as 'mintty')
is implemented using redirection, that function will not identify a
handle to the terminal as a terminal.) On Windows 10, if the handle is
identified as connected to a native terminal, this function does not enable
the processing of 'ANSI' control characters in output (see
hSupportsANSIWithoutEmulation
).
Since: 0.6.2
hSupportsANSIColor :: Handle -> IO Bool Source #
Some terminals (e.g. Emacs) are not fully ANSI compliant but can support ANSI colors. This can be used in such cases, if colors are all that is needed.
Since: 0.9
hSupportsANSIWithoutEmulation :: Handle -> IO (Maybe Bool) Source #
Use heuristics to determine whether a given handle will support 'ANSI' control characters in output. (On Windows versions before Windows 10, that means 'support without emulation'.)
If the handle is not writable (that is, it cannot manage output - see
hIsWritable
), then return (Just False)
is returned.
On Unix-like operating systems, with one exception, the function is
consistent with hSupportsANSI
. The exception is if the handle is not
writable.
On Windows, what is returned will depend on what the handle is connected to
and the version of the operating system. If the handle is identified as
connected to a 'mintty' terminal, return (Just True)
is
returned. If it is identified as connected to a native terminal, then, on
Windows 10, the processing of 'ANSI' control characters will be enabled and
return (Just True)
returned; and, on versions of Windows before Windows 10,
return (Just False)
is returned. Otherwise, if a TERM
environment
variable is set to dumb
, return (Just False)
is returned. In all other
cases of a writable handle, return Nothing
is returned; this indicates that
the heuristics cannot assist - the handle may be connected to a file or
to another type of terminal.
Since: 0.8.1
Getting the cursor position
getCursorPosition :: IO (Maybe (Int, Int)) Source #
Attempts to get the reported cursor position, combining the functions
reportCursorPosition
, getReportedCursorPosition
and cursorPosition
. Any
position (row, column)
is translated to be 0-based (that is, the top-left
corner is at (0, 0)
), consistent with setCursorColumn
and
setCursorPosition
. (Note that the information emitted into the console
input stream by reportCursorPosition
is 1-based.) Returns Nothing
if any
data emitted by reportCursorPosition
, obtained by
getReportedCursorPosition
, cannot be parsed by cursorPosition
. Uses
stdout
. If stdout
will be redirected, see hGetCursorPosition
for a more
general function.
On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on the Windows' Console API. (Command Prompt and PowerShell are based on the Console API.)
Since: 0.10.3
hGetCursorPosition :: Handle -> IO (Maybe (Int, Int)) Source #
Attempts to get the reported cursor position, combining the functions
hReportCursorPosition
(with the specified handle),
getReportedCursorPosition
and cursorPosition
. Any position
(row, column)
is translated to be 0-based (that is, the top-left corner is
at (0, 0)
), consistent with hSetCursorColumn
and hSetCursorPosition
.
(Note that the information emitted into the console input stream by
hReportCursorPosition
is 1-based.) Returns Nothing
if any data emitted by
hReportCursorPosition
, obtained by getReportedCursorPosition
, cannot be
parsed by cursorPosition
.
On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on the Windows' Console API. (Command Prompt and PowerShell are based on the Console API.)
Since: 0.10.1
getReportedCursorPosition :: IO String Source #
Attempts to get the reported cursor position data from the console input
stream. The function is intended to be called immediately after
reportCursorPosition
(or related functions) have caused characters to be
emitted into the stream.
For example, on a Unix-like operating system:
-- set no buffering (if 'no buffering' is not already set, the contents of -- the buffer will be discarded, so this needs to be done before the cursor -- positon is emitted) hSetBuffering stdin NoBuffering -- ensure that echoing is off input <- bracket (hGetEcho stdin) (hSetEcho stdin) $ \_ -> do hSetEcho stdin False reportCursorPosition hFlush stdout -- ensure the report cursor position code is sent to the -- operating system getReportedCursorPosition
On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on the Windows' Console API. (Command Prompt and PowerShell are based on the Console API.)
Since: 0.7.1
cursorPosition :: ReadP (Int, Int) Source #
Parses the characters emitted by reportCursorPosition
into the console
input stream. Returns the cursor row and column as a tuple.
For example, if the characters emitted by reportCursorPosition
are in
String
input
then the parser could be applied like this:
let result = readP_to_S cursorPosition input case result of [] -> putStrLn $ "Error: could not parse " ++ show input [((row, column), _)] -> putStrLn $ "The cursor was at row " ++ show row ++ " and column" ++ show column ++ "." (_:_) -> putStrLn $ "Error: parse not unique"
Since: 0.7.1
Getting the terminal size
getTerminalSize :: IO (Maybe (Int, Int)) Source #
Attempts to get the current terminal size (height in rows, width in columns).
There is no 'ANSI' control character sequence that reports the terminal
size. So, it attempts to set the cursor position beyond the bottom right
corner of the terminal and then use getCursorPosition
to query the console
input stream. It works only on terminals that support each step and if data
can be emitted to stdin
. (Use hIsTerminalDevice
to test if
stdin
is connected to a terminal.) Uses stdout
. If stdout
will be
redirected, see hGetTerminalSize
for a more general function.
On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on Windows' Console API. (Command Prompt and PowerShell are based on the Console API.)
For a different approach, one that does not use control character sequences
and works when stdin
is redirected, see the
terminal-size package.
Since: 0.9
hGetTerminalSize :: Handle -> IO (Maybe (Int, Int)) Source #
Attempts to get the current terminal size (height in rows, width in
columns), by writing control character sequences to the specified handle
(which will typically be stdout
or stderr
).
There is no 'ANSI' control character sequence that reports the terminal
size. So, it attempts to set the cursor position beyond the bottom right
corner of the terminal and then use hGetCursorPosition
to query the console
input stream. It works only on terminals that support each step and if data
can be emitted to stdin
. (Use hIsTerminalDevice
to test if
stdin
is connected to a terminal.)
On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on the Windows' Console API. (Command Prompt and PowerShell are based on the Console API.)
For a different approach, one that does not use control character sequences
and works when stdin
is redirected, see the
terminal-size package.
Since: 0.10.1
Getting the background or foreground colors
getLayerColor :: ConsoleLayer -> IO (Maybe (RGB Word16)) Source #
Attempts to get the reported layer color, combining the functions
reportLayerColor
, getReportedLayerColor
and layerColor
. Any RGB color
is scaled to be 16 bits per channel, the most common format reported by
terminal software. Returns Nothing
if any data emitted by
reportLayerColor
, obtained by getReportedLayerColor
, cannot be parsed by
layerColor
. Uses stdout
. If stdout
will be redirected, see
hGetLayerColor
for a more general function.
On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on the Windows' Console API. (Command Prompt and PowerShell are based on the Console API.) This function also relies on emulation that does not work on Windows Terminal.
Since: 0.11.4
hGetLayerColor :: Handle -> ConsoleLayer -> IO (Maybe (RGB Word16)) Source #
Attempts to get the reported layer color, combining the functions
hReportLayerColor
, getReportedLayerColor
and layerColor
. Any RGB color
is scaled to be 16 bits per channel, the most common format reported by
terminal software. Returns Nothing
if any data emitted by
hReportLayerColor
, obtained by getReportedLayerColor
, cannot be parsed by
layerColor
.
On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on the Windows' Console API. (Command Prompt and PowerShell are based on the Console API.) This function also relies on emulation that does not work on Windows Terminal.
Since: 0.11.4
getReportedLayerColor :: ConsoleLayer -> IO String Source #
Attempts to get the reported layer color data from the console input
stream. The function is intended to be called immediately after
reportLayerColor
(or related functions) have caused characters to be
emitted into the stream.
For example, on a Unix-like operating system:
-- set no buffering (if 'no buffering' is not already set, the contents of -- the buffer will be discarded, so this needs to be done before the cursor -- positon is emitted) hSetBuffering stdin NoBuffering -- ensure that echoing is off input <- bracket (hGetEcho stdin) (hSetEcho stdin) $ \_ -> do hSetEcho stdin False reportLayerColor Foreground hFlush stdout -- ensure the report cursor position code is sent to the -- operating system getReportedLayerColor Foreground
On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on the Windows' Console API. (Command Prompt and PowerShell are based on the Console API.)
Since: 0.11.4
layerColor :: ConsoleLayer -> ReadP (RGB Word16) Source #
Parses the characters emitted by reportLayerColor
into the console input
stream.
For example, if the characters emitted by reportLayerColor
are in String
input
then the parser could be applied like this:
let result = readP_to_S (layerColor layer) input case result of [] -> putStrLn $ "Error: could not parse " ++ show input [(col, _)] -> putStrLn $ "The color was " ++ show col ++ "." (_:_) -> putStrLn $ "Error: parse not unique"
Since: 0.11.4