{-# LANGUAGE LambdaCase #-}
#if __GLASGOW_HASKELL__ < 802
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
#endif
module System.Console.Haskeline.Vi (emptyViState, viKeyCommands) 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 (liftM2, (>=>))
import Control.Monad.Catch (MonadMask)

type EitherMode = Either CommandMode InsertMode

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

data InlineSearch = F -- f | F
                  | T -- t | T

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

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

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
`useKey` 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
`useKey` 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
`useKey` ((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
-> (CommandMode -> CmdM (ViT m) (Maybe String))
-> Command (ViT m) InsertMode (Maybe String)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> CommandMode -> CmdM (ViT m) (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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` 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 :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> [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
-> (CommandMode -> CmdM (ViT m) EitherMode) -> SavedCommand m
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> EitherMode -> CmdM (ViT m) EitherMode
forall a. a -> CmdM (ViT m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (EitherMode -> CmdM (ViT m) EitherMode)
-> (CommandMode -> EitherMode)
-> CommandMode
-> CmdM (ViT m) EitherMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandMode -> EitherMode
CommandMode -> EitherMode
forall a b. a -> Either a b
Left

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

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

exitingCommands :: InputKeyCmd CommandMode InsertMode
exitingCommands :: InputKeyCmd CommandMode InsertMode
exitingCommands = [KeyMap (Command (ViT m) CommandMode InsertMode)]
-> KeyMap (Command (ViT m) CommandMode InsertMode)
forall a. [KeyMap a] -> KeyMap a
choiceCmd [
                      Char -> Key
simpleChar Char
'i' Key
-> Command (ViT m) CommandMode InsertMode
-> KeyMap (Command (ViT m) CommandMode InsertMode)
forall a. Key -> a -> KeyMap a
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (Command (ViT m) CommandMode (ArgMode CommandMode)
forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
noArg Command (ViT m) CommandMode (ArgMode CommandMode)
-> (ArgMode CommandMode -> CmdM (ViT m) InsertMode)
-> Command (ViT m) CommandMode InsertMode
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> KillHelper -> ArgMode CommandMode -> CmdM (ViT m) 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
`useKey` (Command (ViT m) CommandMode (ArgMode CommandMode)
forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
noArg Command (ViT m) CommandMode (ArgMode CommandMode)
-> (ArgMode CommandMode -> CmdM (ViT m) InsertMode)
-> Command (ViT m) CommandMode InsertMode
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> KillHelper -> ArgMode CommandMode -> CmdM (ViT m) 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
`useKey` (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
`useKey` 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
`useKey` 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
`useKey` (Command (ViT m) CommandMode (ArgMode CommandMode)
forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
noArg Command (ViT m) CommandMode (ArgMode CommandMode)
-> (ArgMode CommandMode -> CmdM (ViT m) CommandMode)
-> Command (ViT m) CommandMode CommandMode
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> KillHelper -> ArgMode CommandMode -> CmdM (ViT m) CommandMode
forall (m :: * -> *).
MonadIO m =>
KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
killAndStoreC ((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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` (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 :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (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
`useKey` (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 :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (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
`useKey` (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 :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (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
`useKey` (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 :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` (Command (ViT m) CommandMode (ArgMode CommandMode)
forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
noArg Command (ViT m) CommandMode (ArgMode CommandMode)
-> (ArgMode CommandMode -> CmdM (ViT m) CommandMode)
-> Command (ViT m) CommandMode CommandMode
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> KillHelper -> ArgMode CommandMode -> CmdM (ViT m) CommandMode
forall (m :: * -> *).
MonadIO m =>
KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
killAndStoreC ((InsertMode -> InsertMode) -> KillHelper
SimpleMove InsertMode -> InsertMode
forall s. Move s => s -> s
moveToStart))
                    ]

inlineSearchActions :: InputKeyCmd (ArgMode CommandMode) CommandMode
inlineSearchActions :: InputKeyCmd (ArgMode CommandMode) CommandMode
inlineSearchActions = [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
'f' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
`useKey` KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand ((Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> (Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
F Direction
Forward Char
c CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> CmdM (ViT m) CommandMode
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction)
  -> CmdM (ViT m) CommandMode)
 -> CmdM (ViT m) CommandMode)
-> (ArgMode CommandMode
    -> Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
forall (m :: * -> *).
Monad m =>
(Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
viInlineSearch Direction -> Direction
forall a. a -> a
id)
                    , Char -> Key
simpleChar Char
'F' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
`useKey` KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand ((Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> (Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
F Direction
Reverse Char
c CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> CmdM (ViT m) CommandMode
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction)
  -> CmdM (ViT m) CommandMode)
 -> CmdM (ViT m) CommandMode)
-> (ArgMode CommandMode
    -> Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
forall (m :: * -> *).
Monad m =>
(Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
viInlineSearch Direction -> Direction
forall a. a -> a
id)
                    , Char -> Key
simpleChar Char
't' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
`useKey` KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand ((Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> (Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
T Direction
Forward Char
c CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> CmdM (ViT m) CommandMode
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction)
  -> CmdM (ViT m) CommandMode)
 -> CmdM (ViT m) CommandMode)
-> (ArgMode CommandMode
    -> Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
forall (m :: * -> *).
Monad m =>
(Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
viInlineSearch Direction -> Direction
forall a. a -> a
id)
                    , Char -> Key
simpleChar Char
'T' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
`useKey` KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand ((Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> (Char -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
T Direction
Reverse Char
c CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> CmdM (ViT m) CommandMode
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction)
  -> CmdM (ViT m) CommandMode)
 -> CmdM (ViT m) CommandMode)
-> (ArgMode CommandMode
    -> Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
forall (m :: * -> *).
Monad m =>
(Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
viInlineSearch Direction -> Direction
forall a. a -> a
id)
                    , Char -> Key
simpleChar Char
';' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
`useKey` ((CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
getLastInlineSearch CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> CmdM (ViT m) CommandMode
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction)
  -> CmdM (ViT m) CommandMode)
 -> CmdM (ViT m) CommandMode)
-> (ArgMode CommandMode
    -> Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
forall (m :: * -> *).
Monad m =>
(Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
viInlineSearch Direction -> Direction
forall a. a -> a
id)
                    , Char -> Key
simpleChar Char
',' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
`useKey` ((CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
getLastInlineSearch CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> CmdM (ViT m) CommandMode
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction)
  -> CmdM (ViT m) CommandMode)
 -> CmdM (ViT m) CommandMode)
-> (ArgMode CommandMode
    -> Maybe (Char, InlineSearch, Direction)
    -> CmdM (ViT m) CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
forall (m :: * -> *).
Monad m =>
(Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
viInlineSearch Direction -> Direction
flipDir)
                    ]

viInlineSearch :: Monad m => (Direction -> Direction)
                          -> ArgMode CommandMode
                          -> (Maybe (Char, InlineSearch, Direction))
                          -> CmdM (ViT m) CommandMode
viInlineSearch :: forall (m :: * -> *).
Monad m =>
(Direction -> Direction)
-> ArgMode CommandMode
-> Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) CommandMode
viInlineSearch Direction -> Direction
flipdir = \ArgMode CommandMode
s -> \case
    Maybe (Char, InlineSearch, Direction)
Nothing -> CommandMode -> CmdM (ViT m) CommandMode
forall a. a -> CmdM (ViT m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (CommandMode -> CmdM (ViT m) CommandMode)
-> CommandMode -> CmdM (ViT m) CommandMode
forall a b. (a -> b) -> a -> b
$ ArgMode CommandMode -> CommandMode
forall s. ArgMode s -> s
argState ArgMode CommandMode
s
    Just (Char
g, InlineSearch
fOrT, Direction
dir) -> CommandMode -> CmdM (ViT m) CommandMode
forall (m :: * -> *) s. (Monad m, LineState s) => Command m s s
setState (CommandMode -> CmdM (ViT m) CommandMode)
-> CommandMode -> CmdM (ViT m) CommandMode
forall a b. (a -> b) -> a -> b
$ ((CommandMode -> CommandMode) -> ArgMode CommandMode -> CommandMode
forall s. (s -> s) -> ArgMode s -> s
applyArg ((CommandMode -> CommandMode)
 -> ArgMode CommandMode -> CommandMode)
-> ((Char -> Bool) -> CommandMode -> CommandMode)
-> (Char -> Bool)
-> ArgMode CommandMode
-> CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (InsertMode -> InsertMode) -> CommandMode -> CommandMode
withCommandMode ((InsertMode -> InsertMode) -> CommandMode -> CommandMode)
-> ((Char -> Bool) -> InsertMode -> InsertMode)
-> (Char -> Bool)
-> CommandMode
-> CommandMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InlineSearch
-> Direction -> (Char -> Bool) -> InsertMode -> InsertMode
search InlineSearch
fOrT (Direction -> Direction
flipdir Direction
dir)) (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
g) ArgMode CommandMode
s
    where
        search :: InlineSearch -> Direction -> (Char -> Bool) -> InsertMode -> InsertMode
        search :: InlineSearch
-> Direction -> (Char -> Bool) -> InsertMode -> InsertMode
search InlineSearch
F Direction
Forward = (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> ((Char -> Bool) -> InsertMode -> Bool)
-> (Char -> Bool)
-> InsertMode
-> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> InsertMode -> Bool
overChar
        search InlineSearch
F Direction
Reverse = (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> ((Char -> Bool) -> InsertMode -> Bool)
-> (Char -> Bool)
-> InsertMode
-> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> InsertMode -> Bool
overChar
        search InlineSearch
T Direction
Forward = (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> ((Char -> Bool) -> InsertMode -> Bool)
-> (Char -> Bool)
-> InsertMode
-> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> InsertMode -> Bool
beforeChar
        search InlineSearch
T Direction
Reverse = (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> ((Char -> Bool) -> InsertMode -> Bool)
-> (Char -> Bool)
-> InsertMode
-> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> InsertMode -> Bool
afterChar

getLastInlineSearch :: forall m. Monad m => CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
getLastInlineSearch :: forall (m :: * -> *).
Monad m =>
CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
getLastInlineSearch = ViState m -> Maybe (Char, InlineSearch, Direction)
forall (m :: * -> *).
ViState m -> Maybe (Char, InlineSearch, Direction)
lastInlineSearch (ViState m -> Maybe (Char, InlineSearch, Direction))
-> CmdM (ViT m) (ViState m)
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (CmdM (ViT m) (ViState m)
forall s (m :: * -> *). MonadState s m => m s
get :: CmdM (ViT m) (ViState m)) -- TODO: ideally this is a usage of `gets`

saveInlineSearch :: forall m. Monad m => InlineSearch -> Direction -> Char
                                      -> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch :: forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
fOrT Direction
dir Char
char
  = do let ret :: Maybe (Char, InlineSearch, Direction)
ret = (Char, InlineSearch, Direction)
-> Maybe (Char, InlineSearch, Direction)
forall a. a -> Maybe a
Just (Char
char, InlineSearch
fOrT, Direction
dir)
       (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) -> ViState m
vs {lastInlineSearch = ret}
       Maybe (Char, InlineSearch, Direction)
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall a. a -> CmdM (ViT m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Char, InlineSearch, Direction)
ret

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

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

pureMovements :: InputKeyCmd (ArgMode CommandMode) CommandMode
pureMovements :: InputKeyCmd (ArgMode CommandMode) CommandMode
pureMovements = [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. [KeyMap a] -> KeyMap a
choiceCmd ([KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
 -> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode))
-> [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a b. (a -> b) -> a -> b
$ ((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 (ArgMode CommandMode -> CmdM m CommandMode)
mkSimpleCommand [(Key, InsertMode -> InsertMode)]
movements
    where
        mkSimpleCommand :: (Key, InsertMode -> InsertMode)
-> KeyMap (ArgMode CommandMode -> CmdM m CommandMode)
mkSimpleCommand (Key
k, InsertMode -> InsertMode
move) = Key
k Key
-> (ArgMode CommandMode -> CmdM m CommandMode)
-> KeyMap (ArgMode CommandMode -> CmdM m CommandMode)
forall a. Key -> a -> KeyMap a
`useKey` (ArgMode CommandMode -> CommandMode)
-> ArgMode CommandMode -> CmdM m 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)

useMovementsForKill :: (KillHelper -> Command m s t) -> KeyCommand m s t
useMovementsForKill :: forall (m :: * -> *) s t.
(KillHelper -> Command m s t) -> KeyCommand m s t
useMovementsForKill 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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` KillHelper -> Command m s t
useHelper ((InsertMode -> ([Grapheme], InsertMode)) -> KillHelper
GenericKill InsertMode -> ([Grapheme], InsertMode)
deleteMatchingBrace)
                       ]

useInlineSearchForKill :: Monad m => Command (ViT m) s t -> (KillHelper -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
useInlineSearchForKill :: forall (m :: * -> *) s t.
Monad m =>
Command (ViT m) s t
-> (KillHelper -> Command (ViT m) s t)
-> KeyMap (Command (ViT m) s t)
useInlineSearchForKill Command (ViT m) s t
alternate KillHelper -> Command (ViT m) s t
killCmd = [KeyMap (Command (ViT m) s t)] -> KeyMap (Command (ViT m) s t)
forall a. [KeyMap a] -> KeyMap a
choiceCmd
        [ Char -> Key
simpleChar Char
'f' Key -> Command (ViT m) s t -> KeyMap (Command (ViT m) s t)
forall a. Key -> a -> KeyMap a
`useKey` KeyMap (Command (ViT m) s t) -> Command (ViT m) s t
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand ((Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t))
-> (Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
F Direction
Forward Char
c CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> CmdM (ViT m) t
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
 -> CmdM (ViT m) t)
-> (s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> Command (ViT m) s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t
getSearchAndKill)
        , Char -> Key
simpleChar Char
'F' Key -> Command (ViT m) s t -> KeyMap (Command (ViT m) s t)
forall a. Key -> a -> KeyMap a
`useKey` KeyMap (Command (ViT m) s t) -> Command (ViT m) s t
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand ((Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t))
-> (Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
F Direction
Reverse Char
c CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> CmdM (ViT m) t
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
 -> CmdM (ViT m) t)
-> (s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> Command (ViT m) s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t
getSearchAndKill)
        , Char -> Key
simpleChar Char
't' Key -> Command (ViT m) s t -> KeyMap (Command (ViT m) s t)
forall a. Key -> a -> KeyMap a
`useKey` KeyMap (Command (ViT m) s t) -> Command (ViT m) s t
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand ((Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t))
-> (Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
T Direction
Forward Char
c CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> CmdM (ViT m) t
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
 -> CmdM (ViT m) t)
-> (s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> Command (ViT m) s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t
getSearchAndKill)
        , Char -> Key
simpleChar Char
'T' Key -> Command (ViT m) s t -> KeyMap (Command (ViT m) s t)
forall a. Key -> a -> KeyMap a
`useKey` KeyMap (Command (ViT m) s t) -> Command (ViT m) s t
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand ((Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar ((Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t))
-> (Char -> Command (ViT m) s t) -> KeyMap (Command (ViT m) s t)
forall a b. (a -> b) -> a -> b
$ \Char
c -> (InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
InlineSearch
-> Direction
-> Char
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
saveInlineSearch InlineSearch
T Direction
Reverse Char
c CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> CmdM (ViT m) t
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
 -> CmdM (ViT m) t)
-> (s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> Command (ViT m) s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t
getSearchAndKill)
        , Char -> Key
simpleChar Char
';' Key -> Command (ViT m) s t -> KeyMap (Command (ViT m) s t)
forall a. Key -> a -> KeyMap a
`useKey` ((CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
getLastInlineSearch CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> CmdM (ViT m) t
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
 -> CmdM (ViT m) t)
-> (s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> Command (ViT m) s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t
getSearchAndKill)
        , Char -> Key
simpleChar Char
',' Key -> Command (ViT m) s t -> KeyMap (Command (ViT m) s t)
forall a. Key -> a -> KeyMap a
`useKey` ((Maybe (Char, InlineSearch, Direction)
-> Maybe (Char, InlineSearch, Direction)
forall a b. Maybe (a, b, Direction) -> Maybe (a, b, Direction)
reverseDir (Maybe (Char, InlineSearch, Direction)
 -> Maybe (Char, InlineSearch, Direction))
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
forall (m :: * -> *).
Monad m =>
CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
getLastInlineSearch CmdM (ViT m) (Maybe (Char, InlineSearch, Direction))
-> (Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> CmdM (ViT m) t
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=) ((Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
 -> CmdM (ViT m) t)
-> (s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t)
-> Command (ViT m) s t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t
getSearchAndKill)
        ]
    where
        getSearchAndKill :: s -> Maybe (Char, InlineSearch, Direction) -> CmdM (ViT m) t
getSearchAndKill = \s
s
          -> \case (Just (Char
g, InlineSearch
fOrT, Direction
forOrRev)) -> KillHelper -> Command (ViT m) s t
killCmd ((InsertMode -> InsertMode) -> KillHelper
(InsertMode -> InsertMode) -> KillHelper
SimpleMove ((InsertMode -> InsertMode) -> KillHelper)
-> (InsertMode -> InsertMode) -> KillHelper
forall a b. (a -> b) -> a -> b
$ InlineSearch
-> Direction -> (Char -> Bool) -> InsertMode -> InsertMode
moveForKill InlineSearch
fOrT Direction
forOrRev ((Char -> Bool) -> InsertMode -> InsertMode)
-> (Char -> Bool) -> InsertMode -> InsertMode
forall a b. (a -> b) -> a -> b
$ (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
g)) s
s
                   Maybe (Char, InlineSearch, Direction)
Nothing -> Command (ViT m) s t
alternate s
s

        moveForKill :: InlineSearch
-> Direction -> (Char -> Bool) -> InsertMode -> InsertMode
moveForKill InlineSearch
F Direction
Forward = (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> ((Char -> Bool) -> InsertMode -> Bool)
-> (Char -> Bool)
-> InsertMode
-> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> InsertMode -> Bool
afterChar
        moveForKill InlineSearch
F Direction
Reverse = (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> ((Char -> Bool) -> InsertMode -> Bool)
-> (Char -> Bool)
-> InsertMode
-> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> InsertMode -> Bool
overChar
        moveForKill InlineSearch
T Direction
Forward = (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> ((Char -> Bool) -> InsertMode -> Bool)
-> (Char -> Bool)
-> InsertMode
-> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> InsertMode -> Bool
overChar
        moveForKill InlineSearch
T Direction
Reverse = (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil ((InsertMode -> Bool) -> InsertMode -> InsertMode)
-> ((Char -> Bool) -> InsertMode -> Bool)
-> (Char -> Bool)
-> InsertMode
-> InsertMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> InsertMode -> Bool
afterChar

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

repeatableCmdMode :: InputKeyCmd (ArgMode CommandMode) CommandMode
repeatableCmdMode :: InputKeyCmd (ArgMode CommandMode) CommandMode
repeatableCmdMode = [KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)]
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. [KeyMap a] -> KeyMap a
choiceCmd
                    [ Char -> Key
simpleChar Char
'x' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
forall a. Key -> a -> KeyMap a
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` 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
`useKey` KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *).
MonadIO m =>
KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
killAndStoreC KillHelper
wordErase
                    , KeyMap (Command (ViT m) (ArgMode CommandMode) CommandMode)
InputKeyCmd (ArgMode CommandMode) CommandMode
inlineSearchActions
                    , 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 :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (ArgMode CommandMode -> CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change ((CommandMode -> CommandMode) -> ArgMode CommandMode -> CommandMode
forall s. (s -> s) -> ArgMode s -> s
applyArg CommandMode -> CommandMode
f))

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

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

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

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


yankCommand :: InputCmd (ArgMode CommandMode) CommandMode
yankCommand :: InputCmd (ArgMode CommandMode) CommandMode
yankCommand = [KeyCommand (ViT m) (ArgMode CommandMode) CommandMode]
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
keyChoiceCmd
        [ KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
forall s. LineState s => InputKeyCmd (ArgMode s) (ArgMode s)
InputKeyCmd (ArgMode CommandMode) (ArgMode CommandMode)
reinputArg KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> Command (ViT m) (ArgMode CommandMode) CommandMode
InputCmd (ArgMode CommandMode) CommandMode
yankCommand
        , Char -> Key
simpleChar Char
'y' Key
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall a. Key -> a -> KeyMap a
`useKey` KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *).
MonadIO m =>
KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
copyAndStore KillHelper
killAll
        , (KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t.
(KillHelper -> Command m s t) -> KeyCommand m s t
useMovementsForKill KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *).
MonadIO m =>
KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
copyAndStore
        , Command (ViT m) (ArgMode CommandMode) CommandMode
-> (KillHelper
    -> Command (ViT m) (ArgMode CommandMode) CommandMode)
-> KeyCommand (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) s t.
Monad m =>
Command (ViT m) s t
-> (KillHelper -> Command (ViT m) s t)
-> KeyMap (Command (ViT m) s t)
useInlineSearchForKill ((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
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)
        ]

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

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


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

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

(.||.) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
.||. :: forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
(.||.) = (Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 Bool -> Bool -> Bool
(||)

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 (s -> CmdM m t)
digitCmd String
ds
    where digitCmd :: Char -> KeyMap (s -> CmdM m t)
digitCmd Char
d = Char -> Key
simpleChar Char
d Key -> (s -> CmdM m t) -> KeyMap (s -> CmdM m t)
forall a. Key -> a -> KeyMap a
`useKey` (s -> t) -> s -> CmdM m 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
(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 :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (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
-> (InsertMode -> CmdM (ViT m) CommandMode)
-> Command (ViT m) CommandMode CommandMode
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> InsertMode -> CmdM (ViT m) InsertMode
loop
                (InsertMode -> CmdM (ViT m) InsertMode)
-> (InsertMode -> CmdM (ViT m) CommandMode)
-> InsertMode
-> CmdM (ViT m) CommandMode
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (InsertMode -> CommandMode)
-> InsertMode -> CmdM (ViT m) CommandMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> CommandMode
enterCommandModeRight
    where
        loop :: InsertMode -> CmdM (ViT m) InsertMode
loop = KeyCommand (ViT m) InsertMode InsertMode
-> InsertMode -> CmdM (ViT m) 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
-> (InsertMode -> CmdM (ViT m) 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
>+> InsertMode -> CmdM (ViT m) 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
-> (InsertMode -> CmdM (ViT m) InsertMode)
-> KeyCommand (ViT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
`useKey` (InsertMode -> InsertMode) -> InsertMode -> CmdM (ViT m) 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
-> (InsertMode -> CmdM (ViT m) InsertMode)
-> KeyCommand (ViT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
`useKey` (InsertMode -> InsertMode) -> InsertMode -> CmdM (ViT m) InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
forall s. Move s => s -> s
goRight
                , (Char -> InsertMode -> InsertMode)
-> KeyCommand (ViT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(Char -> s -> t) -> KeyCommand m s t
changeFromChar Char -> InsertMode -> InsertMode
replaceCharIM
                ]


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

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

storedAction :: Monad m => SavedCommand m -> SavedCommand m
storedAction :: forall (m :: * -> *). Monad m => SavedCommand m -> SavedCommand m
storedAction SavedCommand m
act = SavedCommand m
-> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
forall (m :: * -> *) s.
Monad m =>
SavedCommand m -> Command (ViT m) s s
storeLastCmd SavedCommand m
act Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
-> SavedCommand m -> SavedCommand m
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> SavedCommand m
act

storedCmdAction :: Monad m => Command (ViT m) (ArgMode CommandMode) CommandMode
                           -> Command (ViT m) (ArgMode CommandMode) CommandMode
storedCmdAction :: forall (m :: * -> *).
Monad m =>
Command (ViT m) (ArgMode CommandMode) CommandMode
-> Command (ViT m) (ArgMode CommandMode) CommandMode
storedCmdAction Command (ViT m) (ArgMode CommandMode) CommandMode
act = SavedCommand m
-> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
forall (m :: * -> *) s.
Monad m =>
SavedCommand m -> Command (ViT m) s s
storeLastCmd ((CommandMode -> EitherMode)
-> CmdM (ViT m) CommandMode -> CmdM (ViT m) EitherMode
forall a b. (a -> b) -> CmdM (ViT m) a -> CmdM (ViT m) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CommandMode -> EitherMode
CommandMode -> EitherMode
forall a b. a -> Either a b
Left (CmdM (ViT m) CommandMode -> CmdM (ViT m) EitherMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> SavedCommand m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Command (ViT m) (ArgMode CommandMode) CommandMode
act) Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
-> Command (ViT m) (ArgMode CommandMode) CommandMode
-> Command (ViT m) (ArgMode CommandMode) CommandMode
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Command (ViT m) (ArgMode CommandMode) CommandMode
act

storedIAction :: Monad m => Command (ViT m) (ArgMode CommandMode) InsertMode
                         -> Command (ViT m) (ArgMode CommandMode) InsertMode
storedIAction :: forall (m :: * -> *).
Monad m =>
Command (ViT m) (ArgMode CommandMode) InsertMode
-> Command (ViT m) (ArgMode CommandMode) InsertMode
storedIAction Command (ViT m) (ArgMode CommandMode) InsertMode
act = SavedCommand m
-> Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
forall (m :: * -> *) s.
Monad m =>
SavedCommand m -> Command (ViT m) s s
storeLastCmd ((InsertMode -> EitherMode)
-> CmdM (ViT m) InsertMode -> CmdM (ViT m) EitherMode
forall a b. (a -> b) -> CmdM (ViT m) a -> CmdM (ViT m) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap InsertMode -> EitherMode
InsertMode -> EitherMode
forall a b. b -> Either a b
Right (CmdM (ViT m) InsertMode -> CmdM (ViT m) EitherMode)
-> Command (ViT m) (ArgMode CommandMode) InsertMode
-> SavedCommand m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Command (ViT m) (ArgMode CommandMode) InsertMode
act) Command (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
-> Command (ViT m) (ArgMode CommandMode) InsertMode
-> Command (ViT m) (ArgMode CommandMode) InsertMode
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Command (ViT m) (ArgMode CommandMode) InsertMode
act

killAndStoreC :: MonadIO m => KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
killAndStoreC :: forall (m :: * -> *).
MonadIO m =>
KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
killAndStoreC = 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

killAndStoreE :: MonadIO m => KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
killAndStoreE :: forall (m :: * -> *).
MonadIO m =>
KillHelper -> Command (ViT m) (ArgMode CommandMode) EitherMode
killAndStoreE 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
-> (InsertMode -> CmdM (ViT m) EitherMode) -> SavedCommand m
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> EitherMode -> CmdM (ViT m) EitherMode
forall a. a -> CmdM (ViT m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (EitherMode -> CmdM (ViT m) EitherMode)
-> (InsertMode -> EitherMode)
-> InsertMode
-> CmdM (ViT m) EitherMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsertMode -> EitherMode
InsertMode -> EitherMode
forall a b. b -> Either a b
Right)

copyAndStore :: MonadIO m => KillHelper -> Command (ViT m) (ArgMode CommandMode) CommandMode
copyAndStore :: forall (m :: * -> *).
MonadIO m =>
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

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

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

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

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

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

viEnterSearch :: Monad m => Char -> Direction
                    -> Command (ViT m) CommandMode CommandMode
viEnterSearch :: forall (m :: * -> *).
Monad m =>
Char -> Direction -> Command (ViT m) CommandMode CommandMode
viEnterSearch Char
c Direction
dir CommandMode
s = Command (ViT m) SearchEntry SearchEntry
forall (m :: * -> *) s. (Monad m, LineState s) => Command m s s
setState (InsertMode -> Char -> SearchEntry
SearchEntry InsertMode
emptyIM Char
c) CmdM (ViT m) SearchEntry
-> (SearchEntry -> CmdM (ViT m) CommandMode)
-> CmdM (ViT m) CommandMode
forall a b.
CmdM (ViT m) a -> (a -> CmdM (ViT m) b) -> CmdM (ViT m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SearchEntry -> CmdM (ViT m) CommandMode
loopEntry
    where
        modifySE :: (InsertMode -> InsertMode) -> SearchEntry -> SearchEntry
modifySE InsertMode -> InsertMode
f SearchEntry
se = SearchEntry
se {entryState = f (entryState se)}
        loopEntry :: SearchEntry -> CmdM (ViT m) CommandMode
loopEntry = [KeyCommand (ViT m) SearchEntry CommandMode]
-> SearchEntry -> CmdM (ViT m) CommandMode
forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
keyChoiceCmd
                        [ KeyMap (Command (ViT m) SearchEntry SearchEntry)
editEntry KeyMap (Command (ViT m) SearchEntry SearchEntry)
-> (SearchEntry -> CmdM (ViT m) CommandMode)
-> KeyCommand (ViT m) SearchEntry CommandMode
forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> SearchEntry -> CmdM (ViT m) CommandMode
loopEntry
                        , Char -> Key
simpleChar Char
'\n' Key
-> (SearchEntry -> CmdM (ViT m) CommandMode)
-> KeyCommand (ViT m) SearchEntry CommandMode
forall a. Key -> a -> KeyMap a
`useKey` \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
`useKey` (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
`useKey` (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
`useKey` (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
`useKey` (SearchEntry -> SearchEntry)
-> Command (ViT m) SearchEntry SearchEntry
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change ((InsertMode -> InsertMode) -> SearchEntry -> SearchEntry
modifySE InsertMode -> InsertMode
deleteNext)
                        ]

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

reverseDir :: Maybe (a, b, Direction) -> Maybe (a, b, Direction)
reverseDir :: forall a b. Maybe (a, b, Direction) -> Maybe (a, b, Direction)
reverseDir = ((Direction -> Direction) -> (a, b, Direction) -> (a, b, Direction)
forall {t} {c} {a} {b}. (t -> c) -> (a, b, t) -> (a, b, c)
third3 Direction -> Direction
flipDir ((a, b, Direction) -> (a, b, Direction))
-> Maybe (a, b, Direction) -> Maybe (a, b, Direction)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)
    where
        third3 :: (t -> c) -> (a, b, t) -> (a, b, c)
third3 t -> c
f (a
a, b
b, t
c) = (a
a, b
b, t -> c
f t
c)