    {-# LANGUAGE OverloadedStrings #-}
    {-# OPTIONS_HADDOCK show-extensions #-}

    -- |
    -- Module      :  Yi.Keymap.Vim.InsertMap
    -- License     :  GPL-2
    -- Maintainer  :  yi-devel@googlegroups.com
    -- Stability   :  experimental
    -- Portability :  portable

    module Yi.Keymap.Vim.InsertMap (defInsertMap) where

    import           Prelude                  hiding (head)

    import           Lens.Micro.Platform               (use)
    import           Control.Monad            (forM, liftM2, replicateM_, void, when)
    import           Data.Char                (isDigit)
    import           Data.List.NonEmpty       (NonEmpty (..), head, toList)
    import           Data.Monoid              ((<>))
    import qualified Data.Text                as T (pack, unpack)
    import qualified Yi.Buffer                as B (bdeleteB, deleteB, deleteRegionB, insertB, insertN)
    import           Yi.Buffer                as BA hiding (Insert)
    import           Yi.Editor                (EditorM, getEditorDyn, withCurrentBuffer)
    import           Yi.Event                 (Event)
    import           Yi.Keymap.Vim.Common
    import           Yi.Keymap.Vim.Digraph    (charFromDigraph, DigraphTbl)
    import           Yi.Keymap.Vim.EventUtils (eventToEventString, parseEvents)
    import           Yi.Keymap.Vim.Motion     (Move (Move), stringToMove)
    import           Yi.Keymap.Vim.StateUtils
    import           Yi.Keymap.Vim.Utils      (selectBinding, selectPureBinding)
    import           Yi.Monad                 (whenM)
    import qualified Yi.Rope                  as R (fromString, fromText)
    import           Yi.TextCompletion        (CompletionScope (..), completeWordB)

    defInsertMap :: DigraphTbl -> [VimBinding]
    defInsertMap :: DigraphTbl -> [VimBinding]
    defInsertMap DigraphTbl
    digraphs =
        [VimBinding
    rawPrintable] [VimBinding] -> [VimBinding] -> [VimBinding]
    forall a. Semigroup a => a -> a -> a
    <> DigraphTbl -> [VimBinding]
    specials DigraphTbl
    digraphs [VimBinding] -> [VimBinding] -> [VimBinding]
    forall a. Semigroup a => a -> a -> a
    <> [VimBinding
    printable]

    specials :: DigraphTbl -> [VimBinding]
    specials :: DigraphTbl -> [VimBinding]
    specials DigraphTbl
    digraphs =
        [DigraphTbl -> VimBinding
    exitBinding DigraphTbl
    digraphs, VimBinding
    pasteRegisterBinding, DigraphTbl -> VimBinding
    digraphBinding DigraphTbl
    digraphs
        , VimBinding
    oneshotNormalBinding, VimBinding
    completionBinding, VimBinding
    cursorBinding]

    exitBinding :: DigraphTbl -> VimBinding
    exitBinding :: DigraphTbl -> VimBinding
    exitBinding DigraphTbl
    digraphs = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
    -> VimBinding
    VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
    f
      where
        f :: EventString -> VimState -> MatchResult (EditorM RepeatToken)
        f :: EventString -> VimState -> MatchResult (EditorM RepeatToken)
    f EventString
    evs (VimState { vsMode :: VimState -> VimMode
    vsMode = (Insert Char
    _) })
          | EventString
    evs EventString -> [EventString] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [EventString
    "<Esc>", EventString
    "<C-c>"]
          = EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (EditorM RepeatToken -> MatchResult (EditorM RepeatToken))
    -> EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a b. (a -> b) -> a -> b
    $ do
            count <- EditorM Int
    getCountE
            (Insert starter) <- fmap vsMode getEditorDyn
            when (count > 1) $ do
                inputEvents <- fmap (parseEvents . vsOngoingInsertEvents) getEditorDyn
                replicateM_ (count - 1) $ do
                    when (starter `elem` ['O', 'o']) $ withCurrentBuffer $ insertB '\n'
                    replay digraphs inputEvents
            modifyStateE $ \VimState
    s -> VimState
    s { vsOngoingInsertEvents = mempty }
            withCurrentBuffer $ moveXorSol 1
            modifyStateE $ \VimState
    s -> VimState
    s { vsSecondaryCursors = mempty }
            resetCountE
            switchModeE Normal
            withCurrentBuffer $ whenM isCurrentLineAllWhiteSpaceB $ moveToSol >> deleteToEol
            return Finish
        f EventString
    _ VimState
    _ = MatchResult (EditorM RepeatToken)
    forall a. MatchResult a
    NoMatch

    rawPrintable :: VimBinding
    rawPrintable :: VimBinding
    rawPrintable = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
    -> VimBinding
    VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
    f
      where
        f :: EventString -> VimState -> MatchResult (EditorM RepeatToken)
        f :: EventString -> VimState -> MatchResult (EditorM RepeatToken)
    f EventString
    evs s :: VimState
    s@(VimState { vsMode :: VimState -> VimMode
    vsMode = (Insert Char
    _)})
              | VimState -> Bool
    vsPaste VimState
    s Bool -> Bool -> Bool
    && EventString
    evs EventString -> [EventString] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [EventString
    "<Esc>", EventString
    "<C-c>"]
                  = EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (EditorM RepeatToken -> MatchResult (EditorM RepeatToken))
    -> (BufferM RepeatToken -> EditorM RepeatToken)
    -> BufferM RepeatToken
    -> MatchResult (EditorM RepeatToken)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferM RepeatToken -> EditorM RepeatToken
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer (BufferM RepeatToken -> MatchResult (EditorM RepeatToken))
    -> BufferM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a b. (a -> b) -> a -> b
    $ do
                case EventString
    evs of
                  EventString
    "<lt>"       -> Char -> BufferM ()
    insertB Char
    '<'
                  EventString
    "<CR>"       -> BufferM ()
    newlineB
                  EventString
    "<Tab>"      -> Char -> BufferM ()
    insertB Char
    '\t'
                  EventString
    "<BS>"       -> BufferM ()
    bdeleteB
                  EventString
    "<C-h>"      -> BufferM ()
    bdeleteB
                  EventString
    "<Del>"      -> TextUnit -> Direction -> BufferM ()
    deleteB TextUnit
    Character Direction
    Forward
                  EventString
    "<Home>"     -> BufferM ()
    moveToSol
                  EventString
    "<End>"      -> BufferM ()
    moveToEol
                  EventString
    "<PageUp>"   -> Int -> BufferM ()
    scrollScreensB (-Int
    1)
                  EventString
    "<PageDown>" -> Int -> BufferM ()
    scrollScreensB   Int
    1
                  EventString
    c -> YiString -> BufferM ()
    insertN (Text -> YiString
    R.fromText (Text -> YiString) -> Text -> YiString
    forall a b. (a -> b) -> a -> b
    $ EventString -> Text
    _unEv EventString
    c)
                RepeatToken -> BufferM RepeatToken
    forall a. a -> BufferM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RepeatToken
    Continue
        f EventString
    _ VimState
    _ = MatchResult (EditorM RepeatToken)
    forall a. MatchResult a
    NoMatch

    replay :: DigraphTbl -> [Event] -> EditorM ()
    replay :: DigraphTbl -> [Event] -> EditorM ()
    replay DigraphTbl
    _ [] = () -> EditorM ()
    forall a. a -> EditorM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
    replay DigraphTbl
    digraphs (Event
    e1:[Event]
    es1) = do
        state <- EditorM VimState
    forall (m :: * -> *) a.
    (MonadEditor m, YiVariable a, Default a, Functor m) =>
    m a
    getEditorDyn
        let recurse = DigraphTbl -> [Event] -> EditorM ()
    replay DigraphTbl
    digraphs
            evs1 = Event -> EventString
    eventToEventString Event
    e1
            bindingMatch1 = EventString
    -> VimState -> [VimBinding] -> MatchResult (EditorM RepeatToken)
    selectPureBinding EventString
    evs1 VimState
    state (DigraphTbl -> [VimBinding]
    defInsertMap DigraphTbl
    digraphs)
        case bindingMatch1 of
            WholeMatch EditorM RepeatToken
    action -> EditorM RepeatToken -> EditorM ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void EditorM RepeatToken
    action EditorM () -> EditorM () -> EditorM ()
    forall a b. EditorM a -> EditorM b -> EditorM b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> [Event] -> EditorM ()
    recurse [Event]
    es1
            MatchResult (EditorM RepeatToken)
    PartialMatch -> case [Event]
    es1 of
                [] -> () -> EditorM ()
    forall a. a -> EditorM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                (Event
    e2:[Event]
    es2) -> do
                    let evs2 :: EventString
    evs2 = EventString
    evs1 EventString -> EventString -> EventString
    forall a. Semigroup a => a -> a -> a
    <> Event -> EventString
    eventToEventString Event
    e2
                        bindingMatch2 :: MatchResult (EditorM RepeatToken)
    bindingMatch2 = EventString
    -> VimState -> [VimBinding] -> MatchResult (EditorM RepeatToken)
    selectPureBinding EventString
    evs2 VimState
    state (DigraphTbl -> [VimBinding]
    defInsertMap DigraphTbl
    digraphs)
                    case MatchResult (EditorM RepeatToken)
    bindingMatch2 of
                        WholeMatch EditorM RepeatToken
    action -> EditorM RepeatToken -> EditorM ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void EditorM RepeatToken
    action EditorM () -> EditorM () -> EditorM ()
    forall a b. EditorM a -> EditorM b -> EditorM b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> [Event] -> EditorM ()
    recurse [Event]
    es2
                        MatchResult (EditorM RepeatToken)
    _ -> [Event] -> EditorM ()
    recurse [Event]
    es2
            MatchResult (EditorM RepeatToken)
    _ -> [Event] -> EditorM ()
    recurse [Event]
    es1

    oneshotNormalBinding :: VimBinding
    oneshotNormalBinding :: VimBinding
    oneshotNormalBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
    -> VimBinding
    VimBindingE (String -> VimState -> MatchResult (EditorM RepeatToken)
    forall {m :: * -> *}.
    MonadEditor m =>
    String -> VimState -> MatchResult (m RepeatToken)
    f (String -> VimState -> MatchResult (EditorM RepeatToken))
    -> (EventString -> String)
    -> EventString
    -> VimState
    -> MatchResult (EditorM RepeatToken)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> String
    T.unpack (Text -> String) -> (EventString -> Text) -> EventString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . EventString -> Text
    _unEv)
      where
        f :: String -> VimState -> MatchResult (m RepeatToken)
    f String
    "<C-o>" (VimState { vsMode :: VimState -> VimMode
    vsMode = Insert Char
    _ }) = MatchResult (m RepeatToken)
    forall a. MatchResult a
    PartialMatch
        f (Char
    '<':Char
    'C':Char
    '-':Char
    'o':Char
    '>':String
    evs) (VimState { vsMode :: VimState -> VimMode
    vsMode = Insert Char
    _ }) =
            String -> m RepeatToken
    forall {m :: * -> *}. MonadEditor m => String -> m RepeatToken
    action String
    evs m RepeatToken -> MatchResult Move -> MatchResult (m RepeatToken)
    forall a b. a -> MatchResult b -> MatchResult a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ EventString -> MatchResult Move
    stringToMove (Text -> EventString
    Ev (Text -> EventString) -> (String -> Text) -> String -> EventString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    T.pack (String -> EventString) -> String -> EventString
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile Char -> Bool
    isDigit String
    evs)
        f String
    _ VimState
    _ = MatchResult (m RepeatToken)
    forall a. MatchResult a
    NoMatch
        action :: String -> m RepeatToken
    action String
    evs = do
            let (String
    countString, String
    motionCmd) = (Char -> Bool) -> String -> (String, String)
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span Char -> Bool
    isDigit String
    evs
                WholeMatch (Move RegionStyle
    _style Bool
    _isJump Maybe Int -> BufferM ()
    move) = EventString -> MatchResult Move
    stringToMove (EventString -> MatchResult Move)
    -> (String -> EventString) -> String -> MatchResult Move
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> EventString
    Ev (Text -> EventString) -> (String -> Text) -> String -> EventString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    T.pack (String -> MatchResult Move) -> String -> MatchResult Move
    forall a b. (a -> b) -> a -> b
    $ String
    motionCmd
            BufferM () -> m ()
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer (BufferM () -> m ()) -> BufferM () -> m ()
    forall a b. (a -> b) -> a -> b
    $ Maybe Int -> BufferM ()
    move (if String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    countString then Maybe Int
    forall a. Maybe a
    Nothing else Int -> Maybe Int
    forall a. a -> Maybe a
    Just (String -> Int
    forall a. Read a => String -> a
    read String
    countString))
            RepeatToken -> m RepeatToken
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RepeatToken
    Continue

    pasteRegisterBinding :: VimBinding
    pasteRegisterBinding :: VimBinding
    pasteRegisterBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
    -> VimBinding
    VimBindingE (String -> VimState -> MatchResult (EditorM RepeatToken)
    f (String -> VimState -> MatchResult (EditorM RepeatToken))
    -> (EventString -> String)
    -> EventString
    -> VimState
    -> MatchResult (EditorM RepeatToken)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> String
    T.unpack (Text -> String) -> (EventString -> Text) -> EventString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . EventString -> Text
    _unEv)
        where f :: String -> VimState -> MatchResult (EditorM RepeatToken)
    f String
    "<C-r>" (VimState { vsMode :: VimState -> VimMode
    vsMode = Insert Char
    _ }) = MatchResult (EditorM RepeatToken)
    forall a. MatchResult a
    PartialMatch
              f (Char
    '<':Char
    'C':Char
    '-':Char
    'r':Char
    '>':Char
    regName:[]) (VimState { vsMode :: VimState -> VimMode
    vsMode = Insert Char
    _ })
                  = EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (EditorM RepeatToken -> MatchResult (EditorM RepeatToken))
    -> EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a b. (a -> b) -> a -> b
    $ do
                      mr <- Char -> EditorM (Maybe Register)
    getRegisterE Char
    regName
                      case mr of
                        Maybe Register
    Nothing -> () -> EditorM ()
    forall a. a -> EditorM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                        Just (Register RegionStyle
    _style YiString
    rope) -> BufferM () -> EditorM ()
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
    forall a b. (a -> b) -> a -> b
    $ YiString -> RegionStyle -> BufferM ()
    insertRopeWithStyleB YiString
    rope RegionStyle
    Inclusive
                      return Continue
              f String
    _ VimState
    _ = MatchResult (EditorM RepeatToken)
    forall a. MatchResult a
    NoMatch

    digraphBinding :: DigraphTbl -> VimBinding
    digraphBinding :: DigraphTbl -> VimBinding
    digraphBinding DigraphTbl
    digraphs = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
    -> VimBinding
    VimBindingE (String -> VimState -> MatchResult (EditorM RepeatToken)
    forall {m :: * -> *}.
    MonadEditor m =>
    String -> VimState -> MatchResult (m RepeatToken)
    f (String -> VimState -> MatchResult (EditorM RepeatToken))
    -> (EventString -> String)
    -> EventString
    -> VimState
    -> MatchResult (EditorM RepeatToken)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> String
    T.unpack (Text -> String) -> (EventString -> Text) -> EventString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . EventString -> Text
    _unEv)
        where f :: String -> VimState -> MatchResult (m RepeatToken)
    f (Char
    '<':Char
    'C':Char
    '-':Char
    'k':Char
    '>':Char
    c1:Char
    c2:[]) (VimState { vsMode :: VimState -> VimMode
    vsMode = Insert Char
    _ })
                = m RepeatToken -> MatchResult (m RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (m RepeatToken -> MatchResult (m RepeatToken))
    -> m RepeatToken -> MatchResult (m RepeatToken)
    forall a b. (a -> b) -> a -> b
    $ do
                      m () -> (Char -> m ()) -> Maybe Char -> m ()
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (() -> m ()
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()) (BufferM () -> m ()
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer (BufferM () -> m ()) -> (Char -> BufferM ()) -> Char -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> BufferM ()
    insertB) (Maybe Char -> m ()) -> Maybe Char -> m ()
    forall a b. (a -> b) -> a -> b
    $ DigraphTbl -> Char -> Char -> Maybe Char
    charFromDigraph DigraphTbl
    digraphs Char
    c1 Char
    c2
                      RepeatToken -> m RepeatToken
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RepeatToken
    Continue
              f (Char
    '<':Char
    'C':Char
    '-':Char
    'k':Char
    '>':Char
    _c1:[]) (VimState { vsMode :: VimState -> VimMode
    vsMode = Insert Char
    _ }) = MatchResult (m RepeatToken)
    forall a. MatchResult a
    PartialMatch
              f String
    "<C-k>" (VimState { vsMode :: VimState -> VimMode
    vsMode = Insert Char
    _ }) = MatchResult (m RepeatToken)
    forall a. MatchResult a
    PartialMatch
              f String
    _ VimState
    _ = MatchResult (m RepeatToken)
    forall a. MatchResult a
    NoMatch

    printable :: VimBinding
    printable :: VimBinding
    printable = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
    -> VimBinding
    VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
    f
        where f :: EventString -> VimState -> MatchResult (EditorM RepeatToken)
    f EventString
    evs state :: VimState
    state@(VimState { vsMode :: VimState -> VimMode
    vsMode = Insert Char
    _ } ) =
                  case EventString
    -> VimState -> [VimBinding] -> MatchResult (YiM RepeatToken)
    selectBinding EventString
    evs VimState
    state (DigraphTbl -> [VimBinding]
    specials DigraphTbl
    forall a. HasCallStack => a
    undefined) of
                      MatchResult (YiM RepeatToken)
    NoMatch -> EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (EventString -> EditorM RepeatToken
    printableAction EventString
    evs)
                      MatchResult (YiM RepeatToken)
    _ -> MatchResult (EditorM RepeatToken)
    forall a. MatchResult a
    NoMatch
              f EventString
    _ VimState
    _ = MatchResult (EditorM RepeatToken)
    forall a. MatchResult a
    NoMatch

    printableAction :: EventString -> EditorM RepeatToken
    printableAction :: EventString -> EditorM RepeatToken
    printableAction EventString
    evs = do
        EventString -> EditorM ()
    saveInsertEventStringE EventString
    evs
        currentCursor <- BufferM Point -> EditorM Point
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer BufferM Point
    pointB
        IndentSettings et _ sw <- withCurrentBuffer indentSettingsB
        secondaryCursors <- fmap vsSecondaryCursors getEditorDyn
        let allCursors = Point
    currentCursor Point -> [Point] -> NonEmpty Point
    forall a. a -> [a] -> NonEmpty a
    :| [Point]
    secondaryCursors
        marks <- withCurrentBuffer $ forM' allCursors $ \Point
    cursor -> do
            Point -> BufferM ()
    moveTo Point
    cursor
            Maybe String -> BufferM Mark
    getMarkB Maybe String
    forall a. Maybe a
    Nothing

        -- Using autoindenting with multiple cursors
        -- is just too broken.
        let (insertB', insertN', deleteB', bdeleteB', deleteRegionB') =
                if null secondaryCursors
                then (BA.insertB, BA.insertN, BA.deleteB,
                    BA.bdeleteB, BA.deleteRegionB)
                else (B.insertB, B.insertN, B.deleteB,
                    B.bdeleteB, B.deleteRegionB)

        let bufAction = case Text -> String
    T.unpack (Text -> String) -> (EventString -> Text) -> EventString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . EventString -> Text
    _unEv (EventString -> String) -> EventString -> String
    forall a b. (a -> b) -> a -> b
    $ EventString
    evs of
              (Char
    c:[]) -> Char -> BufferM ()
    insertB' Char
    c
              String
    "<CR>" -> do
                  isOldLineEmpty <- BufferM Bool
    isCurrentLineEmptyB
                  shouldTrimOldLine <- isCurrentLineAllWhiteSpaceB
                  if isOldLineEmpty
                  then newlineB
                  else if shouldTrimOldLine
                  then savingPointB $ do
                      moveToSol
                      newlineB
                  else do
                      newlineB
                      indentAsTheMostIndentedNeighborLineB
                  firstNonSpaceB
              String
    "<Tab>" -> do
                  if Bool
    et
                  then YiString -> BufferM ()
    insertN' (YiString -> BufferM ())
    -> (String -> YiString) -> String -> BufferM ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> YiString
    R.fromString (String -> BufferM ()) -> String -> BufferM ()
    forall a b. (a -> b) -> a -> b
    $ Int -> Char -> String
    forall a. Int -> a -> [a]
    replicate Int
    sw Char
    ' '
                  else Char -> BufferM ()
    insertB' Char
    '\t'
              String
    "<C-t>"      -> (Int -> Int) -> BufferM ()
    modifyIndentB (Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    sw)
              String
    "<C-d>"      -> (Int -> Int) -> BufferM ()
    modifyIndentB (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max Int
    0 (Int -> Int) -> (Int -> Int) -> Int -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Int -> Int
    forall a. Num a => a -> a -> a
    subtract Int
    sw)
              String
    "<C-e>"      -> BufferM ()
    insertCharWithBelowB
              String
    "<C-y>"      -> BufferM ()
    insertCharWithAboveB
              String
    "<BS>"       -> BufferM ()
    bdeleteB'
              String
    "<C-h>"      -> BufferM ()
    bdeleteB'
              String
    "<Home>"     -> BufferM ()
    moveToSol
              String
    "<End>"      -> BufferM ()
    moveToEol BufferM () -> BufferM () -> BufferM ()
    forall a b. BufferM a -> BufferM b -> BufferM b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BufferM ()
    leftOnEol
              String
    "<PageUp>"   -> Int -> BufferM ()
    scrollScreensB (-Int
    1)
              String
    "<PageDown>" -> Int -> BufferM ()
    scrollScreensB   Int
    1
              String
    "<Del>"      -> TextUnit -> Direction -> BufferM ()
    deleteB' TextUnit
    Character Direction
    Forward
              String
    "<C-w>"      -> Region -> BufferM ()
    deleteRegionB' (Region -> BufferM ()) -> BufferM Region -> BufferM ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< TextUnit -> Direction -> BufferM Region
    regionOfPartNonEmptyB TextUnit
    unitViWordOnLine Direction
    Backward
              String
    "<C-u>"      -> BufferM ()
    bdeleteLineB
              String
    "<lt>"       -> Char -> BufferM ()
    insertB' Char
    '<'
              String
    evs'         -> String -> BufferM ()
    forall a. HasCallStack => String -> a
    error (String -> BufferM ()) -> String -> BufferM ()
    forall a b. (a -> b) -> a -> b
    $ String
    "Unhandled event " String -> String -> String
    forall a. Semigroup a => a -> a -> a
    <> String -> String
    forall a. Show a => a -> String
    show String
    evs' String -> String -> String
    forall a. Semigroup a => a -> a -> a
    <> String
    " in insert mode"

        updatedCursors <- withCurrentBuffer $ do
            updatedCursors <- forM' marks $ \Mark
    mark -> do
                Point -> BufferM ()
    moveTo (Point -> BufferM ()) -> BufferM Point -> BufferM ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Getting Point FBuffer Point -> BufferM Point
    forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
    use (Mark -> Getting Point FBuffer Point
    forall (f :: * -> *).
    Functor f =>
    Mark -> (Point -> f Point) -> FBuffer -> f FBuffer
    markPointA Mark
    mark)
                BufferM ()
    bufAction
                BufferM Point
    pointB
            mapM_ deleteMarkB $ toList marks
            moveTo $ head updatedCursors
            return $ toList updatedCursors
        modifyStateE $ \VimState
    s -> VimState
    s { vsSecondaryCursors = drop 1 updatedCursors }
        return Continue
      where
        forM' :: Monad m => NonEmpty a -> (a -> m b) -> m (NonEmpty b)
        forM' :: forall (m :: * -> *) a b.
    Monad m =>
    NonEmpty a -> (a -> m b) -> m (NonEmpty b)
    forM' (a
    x :| [a]
    xs) a -> m b
    f = (b -> [b] -> NonEmpty b) -> m b -> m [b] -> m (NonEmpty b)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 b -> [b] -> NonEmpty b
    forall a. a -> [a] -> NonEmpty a
    (:|) (a -> m b
    f a
    x) ([a] -> (a -> m b) -> m [b]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [a]
    xs a -> m b
    f)

    completionBinding :: VimBinding
    completionBinding :: VimBinding
    completionBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
    -> VimBinding
    VimBindingE (String -> VimState -> MatchResult (EditorM RepeatToken)
    forall {a}.
    (Eq a, IsString a) =>
    a -> VimState -> MatchResult (EditorM RepeatToken)
    f (String -> VimState -> MatchResult (EditorM RepeatToken))
    -> (EventString -> String)
    -> EventString
    -> VimState
    -> MatchResult (EditorM RepeatToken)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> String
    T.unpack (Text -> String) -> (EventString -> Text) -> EventString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . EventString -> Text
    _unEv)
        where f :: a -> VimState -> MatchResult (EditorM RepeatToken)
    f a
    evs (VimState { vsMode :: VimState -> VimMode
    vsMode = (Insert Char
    _) })
                | a
    evs a -> [a] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [a
    "<C-n>", a
    "<C-p>"]
                = EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (EditorM RepeatToken -> MatchResult (EditorM RepeatToken))
    -> EditorM RepeatToken -> MatchResult (EditorM RepeatToken)
    forall a b. (a -> b) -> a -> b
    $ do
                      let _direction :: Direction
    _direction = if a
    evs a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    "<C-n>" then Direction
    Forward else Direction
    Backward
                      CompletionScope -> EditorM ()
    completeWordB CompletionScope
    FromAllBuffers
                      RepeatToken -> EditorM RepeatToken
    forall a. a -> EditorM a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RepeatToken
    Continue
              f a
    _ VimState
    _ = MatchResult (EditorM RepeatToken)
    forall a. MatchResult a
    NoMatch

    cursorBinding :: VimBinding
    cursorBinding :: VimBinding
    cursorBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
    -> VimBinding
    VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
    forall {m :: * -> *}.
    MonadEditor m =>
    EventString -> VimState -> MatchResult (m RepeatToken)
    f
        where
        f :: EventString -> VimState -> MatchResult (m RepeatToken)
    f EventString
    "<C-b>" (VimState { vsMode :: VimState -> VimMode
    vsMode = (Insert Char
    _) })
            = m RepeatToken -> MatchResult (m RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (m RepeatToken -> MatchResult (m RepeatToken))
    -> m RepeatToken -> MatchResult (m RepeatToken)
    forall a b. (a -> b) -> a -> b
    $ do
                BufferM () -> m ()
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer (BufferM () -> m ()) -> BufferM () -> m ()
    forall a b. (a -> b) -> a -> b
    $ Int -> BufferM ()
    moveXorSol Int
    1
                RepeatToken -> m RepeatToken
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RepeatToken
    Continue
        f EventString
    "<C-f>" (VimState { vsMode :: VimState -> VimMode
    vsMode = (Insert Char
    _) })
            = m RepeatToken -> MatchResult (m RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (m RepeatToken -> MatchResult (m RepeatToken))
    -> m RepeatToken -> MatchResult (m RepeatToken)
    forall a b. (a -> b) -> a -> b
    $ do
                BufferM () -> m ()
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer (BufferM () -> m ()) -> BufferM () -> m ()
    forall a b. (a -> b) -> a -> b
    $ Int -> BufferM ()
    moveXorEol Int
    1
                RepeatToken -> m RepeatToken
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RepeatToken
    Continue
        f EventString
    evs (VimState { vsMode :: VimState -> VimMode
    vsMode = (Insert Char
    _) })
            | EventString
    evs EventString -> [EventString] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [EventString
    "<Up>", EventString
    "<Left>", EventString
    "<Down>", EventString
    "<Right>"]
            = m RepeatToken -> MatchResult (m RepeatToken)
    forall a. a -> MatchResult a
    WholeMatch (m RepeatToken -> MatchResult (m RepeatToken))
    -> m RepeatToken -> MatchResult (m RepeatToken)
    forall a b. (a -> b) -> a -> b
    $ do
                  let WholeMatch (Move RegionStyle
    _style Bool
    _isJump Maybe Int -> BufferM ()
    move) = EventString -> MatchResult Move
    stringToMove EventString
    evs
                  BufferM () -> m ()
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer (BufferM () -> m ()) -> BufferM () -> m ()
    forall a b. (a -> b) -> a -> b
    $ Maybe Int -> BufferM ()
    move Maybe Int
    forall a. Maybe a
    Nothing
                  RepeatToken -> m RepeatToken
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return RepeatToken
    Continue
        f EventString
    _ VimState
    _ = MatchResult (m RepeatToken)
    forall a. MatchResult a
    NoMatch