haskeline-0.2: System/Console/Haskeline/Emacs.hs
module System.Console.Haskeline.Emacs where
import System.Console.Haskeline.Command
import System.Console.Haskeline.Command.Completion
import System.Console.Haskeline.Command.History
import System.Console.Haskeline.LineState
import System.Console.Haskeline.InputT
import Data.Char
type InputCmd s t = forall m . Monad m => Command (InputCmdT m) s t
emacsCommands :: Monad m => KeyMap (InputCmdT m) InsertMode
emacsCommands = runCommand $ choiceCmd [simpleActions, controlActions]
simpleActions, controlActions :: InputCmd InsertMode InsertMode
simpleActions = choiceCmd
[ KeyChar '\n' +> finish
, KeyChar '\r' +> finish
, KeyLeft +> change goLeft
, KeyRight +> change goRight
, Backspace +> change deletePrev
, KeyChar '\b' +> change deletePrev
, DeleteForward +> change deleteNext
, changeFromChar insertChar
, KeyChar '\t' +> completionCmd
, KeyUp +> historyBack
, KeyDown +> historyForward
, searchHistory
]
controlActions = choiceCmd
[ controlKey 'a' +> change moveToStart
, controlKey 'e' +> change moveToEnd
, controlKey 'b' +> change goLeft
, controlKey 'c' +> change goRight
, controlKey 'd' +> deleteCharOrEOF
, controlKey 'l' +> clearScreenCmd
, KeyMeta 'f' +> change (skipRight isAlphaNum
. skipRight (not . isAlphaNum))
, KeyMeta 'b' +> change (skipLeft isAlphaNum
. skipLeft (not . isAlphaNum))
]
deleteCharOrEOF :: Key -> InputCmd InsertMode InsertMode
deleteCharOrEOF k = k +> acceptKeyOrFail (\s -> if s == emptyIM
then Nothing
else Just $ Change (deleteNext s) >=> justDelete)
where
justDelete = try (change deleteNext k >|> justDelete)