#if __GLASGOW_HASKELL__ < 802
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
#endif
module System.Console.Haskeline.Emacs 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.Undo
import System.Console.Haskeline.Command.KillRing
import System.Console.Haskeline.LineState
import System.Console.Haskeline.InputT

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

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

emacsCommands :: InputKeyCmd InsertMode (Maybe String)
emacsCommands :: KeyCommand (InputCmdT m) InsertMode (Maybe String)
emacsCommands = [KeyCommand (InputCmdT m) InsertMode (Maybe String)]
-> KeyCommand (InputCmdT m) InsertMode (Maybe String)
forall a. [KeyMap a] -> KeyMap a
choiceCmd [
                    [KeyMap (Command (InputCmdT m) InsertMode InsertMode)]
-> KeyMap (Command (InputCmdT m) InsertMode InsertMode)
forall a. [KeyMap a] -> KeyMap a
choiceCmd [KeyMap (Command (InputCmdT m) InsertMode InsertMode)
InputKeyCmd InsertMode InsertMode
simpleActions, KeyMap (Command (InputCmdT m) InsertMode InsertMode)
InputKeyCmd InsertMode InsertMode
controlActions] KeyMap (Command (InputCmdT m) InsertMode InsertMode)
-> Command (InputCmdT m) InsertMode (Maybe String)
-> KeyCommand (InputCmdT m) InsertMode (Maybe String)
forall (m :: * -> *) s t u.
Monad m =>
KeyCommand m s t -> Command m t u -> KeyCommand m s u
>+> 
                        KeyCommand (InputCmdT m) InsertMode (Maybe String)
-> Command (InputCmdT m) InsertMode (Maybe String)
forall (m :: * -> *) s t. KeyCommand m s t -> Command m s t
keyCommand KeyCommand (InputCmdT m) InsertMode (Maybe String)
InputKeyCmd InsertMode (Maybe String)
emacsCommands
                    , KeyCommand (InputCmdT m) InsertMode (Maybe String)
InputKeyCmd InsertMode (Maybe String)
enders]

enders :: InputKeyCmd InsertMode (Maybe String)
enders :: KeyCommand (InputCmdT m) InsertMode (Maybe String)
enders = [KeyCommand (InputCmdT m) InsertMode (Maybe String)]
-> KeyCommand (InputCmdT m) InsertMode (Maybe String)
forall a. [KeyMap a] -> KeyMap a
choiceCmd [Char -> Key
simpleChar Char
'\n' Key
-> Command (InputCmdT m) InsertMode (Maybe String)
-> KeyCommand (InputCmdT m) InsertMode (Maybe String)
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode (Maybe String)
forall (m :: * -> *) s.
(Monad m, Result s) =>
Command m s (Maybe String)
finish, Key
eotKey Key
-> Command (InputCmdT m) InsertMode (Maybe String)
-> KeyCommand (InputCmdT m) InsertMode (Maybe String)
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode (Maybe String)
deleteCharOrEOF]
    where
        eotKey :: Key
eotKey = Char -> Key
ctrlChar Char
'd'
        deleteCharOrEOF :: Command (InputCmdT m) InsertMode (Maybe String)
deleteCharOrEOF InsertMode
s
            | InsertMode
s InsertMode -> InsertMode -> Bool
forall a. Eq a => a -> a -> Bool
== InsertMode
emptyIM  = Maybe String -> CmdM (InputCmdT m) (Maybe String)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe String
forall a. Maybe a
Nothing
            | Bool
otherwise = (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
deleteNext InsertMode
s CmdM (InputCmdT m) InsertMode
-> Command (InputCmdT m) InsertMode (Maybe String)
-> CmdM (InputCmdT m) (Maybe String)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Command (InputCmdT m) InsertMode (Maybe String)
justDelete
        justDelete :: Command (InputCmdT m) InsertMode (Maybe String)
justDelete = [KeyCommand (InputCmdT m) InsertMode (Maybe String)]
-> Command (InputCmdT m) InsertMode (Maybe String)
forall (m :: * -> *) s t. [KeyCommand m s t] -> Command m s t
keyChoiceCmd [Key
eotKey Key
-> Command (InputCmdT m) InsertMode (Maybe String)
-> KeyCommand (InputCmdT m) InsertMode (Maybe String)
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
deleteNext Command (InputCmdT m) InsertMode InsertMode
-> Command (InputCmdT m) InsertMode (Maybe String)
-> Command (InputCmdT m) InsertMode (Maybe String)
forall (m :: * -> *) s t u.
Monad m =>
Command m s t -> Command m t u -> Command m s u
>|> Command (InputCmdT m) InsertMode (Maybe String)
justDelete
                            , KeyCommand (InputCmdT m) InsertMode (Maybe String)
InputKeyCmd InsertMode (Maybe String)
emacsCommands]


simpleActions, controlActions :: InputKeyCmd InsertMode InsertMode
simpleActions :: KeyCommand (InputCmdT m) InsertMode InsertMode
simpleActions = [KeyCommand (InputCmdT m) InsertMode InsertMode]
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. [KeyMap a] -> KeyMap a
choiceCmd 
            [ BaseKey -> Key
simpleKey BaseKey
LeftKey Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT 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 (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT 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 (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT 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 (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
deleteNext 
            , (Char -> InsertMode -> InsertMode)
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(Char -> s -> t) -> KeyCommand m s t
changeFromChar Char -> InsertMode -> InsertMode
insertChar
            , Key -> KeyCommand (InputCmdT m) InsertMode InsertMode
forall (m :: * -> *).
(MonadState Undo m, CommandMonad m) =>
Key -> KeyCommand m InsertMode InsertMode
completionCmd (Char -> Key
simpleChar Char
'\t')
            , BaseKey -> Key
simpleKey BaseKey
UpKey Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall s (m :: * -> *).
(Save s, MonadState HistLog m) =>
Command m s s
historyBack
            , BaseKey -> Key
simpleKey BaseKey
DownKey Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall s (m :: * -> *).
(Save s, MonadState HistLog m) =>
Command m s s
historyForward
            , KeyCommand (InputCmdT m) InsertMode InsertMode
forall (m :: * -> *).
MonadState HistLog m =>
KeyCommand m InsertMode InsertMode
searchHistory
            ] 
            
controlActions :: KeyCommand (InputCmdT m) InsertMode InsertMode
controlActions = [KeyCommand (InputCmdT m) InsertMode InsertMode]
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. [KeyMap a] -> KeyMap a
choiceCmd
            [ Char -> Key
ctrlChar Char
'a' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT 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 
            , Char -> Key
ctrlChar Char
'e' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT 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
            , Char -> Key
ctrlChar Char
'b' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT 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
            , Char -> Key
ctrlChar Char
'f' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
forall s. Move s => s -> s
goRight
            , Char -> Key
ctrlChar Char
'l' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall (m :: * -> *) s. Command m s s
clearScreenCmd
            , Char -> Key
metaChar Char
'f' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
wordRight
            , Char -> Key
metaChar Char
'b' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
wordLeft
            , Key -> Key
ctrlKey (BaseKey -> Key
simpleKey BaseKey
LeftKey) Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
wordLeft
            , Key -> Key
ctrlKey (BaseKey -> Key
simpleKey BaseKey
RightKey) Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
wordRight
            , Char -> Key
metaChar Char
'c' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change (([Grapheme] -> [Grapheme]) -> InsertMode -> InsertMode
modifyWord [Grapheme] -> [Grapheme]
capitalize)
            , Char -> Key
metaChar Char
'l' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change (([Grapheme] -> [Grapheme]) -> InsertMode -> InsertMode
modifyWord ((Char -> Char) -> [Grapheme] -> [Grapheme]
mapBaseChars Char -> Char
toLower))
            , Char -> Key
metaChar Char
'u' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change (([Grapheme] -> [Grapheme]) -> InsertMode -> InsertMode
modifyWord ((Char -> Char) -> [Grapheme] -> [Grapheme]
mapBaseChars Char -> Char
toUpper))
            , Char -> Key
ctrlChar Char
'_' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall (m :: * -> *) s.
(MonadState Undo m, Save s) =>
Command m s s
commandUndo
            , Char -> Key
ctrlChar Char
'x' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> KeyCommand (InputCmdT m) InsertMode InsertMode
-> Command (InputCmdT m) InsertMode InsertMode
forall (m :: * -> *) s.
Monad m =>
KeyCommand m s s -> Command m s s
try (Char -> Key
ctrlChar Char
'u' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall (m :: * -> *) s.
(MonadState Undo m, Save s) =>
Command m s s
commandUndo)
            , Char -> Key
ctrlChar Char
't' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
transposeChars
            , Char -> Key
ctrlChar Char
'p' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall s (m :: * -> *).
(Save s, MonadState HistLog m) =>
Command m s s
historyBack
            , Char -> Key
ctrlChar Char
'n' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall s (m :: * -> *).
(Save s, MonadState HistLog m) =>
Command m s s
historyForward
            , Char -> Key
metaChar Char
'<' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall s (m :: * -> *).
(Save s, MonadState HistLog m) =>
Command m s s
historyStart
            , Char -> Key
metaChar Char
'>' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
forall s (m :: * -> *).
(Save s, MonadState HistLog m) =>
Command m s s
historyEnd
            , BaseKey -> Key
simpleKey BaseKey
Home Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT 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 (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> (InsertMode -> InsertMode)
-> Command (InputCmdT m) InsertMode InsertMode
forall t (m :: * -> *) s.
(LineState t, Monad m) =>
(s -> t) -> Command m s t
change InsertMode -> InsertMode
forall s. Move s => s -> s
moveToEnd
            , [KeyCommand (InputCmdT m) InsertMode InsertMode]
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. [KeyMap a] -> KeyMap a
choiceCmd
                [ Char -> Key
ctrlChar Char
'w' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> KillHelper -> Command (InputCmdT 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
bigWordLeft)
                , Key -> Key
metaKey (BaseKey -> Key
simpleKey BaseKey
Backspace) Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> KillHelper -> Command (InputCmdT 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
wordLeft)
                , Char -> Key
metaChar Char
'd' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> KillHelper -> Command (InputCmdT 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
wordRight)
                , Char -> Key
ctrlChar Char
'k' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> KillHelper -> Command (InputCmdT 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
moveToEnd)
                , BaseKey -> Key
simpleKey BaseKey
KillLine Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> KillHelper -> Command (InputCmdT 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
'y' Key
-> Command (InputCmdT m) InsertMode InsertMode
-> KeyCommand (InputCmdT m) InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> Command (InputCmdT m) InsertMode InsertMode
InputCmd InsertMode InsertMode
rotatePaste
            ]

rotatePaste :: InputCmd InsertMode InsertMode
rotatePaste :: Command (InputCmdT m) InsertMode InsertMode
rotatePaste InsertMode
im = CmdM (InputCmdT m) KillRing
forall s (m :: * -> *). MonadState s m => m s
get CmdM (InputCmdT m) KillRing
-> (KillRing -> CmdM (InputCmdT m) InsertMode)
-> CmdM (InputCmdT m) InsertMode
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= KillRing -> CmdM (InputCmdT m) InsertMode
forall (m :: * -> *). Monad m => KillRing -> CmdM m InsertMode
loop
  where
    loop :: KillRing -> CmdM m InsertMode
loop KillRing
kr = case KillRing -> Maybe [Grapheme]
forall a. Stack a -> Maybe a
peek KillRing
kr of
                    Maybe [Grapheme]
Nothing -> InsertMode -> CmdM m InsertMode
forall (m :: * -> *) a. Monad m => a -> m a
return InsertMode
im
                    Just [Grapheme]
s -> InsertMode -> CmdM m InsertMode
forall (m :: * -> *) s. (Monad m, LineState s) => Command m s s
setState ([Grapheme] -> InsertMode -> InsertMode
insertGraphemes [Grapheme]
s InsertMode
im)
                            CmdM m InsertMode
-> (InsertMode -> CmdM m InsertMode) -> CmdM m InsertMode
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= KeyCommand m InsertMode InsertMode
-> InsertMode -> CmdM m InsertMode
forall (m :: * -> *) s.
Monad m =>
KeyCommand m s s -> Command m s s
try (Char -> Key
metaChar Char
'y' Key
-> (InsertMode -> CmdM m InsertMode)
-> KeyCommand m InsertMode InsertMode
forall a. Key -> a -> KeyMap a
+> \InsertMode
_ -> KillRing -> CmdM m InsertMode
loop (KillRing -> KillRing
forall a. Stack a -> Stack a
rotate KillRing
kr))


wordRight, wordLeft, bigWordLeft :: InsertMode -> InsertMode
wordRight :: InsertMode -> InsertMode
wordRight = (InsertMode -> Bool) -> InsertMode -> InsertMode
goRightUntil ((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
isAlphaNum))
wordLeft :: InsertMode -> InsertMode
wordLeft = (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil ((Char -> Bool) -> InsertMode -> Bool
atStart Char -> Bool
isAlphaNum)
bigWordLeft :: InsertMode -> InsertMode
bigWordLeft = (InsertMode -> Bool) -> InsertMode -> InsertMode
goLeftUntil ((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
isSpace))

modifyWord :: ([Grapheme] -> [Grapheme]) -> InsertMode -> InsertMode
modifyWord :: ([Grapheme] -> [Grapheme]) -> InsertMode -> InsertMode
modifyWord [Grapheme] -> [Grapheme]
f InsertMode
im = [Grapheme] -> [Grapheme] -> InsertMode
IMode ([Grapheme] -> [Grapheme]
forall a. [a] -> [a]
reverse ([Grapheme] -> [Grapheme]
f [Grapheme]
ys1) [Grapheme] -> [Grapheme] -> [Grapheme]
forall a. [a] -> [a] -> [a]
++ [Grapheme]
xs) [Grapheme]
ys2
    where
        IMode [Grapheme]
xs [Grapheme]
ys = (Char -> Bool) -> InsertMode -> InsertMode
skipRight (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isAlphaNum) InsertMode
im
        ([Grapheme]
ys1,[Grapheme]
ys2) = (Grapheme -> Bool) -> [Grapheme] -> ([Grapheme], [Grapheme])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Bool
isAlphaNum (Char -> Bool) -> (Grapheme -> Char) -> Grapheme -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grapheme -> Char
baseChar) [Grapheme]
ys

capitalize :: [Grapheme] -> [Grapheme]
capitalize :: [Grapheme] -> [Grapheme]
capitalize [] = []
capitalize (Grapheme
c:[Grapheme]
cs) = (Char -> Char) -> Grapheme -> Grapheme
modifyBaseChar Char -> Char
toUpper Grapheme
c Grapheme -> [Grapheme] -> [Grapheme]
forall a. a -> [a] -> [a]
: [Grapheme]
cs