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

System.Console.Haskeline

Contents

- Interactive sessions
  - The InputT monad transformer
  - Behaviors
- User interaction functions
  - Reading user input
  - Outputting text
- Customization
  - Settings
  - User preferences
- Ctrl-C handling

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

- 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)
- 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 {
  - complete :: CompletionFunc m
  - historyFile :: Maybe FilePath
  - autoAddHistory :: Bool
  }
- 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

data InputT m a

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 a

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 Bool

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

## Behaviors

data Behavior

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 a

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

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

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

useFile :: FilePath -> Behavior

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

preferTerm :: Behavior

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.

getInputLine

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.

getInputChar

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.

getPassword

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

Write a Unicode string to the user's standard output.

outputStrLn :: MonadIO m => String -> InputT m ()

Write a string to the user's standard output, followed by a newline.

# Customization

## Settings

data Settings m

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 => CommandMonad (InputCmdT m) |
Monad m => MonadReader (Settings m) (InputT m) |

defaultSettings :: MonadIO m => Settings m

A useful default. In particular:

     defaultSettings = Settings {
               complete = completeFilename,
               historyFile = Nothing,
               autoAddHistory = True
               }

setComplete :: CompletionFunc m -> Settings m -> Settings m

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

`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) |
Monad m => CommandMonad (InputCmdT m) |

readPrefs :: FilePath -> IO Prefs

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

defaultPrefs :: Prefs

The default preferences which may be overwritten in the `.haskeline` file.

runInputTWithPrefs :: MonadException m => Prefs -> Settings m -> InputT m a -> m a

Run a line-reading application. Uses `defaultBehavior` to determine the interaction behavior.

runInputTBehaviorWithPrefs :: MonadException m => Behavior -> Prefs -> Settings m -> InputT m a -> m a

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.

data Interrupt

Constructors

Interrupt |

Instances

Eq Interrupt |
Show Interrupt |
Typeable Interrupt |
Exception Interrupt |

withInterrupt :: MonadException m => InputT m a -> InputT m a

If Ctrl-C is pressed during the given computation, throw an exception of type `Interrupt`.

handleInterrupt

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

module System.Console.Haskeline.Completion

module System.Console.Haskeline.MonadException