ansi-terminal-0.8: Simple ANSI terminal support, with Windows compatibility

Safe HaskellSafe
LanguageHaskell98

System.Console.ANSI

Contents

Description

Provides ANSI terminal support for ANSI terminal software running on a Unix-like operating system or on a Windows operating system (where supported) or on other Windows operating systems where the terminal in use is not ANSI-enabled.

The ANSI escape codes are described at http://en.wikipedia.org/wiki/ANSI_escape_code and provide a rich range of functionality for terminal control, which includes:

  • Colored text output, with control over both foreground and background colors
  • Hiding or showing the cursor
  • Moving the cursor around
  • Clearing parts of the screen

The most frequently used parts of this ANSI command set are exposed with a platform independent interface by this module. Every function exported comes in three flavours:

  • Vanilla: has an IO () type and doesn't take a Handle. This just outputs the ANSI command directly on to the terminal corresponding to stdout. Commands issued like this should work as you expect on both Windows and Unix.
  • Chocolate: has an IO () type but takes a Handle. This outputs the ANSI command on the terminal corresponding to the supplied handle. Commands issued like this should also work as you expect on both Windows and Unix.
  • Strawberry: has a String type and just consists of an escape code which can be added to any other bit of text before being output. The use of these codes is generally discouraged because they will not work on Windows operating systems where the terminal in use is not ANSI-enabled (such as those before Windows 10 Threshold 2). On versions of Windows where the terminal in use is not ANSI-enabled, these codes will always be the empty string, so it is possible to use them portably for e.g. coloring console output on the understanding that you will only see colors if you are running on an operating system that is Unix-like or is a version of Windows where the terminal in use is ANSI-enabled.

Example:

-- Set colors and write some text in those colors.
sgrExample :: IO ()
sgrExample = do
    setSGR [SetColor Foreground Vivid Red]
    setSGR [SetColor Background Vivid Blue]
    putStr "Red-On-Blue"
    setSGR [Reset]
    putStr "White-On-Black"

For many more examples, see the project's extensive Example.hs file.

Synopsis

Basic data types

Cursor movement by character

cursorUp Source #

Arguments

:: Int

Number of lines or characters to move

-> IO () 

cursorDown Source #

Arguments

:: Int

Number of lines or characters to move

-> IO () 

cursorForward Source #

Arguments

:: Int

Number of lines or characters to move

-> IO () 

cursorBackward Source #

Arguments

:: Int

Number of lines or characters to move

-> IO () 

hCursorUp Source #

Arguments

:: Handle 
-> Int

Number of lines or characters to move

-> IO () 

hCursorDown Source #

Arguments

:: Handle 
-> Int

Number of lines or characters to move

-> IO () 

hCursorForward Source #

Arguments

:: Handle 
-> Int

Number of lines or characters to move

-> IO () 

hCursorBackward Source #

Arguments

:: Handle 
-> Int

Number of lines or characters to move

-> IO () 

cursorUpCode Source #

Arguments

:: Int

Number of lines or characters to move

-> String 

cursorDownCode Source #

Arguments

:: Int

Number of lines or characters to move

-> String 

cursorForwardCode Source #

Arguments

:: Int

Number of lines or characters to move

-> String 

cursorBackwardCode Source #

Arguments

:: Int

Number of lines or characters to move

-> String 

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.

Also keep in mind that *Line functions are not as portable. See https://github.com/feuerbach/ansi-terminal/issues/10 for the details.

cursorUpLine Source #

Arguments

:: Int

Number of lines to move

-> IO () 

cursorDownLine Source #

Arguments

:: Int

Number of lines to move

-> IO () 

hCursorUpLine Source #

Arguments

:: Handle 
-> Int

Number of lines to move

-> IO () 

hCursorDownLine Source #

Arguments

:: Handle 
-> Int

Number of lines to move

-> IO () 

cursorUpLineCode Source #

Arguments

:: Int

Number of lines to move

-> String 

cursorDownLineCode Source #

Arguments

:: Int

Number of lines to move

-> String 

Directly changing cursor position

setCursorColumn Source #

Arguments

:: Int

0-based column to move to

-> IO () 

hSetCursorColumn Source #

Arguments

:: Handle 
-> Int

0-based column to move to

-> IO () 

setCursorColumnCode Source #

Arguments

:: Int

0-based column to move to

-> String 

setCursorPosition Source #

Arguments

:: Int

0-based row to move to

-> Int

0-based column to move to

-> IO () 

hSetCursorPosition Source #

Arguments

:: Handle 
-> Int

0-based row to move to

-> Int

0-based column to move to

-> IO () 

setCursorPositionCode Source #

Arguments

:: Int

0-based row to move to

-> Int

0-based column to move to

-> String 

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.

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.

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

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. 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).

Clearing parts of the screen

Note that these functions only clear parts of the screen. They do not move the cursor.

Scrolling the screen

scrollPageUp Source #

Arguments

:: Int

Number of lines to scroll by

-> IO () 

Scroll the displayed information up or down the terminal: not widely supported

scrollPageDown Source #

Arguments

:: Int

Number of lines to scroll by

-> IO () 

Scroll the displayed information up or down the terminal: not widely supported

hScrollPageUp Source #

Arguments

:: Handle 
-> Int

Number of lines to scroll by

-> IO () 

Scroll the displayed information up or down the terminal: not widely supported

hScrollPageDown Source #

Arguments

:: Handle 
-> Int

Number of lines to scroll by

-> IO () 

Scroll the displayed information up or down the terminal: not widely supported

scrollPageUpCode Source #

Arguments

:: Int

Number of lines to scroll by

-> String 

scrollPageDownCode Source #

Arguments

:: Int

Number of lines to scroll by

-> String 

Select Graphic Rendition mode: colors and other whizzy stuff

setSGR Source #

Arguments

:: [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 [Reset]. Commands are applied left to right.

-> IO () 

Set the Select Graphic Rendition mode

hSetSGR Source #

Arguments

:: Handle 
-> [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 [Reset]. Commands are applied left to right.

-> IO () 

Set the Select Graphic Rendition mode

setSGRCode Source #

Arguments

:: [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 [Reset]. Commands are applied left to right.

-> String 

Cursor visibilty changes

Changing the title

setTitle Source #

Arguments

:: String

New title

-> IO () 

Set the terminal window title

hSetTitle Source #

Arguments

:: Handle 
-> String

New title

-> IO () 

Set the terminal window title

setTitleCode Source #

Arguments

:: String

New Icon Name and Window Title

-> String 

XTerm control sequence to set the Icon Name and Window Title.

Checking if handle supports ANSI

hSupportsANSI :: Handle -> IO Bool Source #

Use heuristics to determine whether the functions defined in this package will work with a given handle.

The current implementation checks that the handle is a terminal, and that the TERM environment variable doesn't say dumb (which is what Emacs sets for its own terminal).

Getting the cursor position

getCursorPosition :: IO (Maybe (Int, Int)) Source #

Attempts to get the reported cursor position, combining the functions reportCursorPosition, getReportedCursorPosition and cursorPosition. Returns Nothing if any data emitted by reportCursorPosition, 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 Win32 console of the Windows API. (Command Prompt and PowerShell are based on the Win32 console.)

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:

hSetBuffering stdin NoBuffering -- set no buffering (the contents of the
                                -- buffer will be discarded, so this needs
                                -- to be done before the cursor positon is
                                -- emitted)
reportCursorPosition
hFlush stdout -- ensure the report cursor position code is sent to the
              -- operating system
input <- getReportedCursorPosition

On Windows operating systems, the function is not supported on consoles, such as mintty, that are not based on the Win32 console of the Windows API. (Command Prompt and PowerShell are based on the Win32 console.)

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"