    #if __GLASGOW_HASKELL__ < 802
    {-# OPTIONS_GHC -Wno-redundant-constraints #-}
    #endif
    module System.Console.Haskeline.Vi where

    import System.Console.Haskeline.Command
    import System.Console.Haskeline.Monads
    import System.Console.Haskeline.Key
    import System.Console.Haskeline.Command.Completion
    import System.Console.Haskeline.Command.History
    import System.Console.Haskeline.Command.KillRing
    import System.Console.Haskeline.Command.Undo
    import System.Console.Haskeline.LineState
    import System.Console.Haskeline.InputT

    import Data.Char
    import Control.Monad(liftM)
    import Control.Monad.Catch (MonadMask)

    type EitherMode = Either CommandMode InsertMode

    type SavedCommand m = Command (ViT m) (ArgMode CommandMode) EitherMode

    data ViState m = ViState {
                forall (m :: * -> *). ViState m -> SavedCommand m
    lastCommand :: SavedCommand m,
                forall (m :: * -> *). ViState m -> [Grapheme]
    lastSearch :: [Grapheme]
             }

    emptyViState :: Monad m => ViState m
    emptyViState :: forall (m :: * -> *). Monad m => ViState m
    emptyViState = ViState {
                lastCommand :: SavedCommand m
    lastCommand = EitherMode -> CmdM (ViT m) EitherMode
    forall a. a -> CmdM (ViT m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EitherMode -> CmdM (ViT m) EitherMode)
    -> (ArgMode CommandMode -> EitherMode) -> SavedCommand m
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> EitherMode
    forall a b. a -> Either a b
    Left (CommandMode -> EitherMode)
    -> (ArgMode CommandMode -> CommandMode)
    -> ArgMode CommandMode
    -> EitherMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState,
                lastSearch :: [Grapheme]
    lastSearch = []
            }

    type ViT m = StateT (ViState m) (InputCmdT m)

    type InputCmd s t = forall m . (MonadIO m, MonadMask m) => Command (ViT m) s t
    type InputKeyCmd s t = forall m . (MonadIO m, MonadMask m) => KeyCommand (ViT m) s t

    viKeyCommands :: InputKeyCmd InsertMode (Maybe String)
    viKeyCommands :: InputKeyCmd InsertMode (Maybe String)
    viKeyCommands = [KeyMap (Command (ViT m) InsertMode (Maybe String))]
    -> KeyMap (Command (ViT m) InsertMode (Maybe String))
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd [
                    Char -> Key
    simpleChar Char
    '\n' Key
    -> Command (ViT m) InsertMode (Maybe String)
    -> KeyMap (Command (ViT m) InsertMode (Maybe String))
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) InsertMode (Maybe String)
    forall (m :: * -> *) s.
    (Monad m, Result s) =>
    Command m s (Maybe String)
    finish
                    , Char -> Key
    ctrlChar Char
    'd' Key
    -> Command (ViT m) InsertMode (Maybe String)
    -> KeyMap (Command (ViT m) InsertMode (Maybe String))
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) InsertMode (Maybe String)
    forall (m :: * -> *) s.
    (Monad m, Save s, Result s) =>
    Command m s (Maybe String)
    eofIfEmpty
                    , KeyCommand (ViT m) InsertMode InsertMode
    InputKeyCmd InsertMode InsertMode
    simpleInsertions KeyCommand (ViT m) InsertMode InsertMode
    -> Command (ViT m) InsertMode (Maybe String)
    -> KeyMap (Command (ViT m) InsertMode (Maybe String))
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) InsertMode (Maybe String)
    InputCmd InsertMode (Maybe String)
    viCommands
                    , Char -> Key
    simpleChar Char
    '\ESC' Key
    -> Command (ViT m) InsertMode (Maybe String)
    -> KeyMap (Command (ViT m) InsertMode (Maybe String))
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> CommandMode)
    -> Command (ViT m) InsertMode CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> CommandMode
    enterCommandMode
                        Command (ViT m) InsertMode CommandMode
    -> Command (ViT m) CommandMode (Maybe String)
    -> Command (ViT m) InsertMode (Maybe String)
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> Command (ViT m) CommandMode (Maybe String)
    InputCmd CommandMode (Maybe String)
    viCommandActions
                    ]

    viCommands :: InputCmd InsertMode (Maybe String)
    viCommands :: InputCmd InsertMode (Maybe String)
    viCommands = KeyCommand (ViT m) InsertMode (Maybe String)
    -> Command (ViT m) InsertMode (Maybe String)
    forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
    keyCommand KeyCommand (ViT m) InsertMode (Maybe String)
    InputKeyCmd InsertMode (Maybe String)
    viKeyCommands

    simpleInsertions :: InputKeyCmd InsertMode InsertMode
    simpleInsertions :: InputKeyCmd InsertMode InsertMode
    simpleInsertions = [KeyMap (Command (ViT m) InsertMode InsertMode)]
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd
                    [  BaseKey -> Key
    simpleKey BaseKey
    LeftKey Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> InsertMode
    forall s. Move s => s -> s
    goLeft
                       , BaseKey -> Key
    simpleKey BaseKey
    RightKey Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> InsertMode
    forall s. Move s => s -> s
    goRight
                       , BaseKey -> Key
    simpleKey BaseKey
    Backspace Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> InsertMode
    deletePrev
                       , BaseKey -> Key
    simpleKey BaseKey
    Delete Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> InsertMode
    deleteNext
                       , BaseKey -> Key
    simpleKey BaseKey
    Home Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToStart
                       , BaseKey -> Key
    simpleKey BaseKey
    End Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToEnd
                       , KeyMap (Command (ViT m) InsertMode InsertMode)
    InputKeyCmd InsertMode InsertMode
    insertChars
                       , Char -> Key
    ctrlChar Char
    'l' Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s. Command m s s
    clearScreenCmd
                       , BaseKey -> Key
    simpleKey BaseKey
    UpKey Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) InsertMode InsertMode
    forall s (m :: * -> *).
    (Save s, MonadState HistLog m) =>
    Command m s s
    historyBack
                       , BaseKey -> Key
    simpleKey BaseKey
    DownKey Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) InsertMode InsertMode
    forall s (m :: * -> *).
    (Save s, MonadState HistLog m) =>
    Command m s s
    historyForward
                       , BaseKey -> Key
    simpleKey BaseKey
    SearchReverse Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> Direction -> Command (ViT m) InsertMode InsertMode
    forall (m :: * -> *).
    MonadState HistLog m =>
    Direction -> Command m InsertMode InsertMode
    searchForPrefix Direction
    Reverse
                       , BaseKey -> Key
    simpleKey BaseKey
    SearchForward Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> Direction -> Command (ViT m) InsertMode InsertMode
    forall (m :: * -> *).
    MonadState HistLog m =>
    Direction -> Command m InsertMode InsertMode
    searchForPrefix Direction
    Forward
                       , KeyMap (Command (ViT m) InsertMode InsertMode)
    forall (m :: * -> *).
    MonadState HistLog m =>
    KeyCommand m InsertMode InsertMode
    searchHistory
                       , BaseKey -> Key
    simpleKey BaseKey
    KillLine Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s t.
    (MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
    KillHelper -> Command m s t
    killFromHelper ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToStart)
                       , Char -> Key
    ctrlChar Char
    'w' Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s t.
    (MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
    KillHelper -> Command m s t
    killFromHelper KillHelper
    wordErase
                       , Key -> KeyMap (Command (ViT m) InsertMode InsertMode)
    forall (m :: * -> *).
    (MonadState Undo m, CommandMonad m) =>
    Key -> KeyCommand m InsertMode InsertMode
    completionCmd (Char -> Key
    simpleChar Char
    '\t')
                       ]

    insertChars :: InputKeyCmd InsertMode InsertMode
    insertChars :: InputKeyCmd InsertMode InsertMode
    insertChars = (Char -> Command (ViT m) InsertMode InsertMode)
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s t.
    (Char -> Command m s t) -> KeyCommand m s t
    useChar ((Char -> Command (ViT m) InsertMode InsertMode)
     -> KeyCommand (ViT m) InsertMode InsertMode)
    -> (Char -> Command (ViT m) InsertMode InsertMode)
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall a b. (a -> b) -> a -> b
    $ String -> Char -> Command (ViT m) InsertMode InsertMode
    forall {m :: * -> *}.
    Monad m =>
    String -> Char -> Command (ViT m) InsertMode InsertMode
    loop []
        where
            loop :: String -> Char -> Command (ViT m) InsertMode InsertMode
    loop String
    ds Char
    d = (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change (Char -> InsertMode -> InsertMode
    insertChar Char
    d) Command (ViT m) InsertMode InsertMode
    -> Command (ViT m) InsertMode InsertMode
    -> Command (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> [KeyCommand (ViT m) InsertMode InsertMode]
    -> Command (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd [
                            (Char -> Command (ViT m) InsertMode InsertMode)
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s t.
    (Char -> Command m s t) -> KeyCommand m s t
    useChar ((Char -> Command (ViT m) InsertMode InsertMode)
     -> KeyCommand (ViT m) InsertMode InsertMode)
    -> (Char -> Command (ViT m) InsertMode InsertMode)
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall a b. (a -> b) -> a -> b
    $ String -> Char -> Command (ViT m) InsertMode InsertMode
    loop (Char
    dChar -> String -> String
    forall a. a -> [a] -> [a]
    :String
    ds)
                            , Command (ViT m) InsertMode InsertMode
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming (String -> Command (ViT m) InsertMode InsertMode
    forall {m :: * -> *} {s}. Monad m => String -> Command (ViT m) s s
    storeCharInsertion (String -> String
    forall a. [a] -> [a]
    reverse String
    ds))
                            ]
            storeCharInsertion :: String -> Command (ViT m) s s
    storeCharInsertion String
    s = SavedCommand m -> Command (ViT m) s s
    forall (m :: * -> *) s.
    Monad m =>
    SavedCommand m -> Command (ViT m) s s
    storeLastCmd (SavedCommand m -> Command (ViT m) s s)
    -> SavedCommand m -> Command (ViT m) s s
    forall a b. (a -> b) -> a -> b
    $ (ArgMode CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((CommandMode -> CommandMode) -> ArgMode CommandMode -> CommandMode
    forall s. (s -> s) -> ArgMode s -> s
    applyArg
                                                            ((CommandMode -> CommandMode)
     -> ArgMode CommandMode -> CommandMode)
    -> (CommandMode -> CommandMode)
    -> ArgMode CommandMode
    -> CommandMode
    forall a b. (a -> b) -> a -> b
    $ (InsertMode -> InsertMode) -> CommandMode -> CommandMode
    withCommandMode ((InsertMode -> InsertMode) -> CommandMode -> CommandMode)
    -> (InsertMode -> InsertMode) -> CommandMode -> CommandMode
    forall a b. (a -> b) -> a -> b
    $ String -> InsertMode -> InsertMode
    insertString String
    s)
                                                    Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) CommandMode EitherMode -> SavedCommand m
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> EitherMode -> CmdM (ViT m) EitherMode
    forall a. a -> CmdM (ViT m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EitherMode -> CmdM (ViT m) EitherMode)
    -> (CommandMode -> EitherMode)
    -> Command (ViT m) CommandMode EitherMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> EitherMode
    forall a b. a -> Either a b
    Left

    -- If we receive a ^D and the line is empty, return Nothing
    -- otherwise, act like '\n' (mimicking how Readline behaves)
    eofIfEmpty :: (Monad m, Save s, Result s) => Command m s (Maybe String)
    eofIfEmpty :: forall (m :: * -> *) s.
    (Monad m, Save s, Result s) =>
    Command m s (Maybe String)
    eofIfEmpty s
    s
        | s -> InsertMode
    forall s. Save s => s -> InsertMode
    save s
    s InsertMode -> InsertMode -> Bool
    forall a. Eq a => a -> a -> Bool
    == InsertMode
    emptyIM = Maybe String -> CmdM m (Maybe String)
    forall a. a -> CmdM m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe String
    forall a. Maybe a
    Nothing
        | Bool
    otherwise = Command m s (Maybe String)
    forall (m :: * -> *) s.
    (Monad m, Result s) =>
    Command m s (Maybe String)
    finish s
    s

    viCommandActions :: InputCmd CommandMode (Maybe String)
    viCommandActions :: InputCmd CommandMode (Maybe String)
    viCommandActions = [KeyCommand (ViT m) CommandMode (Maybe String)]
    -> Command (ViT m) CommandMode (Maybe String)
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd [
                        Char -> Key
    simpleChar Char
    '\n' Key
    -> Command (ViT m) CommandMode (Maybe String)
    -> KeyCommand (ViT m) CommandMode (Maybe String)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode (Maybe String)
    forall (m :: * -> *) s.
    (Monad m, Result s) =>
    Command m s (Maybe String)
    finish
                        , Char -> Key
    ctrlChar Char
    'd' Key
    -> Command (ViT m) CommandMode (Maybe String)
    -> KeyCommand (ViT m) CommandMode (Maybe String)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode (Maybe String)
    forall (m :: * -> *) s.
    (Monad m, Save s, Result s) =>
    Command m s (Maybe String)
    eofIfEmpty
                        , KeyCommand (ViT m) CommandMode CommandMode
    InputKeyCmd CommandMode CommandMode
    simpleCmdActions KeyCommand (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode (Maybe String)
    -> KeyCommand (ViT m) CommandMode (Maybe String)
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) CommandMode (Maybe String)
    InputCmd CommandMode (Maybe String)
    viCommandActions
                        , KeyCommand (ViT m) CommandMode InsertMode
    InputKeyCmd CommandMode InsertMode
    exitingCommands KeyCommand (ViT m) CommandMode InsertMode
    -> Command (ViT m) InsertMode (Maybe String)
    -> KeyCommand (ViT m) CommandMode (Maybe String)
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) InsertMode (Maybe String)
    InputCmd InsertMode (Maybe String)
    viCommands
                        , KeyCommand (ViT m) CommandMode EitherMode
    InputKeyCmd CommandMode EitherMode
    repeatedCommands KeyCommand (ViT m) CommandMode EitherMode
    -> Command (ViT m) EitherMode (Maybe String)
    -> KeyCommand (ViT m) CommandMode (Maybe String)
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) EitherMode (Maybe String)
    InputCmd EitherMode (Maybe String)
    chooseEitherMode
                        ]
        where
            chooseEitherMode :: InputCmd EitherMode (Maybe String)
            chooseEitherMode :: InputCmd EitherMode (Maybe String)
    chooseEitherMode (Left CommandMode
    cm) = Command (ViT m) CommandMode (Maybe String)
    InputCmd CommandMode (Maybe String)
    viCommandActions CommandMode
    cm
            chooseEitherMode (Right InsertMode
    im) = Command (ViT m) InsertMode (Maybe String)
    InputCmd InsertMode (Maybe String)
    viCommands InsertMode
    im

    exitingCommands :: InputKeyCmd CommandMode InsertMode
    exitingCommands :: InputKeyCmd CommandMode InsertMode
    exitingCommands =  [KeyMap (Command (ViT m) CommandMode InsertMode)]
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd [
                          Char -> Key
    simpleChar Char
    'i' Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> InsertMode)
    -> Command (ViT m) CommandMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change CommandMode -> InsertMode
    insertFromCommandMode
                        , Char -> Key
    simpleChar Char
    'I' Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> InsertMode)
    -> Command (ViT m) CommandMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change (InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToStart (InsertMode -> InsertMode)
    -> (CommandMode -> InsertMode) -> CommandMode -> InsertMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> InsertMode
    insertFromCommandMode)
                        , BaseKey -> Key
    simpleKey BaseKey
    Home Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> InsertMode)
    -> Command (ViT m) CommandMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change (InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToStart (InsertMode -> InsertMode)
    -> (CommandMode -> InsertMode) -> CommandMode -> InsertMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> InsertMode
    insertFromCommandMode)
                        , Char -> Key
    simpleChar Char
    'a' Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> InsertMode)
    -> Command (ViT m) CommandMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change CommandMode -> InsertMode
    appendFromCommandMode
                        , Char -> Key
    simpleChar Char
    'A' Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> InsertMode)
    -> Command (ViT m) CommandMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change (InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToEnd (InsertMode -> InsertMode)
    -> (CommandMode -> InsertMode) -> CommandMode -> InsertMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> InsertMode
    appendFromCommandMode)
                        , BaseKey -> Key
    simpleKey BaseKey
    End Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> InsertMode)
    -> Command (ViT m) CommandMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change (InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToStart  (InsertMode -> InsertMode)
    -> (CommandMode -> InsertMode) -> CommandMode -> InsertMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> InsertMode
    insertFromCommandMode)
                        , Char -> Key
    simpleChar Char
    's' Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> InsertMode)
    -> Command (ViT m) CommandMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change (CommandMode -> InsertMode
    insertFromCommandMode (CommandMode -> InsertMode)
    -> (CommandMode -> CommandMode) -> CommandMode -> InsertMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> CommandMode
    deleteChar)
                        , Char -> Key
    simpleChar Char
    'S' Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode (ArgMode CommandMode)
    forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
    noArg Command (ViT m) CommandMode (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    -> Command (ViT m) CommandMode InsertMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
    killAndStoreI KillHelper
    killAll
                        , Char -> Key
    simpleChar Char
    'C' Key
    -> Command (ViT m) CommandMode InsertMode
    -> KeyMap (Command (ViT m) CommandMode InsertMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode (ArgMode CommandMode)
    forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
    noArg Command (ViT m) CommandMode (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    -> Command (ViT m) CommandMode InsertMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
    killAndStoreI ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToEnd)
                        ]

    simpleCmdActions :: InputKeyCmd CommandMode CommandMode
    simpleCmdActions :: InputKeyCmd CommandMode CommandMode
    simpleCmdActions = [KeyMap (Command (ViT m) CommandMode CommandMode)]
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd [
                        Char -> Key
    simpleChar Char
    '\ESC' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> CommandMode)
    -> Command (ViT m) CommandMode CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change CommandMode -> CommandMode
    forall a. a -> a
    id -- helps break out of loops
                        , Char -> Key
    simpleChar Char
    'r'   Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    InputCmd CommandMode CommandMode
    replaceOnce
                        , Char -> Key
    simpleChar Char
    'R'   Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    InputCmd CommandMode CommandMode
    replaceLoop
                        , Char -> Key
    simpleChar Char
    'D' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode (ArgMode CommandMode)
    forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
    noArg Command (ViT m) CommandMode (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    killAndStoreCmd ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToEnd)
                        , Char -> Key
    ctrlChar Char
    'l' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s. Command m s s
    clearScreenCmd
                        , Char -> Key
    simpleChar Char
    'u' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s.
    (MonadState Undo m, Save s) =>
    Command m s s
    commandUndo
                        , Char -> Key
    ctrlChar Char
    'r' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s.
    (MonadState Undo m, Save s) =>
    Command m s s
    commandRedo
                        -- vi-mode quirk: history is put at the start of the line.
                        , Char -> Key
    simpleChar Char
    'j' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    forall s (m :: * -> *).
    (Save s, MonadState HistLog m) =>
    Command m s s
    historyForward Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> (CommandMode -> CommandMode)
    -> Command (ViT m) CommandMode CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change CommandMode -> CommandMode
    forall s. Move s => s -> s
    moveToStart
                        , Char -> Key
    simpleChar Char
    'k' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    forall s (m :: * -> *).
    (Save s, MonadState HistLog m) =>
    Command m s s
    historyBack Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> (CommandMode -> CommandMode)
    -> Command (ViT m) CommandMode CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change CommandMode -> CommandMode
    forall s. Move s => s -> s
    moveToStart
                        , BaseKey -> Key
    simpleKey BaseKey
    DownKey Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    forall s (m :: * -> *).
    (Save s, MonadState HistLog m) =>
    Command m s s
    historyForward  Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> (CommandMode -> CommandMode)
    -> Command (ViT m) CommandMode CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change CommandMode -> CommandMode
    forall s. Move s => s -> s
    moveToStart
                        , BaseKey -> Key
    simpleKey BaseKey
    UpKey Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode CommandMode
    forall s (m :: * -> *).
    (Save s, MonadState HistLog m) =>
    Command m s s
    historyBack Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> (CommandMode -> CommandMode)
    -> Command (ViT m) CommandMode CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change CommandMode -> CommandMode
    forall s. Move s => s -> s
    moveToStart
                        , Char -> Key
    simpleChar Char
    '/' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Char -> Direction -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *).
    Monad m =>
    Char -> Direction -> Command (ViT m) CommandMode CommandMode
    viEnterSearch Char
    '/' Direction
    Reverse
                        , Char -> Key
    simpleChar Char
    '?' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Char -> Direction -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *).
    Monad m =>
    Char -> Direction -> Command (ViT m) CommandMode CommandMode
    viEnterSearch Char
    '?' Direction
    Forward
                        , Char -> Key
    simpleChar Char
    'n' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *).
    Monad m =>
    Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
    viSearchHist Direction
    Reverse []
                        , Char -> Key
    simpleChar Char
    'N' Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *).
    Monad m =>
    Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
    viSearchHist Direction
    Forward []
                        , BaseKey -> Key
    simpleKey BaseKey
    KillLine Key
    -> Command (ViT m) CommandMode CommandMode
    -> KeyMap (Command (ViT m) CommandMode CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) CommandMode (ArgMode CommandMode)
    forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
    noArg Command (ViT m) CommandMode (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    killAndStoreCmd ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToStart)
                        ]

    replaceOnce :: InputCmd CommandMode CommandMode
    replaceOnce :: InputCmd CommandMode CommandMode
    replaceOnce = KeyCommand (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s.
    Monad m =>
    KeyCommand m s s -> Command m s s
    try (KeyCommand (ViT m) CommandMode CommandMode
     -> Command (ViT m) CommandMode CommandMode)
    -> KeyCommand (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> CommandMode -> CommandMode)
    -> KeyCommand (ViT m) CommandMode CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (Char -> s -> t) -> KeyCommand m s t
    changeFromChar Char -> CommandMode -> CommandMode
    replaceChar

    repeatedCommands :: InputKeyCmd CommandMode EitherMode
    repeatedCommands :: InputKeyCmd CommandMode EitherMode
    repeatedCommands = [KeyMap (Command (ViT m) CommandMode EitherMode)]
    -> KeyMap (Command (ViT m) CommandMode EitherMode)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd [KeyMap (Command (ViT m) CommandMode EitherMode)
    argumented, Command (ViT m) CommandMode (ArgMode CommandMode)
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyMap (Command (ViT m) CommandMode EitherMode)
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> KeyCommand m t u -> KeyCommand m s u
    doBefore Command (ViT m) CommandMode (ArgMode CommandMode)
    forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
    noArg KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    InputKeyCmd (ArgMode CommandMode) EitherMode
    repeatableCommands]
        where
            start :: KeyCommand (ViT m) CommandMode (ArgMode CommandMode)
    start = (Int -> CommandMode -> ArgMode CommandMode)
    -> String -> KeyCommand (ViT m) CommandMode (ArgMode CommandMode)
    forall (m :: * -> *) t s.
    (Monad m, LineState t) =>
    (Int -> s -> t) -> String -> KeyCommand m s t
    foreachDigit Int -> CommandMode -> ArgMode CommandMode
    forall s. Int -> s -> ArgMode s
    startArg [Char
    '1'..Char
    '9']
            addDigit :: KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    addDigit = (Int -> ArgMode CommandMode -> ArgMode CommandMode)
    -> String
    -> KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall (m :: * -> *) t s.
    (Monad m, LineState t) =>
    (Int -> s -> t) -> String -> KeyCommand m s t
    foreachDigit Int -> ArgMode CommandMode -> ArgMode CommandMode
    forall s. Int -> ArgMode s -> ArgMode s
    addNum [Char
    '0'..Char
    '9']
            argumented :: KeyMap (Command (ViT m) CommandMode EitherMode)
    argumented = KeyCommand (ViT m) CommandMode (ArgMode CommandMode)
    start KeyCommand (ViT m) CommandMode (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyMap (Command (ViT m) CommandMode EitherMode)
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) (ArgMode CommandMode) EitherMode
    loop
            loop :: Command (ViT m) (ArgMode CommandMode) EitherMode
    loop = [KeyCommand (ViT m) (ArgMode CommandMode) EitherMode]
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd [KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    addDigit KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) (ArgMode CommandMode) EitherMode
    loop
                                , KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    InputKeyCmd (ArgMode CommandMode) EitherMode
    repeatableCommands
                                -- if no match, bail out.
                                , Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming ((ArgMode CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState) KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) CommandMode EitherMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> EitherMode -> CmdM (ViT m) EitherMode
    forall a. a -> CmdM (ViT m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EitherMode -> CmdM (ViT m) EitherMode)
    -> (CommandMode -> EitherMode)
    -> Command (ViT m) CommandMode EitherMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> EitherMode
    forall a b. a -> Either a b
    Left
                                ]

    pureMovements :: InputKeyCmd (ArgMode CommandMode) CommandMode
    pureMovements :: InputKeyCmd (ArgMode CommandMode) CommandMode
    pureMovements = [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd ([KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
     -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
    -> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a b. (a -> b) -> a -> b
    $ [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    charMovements [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    -> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    -> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    forall a. [a] -> [a] -> [a]
    ++ ((Key, InsertMode -> InsertMode)
     -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
    -> [(Key, InsertMode -> InsertMode)]
    -> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Key, InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall {m :: * -> *}.
    Monad m =>
    (Key, InsertMode -> InsertMode)
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    mkSimpleCommand [(Key, InsertMode -> InsertMode)]
    movements
        where
            charMovements :: [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    charMovements = [ Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall {m :: * -> *}.
    Monad m =>
    Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    charMovement Char
    'f' ((Char -> InsertMode -> InsertMode)
     -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a b. (a -> b) -> a -> b
    $ \Char
    c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    overChar (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    c)
                            , Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall {m :: * -> *}.
    Monad m =>
    Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    charMovement Char
    'F' ((Char -> InsertMode -> InsertMode)
     -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a b. (a -> b) -> a -> b
    $ \Char
    c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    overChar (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    c)
                            , Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall {m :: * -> *}.
    Monad m =>
    Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    charMovement Char
    't' ((Char -> InsertMode -> InsertMode)
     -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a b. (a -> b) -> a -> b
    $ \Char
    c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    beforeChar (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    c)
                            , Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall {m :: * -> *}.
    Monad m =>
    Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    charMovement Char
    'T' ((Char -> InsertMode -> InsertMode)
     -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a b. (a -> b) -> a -> b
    $ \Char
    c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    afterChar (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    c)
                            ]
            mkSimpleCommand :: (Key, InsertMode -> InsertMode)
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    mkSimpleCommand (Key
    k,InsertMode -> InsertMode
    move) = Key
    k Key
    -> Command m (ArgMode CommandMode) CommandMode
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> (ArgMode CommandMode -> CommandMode)
    -> Command m (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((InsertMode -> InsertMode) -> ArgMode CommandMode -> CommandMode
    applyCmdArg InsertMode -> InsertMode
    move)
            charMovement :: Char
    -> (Char -> InsertMode -> InsertMode)
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    charMovement Char
    c Char -> InsertMode -> InsertMode
    move = Char -> Key
    simpleChar Char
    c Key
    -> Command m (ArgMode CommandMode) CommandMode
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> [KeyMap (Command m (ArgMode CommandMode) CommandMode)]
    -> Command m (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd [
                                            (Char -> Command m (ArgMode CommandMode) CommandMode)
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    forall (m :: * -> *) s t.
    (Char -> Command m s t) -> KeyCommand m s t
    useChar ((ArgMode CommandMode -> CommandMode)
    -> Command m (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((ArgMode CommandMode -> CommandMode)
     -> Command m (ArgMode CommandMode) CommandMode)
    -> (Char -> ArgMode CommandMode -> CommandMode)
    -> Char
    -> Command m (ArgMode CommandMode) CommandMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (InsertMode -> InsertMode) -> ArgMode CommandMode -> CommandMode
    applyCmdArg ((InsertMode -> InsertMode) -> ArgMode CommandMode -> CommandMode)
    -> (Char -> InsertMode -> InsertMode)
    -> Char
    -> ArgMode CommandMode
    -> CommandMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> InsertMode -> InsertMode
    move)
                                            , Command m (ArgMode CommandMode) CommandMode
    -> KeyMap (Command m (ArgMode CommandMode) CommandMode)
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming ((ArgMode CommandMode -> CommandMode)
    -> Command m (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState)
                                            ]

    useMovementsForKill :: Command m s t -> (KillHelper -> Command m s t) -> KeyCommand m s t
    useMovementsForKill :: forall (m :: * -> *) s t.
    Command m s t -> (KillHelper -> Command m s t) -> KeyCommand m s t
    useMovementsForKill Command m s t
    alternate KillHelper -> Command m s t
    useHelper = [KeyMap (Command m s t)] -> KeyMap (Command m s t)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd ([KeyMap (Command m s t)] -> KeyMap (Command m s t))
    -> [KeyMap (Command m s t)] -> KeyMap (Command m s t)
    forall a b. (a -> b) -> a -> b
    $
                [KeyMap (Command m s t)]
    specialCases
                [KeyMap (Command m s t)]
    -> [KeyMap (Command m s t)] -> [KeyMap (Command m s t)]
    forall a. [a] -> [a] -> [a]
    ++ ((Key, InsertMode -> InsertMode) -> KeyMap (Command m s t))
    -> [(Key, InsertMode -> InsertMode)] -> [KeyMap (Command m s t)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Key
    k,InsertMode -> InsertMode
    move) -> Key
    k Key -> Command m s t -> KeyMap (Command m s t)
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command m s t
    useHelper ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    move)) [(Key, InsertMode -> InsertMode)]
    movements
        where
            specialCases :: [KeyMap (Command m s t)]
    specialCases = [ Char -> Key
    simpleChar Char
    'e' Key -> Command m s t -> KeyMap (Command m s t)
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command m s t
    useHelper ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    goToWordDelEnd)
                           , Char -> Key
    simpleChar Char
    'E' Key -> Command m s t -> KeyMap (Command m s t)
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command m s t
    useHelper ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    goToBigWordDelEnd)
                           , Char -> Key
    simpleChar Char
    '%' Key -> Command m s t -> KeyMap (Command m s t)
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command m s t
    useHelper ((InsertMode -> ([Grapheme], InsertMode)) -> KillHelper
    GenericKill InsertMode -> ([Grapheme], InsertMode)
    deleteMatchingBrace)
                           -- Note 't' and 'f' behave differently than in pureMovements.
                           , Char
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    charMovement Char
    'f' ((Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t))
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    forall a b. (a -> b) -> a -> b
    $ \Char
    c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    afterChar (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    c)
                           , Char
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    charMovement Char
    'F' ((Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t))
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    forall a b. (a -> b) -> a -> b
    $ \Char
    c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    overChar (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    c)
                           , Char
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    charMovement Char
    't' ((Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t))
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    forall a b. (a -> b) -> a -> b
    $ \Char
    c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    overChar (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    c)
                           , Char
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    charMovement Char
    'T' ((Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t))
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    forall a b. (a -> b) -> a -> b
    $ \Char
    c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    afterChar (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    c)
                           ]
            charMovement :: Char
    -> (Char -> InsertMode -> InsertMode) -> KeyMap (Command m s t)
    charMovement Char
    c Char -> InsertMode -> InsertMode
    move = Char -> Key
    simpleChar Char
    c Key -> Command m s t -> KeyMap (Command m s t)
    forall a. Key -> a -> KeyMap a
    +> [KeyMap (Command m s t)] -> Command m s t
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd [
                                        (Char -> Command m s t) -> KeyMap (Command m s t)
    forall (m :: * -> *) s t.
    (Char -> Command m s t) -> KeyCommand m s t
    useChar (KillHelper -> Command m s t
    useHelper (KillHelper -> Command m s t)
    -> (Char -> KillHelper) -> Char -> Command m s t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (InsertMode -> InsertMode) -> KillHelper
    SimpleMove ((InsertMode -> InsertMode) -> KillHelper)
    -> (Char -> InsertMode -> InsertMode) -> Char -> KillHelper
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> InsertMode -> InsertMode
    move)
                                        , Command m s t -> KeyMap (Command m s t)
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming Command m s t
    alternate]

    repeatableCommands :: InputKeyCmd (ArgMode CommandMode) EitherMode
    repeatableCommands :: InputKeyCmd (ArgMode CommandMode) EitherMode
    repeatableCommands = [KeyMap (Command (ViT m) (ArgMode CommandMode) EitherMode)]
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) EitherMode)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd
                            [ KeyMap (Command (ViT m) (ArgMode CommandMode) EitherMode)
    InputKeyCmd (ArgMode CommandMode) EitherMode
    repeatableCmdToIMode
                            , KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    InputKeyCmd (ArgMode CommandMode) CommandMode
    repeatableCmdMode KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) CommandMode EitherMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) EitherMode)
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> EitherMode -> CmdM (ViT m) EitherMode
    forall a. a -> CmdM (ViT m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EitherMode -> CmdM (ViT m) EitherMode)
    -> (CommandMode -> EitherMode)
    -> Command (ViT m) CommandMode EitherMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> EitherMode
    forall a b. a -> Either a b
    Left
                            , Char -> Key
    simpleChar Char
    '.' Key
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) EitherMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall s (m :: * -> *).
    (Save s, MonadState Undo m) =>
    Command m s s
    saveForUndo Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall {m :: * -> *}.
    Monad m =>
    ArgMode CommandMode -> CmdM (ViT m) EitherMode
    runLastCommand
                            ]
        where
            runLastCommand :: ArgMode CommandMode -> CmdM (ViT m) EitherMode
    runLastCommand ArgMode CommandMode
    s = (ViState m -> ArgMode CommandMode -> CmdM (ViT m) EitherMode)
    -> CmdM (ViT m) (ViState m)
    -> CmdM (ViT m) (ArgMode CommandMode -> CmdM (ViT m) EitherMode)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM ViState m -> ArgMode CommandMode -> CmdM (ViT m) EitherMode
    forall (m :: * -> *). ViState m -> SavedCommand m
    lastCommand CmdM (ViT m) (ViState m)
    forall s (m :: * -> *). MonadState s m => m s
    get CmdM (ViT m) (ArgMode CommandMode -> CmdM (ViT m) EitherMode)
    -> ((ArgMode CommandMode -> CmdM (ViT m) EitherMode)
        -> CmdM (ViT m) EitherMode)
    -> CmdM (ViT m) EitherMode
    forall a b.
    CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= ((ArgMode CommandMode -> CmdM (ViT m) EitherMode)
    -> ArgMode CommandMode -> CmdM (ViT m) EitherMode
    forall a b. (a -> b) -> a -> b
    $ ArgMode CommandMode
    s)

    repeatableCmdMode :: InputKeyCmd (ArgMode CommandMode) CommandMode
    repeatableCmdMode :: InputKeyCmd (ArgMode CommandMode) CommandMode
    repeatableCmdMode = [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd
                        [ Char -> Key
    simpleChar Char
    'x' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall {m :: * -> *}.
    Monad m =>
    (CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    repeatableChange CommandMode -> CommandMode
    deleteChar
                        , Char -> Key
    simpleChar Char
    'X' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall {m :: * -> *}.
    Monad m =>
    (CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    repeatableChange ((InsertMode -> InsertMode) -> CommandMode -> CommandMode
    withCommandMode InsertMode -> InsertMode
    deletePrev)
                        , Char -> Key
    simpleChar Char
    '~' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> (CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall {m :: * -> *}.
    Monad m =>
    (CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    repeatableChange (CommandMode -> CommandMode
    forall s. Move s => s -> s
    goRight (CommandMode -> CommandMode)
    -> (CommandMode -> CommandMode) -> CommandMode -> CommandMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> CommandMode
    flipCase)
                        , Char -> Key
    simpleChar Char
    'p' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    Monad m =>
    Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    storedCmdAction (([Grapheme] -> CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall s (m :: * -> *).
    (Save s, MonadState KillRing m, MonadState Undo m) =>
    ([Grapheme] -> s -> s) -> Command m (ArgMode s) s
    pasteCommand [Grapheme] -> CommandMode -> CommandMode
    pasteGraphemesAfter)
                        , Char -> Key
    simpleChar Char
    'P' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    Monad m =>
    Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    storedCmdAction (([Grapheme] -> CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall s (m :: * -> *).
    (Save s, MonadState KillRing m, MonadState Undo m) =>
    ([Grapheme] -> s -> s) -> Command m (ArgMode s) s
    pasteCommand [Grapheme] -> CommandMode -> CommandMode
    pasteGraphemesBefore)
                        , Char -> Key
    simpleChar Char
    'd' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) (ArgMode CommandMode) CommandMode
    InputCmd (ArgMode CommandMode) CommandMode
    deletionCmd
                        , Char -> Key
    simpleChar Char
    'y' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) (ArgMode CommandMode) CommandMode
    InputCmd (ArgMode CommandMode) CommandMode
    yankCommand
                        , Char -> Key
    ctrlChar Char
    'w' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    killAndStoreCmd KillHelper
    wordErase
                        , KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
    InputKeyCmd (ArgMode CommandMode) CommandMode
    pureMovements
                        ]
        where
            repeatableChange :: (CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    repeatableChange CommandMode -> CommandMode
    f = Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    Monad m =>
    Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    storedCmdAction (Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall s (m :: * -> *).
    (Save s, MonadState Undo m) =>
    Command m s s
    saveForUndo Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> (ArgMode CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((CommandMode -> CommandMode) -> ArgMode CommandMode -> CommandMode
    forall s. (s -> s) -> ArgMode s -> s
    applyArg CommandMode -> CommandMode
    f))

    flipCase :: CommandMode -> CommandMode
    flipCase :: CommandMode -> CommandMode
    flipCase CommandMode
    CEmpty = CommandMode
    CEmpty
    flipCase (CMode [Grapheme]
    xs Grapheme
    y [Grapheme]
    zs) = [Grapheme] -> Grapheme -> [Grapheme] -> CommandMode
    CMode [Grapheme]
    xs ((Char -> Char) -> Grapheme -> Grapheme
    modifyBaseChar Char -> Char
    flipCaseG Grapheme
    y) [Grapheme]
    zs
        where
            flipCaseG :: Char -> Char
    flipCaseG Char
    c | Char -> Bool
    isLower Char
    c = Char -> Char
    toUpper Char
    c
                        | Bool
    otherwise = Char -> Char
    toLower Char
    c

    repeatableCmdToIMode :: InputKeyCmd (ArgMode CommandMode) EitherMode
    repeatableCmdToIMode :: InputKeyCmd (ArgMode CommandMode) EitherMode
    repeatableCmdToIMode = Char -> Key
    simpleChar Char
    'c' Key
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyMap (Command (ViT m) (ArgMode CommandMode) EitherMode)
    forall a. Key -> a -> KeyMap a
    +> Command (ViT m) (ArgMode CommandMode) EitherMode
    InputCmd (ArgMode CommandMode) EitherMode
    deletionToInsertCmd

    deletionCmd :: InputCmd (ArgMode CommandMode) CommandMode
    deletionCmd :: InputCmd (ArgMode CommandMode) CommandMode
    deletionCmd = [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd
                        [ KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall s. LineState s => InputKeyCmd (ArgMode s) (ArgMode s)
    InputKeyCmd (ArgMode CommandMode) (ArgMode CommandMode)
    reinputArg KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) (ArgMode CommandMode) CommandMode
    InputCmd (ArgMode CommandMode) CommandMode
    deletionCmd
                        , Char -> Key
    simpleChar Char
    'd' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    killAndStoreCmd KillHelper
    killAll
                        , Command (ViT m) (ArgMode CommandMode) CommandMode
    -> (KillHelper
        -> Command (ViT m) (ArgMode CommandMode) CommandMode)
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t.
    Command m s t -> (KillHelper -> Command m s t) -> KeyCommand m s t
    useMovementsForKill ((ArgMode CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState) KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    killAndStoreCmd
                        , Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming ((ArgMode CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState)
                        ]

    deletionToInsertCmd :: InputCmd (ArgMode CommandMode) EitherMode
    deletionToInsertCmd :: InputCmd (ArgMode CommandMode) EitherMode
    deletionToInsertCmd = [KeyCommand (ViT m) (ArgMode CommandMode) EitherMode]
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd
            [ KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall s. LineState s => InputKeyCmd (ArgMode s) (ArgMode s)
    InputKeyCmd (ArgMode CommandMode) (ArgMode CommandMode)
    reinputArg KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) (ArgMode CommandMode) EitherMode
    InputCmd (ArgMode CommandMode) EitherMode
    deletionToInsertCmd
            , Char -> Key
    simpleChar Char
    'c' Key
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    killAndStoreIE KillHelper
    killAll
            -- vim, for whatever reason, treats cw same as ce and cW same as cE.
            -- readline does this too, so we should also.
            , Char -> Key
    simpleChar Char
    'w' Key
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    killAndStoreIE ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    goToWordDelEnd)
            , Char -> Key
    simpleChar Char
    'W' Key
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    killAndStoreIE ((InsertMode -> InsertMode) -> KillHelper
    SimpleMove InsertMode -> InsertMode
    goToBigWordDelEnd)
            , Command (ViT m) (ArgMode CommandMode) EitherMode
    -> (KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode)
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *) s t.
    Command m s t -> (KillHelper -> Command m s t) -> KeyCommand m s t
    useMovementsForKill ((CommandMode -> EitherMode)
    -> CmdM (ViT m) CommandMode -> CmdM (ViT m) EitherMode
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM CommandMode -> EitherMode
    forall a b. a -> Either a b
    Left (CmdM (ViT m) CommandMode -> CmdM (ViT m) EitherMode)
    -> (ArgMode CommandMode -> CmdM (ViT m) CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ArgMode CommandMode -> CommandMode)
    -> ArgMode CommandMode -> CmdM (ViT m) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState) KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    killAndStoreIE
            , Command (ViT m) (ArgMode CommandMode) EitherMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) EitherMode
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming (EitherMode -> CmdM (ViT m) EitherMode
    forall a. a -> CmdM (ViT m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EitherMode -> CmdM (ViT m) EitherMode)
    -> (ArgMode CommandMode -> EitherMode)
    -> Command (ViT m) (ArgMode CommandMode) EitherMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CommandMode -> EitherMode
    forall a b. a -> Either a b
    Left (CommandMode -> EitherMode)
    -> (ArgMode CommandMode -> CommandMode)
    -> ArgMode CommandMode
    -> EitherMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState)
            ]

    yankCommand :: InputCmd (ArgMode CommandMode) CommandMode
    yankCommand :: InputCmd (ArgMode CommandMode) CommandMode
    yankCommand = [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd
                    [ KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall s. LineState s => InputKeyCmd (ArgMode s) (ArgMode s)
    InputKeyCmd (ArgMode CommandMode) (ArgMode CommandMode)
    reinputArg KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) (ArgMode CommandMode) CommandMode
    InputCmd (ArgMode CommandMode) CommandMode
    yankCommand
                    , Char -> Key
    simpleChar Char
    'y' Key
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall a. Key -> a -> KeyMap a
    +> KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    copyAndStore KillHelper
    killAll
                    , Command (ViT m) (ArgMode CommandMode) CommandMode
    -> (KillHelper
        -> Command (ViT m) (ArgMode CommandMode) CommandMode)
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t.
    Command m s t -> (KillHelper -> Command m s t) -> KeyCommand m s t
    useMovementsForKill ((ArgMode CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState) KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    copyAndStore
                    , Command (ViT m) (ArgMode CommandMode) CommandMode
    -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming ((ArgMode CommandMode -> CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ArgMode CommandMode -> CommandMode
    forall s. ArgMode s -> s
    argState)
                    ]
        where
            copyAndStore :: KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    copyAndStore = Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    Monad m =>
    Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    storedCmdAction (Command (ViT m) (ArgMode CommandMode) CommandMode
     -> Command (ViT m) (ArgMode CommandMode) CommandMode)
    -> (KillHelper
        -> Command (ViT m) (ArgMode CommandMode) CommandMode)
    -> KillHelper
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s.
    (MonadState KillRing m, Save s) =>
    KillHelper -> Command m (ArgMode s) s
    copyFromArgHelper

    reinputArg :: LineState s => InputKeyCmd (ArgMode s) (ArgMode s)
    reinputArg :: forall s. LineState s => InputKeyCmd (ArgMode s) (ArgMode s)
    reinputArg = (Int -> ArgMode s -> ArgMode s)
    -> String -> KeyCommand (ViT m) (ArgMode s) (ArgMode s)
    forall (m :: * -> *) t s.
    (Monad m, LineState t) =>
    (Int -> s -> t) -> String -> KeyCommand m s t
    foreachDigit Int -> ArgMode s -> ArgMode s
    forall s. Int -> ArgMode s -> ArgMode s
    restartArg [Char
    '1'..Char
    '9'] KeyCommand (ViT m) (ArgMode s) (ArgMode s)
    -> Command (ViT m) (ArgMode s) (ArgMode s)
    -> KeyCommand (ViT m) (ArgMode s) (ArgMode s)
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) (ArgMode s) (ArgMode s)
    loop
      where
        restartArg :: Int -> ArgMode b -> ArgMode b
    restartArg Int
    n = Int -> b -> ArgMode b
    forall s. Int -> s -> ArgMode s
    startArg Int
    n (b -> ArgMode b) -> (ArgMode b -> b) -> ArgMode b -> ArgMode b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ArgMode b -> b
    forall s. ArgMode s -> s
    argState
        loop :: Command (ViT m) (ArgMode s) (ArgMode s)
    loop = [KeyCommand (ViT m) (ArgMode s) (ArgMode s)]
    -> Command (ViT m) (ArgMode s) (ArgMode s)
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd
                [ (Int -> ArgMode s -> ArgMode s)
    -> String -> KeyCommand (ViT m) (ArgMode s) (ArgMode s)
    forall (m :: * -> *) t s.
    (Monad m, LineState t) =>
    (Int -> s -> t) -> String -> KeyCommand m s t
    foreachDigit Int -> ArgMode s -> ArgMode s
    forall s. Int -> ArgMode s -> ArgMode s
    addNum [Char
    '0'..Char
    '9'] KeyCommand (ViT m) (ArgMode s) (ArgMode s)
    -> Command (ViT m) (ArgMode s) (ArgMode s)
    -> KeyCommand (ViT m) (ArgMode s) (ArgMode s)
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) (ArgMode s) (ArgMode s)
    loop
                , Command (ViT m) (ArgMode s) (ArgMode s)
    -> KeyCommand (ViT m) (ArgMode s) (ArgMode s)
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming Command (ViT m) (ArgMode s) (ArgMode s)
    forall a. a -> CmdM (ViT m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return
                ]

    goToWordDelEnd, goToBigWordDelEnd :: InsertMode -> InsertMode
    goToWordDelEnd :: InsertMode -> InsertMode
    goToWordDelEnd = (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    atStart (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Bool
    isWordChar)
                                        (InsertMode -> Bool) -> (InsertMode -> Bool) -> InsertMode -> Bool
    forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
    .||. (Char -> Bool) -> InsertMode -> Bool
    atStart (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Bool
    isOtherChar)
    goToBigWordDelEnd :: InsertMode -> InsertMode
    goToBigWordDelEnd = (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    atStart (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Bool
    isBigWordChar)

    movements :: [(Key,InsertMode -> InsertMode)]
    movements :: [(Key, InsertMode -> InsertMode)]
    movements = [ (Char -> Key
    simpleChar Char
    'h', InsertMode -> InsertMode
    forall s. Move s => s -> s
    goLeft)
                , (Char -> Key
    simpleChar Char
    'l', InsertMode -> InsertMode
    forall s. Move s => s -> s
    goRight)
                , (Char -> Key
    simpleChar Char
    ' ', InsertMode -> InsertMode
    forall s. Move s => s -> s
    goRight)
                , (BaseKey -> Key
    simpleKey BaseKey
    LeftKey, InsertMode -> InsertMode
    forall s. Move s => s -> s
    goLeft)
                , (BaseKey -> Key
    simpleKey BaseKey
    RightKey, InsertMode -> InsertMode
    forall s. Move s => s -> s
    goRight)
                , (Char -> Key
    simpleChar Char
    '0', InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToStart)
                , (Char -> Key
    simpleChar Char
    '$', InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToEnd)
                , (Char -> Key
    simpleChar Char
    '^', (Char -> Bool) -> InsertMode -> InsertMode
    skipRight Char -> Bool
    isSpace (InsertMode -> InsertMode)
    -> (InsertMode -> InsertMode) -> InsertMode -> InsertMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . InsertMode -> InsertMode
    forall s. Move s => s -> s
    moveToStart)
                , (Char -> Key
    simpleChar Char
    '%', InsertMode -> InsertMode
    findMatchingBrace)
                ------------------
                -- Word movements
                -- move to the start of the next word
                , (Char -> Key
    simpleChar Char
    'w', (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $
                                    (Char -> Bool) -> InsertMode -> Bool
    atStart Char -> Bool
    isWordChar (InsertMode -> Bool) -> (InsertMode -> Bool) -> InsertMode -> Bool
    forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
    .||. (Char -> Bool) -> InsertMode -> Bool
    atStart Char -> Bool
    isOtherChar)
                , (Char -> Key
    simpleChar Char
    'W', (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((Char -> Bool) -> InsertMode -> Bool
    atStart Char -> Bool
    isBigWordChar))
                -- move to the beginning of the previous word
                , (Char -> Key
    simpleChar Char
    'b', (InsertMode -> Bool) -> InsertMode -> InsertMode
    goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $
                                    (Char -> Bool) -> InsertMode -> Bool
    atStart Char -> Bool
    isWordChar (InsertMode -> Bool) -> (InsertMode -> Bool) -> InsertMode -> Bool
    forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
    .||. (Char -> Bool) -> InsertMode -> Bool
    atStart Char -> Bool
    isOtherChar)
                , (Char -> Key
    simpleChar Char
    'B', (InsertMode -> Bool) -> InsertMode -> InsertMode
    goLeftUntil ((Char -> Bool) -> InsertMode -> Bool
    atStart Char -> Bool
    isBigWordChar))
                -- move to the end of the current word
                , (Char -> Key
    simpleChar Char
    'e', (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $
                                    (Char -> Bool) -> InsertMode -> Bool
    atEnd Char -> Bool
    isWordChar (InsertMode -> Bool) -> (InsertMode -> Bool) -> InsertMode -> Bool
    forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
    .||. (Char -> Bool) -> InsertMode -> Bool
    atEnd Char -> Bool
    isOtherChar)
                , (Char -> Key
    simpleChar Char
    'E', (InsertMode -> Bool) -> InsertMode -> InsertMode
    goRightUntil ((Char -> Bool) -> InsertMode -> Bool
    atEnd Char -> Bool
    isBigWordChar))
                ]

    {-
    From IEEE 1003.1:
    A "bigword" consists of: a maximal sequence of non-blanks preceded and followed by blanks
    A "word" consists of either:
     - a maximal sequence of wordChars, delimited at both ends by non-wordchars
     - a maximal sequence of non-blank non-wordchars, delimited at both ends by either blanks
       or a wordchar.
    -}
    isBigWordChar, isWordChar, isOtherChar :: Char -> Bool
    isBigWordChar :: Char -> Bool
    isBigWordChar = Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Bool
    isSpace
    isWordChar :: Char -> Bool
    isWordChar = Char -> Bool
    isAlphaNum (Char -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
    .||. (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Char
    '_')
    isOtherChar :: Char -> Bool
    isOtherChar = Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> Bool
    isSpace (Char -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
    .||. Char -> Bool
    isWordChar)

    (.||.) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
    (a -> Bool
    f .||. :: forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
    .||. a -> Bool
    g) a
    x = a -> Bool
    f a
    x Bool -> Bool -> Bool
    || a -> Bool
    g a
    x

    foreachDigit :: (Monad m, LineState t) => (Int -> s -> t) -> [Char]
                    -> KeyCommand m s t
    foreachDigit :: forall (m :: * -> *) t s.
    (Monad m, LineState t) =>
    (Int -> s -> t) -> String -> KeyCommand m s t
    foreachDigit Int -> s -> t
    f String
    ds = [KeyMap (Command m s t)] -> KeyMap (Command m s t)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd ([KeyMap (Command m s t)] -> KeyMap (Command m s t))
    -> [KeyMap (Command m s t)] -> KeyMap (Command m s t)
    forall a b. (a -> b) -> a -> b
    $ (Char -> KeyMap (Command m s t))
    -> String -> [KeyMap (Command m s t)]
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> KeyMap (Command m s t)
    forall {m :: * -> *}. Monad m => Char -> KeyMap (Command m s t)
    digitCmd String
    ds
        where digitCmd :: Char -> KeyMap (Command m s t)
    digitCmd Char
    d = Char -> Key
    simpleChar Char
    d Key -> Command m s t -> KeyMap (Command m s t)
    forall a. Key -> a -> KeyMap a
    +> (s -> t) -> Command m s t
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change (Int -> s -> t
    f (Char -> Int
    forall {a}. Enum a => a -> Int
    toDigit Char
    d))
              toDigit :: a -> Int
    toDigit a
    d = a -> Int
    forall {a}. Enum a => a -> Int
    fromEnum a
    d Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Char -> Int
    forall {a}. Enum a => a -> Int
    fromEnum Char
    '0'

    -- This mimics the ctrl-w command in readline's vi mode, which corresponds to
    -- the tty's werase character.
    wordErase :: KillHelper
    wordErase :: KillHelper
    wordErase = (InsertMode -> InsertMode) -> KillHelper
    SimpleMove ((InsertMode -> InsertMode) -> KillHelper)
    -> (InsertMode -> InsertMode) -> KillHelper
    forall a b. (a -> b) -> a -> b
    $ (InsertMode -> Bool) -> InsertMode -> InsertMode
    goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
    -> (InsertMode -> Bool) -> InsertMode -> InsertMode
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> InsertMode -> Bool
    atStart Char -> Bool
    isBigWordChar

    ------------------
    -- Matching braces

    findMatchingBrace :: InsertMode -> InsertMode
    findMatchingBrace :: InsertMode -> InsertMode
    findMatchingBrace (IMode [Grapheme]
    xs (Grapheme
    y:[Grapheme]
    ys))
        | Just Char
    b <- Char -> Maybe Char
    matchingRightBrace Char
    yc,
          Just ((Grapheme
    b':[Grapheme]
    bs),[Grapheme]
    ys') <- Char -> Char -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    scanBraces Char
    yc Char
    b [Grapheme]
    ys = [Grapheme] -> [Grapheme] -> InsertMode
    IMode ([Grapheme]
    bs[Grapheme] -> [Grapheme] -> [Grapheme]
    forall a. [a] -> [a] -> [a]
    ++[Grapheme
    y][Grapheme] -> [Grapheme] -> [Grapheme]
    forall a. [a] -> [a] -> [a]
    ++[Grapheme]
    xs) (Grapheme
    b'Grapheme -> [Grapheme] -> [Grapheme]
    forall a. a -> [a] -> [a]
    :[Grapheme]
    ys')
        | Just Char
    b <- Char -> Maybe Char
    matchingLeftBrace Char
    yc,
          Just ([Grapheme]
    bs,[Grapheme]
    xs') <- Char -> Char -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    scanBraces Char
    yc Char
    b [Grapheme]
    xs = [Grapheme] -> [Grapheme] -> InsertMode
    IMode [Grapheme]
    xs' ([Grapheme]
    bs [Grapheme] -> [Grapheme] -> [Grapheme]
    forall a. [a] -> [a] -> [a]
    ++ [Grapheme
    y][Grapheme] -> [Grapheme] -> [Grapheme]
    forall a. [a] -> [a] -> [a]
    ++[Grapheme]
    ys)
      where yc :: Char
    yc = Grapheme -> Char
    baseChar Grapheme
    y
    findMatchingBrace InsertMode
    im = InsertMode
    im

    deleteMatchingBrace :: InsertMode -> ([Grapheme],InsertMode)
    deleteMatchingBrace :: InsertMode -> ([Grapheme], InsertMode)
    deleteMatchingBrace (IMode [Grapheme]
    xs (Grapheme
    y:[Grapheme]
    ys))
        | Just Char
    b <- Char -> Maybe Char
    matchingRightBrace Char
    yc,
          Just ([Grapheme]
    bs,[Grapheme]
    ys') <- Char -> Char -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    scanBraces Char
    yc Char
    b [Grapheme]
    ys = (Grapheme
    y Grapheme -> [Grapheme] -> [Grapheme]
    forall a. a -> [a] -> [a]
    : [Grapheme] -> [Grapheme]
    forall a. [a] -> [a]
    reverse [Grapheme]
    bs, [Grapheme] -> [Grapheme] -> InsertMode
    IMode [Grapheme]
    xs [Grapheme]
    ys')
        | Just Char
    b <- Char -> Maybe Char
    matchingLeftBrace Char
    yc,
          Just ([Grapheme]
    bs,[Grapheme]
    xs') <- Char -> Char -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    scanBraces Char
    yc Char
    b [Grapheme]
    xs = ([Grapheme]
    bs [Grapheme] -> [Grapheme] -> [Grapheme]
    forall a. [a] -> [a] -> [a]
    ++ [Grapheme
    y], [Grapheme] -> [Grapheme] -> InsertMode
    IMode [Grapheme]
    xs' [Grapheme]
    ys)
      where yc :: Char
    yc = Grapheme -> Char
    baseChar Grapheme
    y
    deleteMatchingBrace InsertMode
    im = ([],InsertMode
    im)

    scanBraces :: Char -> Char -> [Grapheme] -> Maybe ([Grapheme],[Grapheme])
    scanBraces :: Char -> Char -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    scanBraces Char
    c Char
    d = Int -> [Grapheme] -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    forall {t}.
    (Eq t, Num t) =>
    t -> [Grapheme] -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    scanBraces' (Int
    1::Int) []
        where
            scanBraces' :: t -> [Grapheme] -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    scanBraces' t
    0 [Grapheme]
    bs [Grapheme]
    xs = ([Grapheme], [Grapheme]) -> Maybe ([Grapheme], [Grapheme])
    forall a. a -> Maybe a
    Just ([Grapheme]
    bs,[Grapheme]
    xs)
            scanBraces' t
    _ [Grapheme]
    _ [] = Maybe ([Grapheme], [Grapheme])
    forall a. Maybe a
    Nothing
            scanBraces' t
    n [Grapheme]
    bs (Grapheme
    x:[Grapheme]
    xs) = t -> [Grapheme] -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
    scanBraces' t
    m (Grapheme
    xGrapheme -> [Grapheme] -> [Grapheme]
    forall a. a -> [a] -> [a]
    :[Grapheme]
    bs) [Grapheme]
    xs
                where m :: t
    m | Grapheme -> Char
    baseChar Grapheme
    x Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    c = t
    nt -> t -> t
    forall a. Num a => a -> a -> a
    +t
    1
                        | Grapheme -> Char
    baseChar Grapheme
    x Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    d = t
    nt -> t -> t
    forall a. Num a => a -> a -> a
    -t
    1
                        | Bool
    otherwise = t
    n

    matchingRightBrace, matchingLeftBrace :: Char -> Maybe Char
    matchingRightBrace :: Char -> Maybe Char
    matchingRightBrace = (Char -> [(Char, Char)] -> Maybe Char)
    -> [(Char, Char)] -> Char -> Maybe Char
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Char -> [(Char, Char)] -> Maybe Char
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup [(Char, Char)]
    braceList
    matchingLeftBrace :: Char -> Maybe Char
    matchingLeftBrace = (Char -> [(Char, Char)] -> Maybe Char)
    -> [(Char, Char)] -> Char -> Maybe Char
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Char -> [(Char, Char)] -> Maybe Char
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup (((Char, Char) -> (Char, Char)) -> [(Char, Char)] -> [(Char, Char)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Char
    c,Char
    d) -> (Char
    d,Char
    c)) [(Char, Char)]
    braceList)

    braceList :: [(Char,Char)]
    braceList :: [(Char, Char)]
    braceList = [(Char
    '(',Char
    ')'), (Char
    '[',Char
    ']'), (Char
    '{',Char
    '}')]

    ---------------
    -- Replace mode
    replaceLoop :: InputCmd CommandMode CommandMode
    replaceLoop :: InputCmd CommandMode CommandMode
    replaceLoop = Command (ViT m) CommandMode CommandMode
    forall s (m :: * -> *).
    (Save s, MonadState Undo m) =>
    Command m s s
    saveForUndo Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> (CommandMode -> InsertMode)
    -> Command (ViT m) CommandMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change CommandMode -> InsertMode
    insertFromCommandMode Command (ViT m) CommandMode InsertMode
    -> Command (ViT m) InsertMode CommandMode
    -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> Command (ViT m) InsertMode InsertMode
    loop
                    Command (ViT m) InsertMode InsertMode
    -> Command (ViT m) InsertMode CommandMode
    -> Command (ViT m) InsertMode CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> (InsertMode -> CommandMode)
    -> Command (ViT m) InsertMode CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> CommandMode
    enterCommandModeRight
        where
            loop :: Command (ViT m) InsertMode InsertMode
    loop = KeyCommand (ViT m) InsertMode InsertMode
    -> Command (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s.
    Monad m =>
    KeyCommand m s s -> Command m s s
    try (KeyCommand (ViT m) InsertMode InsertMode
    oneReplaceCmd KeyCommand (ViT m) InsertMode InsertMode
    -> Command (ViT m) InsertMode InsertMode
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> Command (ViT m) InsertMode InsertMode
    loop)
            oneReplaceCmd :: KeyCommand (ViT m) InsertMode InsertMode
    oneReplaceCmd = [KeyCommand (ViT m) InsertMode InsertMode]
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd [
                    BaseKey -> Key
    simpleKey BaseKey
    LeftKey Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> InsertMode
    forall s. Move s => s -> s
    goLeft
                    , BaseKey -> Key
    simpleKey BaseKey
    RightKey Key
    -> Command (ViT m) InsertMode InsertMode
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall a. Key -> a -> KeyMap a
    +> (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change InsertMode -> InsertMode
    forall s. Move s => s -> s
    goRight
                    , (Char -> InsertMode -> InsertMode)
    -> KeyCommand (ViT m) InsertMode InsertMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (Char -> s -> t) -> KeyCommand m s t
    changeFromChar Char -> InsertMode -> InsertMode
    replaceCharIM
                    ]

    ---------------------------
    -- Saving previous commands

    storeLastCmd :: Monad m => SavedCommand m -> Command (ViT m) s s
    storeLastCmd :: forall (m :: * -> *) s.
    Monad m =>
    SavedCommand m -> Command (ViT m) s s
    storeLastCmd SavedCommand m
    act = \s
    s -> do
            (ViState m -> ViState m) -> CmdM (ViT m) ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((ViState m -> ViState m) -> CmdM (ViT m) ())
    -> (ViState m -> ViState m) -> CmdM (ViT m) ()
    forall a b. (a -> b) -> a -> b
    $ \ViState m
    vs -> ViState m
    vs {lastCommand = act}
            s -> CmdM (ViT m) s
    forall a. a -> CmdM (ViT m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return s
    s

    storedAction :: Monad m => SavedCommand m -> SavedCommand m
    storedAction :: forall (m :: * -> *). Monad m => SavedCommand m -> SavedCommand m
    storedAction SavedCommand m
    act = SavedCommand m
    -> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall (m :: * -> *) s.
    Monad m =>
    SavedCommand m -> Command (ViT m) s s
    storeLastCmd SavedCommand m
    act Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> SavedCommand m -> SavedCommand m
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> SavedCommand m
    act

    storedCmdAction :: Monad m => Command (ViT m) (ArgMode CommandMode) CommandMode
                                -> Command (ViT m) (ArgMode CommandMode) CommandMode
    storedCmdAction :: forall (m :: * -> *).
    Monad m =>
    Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    storedCmdAction Command (ViT m) (ArgMode CommandMode) CommandMode
    act = SavedCommand m
    -> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall (m :: * -> *) s.
    Monad m =>
    SavedCommand m -> Command (ViT m) s s
    storeLastCmd ((CommandMode -> EitherMode)
    -> CmdM (ViT m) CommandMode -> CmdM (ViT m) EitherMode
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM CommandMode -> EitherMode
    forall a b. a -> Either a b
    Left (CmdM (ViT m) CommandMode -> CmdM (ViT m) EitherMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> SavedCommand m
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Command (ViT m) (ArgMode CommandMode) CommandMode
    act) Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> Command (ViT m) (ArgMode CommandMode) CommandMode
    act

    storedIAction :: Monad m => Command (ViT m) (ArgMode CommandMode) InsertMode
                            -> Command (ViT m) (ArgMode CommandMode) InsertMode
    storedIAction :: forall (m :: * -> *).
    Monad m =>
    Command (ViT m) (ArgMode CommandMode) InsertMode
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    storedIAction Command (ViT m) (ArgMode CommandMode) InsertMode
    act = SavedCommand m
    -> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    forall (m :: * -> *) s.
    Monad m =>
    SavedCommand m -> Command (ViT m) s s
    storeLastCmd ((InsertMode -> EitherMode)
    -> CmdM (ViT m) InsertMode -> CmdM (ViT m) EitherMode
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM InsertMode -> EitherMode
    forall a b. b -> Either a b
    Right (CmdM (ViT m) InsertMode -> CmdM (ViT m) EitherMode)
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    -> SavedCommand m
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Command (ViT m) (ArgMode CommandMode) InsertMode
    act) Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> Command (ViT m) (ArgMode CommandMode) InsertMode
    act

    killAndStoreCmd :: MonadIO m => KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    killAndStoreCmd :: forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    killAndStoreCmd = Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *).
    Monad m =>
    Command (ViT m) (ArgMode CommandMode) CommandMode
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    storedCmdAction (Command (ViT m) (ArgMode CommandMode) CommandMode
     -> Command (ViT m) (ArgMode CommandMode) CommandMode)
    -> (KillHelper
        -> Command (ViT m) (ArgMode CommandMode) CommandMode)
    -> KillHelper
    -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
    forall (m :: * -> *) s t.
    (MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
    KillHelper -> Command m (ArgMode s) t
    killFromArgHelper

    killAndStoreI :: MonadIO m => KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
    killAndStoreI :: forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
    killAndStoreI = Command (ViT m) (ArgMode CommandMode) InsertMode
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    forall (m :: * -> *).
    Monad m =>
    Command (ViT m) (ArgMode CommandMode) InsertMode
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    storedIAction (Command (ViT m) (ArgMode CommandMode) InsertMode
     -> Command (ViT m) (ArgMode CommandMode) InsertMode)
    -> (KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode)
    -> KillHelper
    -> Command (ViT m) (ArgMode CommandMode) InsertMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
    forall (m :: * -> *) s t.
    (MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
    KillHelper -> Command m (ArgMode s) t
    killFromArgHelper

    killAndStoreIE :: MonadIO m => KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    killAndStoreIE :: forall (m :: * -> *).
    MonadIO m =>
    KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
    killAndStoreIE KillHelper
    helper = SavedCommand m -> SavedCommand m
    forall (m :: * -> *). Monad m => SavedCommand m -> SavedCommand m
    storedAction (KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
    forall (m :: * -> *) s t.
    (MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
    KillHelper -> Command m (ArgMode s) t
    killFromArgHelper KillHelper
    helper Command (ViT m) (ArgMode CommandMode) InsertMode
    -> Command (ViT m) InsertMode EitherMode -> SavedCommand m
    forall (m :: * -> *) s t u.
    Monad m =>
    Command m s t -> Command m t u -> Command m s u
    >|> EitherMode -> CmdM (ViT m) EitherMode
    forall a. a -> CmdM (ViT m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (EitherMode -> CmdM (ViT m) EitherMode)
    -> (InsertMode -> EitherMode)
    -> Command (ViT m) InsertMode EitherMode
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . InsertMode -> EitherMode
    forall a b. b -> Either a b
    Right)

    noArg :: Monad m => Command m s (ArgMode s)
    noArg :: forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
    noArg = ArgMode s -> CmdM m (ArgMode s)
    forall a. a -> CmdM m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ArgMode s -> CmdM m (ArgMode s))
    -> (s -> ArgMode s) -> s -> CmdM m (ArgMode s)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> s -> ArgMode s
    forall s. Int -> s -> ArgMode s
    startArg Int
    1

    -------------------
    -- Vi-style searching

    data SearchEntry = SearchEntry {
                        SearchEntry -> InsertMode
    entryState :: InsertMode,
                        SearchEntry -> Char
    searchChar :: Char
                        }

    searchText :: SearchEntry -> [Grapheme]
    searchText :: SearchEntry -> [Grapheme]
    searchText SearchEntry {entryState :: SearchEntry -> InsertMode
    entryState = IMode [Grapheme]
    xs [Grapheme]
    ys} = [Grapheme] -> [Grapheme]
    forall a. [a] -> [a]
    reverse [Grapheme]
    xs [Grapheme] -> [Grapheme] -> [Grapheme]
    forall a. [a] -> [a] -> [a]
    ++ [Grapheme]
    ys

    instance LineState SearchEntry where
        beforeCursor :: [Grapheme] -> SearchEntry -> [Grapheme]
    beforeCursor [Grapheme]
    prefix SearchEntry
    se = [Grapheme] -> InsertMode -> [Grapheme]
    forall s. LineState s => [Grapheme] -> s -> [Grapheme]
    beforeCursor ([Grapheme]
    prefix [Grapheme] -> [Grapheme] -> [Grapheme]
    forall a. [a] -> [a] -> [a]
    ++ String -> [Grapheme]
    stringToGraphemes [SearchEntry -> Char
    searchChar SearchEntry
    se])
                                    (SearchEntry -> InsertMode
    entryState SearchEntry
    se)
        afterCursor :: SearchEntry -> [Grapheme]
    afterCursor = InsertMode -> [Grapheme]
    forall s. LineState s => s -> [Grapheme]
    afterCursor (InsertMode -> [Grapheme])
    -> (SearchEntry -> InsertMode) -> SearchEntry -> [Grapheme]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SearchEntry -> InsertMode
    entryState

    viEnterSearch :: Monad m => Char -> Direction
                        -> Command (ViT m) CommandMode CommandMode
    viEnterSearch :: forall (m :: * -> *).
    Monad m =>
    Char -> Direction -> Command (ViT m) CommandMode CommandMode
    viEnterSearch Char
    c Direction
    dir CommandMode
    s = Command (ViT m) SearchEntry SearchEntry
    forall (m :: * -> *) s. (Monad m, LineState s) => Command m s s
    setState (InsertMode -> Char -> SearchEntry
    SearchEntry InsertMode
    emptyIM Char
    c) CmdM (ViT m) SearchEntry
    -> (SearchEntry -> CmdM (ViT m) CommandMode)
    -> CmdM (ViT m) CommandMode
    forall a b.
    CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= SearchEntry -> CmdM (ViT m) CommandMode
    loopEntry
        where
            modifySE :: (InsertMode -> InsertMode) -> SearchEntry -> SearchEntry
    modifySE InsertMode -> InsertMode
    f SearchEntry
    se = SearchEntry
    se {entryState = f (entryState se)}
            loopEntry :: SearchEntry -> CmdM (ViT m) CommandMode
    loopEntry = [KeyCommand (ViT m) SearchEntry CommandMode]
    -> SearchEntry -> CmdM (ViT m) CommandMode
    forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
    keyChoiceCmd [
                            KeyMap (Command (ViT m) SearchEntry SearchEntry)
    editEntry KeyMap (Command (ViT m) SearchEntry SearchEntry)
    -> (SearchEntry -> CmdM (ViT m) CommandMode)
    -> KeyCommand (ViT m) SearchEntry CommandMode
    forall (m :: * -> *) s t u.
    Monad m =>
    KeyCommand m s t -> Command m t u -> KeyCommand m s u
    >+> SearchEntry -> CmdM (ViT m) CommandMode
    loopEntry
                            , Char -> Key
    simpleChar Char
    '\n' Key
    -> (SearchEntry -> CmdM (ViT m) CommandMode)
    -> KeyCommand (ViT m) SearchEntry CommandMode
    forall a. Key -> a -> KeyMap a
    +> \SearchEntry
    se ->
                                Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *).
    Monad m =>
    Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
    viSearchHist Direction
    dir (SearchEntry -> [Grapheme]
    searchText SearchEntry
    se) CommandMode
    s
                            , (SearchEntry -> CmdM (ViT m) CommandMode)
    -> KeyCommand (ViT m) SearchEntry CommandMode
    forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
    withoutConsuming ((SearchEntry -> CommandMode)
    -> SearchEntry -> CmdM (ViT m) CommandMode
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change (CommandMode -> SearchEntry -> CommandMode
    forall a b. a -> b -> a
    const CommandMode
    s))
                            ]
            editEntry :: KeyMap (Command (ViT m) SearchEntry SearchEntry)
    editEntry = [KeyMap (Command (ViT m) SearchEntry SearchEntry)]
    -> KeyMap (Command (ViT m) SearchEntry SearchEntry)
    forall a. [KeyMap a] -> KeyMap a
    choiceCmd [
                            (Char -> Command (ViT m) SearchEntry SearchEntry)
    -> KeyMap (Command (ViT m) SearchEntry SearchEntry)
    forall (m :: * -> *) s t.
    (Char -> Command m s t) -> KeyCommand m s t
    useChar ((SearchEntry -> SearchEntry)
    -> Command (ViT m) SearchEntry SearchEntry
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((SearchEntry -> SearchEntry)
     -> Command (ViT m) SearchEntry SearchEntry)
    -> (Char -> SearchEntry -> SearchEntry)
    -> Char
    -> Command (ViT m) SearchEntry SearchEntry
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (InsertMode -> InsertMode) -> SearchEntry -> SearchEntry
    modifySE ((InsertMode -> InsertMode) -> SearchEntry -> SearchEntry)
    -> (Char -> InsertMode -> InsertMode)
    -> Char
    -> SearchEntry
    -> SearchEntry
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> InsertMode -> InsertMode
    insertChar)
                            , BaseKey -> Key
    simpleKey BaseKey
    LeftKey Key
    -> Command (ViT m) SearchEntry SearchEntry
    -> KeyMap (Command (ViT m) SearchEntry SearchEntry)
    forall a. Key -> a -> KeyMap a
    +> (SearchEntry -> SearchEntry)
    -> Command (ViT m) SearchEntry SearchEntry
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((InsertMode -> InsertMode) -> SearchEntry -> SearchEntry
    modifySE InsertMode -> InsertMode
    forall s. Move s => s -> s
    goLeft)
                            , BaseKey -> Key
    simpleKey BaseKey
    RightKey Key
    -> Command (ViT m) SearchEntry SearchEntry
    -> KeyMap (Command (ViT m) SearchEntry SearchEntry)
    forall a. Key -> a -> KeyMap a
    +> (SearchEntry -> SearchEntry)
    -> Command (ViT m) SearchEntry SearchEntry
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((InsertMode -> InsertMode) -> SearchEntry -> SearchEntry
    modifySE InsertMode -> InsertMode
    forall s. Move s => s -> s
    goRight)
                            , BaseKey -> Key
    simpleKey BaseKey
    Backspace Key
    -> Command (ViT m) SearchEntry SearchEntry
    -> KeyMap (Command (ViT m) SearchEntry SearchEntry)
    forall a. Key -> a -> KeyMap a
    +> (SearchEntry -> SearchEntry)
    -> Command (ViT m) SearchEntry SearchEntry
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((InsertMode -> InsertMode) -> SearchEntry -> SearchEntry
    modifySE InsertMode -> InsertMode
    deletePrev)
                            , BaseKey -> Key
    simpleKey BaseKey
    Delete Key
    -> Command (ViT m) SearchEntry SearchEntry
    -> KeyMap (Command (ViT m) SearchEntry SearchEntry)
    forall a. Key -> a -> KeyMap a
    +> (SearchEntry -> SearchEntry)
    -> Command (ViT m) SearchEntry SearchEntry
    forall t (m :: * -> *) s.
    (LineState t, Monad m) =>
    (s -> t) -> Command m s t
    change ((InsertMode -> InsertMode) -> SearchEntry -> SearchEntry
    modifySE InsertMode -> InsertMode
    deleteNext)
                            ]

    viSearchHist :: forall m . Monad m
        => Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
    viSearchHist :: forall (m :: * -> *).
    Monad m =>
    Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
    viSearchHist Direction
    dir [Grapheme]
    toSearch CommandMode
    cm = do
        vstate :: ViState m <- CmdM (ViT m) (ViState m)
    forall s (m :: * -> *). MonadState s m => m s
    get
        let toSearch' = if [Grapheme] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Grapheme]
    toSearch
                            then ViState m -> [Grapheme]
    forall (m :: * -> *). ViState m -> [Grapheme]
    lastSearch ViState m
    vstate
                            else [Grapheme]
    toSearch
        result <- doSearch False SearchMode {
                                        searchTerm = toSearch',
                                        foundHistory = save cm, -- TODO: not needed
                                        direction = dir}
        case result of
            Left Effect
    e -> Effect -> CmdM (ViT m) ()
    forall (m :: * -> *). Effect -> CmdM m ()
    effect Effect
    e CmdM (ViT m) ()
    -> CmdM (ViT m) CommandMode -> CmdM (ViT m) CommandMode
    forall a b. CmdM (ViT m) a -> CmdM (ViT m) b -> CmdM (ViT m) b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s. (Monad m, LineState s) => Command m s s
    setState CommandMode
    cm
            Right SearchMode
    sm -> do
                ViState m -> CmdM (ViT m) ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put ViState m
    vstate {lastSearch = toSearch'}
                Command (ViT m) CommandMode CommandMode
    forall (m :: * -> *) s. (Monad m, LineState s) => Command m s s
    setState (InsertMode -> CommandMode
    forall s. Save s => InsertMode -> s
    restore (SearchMode -> InsertMode
    foundHistory SearchMode
    sm))