A rich user interface for line input in command-line programs. Haskeline is Unicode-aware and runs both on POSIX-compatible systems and on Windows.
Users may customize the interface with a ~/.haskeline
file; see
http://trac.haskell.org/haskeline/wiki/UserPrefs for more information.
An example use of this library for a simple read-eval-print loop (REPL) is the following:
import System.Console.Haskeline main :: IO () main = runInputT defaultSettings loop where loop :: InputT IO () loop = do minput <- getInputLine "% " case minput of Nothing -> return () Just "quit" -> return () Just input -> do outputStrLn $ "Input was: " ++ input loop
- data InputT m a
- runInputT :: MonadException m => Settings m -> InputT m a -> m a
- haveTerminalUI :: Monad m => InputT m Bool
- data Behavior
- runInputTBehavior :: MonadException m => Behavior -> Settings m -> InputT m a -> m a
- defaultBehavior :: Behavior
- useFileHandle :: Handle -> Behavior
- useFile :: FilePath -> Behavior
- preferTerm :: Behavior
- getInputLine :: MonadException m => String -> InputT m (Maybe String)
- getInputLineWithInitial :: MonadException m => String -> (String, String) -> InputT m (Maybe String)
- getInputChar :: MonadException m => String -> InputT m (Maybe Char)
- getPassword :: MonadException m => Maybe Char -> String -> InputT m (Maybe String)
- outputStr :: MonadIO m => String -> InputT m ()
- outputStrLn :: MonadIO m => String -> InputT m ()
- data Settings m = Settings {}
- defaultSettings :: MonadIO m => Settings m
- setComplete :: CompletionFunc m -> Settings m -> Settings m
- data Prefs
- readPrefs :: FilePath -> IO Prefs
- defaultPrefs :: Prefs
- runInputTWithPrefs :: MonadException m => Prefs -> Settings m -> InputT m a -> m a
- runInputTBehaviorWithPrefs :: MonadException m => Behavior -> Prefs -> Settings m -> InputT m a -> m a
- data Interrupt = Interrupt
- withInterrupt :: MonadException m => InputT m a -> InputT m a
- handleInterrupt :: MonadException m => m a -> m a -> m a
- module System.Console.Haskeline.Completion
- module System.Console.Haskeline.MonadException
Interactive sessions
The InputT monad transformer
A monad transformer which carries all of the state and settings relevant to a line-reading application.
MonadTrans InputT | |
Monad m => MonadState History (InputT m) | |
Monad m => MonadState History (InputT m) | |
Monad m => MonadReader Prefs (InputT m) | |
Monad m => MonadReader RunTerm (InputT m) | |
Monad m => Monad (InputT m) | |
Monad m => Functor (InputT m) | |
Monad m => Applicative (InputT m) | |
MonadIO m => MonadIO (InputT m) | |
MonadException m => MonadException (InputT m) | |
Monad m => MonadReader (Settings m) (InputT m) |
runInputT :: MonadException m => Settings m -> InputT m a -> m aSource
Run a line-reading application. This function should suffice for most applications.
This function is equivalent to
. It
uses terminal-style interaction if runInputTBehavior
defaultBehavior
stdin
is connected to a terminal and has
echoing enabled. Otherwise (e.g., if stdin
is a pipe), it uses file-style interaction.
If it uses terminal-style interaction, Prefs
will be read from the user's ~/.haskeline
file
(if present).
If it uses file-style interaction, Prefs
are not relevant and will not be read.
haveTerminalUI :: Monad m => InputT m BoolSource
Behaviors
Haskeline has two ways of interacting with the user:
- "Terminal-style" interaction provides an rich user interface by connecting
to the user's terminal (which may be different than
stdin
orstdout
). - "File-style" interaction treats the input as a simple stream of characters, for example
when reading from a file or pipe. Input functions (e.g.,
getInputLine
) print the prompt tostdout
.
A Behavior
is a method for deciding at run-time which type of interaction to use.
For most applications (e.g., a REPL), defaultBehavior
should have the correct effect.
runInputTBehavior :: MonadException m => Behavior -> Settings m -> InputT m a -> m aSource
useFileHandle :: Handle -> BehaviorSource
Use file-style interaction, reading input from the given Handle
.
User interaction functions
Reading user input
The following functions read one line or character of input from the user.
When using terminal-style interaction, these functions return Nothing
if the user
pressed Ctrl-D
when the input text was empty.
When using file-style interaction, these functions return Nothing
if
an EOF
was encountered before any characters were read.
:: MonadException m | |
=> String | The input prompt |
-> InputT m (Maybe String) |
Reads one line of input. The final newline (if any) is removed. When using terminal-style interaction, this function provides a rich line-editing user interface.
If
and the line input is nonblank (i.e., is not all
spaces), it will be automatically added to the history.
autoAddHistory
== True
:: MonadException m | |
=> String | The input prompt |
-> (String, String) | The initial value left and right of the cursor |
-> InputT m (Maybe String) |
Reads one line of input and fills the insertion space with initial text. When using terminal-style interaction, this function provides a rich line-editing user interface with the added ability to give the user default values.
This function behaves in the exact same manner as getInputLine
, except that
it pre-populates the input area. The text that resides in the input area is given as a 2-tuple
with two String
s. The string on the left of the tuple (obtained by calling fst
) is
what will appear to the left of the cursor and the string on the right (obtained by
calling snd
) is what will appear to the right of the cursor.
Some examples of calling of this function are:
getInputLineWithInitial "prompt> " ("left", "") -- The cursor starts at the end of the line. getInputLineWithInitial "prompt> " ("left ", "right") -- The cursor starts before the second word.
:: MonadException m | |
=> String | The input prompt |
-> InputT m (Maybe Char) |
Reads one character of input. Ignores non-printable characters.
When using terminal-style interaction, the character will be read without waiting for a newline.
When using file-style interaction, a newline will be read if it is immediately available after the input character.
:: MonadException m | |
=> Maybe Char | A masking character; e.g., |
-> String | |
-> InputT m (Maybe String) |
Reads one line of input, without displaying the input while it is being typed. When using terminal-style interaction, the masking character (if given) will replace each typed character.
When using file-style interaction, this function turns off echoing while reading the line of input.
Outputting text
The following functions enable cross-platform output of text that may contain Unicode characters.
outputStr :: MonadIO m => String -> InputT m ()Source
Write a Unicode string to the user's standard output.
outputStrLn :: MonadIO m => String -> InputT m ()Source
Write a string to the user's standard output, followed by a newline.
Customization
Settings
Application-specific customizations to the user interface.
Settings | |
|
defaultSettings :: MonadIO m => Settings mSource
A useful default. In particular:
defaultSettings = Settings { complete = completeFilename, historyFile = Nothing, autoAddHistory = True }
setComplete :: CompletionFunc m -> Settings m -> Settings mSource
User preferences
Prefs
allow the user to customize the terminal-style line-editing interface. They are
read by default from ~/.haskeline
; to override that behavior, use
readPrefs
and runInputTWithPrefs
.
Each line of a .haskeline
file defines
one field of the Prefs
datatype; field names are case-insensitive and
unparseable lines are ignored. For example:
editMode: Vi completionType: MenuCompletion maxhistorysize: Just 40
readPrefs :: FilePath -> IO PrefsSource
Read Prefs
from a given file. If there is an error reading the file,
the defaultPrefs
will be returned.
The default preferences which may be overwritten in the
.haskeline
file.
runInputTWithPrefs :: MonadException m => Prefs -> Settings m -> InputT m a -> m aSource
Run a line-reading application. Uses defaultBehavior
to determine the
interaction behavior.
runInputTBehaviorWithPrefs :: MonadException m => Behavior -> Prefs -> Settings m -> InputT m a -> m aSource
Run a line-reading application.
Ctrl-C handling
The following functions provide portable handling of Ctrl-C events.
These functions are not necessary on GHC version 6.10 or later, which processes Ctrl-C events as exceptions by default.
withInterrupt :: MonadException m => InputT m a -> InputT m aSource
If Ctrl-C is pressed during the given computation, throw an exception of type
Interrupt
.
:: MonadException m | |
=> m a | Handler to run if Ctrl-C is pressed |
-> m a | Computation to run |
-> m a |
Catch and handle an exception of type Interrupt
.