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

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

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

type EitherMode = Either CommandMode InsertMode

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

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

emptyViState :: Monad m => ViState m
emptyViState :: forall (m :: * -> *). Monad m => ViState m
emptyViState = ViState :: 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 . (MonadIO m, MonadMask m) => Command (ViT m) s t
type InputKeyCmd s t = forall m . (MonadIO m, MonadMask m) => KeyCommand (ViT m) s t

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

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

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

insertChars :: InputKeyCmd InsertMode InsertMode
insertChars :: InputKeyCmd InsertMode InsertMode
insertChars = (Char -> Command (ViT m) InsertMode InsertMode)
-> KeyCommand (ViT m) InsertMode InsertMode
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) InsertMode InsertMode)
 -> KeyCommand (ViT m) InsertMode InsertMode)
-> (Char -> Command (ViT m) InsertMode InsertMode)
-> KeyCommand (ViT m) InsertMode InsertMode
forall a b. (a -> b) -> a -> b
$ String -> Char -> Command (ViT m) InsertMode InsertMode
forall {m :: * -> *}.
Monad m =>
String -> Char -> Command (ViT m) InsertMode InsertMode
loop []
    where
        loop :: String -> Char -> Command (ViT m) InsertMode InsertMode
loop String
ds Char
d = (InsertMode -> InsertMode) -> Command (ViT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change (Char -> InsertMode -> InsertMode
insertChar Char
d) Command (ViT m) InsertMode InsertMode
-> Command (ViT m) InsertMode InsertMode
-> Command (ViT m) InsertMode InsertMode
forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> [KeyCommand (ViT m) InsertMode InsertMode]
-> Command (ViT m) InsertMode InsertMode
forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
keyChoiceCmd [
                        (Char -> Command (ViT m) InsertMode InsertMode)
-> KeyCommand (ViT m) InsertMode InsertMode
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) InsertMode InsertMode)
 -> KeyCommand (ViT m) InsertMode InsertMode)
-> (Char -> Command (ViT m) InsertMode InsertMode)
-> KeyCommand (ViT m) InsertMode InsertMode
forall a b. (a -> b) -> a -> b
$ String -> Char -> Command (ViT m) InsertMode InsertMode
loop (Char
dChar -> String -> String
forall a. a -> [a] -> [a]
:String
ds)
                        , Command (ViT m) InsertMode InsertMode
-> KeyCommand (ViT m) InsertMode InsertMode
forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
withoutConsuming (String -> Command (ViT m) InsertMode InsertMode
forall {m :: * -> *} {s}. Monad m => String -> Command (ViT m) s s
storeCharInsertion (String -> String
forall a. [a] -> [a]
reverse String
ds))
                        ]
        storeCharInsertion :: String -> Command (ViT m) s s
storeCharInsertion String
s = SavedCommand m -> Command (ViT m) s s
forall (m :: * -> *) s.
Monad m =>
SavedCommand m -> Command (ViT m) s s
storeLastCmd (SavedCommand m -> Command (ViT m) s s)
-> SavedCommand m -> Command (ViT m) s s
forall a b. (a -> b) -> a -> b
$ (ArgMode CommandMode -> CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change ((CommandMode -> CommandMode) -> ArgMode CommandMode -> CommandMode
forall s. (s -> s) -> ArgMode s -> s
applyArg 
                                                        ((CommandMode -> CommandMode)
 -> ArgMode CommandMode -> CommandMode)
-> (CommandMode -> CommandMode)
-> ArgMode CommandMode
-> CommandMode
forall a b. (a -> b) -> a -> b
$ (InsertMode -> InsertMode) -> CommandMode -> CommandMode
withCommandMode ((InsertMode -> InsertMode) -> CommandMode -> CommandMode)
-> (InsertMode -> InsertMode) -> CommandMode -> CommandMode
forall a b. (a -> b) -> a -> b
$ String -> InsertMode -> InsertMode
insertString String
s)
                                                Command (ViT m) (ArgMode CommandMode) CommandMode
-> Command (ViT m) CommandMode (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 :: forall (m :: * -> *) s.
(Monad m, Save s, Result s) =>
Command m s (Maybe String)
eofIfEmpty s
s
    | s -> InsertMode
forall s. Save s => s -> InsertMode
save s
s InsertMode -> InsertMode -> Bool
forall a. Eq a => a -> a -> Bool
== InsertMode
emptyIM = Maybe String -> CmdM m (Maybe String)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe String
forall a. Maybe a
Nothing
    | Bool
otherwise = Command m s (Maybe String)
forall (m :: * -> *) s.
(Monad m, Result s) =>
Command m s (Maybe String)
finish s
s

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

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

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

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

repeatedCommands :: InputKeyCmd CommandMode EitherMode
repeatedCommands :: InputKeyCmd CommandMode (Either CommandMode InsertMode)
repeatedCommands = [KeyMap
   (Command (ViT m) CommandMode (Either CommandMode InsertMode))]
-> KeyMap
     (Command (ViT m) CommandMode (Either CommandMode InsertMode))
forall a. [KeyMap a] -> KeyMap a
choiceCmd [KeyMap
  (Command (ViT m) CommandMode (Either CommandMode InsertMode))
argumented, Command (ViT m) CommandMode (ArgMode CommandMode)
-> KeyCommand
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
-> KeyMap
     (Command (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 [Char
'1'..Char
'9']
        addDigit :: KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
addDigit = (Int -> ArgMode CommandMode -> ArgMode CommandMode)
-> String
-> KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
forall (m :: * -> *) t s.
(Monad m, LineState t) =>
(Int -> s -> t) -> String -> KeyCommand m s t
foreachDigit Int -> ArgMode CommandMode -> ArgMode CommandMode
forall s. Int -> ArgMode s -> ArgMode s
addNum [Char
'0'..Char
'9']
        argumented :: KeyMap
  (Command (ViT m) CommandMode (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)
-> KeyMap
     (Command (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 :: InputKeyCmd (ArgMode CommandMode) CommandMode
pureMovements = [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. [KeyMap a] -> KeyMap a
choiceCmd ([KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
charMovements [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
-> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
-> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
forall a. [a] -> [a] -> [a]
++ ((Key, InsertMode -> InsertMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> [(Key, InsertMode -> InsertMode)]
-> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
forall a b. (a -> b) -> [a] -> [b]
map (Key, InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall {m :: * -> *}.
Monad m =>
(Key, InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
mkSimpleCommand [(Key, InsertMode -> InsertMode)]
movements
    where
        charMovements :: [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
charMovements = [ Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall {m :: * -> *}.
Monad m =>
Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement Char
'f' ((Char -> InsertMode -> InsertMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> (InsertMode -> Bool) -> InsertMode -> InsertMode
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> InsertMode -> Bool
overChar (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
c)
                        , Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall {m :: * -> *}.
Monad m =>
Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement Char
'F' ((Char -> InsertMode -> InsertMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> (InsertMode -> Bool) -> InsertMode -> InsertMode
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> InsertMode -> Bool
overChar (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
c)
                        , Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall {m :: * -> *}.
Monad m =>
Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement Char
't' ((Char -> InsertMode -> InsertMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> (InsertMode -> Bool) -> InsertMode -> InsertMode
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> InsertMode -> Bool
beforeChar (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
c)
                        , Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall {m :: * -> *}.
Monad m =>
Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement Char
'T' ((Char -> InsertMode -> InsertMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> (InsertMode -> Bool) -> InsertMode -> InsertMode
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> InsertMode -> Bool
afterChar (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
c)
                        ]
        mkSimpleCommand :: (Key, InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
mkSimpleCommand (Key
k,InsertMode -> InsertMode
move) = Key
k Key
-> Command m (ArgMode CommandMode) CommandMode
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
+> (ArgMode CommandMode -> CommandMode)
-> Command m (ArgMode CommandMode) CommandMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change ((InsertMode -> InsertMode) -> ArgMode CommandMode -> CommandMode
applyCmdArg InsertMode -> InsertMode
move)
        charMovement :: Char
-> (Char -> InsertMode -> InsertMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
charMovement Char
c Char -> InsertMode -> InsertMode
move = Char -> Key
simpleChar Char
c Key
-> Command m (ArgMode CommandMode) CommandMode
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
+> [KeyMap (Command m (ArgMode CommandMode) CommandMode)]
-> Command m (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
keyChoiceCmd [
                                        (Char -> Command m (ArgMode CommandMode) CommandMode)
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((ArgMode CommandMode -> CommandMode)
-> Command m (ArgMode CommandMode) CommandMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change ((ArgMode CommandMode -> CommandMode)
 -> Command m (ArgMode CommandMode) CommandMode)
-> (Char -> ArgMode CommandMode -> CommandMode)
-> Char
-> Command m (ArgMode CommandMode) CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsertMode -> InsertMode) -> ArgMode CommandMode -> CommandMode
applyCmdArg ((InsertMode -> InsertMode) -> ArgMode CommandMode -> CommandMode)
-> (Char -> InsertMode -> InsertMode)
-> Char
-> ArgMode CommandMode
-> CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> InsertMode -> InsertMode
move)
                                        , Command m (ArgMode CommandMode) CommandMode
-> KeyMap (Command m (ArgMode CommandMode) CommandMode)
forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
withoutConsuming ((ArgMode CommandMode -> CommandMode)
-> Command m (ArgMode CommandMode) CommandMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change ArgMode CommandMode -> CommandMode
forall s. ArgMode s -> s
argState)
                                        ]

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


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

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

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

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

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

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


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

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

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

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


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

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

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

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


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

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

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

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


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

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

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

storedCmdAction :: Monad m => Command (ViT m) (ArgMode CommandMode) CommandMode
                            -> Command (ViT m) (ArgMode CommandMode) CommandMode
storedCmdAction :: forall (m :: * -> *).
Monad m =>
Command (ViT m) (ArgMode CommandMode) CommandMode
-> Command (ViT m) (ArgMode CommandMode) CommandMode
storedCmdAction Command (ViT m) (ArgMode CommandMode) CommandMode
act = SavedCommand m
-> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
forall (m :: * -> *) s.
Monad m =>
SavedCommand m -> Command (ViT m) s s
storeLastCmd ((CommandMode -> 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 :: forall (m :: * -> *).
Monad m =>
Command (ViT m) (ArgMode CommandMode) InsertMode
-> Command (ViT m) (ArgMode CommandMode) InsertMode
storedIAction Command (ViT m) (ArgMode CommandMode) InsertMode
act = SavedCommand m
-> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
forall (m :: * -> *) s.
Monad m =>
SavedCommand m -> Command (ViT m) s s
storeLastCmd ((InsertMode -> 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 :: forall (m :: * -> *).
MonadIO m =>
KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
killAndStoreCmd = Command (ViT m) (ArgMode CommandMode) CommandMode
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *).
Monad m =>
Command (ViT m) (ArgMode CommandMode) CommandMode
-> Command (ViT m) (ArgMode CommandMode) CommandMode
storedCmdAction (Command (ViT m) (ArgMode CommandMode) CommandMode
 -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> (KillHelper
    -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KillHelper
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t.
(MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
KillHelper -> Command m (ArgMode s) t
killFromArgHelper

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

killAndStoreIE :: MonadIO m => KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
killAndStoreIE :: forall (m :: * -> *).
MonadIO m =>
KillHelper
-> Command
     (ViT m) (ArgMode CommandMode) (Either CommandMode InsertMode)
killAndStoreIE KillHelper
helper = SavedCommand m -> SavedCommand m
forall (m :: * -> *). Monad m => SavedCommand m -> SavedCommand m
storedAction (KillHelper -> Command (ViT m) (ArgMode CommandMode) InsertMode
forall (m :: * -> *) s t.
(MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
KillHelper -> Command m (ArgMode s) t
killFromArgHelper KillHelper
helper Command (ViT m) (ArgMode CommandMode) InsertMode
-> Command (ViT m) InsertMode (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))
-> (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 :: forall (m :: * -> *) s. Monad m => 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) -> s -> CmdM m (ArgMode s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> s -> ArgMode s
forall s. Int -> s -> ArgMode s
startArg Int
1

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

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

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

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

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

viSearchHist :: forall m . Monad m
    => Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
viSearchHist :: forall (m :: * -> *).
Monad m =>
Direction -> [Grapheme] -> Command (ViT m) CommandMode CommandMode
viSearchHist Direction
dir [Grapheme]
toSearch CommandMode
cm = do
    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 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 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))