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

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

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

type EitherMode = Either CommandMode InsertMode

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

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

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

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

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

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

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

simpleInsertions :: InputKeyCmd InsertMode InsertMode
simpleInsertions :: InputKeyCmd InsertMode InsertMode
simpleInsertions = forall a. [KeyMap a] -> KeyMap a
choiceCmd
                [  BaseKey -> Key
simpleKey BaseKey
LeftKey forall a. Key -> a -> KeyMap a
+> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change forall s. Move s => s -> s
goLeft 
                   , BaseKey -> Key
simpleKey BaseKey
RightKey forall a. Key -> a -> KeyMap a
+> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change forall s. Move s => s -> s
goRight
                   , BaseKey -> Key
simpleKey BaseKey
Backspace forall a. Key -> a -> KeyMap a
+> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
deletePrev 
                   , BaseKey -> Key
simpleKey BaseKey
Delete forall a. Key -> a -> KeyMap a
+> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
deleteNext 
                   , BaseKey -> Key
simpleKey BaseKey
Home forall a. Key -> a -> KeyMap a
+> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change forall s. Move s => s -> s
moveToStart
                   , BaseKey -> Key
simpleKey BaseKey
End forall a. Key -> a -> KeyMap a
+> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change forall s. Move s => s -> s
moveToEnd
                   , InputKeyCmd InsertMode InsertMode
insertChars
                   , Char -> Key
ctrlChar Char
'l' forall a. Key -> a -> KeyMap a
+> forall (m :: * -> *) s. Command m s s
clearScreenCmd
                   , BaseKey -> Key
simpleKey BaseKey
UpKey forall a. Key -> a -> KeyMap a
+> forall s (m :: * -> *).
(Save s, MonadState HistLog m) =>
Command m s s
historyBack
                   , BaseKey -> Key
simpleKey BaseKey
DownKey forall a. Key -> a -> KeyMap a
+> forall s (m :: * -> *).
(Save s, MonadState HistLog m) =>
Command m s s
historyForward
                   , BaseKey -> Key
simpleKey BaseKey
SearchReverse forall a. Key -> a -> KeyMap a
+> forall (m :: * -> *).
MonadState HistLog m =>
Direction -> Command m InsertMode InsertMode
searchForPrefix Direction
Reverse
                   , BaseKey -> Key
simpleKey BaseKey
SearchForward forall a. Key -> a -> KeyMap a
+> forall (m :: * -> *).
MonadState HistLog m =>
Direction -> Command m InsertMode InsertMode
searchForPrefix Direction
Forward
                   , forall (m :: * -> *).
MonadState HistLog m =>
KeyCommand m InsertMode InsertMode
searchHistory
                   , BaseKey -> Key
simpleKey BaseKey
KillLine forall a. Key -> a -> KeyMap a
+> forall (m :: * -> *) s t.
(MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
KillHelper -> Command m s t
killFromHelper ((InsertMode -> InsertMode) -> KillHelper
SimpleMove forall s. Move s => s -> s
moveToStart)
                   , Char -> Key
ctrlChar Char
'w' forall a. Key -> a -> KeyMap a
+> forall (m :: * -> *) s t.
(MonadState KillRing m, MonadState Undo m, Save s, Save t) =>
KillHelper -> Command m s t
killFromHelper KillHelper
wordErase
                   , 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 = forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar forall a b. (a -> b) -> a -> b
$ 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 = forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change (Char -> InsertMode -> InsertMode
insertChar Char
d) forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
keyChoiceCmd [
                        forall (m :: * -> *) s t.
(Char -> Command m s t) -> KeyCommand m s t
useChar forall a b. (a -> b) -> a -> b
$ String -> Char -> Command (ViT m) InsertMode InsertMode
loop (Char
dforall a. a -> [a] -> [a]
:String
ds)
                        , forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
withoutConsuming (forall {m :: * -> *} {s}. Monad m => String -> Command (ViT m) s s
storeCharInsertion (forall a. [a] -> [a]
reverse String
ds))
                        ]
        storeCharInsertion :: String -> Command (ViT m) s s
storeCharInsertion String
s = forall (m :: * -> *) s.
Monad m =>
SavedCommand m -> Command (ViT m) s s
storeLastCmd forall a b. (a -> b) -> a -> b
$ forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change (forall s. (s -> s) -> ArgMode s -> s
applyArg 
                                                        forall a b. (a -> b) -> a -> b
$ (InsertMode -> InsertMode) -> CommandMode -> CommandMode
withCommandMode forall a b. (a -> b) -> a -> b
$ String -> InsertMode -> InsertMode
insertString String
s)
                                                forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left

-- If we receive a ^D and the line is empty, return Nothing
-- otherwise, act like '\n' (mimicing how Readline behaves)
eofIfEmpty :: (Monad m, Save s, Result s) => Command m s (Maybe String)
eofIfEmpty :: forall (m :: * -> *) s.
(Monad m, Save s, Result s) =>
Command m s (Maybe String)
eofIfEmpty s
s
    | forall s. Save s => s -> InsertMode
save s
s forall a. Eq a => a -> a -> Bool
== InsertMode
emptyIM = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    | Bool
otherwise = 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 = forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
keyChoiceCmd [
                    Char -> Key
simpleChar Char
'\n' forall a. Key -> a -> KeyMap a
+> forall (m :: * -> *) s.
(Monad m, Result s) =>
Command m s (Maybe String)
finish
                    , Char -> Key
ctrlChar Char
'd' forall a. Key -> a -> KeyMap a
+> forall (m :: * -> *) s.
(Monad m, Save s, Result s) =>
Command m s (Maybe String)
eofIfEmpty
                    , InputKeyCmd CommandMode CommandMode
simpleCmdActions forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> InputCmd CommandMode (Maybe String)
viCommandActions
                    , InputKeyCmd CommandMode InsertMode
exitingCommands forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> InputCmd InsertMode (Maybe String)
viCommands
                    , InputKeyCmd CommandMode EitherMode
repeatedCommands forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> InputCmd EitherMode (Maybe String)
chooseEitherMode
                    ]
    where
        chooseEitherMode :: InputCmd EitherMode (Maybe String)
        chooseEitherMode :: InputCmd EitherMode (Maybe String)
chooseEitherMode (Left CommandMode
cm) = InputCmd CommandMode (Maybe String)
viCommandActions CommandMode
cm
        chooseEitherMode (Right InsertMode
im) = InputCmd InsertMode (Maybe String)
viCommands InsertMode
im

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

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

replaceOnce :: InputCmd CommandMode CommandMode
replaceOnce :: InputCmd CommandMode CommandMode
replaceOnce = forall (m :: * -> *) s.
Monad m =>
KeyCommand m s s -> Command m s s
try forall a b. (a -> b) -> a -> b
$ 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 = forall a. [KeyMap a] -> KeyMap a
choiceCmd [KeyMap (Command (ViT m) CommandMode EitherMode)
argumented, forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> KeyCommand m t u -> KeyCommand m s u
doBefore forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
noArg InputKeyCmd (ArgMode CommandMode) EitherMode
repeatableCommands]
    where
        start :: KeyCommand (ViT m) CommandMode (ArgMode CommandMode)
start = forall (m :: * -> *) t s.
(Monad m, LineState t) =>
(Int -> s -> t) -> String -> KeyCommand m s t
foreachDigit forall s. Int -> s -> ArgMode s
startArg [Char
'1'..Char
'9']
        addDigit :: KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
addDigit = forall (m :: * -> *) t s.
(Monad m, LineState t) =>
(Int -> s -> t) -> String -> KeyCommand m s t
foreachDigit 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 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 = forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
keyChoiceCmd [KeyCommand (ViT m) (ArgMode CommandMode) (ArgMode CommandMode)
addDigit 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
                            , InputKeyCmd (ArgMode CommandMode) EitherMode
repeatableCommands
                            -- if no match, bail out.
                            , forall (m :: * -> *) s t. Command m s t -> KeyCommand m s t
withoutConsuming (forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change forall s. ArgMode s -> s
argState) forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left
                            ]

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

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


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

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

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

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


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

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

goToWordDelEnd, goToBigWordDelEnd :: InsertMode -> InsertMode
goToWordDelEnd :: InsertMode -> InsertMode
goToWordDelEnd = (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> InsertMode -> Bool
atStart (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isWordChar)
                                    forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
.||. (Char -> Bool) -> InsertMode -> Bool
atStart (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isOtherChar)
goToBigWordDelEnd :: InsertMode -> InsertMode
goToBigWordDelEnd = (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> InsertMode -> Bool
atStart (Bool -> Bool
not 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', forall s. Move s => s -> s
goLeft)
            , (Char -> Key
simpleChar Char
'l', forall s. Move s => s -> s
goRight)
            , (Char -> Key
simpleChar Char
' ', forall s. Move s => s -> s
goRight)
            , (BaseKey -> Key
simpleKey BaseKey
LeftKey, forall s. Move s => s -> s
goLeft)
            , (BaseKey -> Key
simpleKey BaseKey
RightKey, forall s. Move s => s -> s
goRight)
            , (Char -> Key
simpleChar Char
'0', forall s. Move s => s -> s
moveToStart)
            , (Char -> Key
simpleChar Char
'$', forall s. Move s => s -> s
moveToEnd)
            , (Char -> Key
simpleChar Char
'^', (Char -> Bool) -> InsertMode -> InsertMode
skipRight Char -> Bool
isSpace forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 forall a b. (a -> b) -> a -> b
$
                                (Char -> Bool) -> InsertMode -> Bool
atStart Char -> Bool
isWordChar 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 forall a b. (a -> b) -> a -> b
$
                                (Char -> Bool) -> InsertMode -> Bool
atStart Char -> Bool
isWordChar 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 forall a b. (a -> b) -> a -> b
$
                                (Char -> Bool) -> InsertMode -> Bool
atEnd Char -> Bool
isWordChar 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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace
isWordChar :: Char -> Bool
isWordChar = Char -> Bool
isAlphaNum forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
.||. (forall a. Eq a => a -> a -> Bool
==Char
'_')
isOtherChar :: Char -> Bool
isOtherChar = Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool
isSpace forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
.||. Char -> Bool
isWordChar)

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

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


-- This mimics the ctrl-w command in readline's vi mode, which corresponds to
-- the tty's werase character.
wordErase :: KillHelper
wordErase :: KillHelper
wordErase = (InsertMode -> InsertMode) -> KillHelper
SimpleMove forall a b. (a -> b) -> a -> b
$ (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil 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]
bsforall a. [a] -> [a] -> [a]
++[Grapheme
y]forall a. [a] -> [a] -> [a]
++[Grapheme]
xs) (Grapheme
b'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 forall a. [a] -> [a] -> [a]
++ [Grapheme
y]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 forall a. a -> [a] -> [a]
: 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 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 = 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 = forall a. a -> Maybe a
Just ([Grapheme]
bs,[Grapheme]
xs)
        scanBraces' t
_ [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
xforall a. a -> [a] -> [a]
:[Grapheme]
bs) [Grapheme]
xs
            where m :: t
m | Grapheme -> Char
baseChar Grapheme
x forall a. Eq a => a -> a -> Bool
== Char
c = t
nforall a. Num a => a -> a -> a
+t
1
                    | Grapheme -> Char
baseChar Grapheme
x forall a. Eq a => a -> a -> Bool
== Char
d = t
nforall a. Num a => a -> a -> a
-t
1
                    | Bool
otherwise = t
n

matchingRightBrace, matchingLeftBrace :: Char -> Maybe Char 
matchingRightBrace :: Char -> Maybe Char
matchingRightBrace = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup [(Char, Char)]
braceList
matchingLeftBrace :: Char -> Maybe Char
matchingLeftBrace = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (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 = forall s (m :: * -> *).
(Save s, MonadState Undo m) =>
Command m s s
saveForUndo forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change CommandMode -> InsertMode
insertFromCommandMode forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> Command (ViT m) InsertMode InsertMode
loop
                forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> CommandMode
enterCommandModeRight
    where
        loop :: Command (ViT m) InsertMode InsertMode
loop = forall (m :: * -> *) s.
Monad m =>
KeyCommand m s s -> Command m s s
try (KeyCommand (ViT m) InsertMode InsertMode
oneReplaceCmd forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> Command (ViT m) InsertMode InsertMode
loop)
        oneReplaceCmd :: KeyCommand (ViT m) InsertMode InsertMode
oneReplaceCmd = forall a. [KeyMap a] -> KeyMap a
choiceCmd [
                BaseKey -> Key
simpleKey BaseKey
LeftKey forall a. Key -> a -> KeyMap a
+> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change forall s. Move s => s -> s
goLeft
                , BaseKey -> Key
simpleKey BaseKey
RightKey forall a. Key -> a -> KeyMap a
+> forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change forall s. Move s => s -> s
goRight
                , 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
        forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \ViState m
vs -> ViState m
vs {lastCommand :: SavedCommand m
lastCommand = SavedCommand m
act}
        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 = forall (m :: * -> *) s.
Monad m =>
SavedCommand m -> Command (ViT m) s s
storeLastCmd SavedCommand m
act forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> SavedCommand m
act

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

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

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

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

noArg :: Monad m => Command m s (ArgMode s)
noArg :: forall (m :: * -> *) s. Monad m => Command m s (ArgMode s)
noArg = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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} = forall a. [a] -> [a]
reverse [Grapheme]
xs forall a. [a] -> [a] -> [a]
++ [Grapheme]
ys

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

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