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)

type EitherMode = Either CommandMode InsertMode

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

data ViState m = ViState { 
            ViState m -> SavedCommand m
lastCommand :: SavedCommand m,
            ViState m -> [Grapheme]
lastSearch :: [Grapheme]
         }

emptyViState :: Monad m => ViState m
emptyViState :: ViState m
emptyViState = ViState :: forall (m :: * -> *). SavedCommand m -> [Grapheme] -> ViState m
ViState {
            lastCommand :: SavedCommand m
lastCommand = Either CommandMode InsertMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CommandMode InsertMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> (ArgMode CommandMode -> Either CommandMode InsertMode)
-> SavedCommand m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> Either CommandMode InsertMode
forall a b. a -> Either a b
Left (CommandMode -> Either CommandMode InsertMode)
-> (ArgMode CommandMode -> CommandMode)
-> ArgMode CommandMode
-> Either CommandMode InsertMode
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 . MonadException m => Command (ViT m) s t
type InputKeyCmd s t = forall m . MonadException m => KeyCommand (ViT m) s t

viKeyCommands :: InputKeyCmd InsertMode (Maybe String)
viKeyCommands :: KeyCommand (ViT m) InsertMode (Maybe String)
viKeyCommands = [KeyCommand (ViT m) InsertMode (Maybe String)]
-> KeyCommand (ViT m) InsertMode (Maybe String)
forall a. [KeyMap a] -> KeyMap a
choiceCmd [
                Char -> Key
simpleChar '\n' Key
-> Command (ViT m) InsertMode (Maybe String)
-> KeyCommand (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 'd' Key
-> Command (ViT m) InsertMode (Maybe String)
-> KeyCommand (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)
-> KeyCommand (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 '\ESC' Key
-> Command (ViT m) InsertMode (Maybe String)
-> KeyCommand (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 :: Command (ViT m) 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 :: KeyCommand (ViT m) InsertMode InsertMode
simpleInsertions = [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
                   , BaseKey -> Key
simpleKey BaseKey
Backspace 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
deletePrev 
                   , BaseKey -> Key
simpleKey BaseKey
Delete 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
deleteNext 
                   , BaseKey -> Key
simpleKey BaseKey
Home 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
moveToStart
                   , BaseKey -> Key
simpleKey BaseKey
End 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
moveToEnd
                   , KeyCommand (ViT m) InsertMode InsertMode
InputKeyCmd InsertMode InsertMode
insertChars
                   , Char -> Key
ctrlChar 'l' Key
-> Command (ViT m) InsertMode InsertMode
-> KeyCommand (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
-> KeyCommand (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
-> KeyCommand (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
                   , KeyCommand (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
-> KeyCommand (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 'w' Key
-> Command (ViT m) InsertMode InsertMode
-> KeyCommand (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 -> KeyCommand (ViT m) InsertMode InsertMode
forall (m :: * -> *).
(MonadState Undo m, CommandMonad m) =>
Key -> KeyCommand m InsertMode InsertMode
completionCmd (Char -> Key
simpleChar '\t')
                   ]

insertChars :: InputKeyCmd InsertMode InsertMode
insertChars :: KeyCommand (ViT m) 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 ds :: String
ds d :: 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 s :: 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 (Either CommandMode InsertMode)
-> SavedCommand m
forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> Either CommandMode InsertMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CommandMode InsertMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> (CommandMode -> Either CommandMode InsertMode)
-> Command (ViT m) CommandMode (Either CommandMode InsertMode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> Either CommandMode InsertMode
forall a b. a -> Either a b
Left

-- If we receive a ^D and the line is empty, return Nothing
-- otherwise, act like '\n' (mimicing how Readline behaves)
eofIfEmpty :: (Monad m, Save s, Result s) => Command m s (Maybe String)
eofIfEmpty :: Command m s (Maybe String)
eofIfEmpty s :: 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 (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 :: Command (ViT m) 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 '\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 '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 (Either CommandMode InsertMode)
InputKeyCmd CommandMode (Either CommandMode InsertMode)
repeatedCommands KeyCommand (ViT m) CommandMode (Either CommandMode InsertMode)
-> Command (ViT m) (Either CommandMode 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) (Either CommandMode InsertMode) (Maybe String)
InputCmd (Either CommandMode InsertMode) (Maybe String)
chooseEitherMode
                    ]
    where
        chooseEitherMode :: InputCmd EitherMode (Maybe String)
        chooseEitherMode :: Command (ViT m) (Either CommandMode InsertMode) (Maybe String)
chooseEitherMode (Left cm :: CommandMode
cm) = Command (ViT m) CommandMode (Maybe String)
InputCmd CommandMode (Maybe String)
viCommandActions CommandMode
cm
        chooseEitherMode (Right im :: InsertMode
im) = Command (ViT m) InsertMode (Maybe String)
InputCmd InsertMode (Maybe String)
viCommands InsertMode
im

exitingCommands :: InputKeyCmd CommandMode InsertMode
exitingCommands :: KeyCommand (ViT m) CommandMode InsertMode
exitingCommands =  [KeyCommand (ViT m) CommandMode InsertMode]
-> KeyCommand (ViT m) CommandMode InsertMode
forall a. [KeyMap a] -> KeyMap a
choiceCmd [ 
                      Char -> Key
simpleChar 'i' Key
-> Command (ViT m) CommandMode InsertMode
-> KeyCommand (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 'I' Key
-> Command (ViT m) CommandMode InsertMode
-> KeyCommand (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
-> KeyCommand (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 'a' Key
-> Command (ViT m) CommandMode InsertMode
-> KeyCommand (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 'A' Key
-> Command (ViT m) CommandMode InsertMode
-> KeyCommand (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
-> KeyCommand (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 's' Key
-> Command (ViT m) CommandMode InsertMode
-> KeyCommand (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 'S' Key
-> Command (ViT m) CommandMode InsertMode
-> KeyCommand (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 'C' Key
-> Command (ViT m) CommandMode InsertMode
-> KeyCommand (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 :: KeyCommand (ViT m) CommandMode CommandMode
simpleCmdActions = [KeyCommand (ViT m) CommandMode CommandMode]
-> KeyCommand (ViT m) CommandMode CommandMode
forall a. [KeyMap a] -> KeyMap a
choiceCmd [ 
                    Char -> Key
simpleChar '\ESC' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 'r'   Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (ViT m) CommandMode CommandMode
forall a. Key -> a -> KeyMap a
+> Command (ViT m) CommandMode CommandMode
InputCmd CommandMode CommandMode
replaceOnce 
                    , Char -> Key
simpleChar 'R'   Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (ViT m) CommandMode CommandMode
forall a. Key -> a -> KeyMap a
+> Command (ViT m) CommandMode CommandMode
InputCmd CommandMode CommandMode
replaceLoop
                    , Char -> Key
simpleChar 'D' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 'l' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 'u' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 'r' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 'j' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 'k' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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
-> KeyCommand (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
-> KeyCommand (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 '/' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 '/' Direction
Reverse
                    , Char -> Key
simpleChar '?' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 '?' Direction
Forward
                    , Char -> Key
simpleChar 'n' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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 'N' Key
-> Command (ViT m) CommandMode CommandMode
-> KeyCommand (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
-> KeyCommand (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 :: Command (ViT m) 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 :: KeyCommand (ViT m) CommandMode (Either CommandMode InsertMode)
repeatedCommands = [KeyCommand (ViT m) CommandMode (Either CommandMode InsertMode)]
-> KeyCommand (ViT m) CommandMode (Either CommandMode InsertMode)
forall a. [KeyMap a] -> KeyMap a
choiceCmd [KeyCommand (ViT m) CommandMode (Either CommandMode InsertMode)
argumented, Command (ViT m) CommandMode (ArgMode CommandMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand (ViT m) CommandMode (Either CommandMode InsertMode)
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) (Either CommandMode InsertMode)
InputKeyCmd (ArgMode CommandMode) (Either CommandMode InsertMode)
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 ['1'..'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 ['0'..'9']
        argumented :: KeyCommand (ViT m) CommandMode (Either CommandMode InsertMode)
argumented = KeyCommand (ViT m) CommandMode (ArgMode CommandMode)
start KeyCommand (ViT m) CommandMode (ArgMode CommandMode)
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand (ViT m) CommandMode (Either CommandMode InsertMode)
forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
loop
        loop :: Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
loop = [KeyCommand
   (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)]
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
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) (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
loop
                            , KeyCommand
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
InputKeyCmd (ArgMode CommandMode) (Either CommandMode InsertMode)
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 (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> Either CommandMode InsertMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CommandMode InsertMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> (CommandMode -> Either CommandMode InsertMode)
-> Command (ViT m) CommandMode (Either CommandMode InsertMode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> Either CommandMode InsertMode
forall a b. a -> Either a b
Left
                            ]

pureMovements :: InputKeyCmd (ArgMode CommandMode) CommandMode
pureMovements :: KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
pureMovements = [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall a. [KeyMap a] -> KeyMap a
choiceCmd ([KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
 -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode)
-> [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall a b. (a -> b) -> a -> b
$ [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
charMovements [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
-> [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
-> [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
forall a. [a] -> [a] -> [a]
++ ((Key, InsertMode -> InsertMode)
 -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode)
-> [(Key, InsertMode -> InsertMode)]
-> [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
forall a b. (a -> b) -> [a] -> [b]
map (Key, InsertMode -> InsertMode)
-> KeyCommand (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 :: [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
charMovements = [ Char
-> (Char -> InsertMode -> InsertMode)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *).
Monad m =>
Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement 'f' ((Char -> InsertMode -> InsertMode)
 -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode)
-> (Char -> InsertMode -> InsertMode)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall a b. (a -> b) -> a -> b
$ \c :: 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)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *).
Monad m =>
Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement 'F' ((Char -> InsertMode -> InsertMode)
 -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode)
-> (Char -> InsertMode -> InsertMode)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall a b. (a -> b) -> a -> b
$ \c :: 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)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *).
Monad m =>
Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement 't' ((Char -> InsertMode -> InsertMode)
 -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode)
-> (Char -> InsertMode -> InsertMode)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall a b. (a -> b) -> a -> b
$ \c :: 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)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *).
Monad m =>
Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement 'T' ((Char -> InsertMode -> InsertMode)
 -> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode)
-> (Char -> InsertMode -> InsertMode)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall a b. (a -> b) -> a -> b
$ \c :: 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 (k :: Key
k,move :: 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 c :: Char
c move :: 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 :: Command m s t -> (KillHelper -> Command m s t) -> KeyCommand m s t
useMovementsForKill alternate :: Command m s t
alternate useHelper :: KillHelper -> Command m s t
useHelper = [KeyCommand m s t] -> KeyCommand m s t
forall a. [KeyMap a] -> KeyMap a
choiceCmd ([KeyCommand m s t] -> KeyCommand m s t)
-> [KeyCommand m s t] -> KeyCommand m s t
forall a b. (a -> b) -> a -> b
$
            [KeyCommand m s t]
specialCases
            [KeyCommand m s t] -> [KeyCommand m s t] -> [KeyCommand m s t]
forall a. [a] -> [a] -> [a]
++ ((Key, InsertMode -> InsertMode) -> KeyCommand m s t)
-> [(Key, InsertMode -> InsertMode)] -> [KeyCommand m s t]
forall a b. (a -> b) -> [a] -> [b]
map (\(k :: Key
k,move :: InsertMode -> InsertMode
move) -> Key
k Key -> Command m s t -> KeyCommand 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 :: [KeyCommand m s t]
specialCases = [ Char -> Key
simpleChar 'e' Key -> Command m s t -> KeyCommand 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 'E' Key -> Command m s t -> KeyCommand 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 '%' Key -> Command m s t -> KeyCommand 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) -> KeyCommand m s t
charMovement 'f' ((Char -> InsertMode -> InsertMode) -> KeyCommand m s t)
-> (Char -> InsertMode -> InsertMode) -> KeyCommand m s t
forall a b. (a -> b) -> a -> b
$ \c :: 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) -> KeyCommand m s t
charMovement 'F' ((Char -> InsertMode -> InsertMode) -> KeyCommand m s t)
-> (Char -> InsertMode -> InsertMode) -> KeyCommand m s t
forall a b. (a -> b) -> a -> b
$ \c :: 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) -> KeyCommand m s t
charMovement 't' ((Char -> InsertMode -> InsertMode) -> KeyCommand m s t)
-> (Char -> InsertMode -> InsertMode) -> KeyCommand m s t
forall a b. (a -> b) -> a -> b
$ \c :: 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) -> KeyCommand m s t
charMovement 'T' ((Char -> InsertMode -> InsertMode) -> KeyCommand m s t)
-> (Char -> InsertMode -> InsertMode) -> KeyCommand m s t
forall a b. (a -> b) -> a -> b
$ \c :: 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) -> KeyCommand m s t
charMovement c :: Char
c move :: Char -> InsertMode -> InsertMode
move = Char -> Key
simpleChar Char
c Key -> Command m s t -> KeyCommand m s t
forall a. Key -> a -> KeyMap a
+> [KeyCommand 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) -> KeyCommand 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 -> KeyCommand 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 :: KeyCommand
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
repeatableCommands = [KeyCommand
   (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)]
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall a. [KeyMap a] -> KeyMap a
choiceCmd
                        [ KeyCommand
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
InputKeyCmd (ArgMode CommandMode) (Either CommandMode InsertMode)
repeatableCmdToIMode
                        , KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
InputKeyCmd (ArgMode CommandMode) CommandMode
repeatableCmdMode KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
-> Command (ViT m) CommandMode (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> Either CommandMode InsertMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CommandMode InsertMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> (CommandMode -> Either CommandMode InsertMode)
-> Command (ViT m) CommandMode (Either CommandMode InsertMode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> Either CommandMode InsertMode
forall a b. a -> Either a b
Left
                        , Char -> Key
simpleChar '.' Key
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
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) (Either CommandMode InsertMode)
-> Command
     (ViT m) (ArgMode CommandMode) (Either 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) (Either CommandMode InsertMode)
forall (m :: * -> *).
Monad m =>
ArgMode CommandMode -> CmdM (ViT m) (Either CommandMode InsertMode)
runLastCommand
                        ]
    where
        runLastCommand :: ArgMode CommandMode -> CmdM (ViT m) (Either CommandMode InsertMode)
runLastCommand s :: ArgMode CommandMode
s = (ViState m
 -> ArgMode CommandMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> CmdM (ViT m) (ViState m)
-> CmdM
     (ViT m)
     (ArgMode CommandMode
      -> CmdM (ViT m) (Either CommandMode InsertMode))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ViState m
-> ArgMode CommandMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
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) (Either CommandMode InsertMode))
-> ((ArgMode CommandMode
     -> CmdM (ViT m) (Either CommandMode InsertMode))
    -> CmdM (ViT m) (Either CommandMode InsertMode))
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ((ArgMode CommandMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> ArgMode CommandMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall a b. (a -> b) -> a -> b
$ ArgMode CommandMode
s)

repeatableCmdMode :: InputKeyCmd (ArgMode CommandMode) CommandMode
repeatableCmdMode :: KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
repeatableCmdMode = [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall a. [KeyMap a] -> KeyMap a
choiceCmd
                    [ Char -> Key
simpleChar 'x' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (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 'X' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (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 '~' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (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 'p' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (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 'P' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (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 'd' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (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 'y' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (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 'w' 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
wordErase
                    , KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
InputKeyCmd (ArgMode CommandMode) CommandMode
pureMovements
                    ]
    where
        repeatableChange :: (CommandMode -> CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
repeatableChange f :: 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 CEmpty = CommandMode
CEmpty
flipCase (CMode xs :: [Grapheme]
xs y :: Grapheme
y zs :: [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 c :: 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 :: KeyCommand
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
repeatableCmdToIMode = Char -> Key
simpleChar 'c' Key
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall a. Key -> a -> KeyMap a
+> Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
InputCmd (ArgMode CommandMode) (Either CommandMode InsertMode)
deletionToInsertCmd

deletionCmd :: InputCmd (ArgMode CommandMode) CommandMode
deletionCmd :: Command (ViT m) (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)
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 '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 :: Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
deletionToInsertCmd = [KeyCommand
   (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)]
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
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)
reinputArg KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
InputCmd (ArgMode CommandMode) (Either CommandMode InsertMode)
deletionToInsertCmd
        , Char -> Key
simpleChar 'c' Key
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall a. Key -> a -> KeyMap a
+> KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *).
MonadIO m =>
KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
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 'w' Key
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall a. Key -> a -> KeyMap a
+> KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *).
MonadIO m =>
KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
killAndStoreIE ((InsertMode -> InsertMode) -> KillHelper
SimpleMove InsertMode -> InsertMode
goToWordDelEnd)
        , Char -> Key
simpleChar 'W' Key
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall a. Key -> a -> KeyMap a
+> KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *).
MonadIO m =>
KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
killAndStoreIE ((InsertMode -> InsertMode) -> KillHelper
SimpleMove InsertMode -> InsertMode
goToBigWordDelEnd)
        , Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> (KillHelper
    -> Command
         (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode))
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *) s t.
Command m s t -> (KillHelper -> Command m s t) -> KeyCommand m s t
useMovementsForKill ((CommandMode -> Either CommandMode InsertMode)
-> CmdM (ViT m) CommandMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM CommandMode -> Either CommandMode InsertMode
forall a b. a -> Either a b
Left (CmdM (ViT m) CommandMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> (ArgMode CommandMode -> CmdM (ViT m) CommandMode)
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
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) (Either CommandMode InsertMode)
forall (m :: * -> *).
MonadIO m =>
KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
killAndStoreIE
        , Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
withoutConsuming (Either CommandMode InsertMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CommandMode InsertMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> (ArgMode CommandMode -> Either CommandMode InsertMode)
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> Either CommandMode InsertMode
forall a b. a -> Either a b
Left (CommandMode -> Either CommandMode InsertMode)
-> (ArgMode CommandMode -> CommandMode)
-> ArgMode CommandMode
-> Either CommandMode InsertMode
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 :: Command (ViT m) (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)
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 '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 :: 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 ['1'..'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 s -> ArgMode s
restartArg n :: Int
n = Int -> s -> ArgMode s
forall s. Int -> s -> ArgMode s
startArg Int
n (s -> ArgMode s) -> (ArgMode s -> s) -> ArgMode s -> ArgMode s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ArgMode s -> s
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 ['0'..'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 (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 'h', InsertMode -> InsertMode
forall s. Move s => s -> s
goLeft)
            , (Char -> Key
simpleChar 'l', InsertMode -> InsertMode
forall s. Move s => s -> s
goRight)
            , (Char -> Key
simpleChar ' ', 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 '0', InsertMode -> InsertMode
forall s. Move s => s -> s
moveToStart)
            , (Char -> Key
simpleChar '$', InsertMode -> InsertMode
forall s. Move s => s -> s
moveToEnd)
            , (Char -> Key
simpleChar '^', (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 '%', InsertMode -> InsertMode
findMatchingBrace)
            ------------------
            -- Word movements
            -- move to the start of the next word
            , (Char -> Key
simpleChar '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 '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 '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 '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 '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 '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
=='_')
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
(f :: a -> Bool
f .||. :: (a -> Bool) -> (a -> Bool) -> a -> Bool
.||. g :: a -> Bool
g) x :: 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 :: (Int -> s -> t) -> String -> KeyCommand m s t
foreachDigit f :: Int -> s -> t
f ds :: String
ds = [KeyCommand m s t] -> KeyCommand m s t
forall a. [KeyMap a] -> KeyMap a
choiceCmd ([KeyCommand m s t] -> KeyCommand m s t)
-> [KeyCommand m s t] -> KeyCommand m s t
forall a b. (a -> b) -> a -> b
$ (Char -> KeyCommand m s t) -> String -> [KeyCommand m s t]
forall a b. (a -> b) -> [a] -> [b]
map Char -> KeyCommand 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 d :: 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 d :: 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 '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 xs :: [Grapheme]
xs (y :: Grapheme
y:ys :: [Grapheme]
ys))
    | Just b :: Char
b <- Char -> Maybe Char
matchingRightBrace Char
yc,
      Just ((b' :: Grapheme
b':bs :: [Grapheme]
bs),ys' :: [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 b :: Char
b <- Char -> Maybe Char
matchingLeftBrace Char
yc,
      Just (bs :: [Grapheme]
bs,xs' :: [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 im :: InsertMode
im = InsertMode
im

deleteMatchingBrace :: InsertMode -> ([Grapheme],InsertMode)
deleteMatchingBrace :: InsertMode -> ([Grapheme], InsertMode)
deleteMatchingBrace (IMode xs :: [Grapheme]
xs (y :: Grapheme
y:ys :: [Grapheme]
ys))
    | Just b :: Char
b <- Char -> Maybe Char
matchingRightBrace Char
yc,
      Just (bs :: [Grapheme]
bs,ys' :: [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 b :: Char
b <- Char -> Maybe Char
matchingLeftBrace Char
yc,
      Just (bs :: [Grapheme]
bs,xs' :: [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 im :: InsertMode
im = ([],InsertMode
im)


scanBraces :: Char -> Char -> [Grapheme] -> Maybe ([Grapheme],[Grapheme])
scanBraces :: Char -> Char -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
scanBraces c :: Char
c d :: Char
d = Int -> [Grapheme] -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
forall t.
(Eq t, Num t) =>
t -> [Grapheme] -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
scanBraces' (1::Int) []
    where
        scanBraces' :: t -> [Grapheme] -> [Grapheme] -> Maybe ([Grapheme], [Grapheme])
scanBraces' 0 bs :: [Grapheme]
bs xs :: [Grapheme]
xs = ([Grapheme], [Grapheme]) -> Maybe ([Grapheme], [Grapheme])
forall a. a -> Maybe a
Just ([Grapheme]
bs,[Grapheme]
xs)
        scanBraces' _ _ [] = Maybe ([Grapheme], [Grapheme])
forall a. Maybe a
Nothing
        scanBraces' n :: t
n bs :: [Grapheme]
bs (x :: Grapheme
x:xs :: [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
+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
-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 (\(c :: Char
c,d :: Char
d) -> (Char
d,Char
c)) [(Char, Char)]
braceList)

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

---------------
-- Replace mode
replaceLoop :: InputCmd CommandMode CommandMode
replaceLoop :: Command (ViT m) 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 :: SavedCommand m -> Command (ViT m) s s
storeLastCmd act :: SavedCommand m
act = \s :: 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
$ \vs :: ViState m
vs -> ViState m
vs {lastCommand :: SavedCommand m
lastCommand = SavedCommand m
act}
        Command (ViT m) s s
forall (m :: * -> *) a. Monad m => a -> m a
return s
s

storedAction :: Monad m => SavedCommand m -> SavedCommand m
storedAction :: SavedCommand m -> SavedCommand m
storedAction act :: 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 :: Command (ViT m) (ArgMode CommandMode) CommandMode
-> Command (ViT m) (ArgMode CommandMode) CommandMode
storedCmdAction act :: 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 -> Either CommandMode InsertMode)
-> CmdM (ViT m) CommandMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM CommandMode -> Either CommandMode InsertMode
forall a b. a -> Either a b
Left (CmdM (ViT m) CommandMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> 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 :: Command (ViT m) (ArgMode CommandMode) InsertMode
-> Command (ViT m) (ArgMode CommandMode) InsertMode
storedIAction act :: 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 -> Either CommandMode InsertMode)
-> CmdM (ViT m) InsertMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM InsertMode -> Either CommandMode InsertMode
forall a b. b -> Either a b
Right (CmdM (ViT m) InsertMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> 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 :: 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 :: 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 :: KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
killAndStoreIE helper :: KillHelper
helper = Command
  (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
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 (Either CommandMode InsertMode)
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> Either CommandMode InsertMode
-> CmdM (ViT m) (Either CommandMode InsertMode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either CommandMode InsertMode
 -> CmdM (ViT m) (Either CommandMode InsertMode))
-> (InsertMode -> Either CommandMode InsertMode)
-> Command (ViT m) InsertMode (Either CommandMode InsertMode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsertMode -> Either CommandMode InsertMode
forall a b. b -> Either a b
Right)

noArg :: Monad m => Command m s (ArgMode s)
noArg :: Command m s (ArgMode s)
noArg = ArgMode s -> CmdM m (ArgMode s)
forall (m :: * -> *) a. Monad m => a -> m a
return (ArgMode s -> CmdM m (ArgMode s))
-> (s -> ArgMode s) -> Command m s (ArgMode s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> s -> ArgMode s
forall s. Int -> s -> ArgMode s
startArg 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 xs :: [Grapheme]
xs ys :: [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 prefix :: [Grapheme]
prefix se :: 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 :: Char -> Direction -> Command (ViT m) CommandMode CommandMode
viEnterSearch c :: Char
c dir :: Direction
dir s :: 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 (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 f :: InsertMode -> InsertMode
f se :: SearchEntry
se = SearchEntry
se {entryState :: InsertMode
entryState = InsertMode -> InsertMode
f (SearchEntry -> InsertMode
entryState SearchEntry
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 '\n' Key
-> (SearchEntry -> CmdM (ViT m) CommandMode)
-> KeyCommand (ViT m) SearchEntry CommandMode
forall a. Key -> a -> KeyMap a
+> \se :: 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 :: Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
viSearchHist dir :: Direction
dir toSearch :: [Grapheme]
toSearch cm :: CommandMode
cm = do
    ViState m
vstate :: ViState m <- CmdM (ViT m) (ViState m)
forall s (m :: * -> *). MonadState s m => m s
get
    let toSearch' :: [Grapheme]
toSearch' = if [Grapheme] -> 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
    Either Effect SearchMode
result <- Bool -> SearchMode -> CmdM (ViT m) (Either Effect SearchMode)
forall (m :: * -> *).
MonadState HistLog m =>
Bool -> SearchMode -> m (Either Effect SearchMode)
doSearch Bool
False SearchMode :: [Grapheme] -> InsertMode -> Direction -> SearchMode
SearchMode {
                                    searchTerm :: [Grapheme]
searchTerm = [Grapheme]
toSearch',
                                    foundHistory :: InsertMode
foundHistory = CommandMode -> InsertMode
forall s. Save s => s -> InsertMode
save CommandMode
cm, -- TODO: not needed
                                    direction :: Direction
direction = Direction
dir}
    case Either Effect SearchMode
result of
        Left e :: 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 (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 sm :: SearchMode
sm -> do
            ViState m -> CmdM (ViT m) ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put ViState m
vstate {lastSearch :: [Grapheme]
lastSearch = [Grapheme]
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))