Overview of Haskeline
masterreadline, offering a rich line-editing interface with features like history recall, incremental search, and Unicode support. It is compatible with POSIX systems (via terminfo) and Windows (via MinGW).repository·master·Indexed 42 days ago
https://github.com/haskell/haskelineA Haskell-native library providing a rich line-editing interface for command-line applications, serving as an alternative to GNU Readline. It features history recall, incremental search, Unicode support, and compatibility with POSIX and Windows. The library includes support for custom tab completion via completionCmd, a Kill Ring for cut/paste operations, and an undo/redo mechanism using the Save typeclass.
readline, offering a rich line-editing interface with features like history recall, incremental search, and Unicode support. It is compatible with POSIX systems (via terminfo) and Windows (via MinGW).Users can customize their Haskeline experience by creating and modifying a ~/.haskeline configuration file. This file allows for the definition of:
The undo/redo system is managed by the Undo data type, which tracks two lists of states: pastUndo (the history of previous states) and futureRedo (the history of states that were undone and can be re-applied).
pastUndo, and the futureRedo list is cleared. This prevents 'branching' histories.futureRedo, and the top element of pastUndo is restored as the current state.pastUndo, and the top element of futureRedo is restored as the current state.The state type s must implement the Save typeclass, which provides save (to capture a snapshot) and restore (to revert to a snapshot) methods.
The way completions are presented to the user is determined by the completionType field in your Prefs. The CompletionType type controls the interaction model when multiple matches exist:
MenuCompletion: Allows the user to cycle through available completions using the completion key.ListCompletion: Displays the completions as a list. This may involve paging if the list is long or if completionPaging is enabled in Prefs.data CompletionType = MenuCompletion | ListCompletionThe Kill Ring is a stack-based buffer used for cut/paste operations (similar to a clipboard). To use any Kill Ring commands, you must wrap your action in runKillRing. This initializes an empty stack and provides the necessary environment for managing the ring's state.
runKillRing takes a ReaderT (IORef KillRing) m a action and executes it within a MonadIO context.
runKillRing :: MonadIO m => ReaderT (IORef KillRing) m a -> m aHaskeline provides commands to manage undo and redo operations for the line state. These commands rely on the Save typeclass to capture and restore snapshots of the line state.
commandUndo: Reverts the current line state to the previous state stored in the undo history. This clears the 'redo' history.commandRedo: Re-applies a state from the redo history. This moves the current state into the 'undo' history.To use these, your line state must implement the Save typeclass, and you must be operating within a monad that has Undo state (typically via UndoT).
-- Assuming a monad m that supports Undo state and a state s that implements Save
-- Use commandUndo to revert changes
result <- commandUndo
-- Use commandRedo to re-apply changes
result <- commandRedoHaskeline uses KillHelper to define how text is selected and removed (killed) or copied from the buffer.
SimpleMove (InsertMode -> InsertMode): Used for standard movements where the text to be killed is the difference between the current position and a new position.GenericKill (InsertMode -> ([Grapheme], InsertMode)): Provides full control over which graphemes are captured and what the resulting InsertMode should be. This is used for complex commands like dd or cc.killFromHelper: Removes text from the buffer and pushes it onto the Kill Ring. This operation is undoable.killFromArgHelper: A variant of killFromHelper designed for use within ArgMode (when the command is part of a multi-argument sequence).copyFromArgHelper: Copies text to the Kill Ring without modifying the current state (non-destructive).data KillHelper = SimpleMove (InsertMode -> InsertMode)
| GenericKill (InsertMode -> ([Grapheme], InsertMode))
killFromHelper :: (MonadState KillRing m, MonadState Undo m, Save s, Save t)
=> KillHelper -> Command m s t
killFromArgHelper :: (MonadState KillRing m, MonadState Undo m, Save s, Save t)
=> KillHelper -> Command m (ArgMode s) t
copyFromArgHelper :: (MonadState KillRing m, MonadState s)
=> KillHelper -> Command m (ArgMode s) sTo ensure that changes can be undone, you must manually trigger a save operation using saveForUndo. This function captures the current state and adds it to the pastUndo list. If the new state is identical to the most recent state in the history, it avoids creating a duplicate entry.
This is typically used after a user action that modifies the input line.
-- Within a Command m s s context where m has MonadState Undo
saveForUndo sThe pasteCommand function allows you to insert the most recent item from the Kill Ring into the current state.
It requires a function use that defines how the retrieved [Grapheme] (the text from the ring) should be applied to the current state s. It also integrates with the Undo mechanism, saving the current state before applying the paste so it can be undone.
Parameters:
use: A function of type ([Grapheme] -> s -> s) that describes how to merge the pasted text into the state.pasteCommand :: (Save s, MonadState KillRing m, MonadState Undo m)
=> ([Grapheme] -> s -> s)
-> Command m (ArgMode s) sTo add tab completion functionality to your Haskeline-based application, use the completionCmd function. This function creates a KeyCommand that handles the logic of looking up completions, managing undo states, and presenting results to the user (either by inserting the best match or showing a list/menu).
completionCmd requires the monad m to satisfy both MonadState Undo m and CommandMonad m.
It behaves as follows:
RingBell effect.completionType configured in your Prefs (either MenuCompletion or ListCompletion).completionCmd :: (MonadState Undo m, CommandMonad m)
=> Key -> KeyCommand m InsertMode InsertModeThe following types and functions are used to manage the completion lifecycle in Haskeline:
CompletionFunc: A type for defining custom completion logic.Completion: A data type representing a single completion result.CompletionType: Determines if completions are shown as a menu or a list.completionCmd: The primary constructor for a tab-completion key command.