haskeline-0.6.3: A command-line interface for user input, written in Haskell.

System.Console.Haskeline

Contents

Description

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

Synopsis

Interactive sessions

The InputT monad transformer

data InputT m a Source

A monad transformer which carries all of the state and settings relevant to a line-reading application.

Instances

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 runInputTBehavior defaultBehavior. It uses terminal-style interaction if 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

Returns True if the current session uses terminal-style interaction. (See Behavior.)

Behaviors

data Behavior Source

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 or stdout).
  • "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 to stdout.

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

Run a line-reading application according to the given behavior.

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.

defaultBehavior :: BehaviorSource

Read input from stdin. Use terminal-style interaction if stdin is connected to a terminal and has echoing enabled. Otherwise (e.g., if stdin is a pipe), use file-style interaction.

This behavior should suffice for most applications.

useFileHandle :: Handle -> BehaviorSource

Use file-style interaction, reading input from the given Handle.

useFile :: FilePath -> BehaviorSource

Use file-style interaction, reading input from the given file.

preferTerm :: BehaviorSource

Use terminal-style interaction whenever possible, even if stdin and/or stdout are not terminals.

If it cannot open the user's terminal, use file-style interaction, reading input from stdin.

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.

getInputLineSource

Arguments

:: 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 autoAddHistory == True and the line input is nonblank (i.e., is not all spaces), it will be automatically added to the history.

getInputCharSource

Arguments

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

getPasswordSource

Arguments

:: MonadException m 
=> Maybe Char

A masking character; e.g., Just '*'

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

data Settings m Source

Application-specific customizations to the user interface.

Constructors

Settings 

Fields

complete :: CompletionFunc m

Custom tab completion.

historyFile :: Maybe FilePath

Where to read/write the history at the start and end of each line input session.

autoAddHistory :: Bool

If True, each nonblank line returned by getInputLine will be automatically added to the history.

Instances

Monad m => MonadReader (Settings m) (InputT m) 

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

Because complete is the only field of Settings depending on m, the expression defaultSettings {completionFunc = f} leads to a type error from being too general. This function works around that issue, and may become unnecessary if another field depending on m is added.

User preferences

data Prefs Source

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

Instances

Show Prefs 
Monad m => MonadReader Prefs (InputT m) 

readPrefs :: FilePath -> IO PrefsSource

Read Prefs from a given file. If there is an error reading the file, the defaultPrefs will be returned.

defaultPrefs :: PrefsSource

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.

handleInterruptSource

Arguments

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