{-# 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