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

-- |
-- Module      :  Yi.Keymap.Vim.VisualMap
-- License     :  GPL-2
-- Maintainer  :  yi-devel@googlegroups.com
-- Stability   :  experimental
-- Portability :  portable
--
-- I'm a module waiting for some kind soul to give me a commentary!

module Yi.Keymap.Vim.VisualMap ( defVisualMap ) where

import           Lens.Micro.Platform        ((.=))
import           Control.Monad              (forM_, void, when)
import           Data.Char                  (ord)
import           Data.List                  (group)
import           Data.Maybe                 (fromJust, fromMaybe)
import qualified Data.Text                  as T (unpack)
import           Yi.Buffer                  hiding (Insert)
import           Yi.Editor
import           Yi.Keymap.Vim.Common
import           Yi.Keymap.Vim.Operator     (VimOperator (..), opDelete, stringToOperator)
import           Yi.Keymap.Vim.StateUtils
import           Yi.Keymap.Vim.StyledRegion (StyledRegion (StyledRegion), transformCharactersInRegionB)
import           Yi.Keymap.Vim.Tag          (gotoTag)
import           Yi.Keymap.Vim.TextObject
import           Yi.Keymap.Vim.Utils        (matchFromBool, mkChooseRegisterBinding, mkMotionBinding, addNewLineIfNecessary, pasteInclusiveB)
import           Yi.MiniBuffer              (spawnMinibufferE)
import           Yi.Monad                   (whenM)
import qualified Yi.Rope                    as R (toText, countNewLines)
import           Yi.Tag                     (Tag (Tag))
import           Yi.Utils                   (SemiNum ((-~)))

defVisualMap :: [VimOperator] -> [VimBinding]
defVisualMap :: [VimOperator] -> [VimBinding]
defVisualMap [VimOperator]
operators =
    [VimBinding
escBinding, VimBinding
motionBinding, VimBinding
textObjectBinding, VimBinding
changeVisualStyleBinding, VimBinding
setMarkBinding]
    [VimBinding] -> [VimBinding] -> [VimBinding]
forall a. [a] -> [a] -> [a]
++ [VimBinding
chooseRegisterBinding, VimBinding
pasteBinding]
    [VimBinding] -> [VimBinding] -> [VimBinding]
forall a. [a] -> [a] -> [a]
++ [VimOperator] -> [VimBinding]
operatorBindings [VimOperator]
operators [VimBinding] -> [VimBinding] -> [VimBinding]
forall a. [a] -> [a] -> [a]
++ [VimBinding]
digitBindings [VimBinding] -> [VimBinding] -> [VimBinding]
forall a. [a] -> [a] -> [a]
++ [VimBinding
replaceBinding, VimBinding
switchEdgeBinding]
    [VimBinding] -> [VimBinding] -> [VimBinding]
forall a. [a] -> [a] -> [a]
++ [VimBinding
insertBinding, VimBinding
exBinding, VimBinding
shiftDBinding]
    [VimBinding] -> [VimBinding] -> [VimBinding]
forall a. [a] -> [a] -> [a]
++ [VimBinding
tagJumpBinding]

escAction :: EditorM RepeatToken
escAction :: EditorM RepeatToken
escAction = do
    EditorM ()
resetCountE
    EditorM ()
clrStatus
    BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ do
        Bool -> BufferM ()
setVisibleSelection Bool
False
        RegionStyle -> BufferM ()
putRegionStyle RegionStyle
Inclusive
    VimMode -> EditorM ()
switchModeE VimMode
Normal
    RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Drop

escBinding :: VimBinding
escBinding :: VimBinding
escBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
forall a.
(Eq a, IsString a) =>
a -> VimState -> MatchResult (EditorM RepeatToken)
f
    where f :: a -> VimState -> MatchResult (EditorM RepeatToken)
f a
evs (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) = EditorM RepeatToken
escAction EditorM RepeatToken
-> MatchResult () -> MatchResult (EditorM RepeatToken)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
              Bool -> MatchResult ()
matchFromBool (a
evs a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a
"<Esc>", a
"<C-c>"])
          f a
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch

exBinding :: VimBinding
exBinding :: VimBinding
exBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
forall a.
(Eq a, IsString a) =>
a -> VimState -> MatchResult (EditorM RepeatToken)
f
    where f :: a -> VimState -> MatchResult (EditorM RepeatToken)
f a
":" (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) = 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
              EditorM BufferRef -> EditorM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (EditorM BufferRef -> EditorM ())
-> EditorM BufferRef -> EditorM ()
forall a b. (a -> b) -> a -> b
$ Text -> KeymapEndo -> EditorM BufferRef
spawnMinibufferE Text
":" KeymapEndo
forall a. a -> a
id
              BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ YiString -> BufferM ()
writeN YiString
"'<,'>"
              VimMode -> EditorM ()
switchModeE VimMode
Ex
              RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Finish
          f a
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch

digitBindings :: [VimBinding]
digitBindings :: [VimBinding]
digitBindings = VimBinding
zeroBinding VimBinding -> [VimBinding] -> [VimBinding]
forall a. a -> [a] -> [a]
: (Char -> VimBinding) -> [Char] -> [VimBinding]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> VimBinding
mkDigitBinding [Char
'1' .. Char
'9']

zeroBinding :: VimBinding
zeroBinding :: VimBinding
zeroBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
forall a.
(IsString a, Eq a) =>
a -> VimState -> MatchResult (EditorM RepeatToken)
f
    where f :: a -> VimState -> MatchResult (EditorM RepeatToken)
f a
"0" (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) = 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
              VimState
currentState <- EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
              case VimState -> Maybe Int
vsCount VimState
currentState of
                  Just Int
c -> do
                      Int -> EditorM ()
setCountE (Int
10 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
c)
                      RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
                  Maybe Int
Nothing -> do
                      BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM ()
moveToSol
                      EditorM ()
resetCountE
                      BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ (Bool -> Identity Bool) -> FBuffer -> Identity FBuffer
forall c. HasAttributes c => Lens' c Bool
stickyEolA ((Bool -> Identity Bool) -> FBuffer -> Identity FBuffer)
-> Bool -> BufferM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Bool
False
                      RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
          f a
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch

setMarkBinding :: VimBinding
setMarkBinding :: VimBinding
setMarkBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
forall (m :: * -> *).
MonadEditor m =>
[Char] -> VimState -> MatchResult (m RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where f :: [Char] -> VimState -> MatchResult (m RepeatToken)
f [Char]
"m" (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) = MatchResult (m RepeatToken)
forall a. MatchResult a
PartialMatch
          f (Char
'm':Char
c:[]) (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) = 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
$ [Char] -> BufferM ()
setNamedMarkHereB [Char
c]
              RepeatToken -> m RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
          f [Char]
_ VimState
_ = MatchResult (m RepeatToken)
forall a. MatchResult a
NoMatch

changeVisualStyleBinding :: VimBinding
changeVisualStyleBinding :: VimBinding
changeVisualStyleBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
forall a.
(Eq a, IsString a) =>
a -> VimState -> MatchResult (EditorM RepeatToken)
f
    where f :: a -> VimState -> MatchResult (EditorM RepeatToken)
f a
evs (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) })
            | a
evs a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a
"v", a
"V", a
"<C-v>"]
            = 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
                  VimMode
currentMode <- (VimState -> VimMode) -> EditorM VimState -> EditorM VimMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VimState -> VimMode
vsMode EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
                  let newStyle :: RegionStyle
newStyle = case a
evs of
                         a
"v" -> RegionStyle
Inclusive
                         a
"V" -> RegionStyle
LineWise
                         a
"<C-v>" -> RegionStyle
Block
                         a
_ -> [Char] -> RegionStyle
forall a. HasCallStack => [Char] -> a
error [Char]
"Just silencing false positive warning."
                      newMode :: VimMode
newMode = RegionStyle -> VimMode
Visual RegionStyle
newStyle
                  if VimMode
newMode VimMode -> VimMode -> Bool
forall a. Eq a => a -> a -> Bool
== VimMode
currentMode
                  then EditorM RepeatToken
escAction
                  else do
                      (VimState -> VimState) -> EditorM ()
modifyStateE ((VimState -> VimState) -> EditorM ())
-> (VimState -> VimState) -> EditorM ()
forall a b. (a -> b) -> a -> b
$ \VimState
s -> VimState
s { vsMode :: VimMode
vsMode = VimMode
newMode }
                      BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ do
                          RegionStyle -> BufferM ()
putRegionStyle RegionStyle
newStyle
                          (Bool -> Identity Bool) -> FBuffer -> Identity FBuffer
Lens' FBuffer Bool
rectangleSelectionA ((Bool -> Identity Bool) -> FBuffer -> Identity FBuffer)
-> Bool -> BufferM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= (RegionStyle
Block RegionStyle -> RegionStyle -> Bool
forall a. Eq a => a -> a -> Bool
== RegionStyle
newStyle)
                          Bool -> BufferM ()
setVisibleSelection Bool
True
                      RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Finish
          f a
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch

mkDigitBinding :: Char -> VimBinding
mkDigitBinding :: Char -> VimBinding
mkDigitBinding Char
c = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where f :: [Char] -> VimState -> MatchResult (EditorM RepeatToken)
f [Char
c'] (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
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
                  (VimState -> VimState) -> EditorM ()
modifyStateE VimState -> VimState
mutate
                  RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
          f [Char]
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
          mutate :: VimState -> VimState
mutate vs :: VimState
vs@(VimState {vsCount :: VimState -> Maybe Int
vsCount = Maybe Int
Nothing}) = VimState
vs { vsCount :: Maybe Int
vsCount = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
d }
          mutate vs :: VimState
vs@(VimState {vsCount :: VimState -> Maybe Int
vsCount = Just Int
count}) = VimState
vs { vsCount :: Maybe Int
vsCount = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
d }
          d :: Int
d = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'0'

motionBinding :: VimBinding
motionBinding :: VimBinding
motionBinding = RepeatToken -> (VimMode -> Bool) -> VimBinding
mkMotionBinding RepeatToken
Continue ((VimMode -> Bool) -> VimBinding)
-> (VimMode -> Bool) -> VimBinding
forall a b. (a -> b) -> a -> b
$
    \VimMode
m -> case VimMode
m of
        Visual RegionStyle
_ -> Bool
True
        VimMode
_ -> Bool
False

textObjectBinding :: VimBinding
textObjectBinding :: VimBinding
textObjectBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
forall (m :: * -> *).
MonadEditor m =>
[Char] -> VimState -> MatchResult (m RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where
    f :: [Char] -> VimState -> MatchResult (m RepeatToken)
f ([Char] -> MatchResult TextObject
stringToTextObject -> MatchResult TextObject
PartialMatch) (VimState {vsMode :: VimState -> VimMode
vsMode = Visual RegionStyle
_}) = MatchResult (m RepeatToken)
forall a. MatchResult a
PartialMatch
    f ([Char] -> MatchResult TextObject
stringToTextObject -> WholeMatch TextObject
to) (VimState {vsMode :: VimState -> VimMode
vsMode = Visual RegionStyle
_, vsCount :: VimState -> Maybe Int
vsCount = Maybe Int
mbCount}) =
        let count :: Int
count = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 Maybe Int
mbCount
        in
        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
$ do
                StyledRegion RegionStyle
_ Region
reg <- CountedTextObject -> BufferM StyledRegion
regionOfTextObjectB (Int -> TextObject -> CountedTextObject
CountedTextObject Int
count TextObject
to)
                Point -> BufferM ()
setSelectionMarkPointB (Region -> Point
regionStart Region
reg)
                Point -> BufferM ()
moveTo (Region -> Point
regionEnd Region
reg Point -> Size -> Point
forall absolute relative.
SemiNum absolute relative =>
absolute -> relative -> absolute
-~ Size
1)
            RepeatToken -> m RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
    f [Char]
_ VimState
_ = MatchResult (m RepeatToken)
forall a. MatchResult a
NoMatch

regionOfSelectionB :: BufferM Region
regionOfSelectionB :: BufferM Region
regionOfSelectionB = BufferM Region -> BufferM Region
forall a. BufferM a -> BufferM a
savingPointB (BufferM Region -> BufferM Region)
-> BufferM Region -> BufferM Region
forall a b. (a -> b) -> a -> b
$ do
    Point
start <- BufferM Point
getSelectionMarkPointB
    Point
stop <- BufferM Point
pointB
    Region -> BufferM Region
forall (m :: * -> *) a. Monad m => a -> m a
return (Region -> BufferM Region) -> Region -> BufferM Region
forall a b. (a -> b) -> a -> b
$! Point -> Point -> Region
mkRegion Point
start Point
stop

operatorBindings :: [VimOperator] -> [VimBinding]
operatorBindings :: [VimOperator] -> [VimBinding]
operatorBindings [VimOperator]
operators = (VimOperator -> VimBinding) -> [VimOperator] -> [VimBinding]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VimOperator -> VimBinding
mkOperatorBinding ([VimOperator] -> [VimBinding]) -> [VimOperator] -> [VimBinding]
forall a b. (a -> b) -> a -> b
$ [VimOperator]
operators [VimOperator] -> [VimOperator] -> [VimOperator]
forall a. [a] -> [a] -> [a]
++ [VimOperator]
visualOperators
    where visualOperators :: [VimOperator]
visualOperators = ((OperatorName, OperatorName) -> VimOperator)
-> [(OperatorName, OperatorName)] -> [VimOperator]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (OperatorName, OperatorName) -> VimOperator
synonymOp
                                  [ (OperatorName
"x", OperatorName
"d")
                                  , (OperatorName
"s", OperatorName
"c")
                                  , (OperatorName
"S", OperatorName
"c")
                                  , (OperatorName
"C", OperatorName
"c")
                                  , (OperatorName
"~", OperatorName
"g~")
                                  , (OperatorName
"Y", OperatorName
"y")
                                  , (OperatorName
"u", OperatorName
"gu")
                                  , (OperatorName
"U", OperatorName
"gU")
                                  ]
          synonymOp :: (OperatorName, OperatorName) -> VimOperator
synonymOp (OperatorName
newName, OperatorName
existingName) =
                    OperatorName
-> (Int -> StyledRegion -> EditorM RepeatToken) -> VimOperator
VimOperator OperatorName
newName ((Int -> StyledRegion -> EditorM RepeatToken) -> VimOperator)
-> (OperatorName -> Int -> StyledRegion -> EditorM RepeatToken)
-> OperatorName
-> VimOperator
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VimOperator -> Int -> StyledRegion -> EditorM RepeatToken
operatorApplyToRegionE (VimOperator -> Int -> StyledRegion -> EditorM RepeatToken)
-> (OperatorName -> VimOperator)
-> OperatorName
-> Int
-> StyledRegion
-> EditorM RepeatToken
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe VimOperator -> VimOperator
forall a. HasCallStack => Maybe a -> a
fromJust
                    (Maybe VimOperator -> VimOperator)
-> (OperatorName -> Maybe VimOperator)
-> OperatorName
-> VimOperator
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [VimOperator] -> OperatorName -> Maybe VimOperator
stringToOperator [VimOperator]
operators (OperatorName -> VimOperator) -> OperatorName -> VimOperator
forall a b. (a -> b) -> a -> b
$ OperatorName
existingName

chooseRegisterBinding :: VimBinding
chooseRegisterBinding :: VimBinding
chooseRegisterBinding = (VimState -> Bool) -> VimBinding
mkChooseRegisterBinding ((VimState -> Bool) -> VimBinding)
-> (VimState -> Bool) -> VimBinding
forall a b. (a -> b) -> a -> b
$
    \VimState
s -> case VimState
s of
        (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) -> Bool
True
        VimState
_ -> Bool
False

shiftDBinding :: VimBinding
shiftDBinding :: VimBinding
shiftDBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
forall a.
(Eq a, IsString a) =>
a -> VimState -> MatchResult (EditorM RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where f :: a -> VimState -> MatchResult (EditorM RepeatToken)
f a
"D" (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) = 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
              (Visual RegionStyle
style) <- VimState -> VimMode
vsMode (VimState -> VimMode) -> EditorM VimState -> EditorM VimMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
              Region
reg <- BufferM Region -> EditorM Region
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM Region
regionOfSelectionB
              case RegionStyle
style of
                  RegionStyle
Block -> BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ do
                      (Point
start, [Int]
lengths) <- Region -> BufferM (Point, [Int])
shapeOfBlockRegionB Region
reg
                      Point -> BufferM ()
moveTo Point
start
                      Int
startCol <- BufferM Int
curCol
                      [Int] -> (Int -> BufferM ()) -> BufferM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([Int] -> [Int]
forall a. [a] -> [a]
reverse [Int
0 .. [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
lengths Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]) ((Int -> BufferM ()) -> BufferM ())
-> (Int -> BufferM ()) -> BufferM ()
forall a b. (a -> b) -> a -> b
$ \Int
l -> do
                          Point -> BufferM ()
moveTo Point
start
                          BufferM Int -> BufferM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (BufferM Int -> BufferM ()) -> BufferM Int -> BufferM ()
forall a b. (a -> b) -> a -> b
$ Int -> BufferM Int
lineMoveRel Int
l
                          BufferM Bool -> BufferM () -> BufferM ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM ((Int -> Bool) -> BufferM Int -> BufferM Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
startCol) BufferM Int
curCol) BufferM ()
deleteToEol
                      BufferM ()
leftOnEol
                  RegionStyle
_ ->  do
                      Region
reg' <- BufferM Region -> EditorM Region
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM Region -> EditorM Region)
-> BufferM Region -> EditorM Region
forall a b. (a -> b) -> a -> b
$ Region -> RegionStyle -> BufferM Region
convertRegionToStyleB Region
reg RegionStyle
LineWise
                      Region
reg'' <- BufferM Region -> EditorM Region
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM Region -> EditorM Region)
-> BufferM Region -> EditorM Region
forall a b. (a -> b) -> a -> b
$ Point -> Point -> RegionStyle -> BufferM Region
mkRegionOfStyleB (Region -> Point
regionStart Region
reg')
                                                              (Region -> Point
regionEnd Region
reg' Point -> Size -> Point
forall absolute relative.
SemiNum absolute relative =>
absolute -> relative -> absolute
-~ Int -> Size
Size Int
1)
                                                              RegionStyle
Exclusive
                      EditorM RepeatToken -> EditorM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (EditorM RepeatToken -> EditorM ())
-> EditorM RepeatToken -> EditorM ()
forall a b. (a -> b) -> a -> b
$ VimOperator -> Int -> StyledRegion -> EditorM RepeatToken
operatorApplyToRegionE VimOperator
opDelete Int
1 (StyledRegion -> EditorM RepeatToken)
-> StyledRegion -> EditorM RepeatToken
forall a b. (a -> b) -> a -> b
$ RegionStyle -> Region -> StyledRegion
StyledRegion RegionStyle
LineWise Region
reg''
              EditorM ()
resetCountE
              VimMode -> EditorM ()
switchModeE VimMode
Normal
              RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Finish
          f a
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch

mkOperatorBinding :: VimOperator -> VimBinding
mkOperatorBinding :: VimOperator -> VimBinding
mkOperatorBinding VimOperator
op = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
f
  where
    f :: EventString -> VimState -> MatchResult (EditorM RepeatToken)
f EventString
evs (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) =
      EditorM RepeatToken
action EditorM RepeatToken
-> MatchResult () -> MatchResult (EditorM RepeatToken)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ EventString
evs EventString -> EventString -> MatchResult ()
`matchesString` Text -> EventString
Ev (OperatorName -> Text
_unOp (OperatorName -> Text) -> OperatorName -> Text
forall a b. (a -> b) -> a -> b
$ VimOperator -> OperatorName
operatorName VimOperator
op)
    f EventString
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
    action :: EditorM RepeatToken
action = do
        (Visual RegionStyle
style) <- VimState -> VimMode
vsMode (VimState -> VimMode) -> EditorM VimState -> EditorM VimMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
        Region
region <- BufferM Region -> EditorM Region
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM Region
regionOfSelectionB
        Int
count <- EditorM Int
getCountE
        RepeatToken
token <- VimOperator -> Int -> StyledRegion -> EditorM RepeatToken
operatorApplyToRegionE VimOperator
op Int
count (StyledRegion -> EditorM RepeatToken)
-> StyledRegion -> EditorM RepeatToken
forall a b. (a -> b) -> a -> b
$ RegionStyle -> Region -> StyledRegion
StyledRegion RegionStyle
style Region
region
        EditorM ()
resetCountE
        EditorM ()
clrStatus
        BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ do
            Bool -> BufferM ()
setVisibleSelection Bool
False
            RegionStyle -> BufferM ()
putRegionStyle RegionStyle
Inclusive
        RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
token

replaceBinding :: VimBinding
replaceBinding :: VimBinding
replaceBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where f :: [Char] -> VimState -> MatchResult (EditorM RepeatToken)
f [Char]
evs (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) =
              case [Char]
evs of
                [Char]
"r" -> MatchResult (EditorM RepeatToken)
forall a. MatchResult a
PartialMatch
                (Char
'r':Char
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
                    (Visual RegionStyle
style) <- VimState -> VimMode
vsMode (VimState -> VimMode) -> EditorM VimState -> EditorM VimMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
                    Region
region <- BufferM Region -> EditorM Region
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM Region
regionOfSelectionB
                    BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ StyledRegion -> (Char -> Char) -> BufferM ()
transformCharactersInRegionB (RegionStyle -> Region -> StyledRegion
StyledRegion RegionStyle
style Region
region)
                                      (\Char
x -> if Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' then Char
x else Char
c)
                    EditorM RepeatToken -> EditorM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void EditorM RepeatToken
escAction
                    RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Finish
                [Char]
_ -> MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
          f [Char]
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch


data VisualPaste
  = PasteBefore
  | ReplaceSelection
  deriving (VisualPaste -> VisualPaste -> Bool
(VisualPaste -> VisualPaste -> Bool)
-> (VisualPaste -> VisualPaste -> Bool) -> Eq VisualPaste
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VisualPaste -> VisualPaste -> Bool
$c/= :: VisualPaste -> VisualPaste -> Bool
== :: VisualPaste -> VisualPaste -> Bool
$c== :: VisualPaste -> VisualPaste -> Bool
Eq, Eq VisualPaste
Eq VisualPaste
-> (VisualPaste -> VisualPaste -> Ordering)
-> (VisualPaste -> VisualPaste -> Bool)
-> (VisualPaste -> VisualPaste -> Bool)
-> (VisualPaste -> VisualPaste -> Bool)
-> (VisualPaste -> VisualPaste -> Bool)
-> (VisualPaste -> VisualPaste -> VisualPaste)
-> (VisualPaste -> VisualPaste -> VisualPaste)
-> Ord VisualPaste
VisualPaste -> VisualPaste -> Bool
VisualPaste -> VisualPaste -> Ordering
VisualPaste -> VisualPaste -> VisualPaste
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: VisualPaste -> VisualPaste -> VisualPaste
$cmin :: VisualPaste -> VisualPaste -> VisualPaste
max :: VisualPaste -> VisualPaste -> VisualPaste
$cmax :: VisualPaste -> VisualPaste -> VisualPaste
>= :: VisualPaste -> VisualPaste -> Bool
$c>= :: VisualPaste -> VisualPaste -> Bool
> :: VisualPaste -> VisualPaste -> Bool
$c> :: VisualPaste -> VisualPaste -> Bool
<= :: VisualPaste -> VisualPaste -> Bool
$c<= :: VisualPaste -> VisualPaste -> Bool
< :: VisualPaste -> VisualPaste -> Bool
$c< :: VisualPaste -> VisualPaste -> Bool
compare :: VisualPaste -> VisualPaste -> Ordering
$ccompare :: VisualPaste -> VisualPaste -> Ordering
$cp1Ord :: Eq VisualPaste
Ord, Int -> VisualPaste -> ShowS
[VisualPaste] -> ShowS
VisualPaste -> [Char]
(Int -> VisualPaste -> ShowS)
-> (VisualPaste -> [Char])
-> ([VisualPaste] -> ShowS)
-> Show VisualPaste
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [VisualPaste] -> ShowS
$cshowList :: [VisualPaste] -> ShowS
show :: VisualPaste -> [Char]
$cshow :: VisualPaste -> [Char]
showsPrec :: Int -> VisualPaste -> ShowS
$cshowsPrec :: Int -> VisualPaste -> ShowS
Show)

pasteBinding :: VimBinding
pasteBinding :: VimBinding
pasteBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
forall a.
(Eq a, IsString a) =>
a -> VimState -> MatchResult (EditorM RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where
    f :: a -> VimState -> MatchResult (EditorM RepeatToken)
f a
"P" VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
style) } = RegionStyle -> VisualPaste -> MatchResult (EditorM RepeatToken)
pasteMatch RegionStyle
style VisualPaste
PasteBefore
    f a
"p" VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
style) } = RegionStyle -> VisualPaste -> MatchResult (EditorM RepeatToken)
pasteMatch RegionStyle
style VisualPaste
ReplaceSelection
    f a
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch

    pasteMatch :: RegionStyle -> VisualPaste -> MatchResult (EditorM RepeatToken)
    pasteMatch :: RegionStyle -> VisualPaste -> MatchResult (EditorM RepeatToken)
pasteMatch RegionStyle
style VisualPaste
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
        Maybe Register
register <- Char -> EditorM (Maybe Register)
getRegisterE (Char -> EditorM (Maybe Register))
-> (VimState -> Char) -> VimState -> EditorM (Maybe Register)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VimState -> Char
vsActiveRegister (VimState -> EditorM (Maybe Register))
-> EditorM VimState -> EditorM (Maybe Register)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
        EditorM ()
-> (Register -> EditorM ()) -> Maybe Register -> EditorM ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> EditorM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (RegionStyle -> VisualPaste -> Register -> EditorM ()
paste RegionStyle
style VisualPaste
p) Maybe Register
register
        EditorM RepeatToken -> EditorM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void EditorM RepeatToken
escAction
        RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Finish

    paste :: RegionStyle -> VisualPaste -> Register -> EditorM ()
    paste :: RegionStyle -> VisualPaste -> Register -> EditorM ()
paste RegionStyle
LineWise  = VisualPaste -> Register -> EditorM ()
linePaste
    paste RegionStyle
Block     = VisualPaste -> Register -> EditorM ()
blockPaste
    paste RegionStyle
Inclusive = VisualPaste -> Register -> EditorM ()
otherPaste
    paste RegionStyle
Exclusive = VisualPaste -> Register -> EditorM ()
otherPaste

    linePaste :: VisualPaste -> Register -> EditorM ()
    linePaste :: VisualPaste -> Register -> EditorM ()
linePaste VisualPaste
p (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
$ do
        Region
region <- BufferM Region
regionOfSelectionB
        Bool -> BufferM () -> BufferM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (VisualPaste
p VisualPaste -> VisualPaste -> Bool
forall a. Eq a => a -> a -> Bool
== VisualPaste
ReplaceSelection) (BufferM () -> BufferM ())
-> (BufferM (NonEmpty Point) -> BufferM ())
-> BufferM (NonEmpty Point)
-> BufferM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BufferM (NonEmpty Point) -> BufferM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (BufferM (NonEmpty Point) -> BufferM ())
-> BufferM (NonEmpty Point) -> BufferM ()
forall a b. (a -> b) -> a -> b
$ Region -> RegionStyle -> BufferM (NonEmpty Point)
deleteRegionWithStyleB Region
region RegionStyle
LineWise
        YiString -> RegionStyle -> BufferM ()
insertRopeWithStyleB (YiString -> YiString
addNewLineIfNecessary YiString
rope) RegionStyle
LineWise

    blockPaste :: VisualPaste -> Register -> EditorM ()
    blockPaste :: VisualPaste -> Register -> EditorM ()
blockPaste VisualPaste
p (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
$ do
        Point
here <- BufferM Point
pointB
        Point
there <- BufferM Point
getSelectionMarkPointB
        (Point
here', Point
there') <- Point -> Point -> BufferM (Point, Point)
flipRectangleB Point
here Point
there
        Region
reg <- BufferM Region
regionOfSelectionB
        Point -> BufferM ()
moveTo ([Point] -> Point
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [Point
here, Point
there, Point
here', Point
there'])
        Bool -> BufferM () -> BufferM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (VisualPaste
p VisualPaste -> VisualPaste -> Bool
forall a. Eq a => a -> a -> Bool
== VisualPaste
ReplaceSelection) (BufferM () -> BufferM ())
-> (BufferM (NonEmpty Point) -> BufferM ())
-> BufferM (NonEmpty Point)
-> BufferM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BufferM (NonEmpty Point) -> BufferM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (BufferM (NonEmpty Point) -> BufferM ())
-> BufferM (NonEmpty Point) -> BufferM ()
forall a b. (a -> b) -> a -> b
$ Region -> RegionStyle -> BufferM (NonEmpty Point)
deleteRegionWithStyleB Region
reg RegionStyle
Block
        if YiString -> Int
R.countNewLines YiString
rope Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
        then Region -> (Maybe Point -> BufferM ()) -> BufferM ()
actionOnLeft Region
reg ((Maybe Point -> BufferM ()) -> BufferM ())
-> (Maybe Point -> BufferM ()) -> BufferM ()
forall a b. (a -> b) -> a -> b
$ BufferM () -> (Point -> BufferM ()) -> Maybe Point -> BufferM ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> BufferM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) (\Point
_ -> YiString -> RegionStyle -> BufferM ()
insertRopeWithStyleB YiString
rope RegionStyle
_style)
        else YiString -> RegionStyle -> BufferM ()
pasteInclusiveB YiString
rope RegionStyle
_style
      where
        -- Taken from deleteRegionWithStyleB
        actionOnLeft :: Region -> (Maybe Point -> BufferM ()) -> BufferM ()
        actionOnLeft :: Region -> (Maybe Point -> BufferM ()) -> BufferM ()
actionOnLeft Region
reg Maybe Point -> BufferM ()
action = BufferM () -> BufferM ()
forall a. BufferM a -> BufferM a
savingPointB (BufferM () -> BufferM ()) -> BufferM () -> BufferM ()
forall a b. (a -> b) -> a -> b
$ do
            (Point
start, [Int]
lengths) <- Region -> BufferM (Point, [Int])
shapeOfBlockRegionB Region
reg
            Point -> BufferM ()
moveTo Point
start
            [(Int, Int)] -> ((Int, Int) -> BufferM ()) -> BufferM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([Int] -> [Int] -> [(Int, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [Int]
lengths) (((Int, Int) -> BufferM ()) -> BufferM ())
-> ((Int, Int) -> BufferM ()) -> BufferM ()
forall a b. (a -> b) -> a -> b
$ \(Int
i, Int
l) -> do
                Point
p' <- BufferM Point
pointB
                Point -> BufferM ()
moveTo Point
start
                BufferM Int -> BufferM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (BufferM Int -> BufferM ()) -> BufferM Int -> BufferM ()
forall a b. (a -> b) -> a -> b
$ Int -> BufferM Int
lineMoveRel Int
i
                Maybe Point -> BufferM ()
action (if Int
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe Point
forall a. Maybe a
Nothing else Point -> Maybe Point
forall a. a -> Maybe a
Just Point
p')

    otherPaste :: VisualPaste -> Register -> EditorM ()
    otherPaste :: VisualPaste -> Register -> EditorM ()
otherPaste VisualPaste
_ (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
$ do
      Region
region <- BufferM Region
regionOfSelectionB
      Region
region' <- Region -> RegionStyle -> BufferM Region
convertRegionToStyleB Region
region RegionStyle
Inclusive
      Region -> YiString -> BufferM ()
replaceRegionB Region
region' YiString
rope


switchEdgeBinding :: VimBinding
switchEdgeBinding :: VimBinding
switchEdgeBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
forall (m :: * -> *).
(MonadEditor m, MonadFail m) =>
[Char] -> VimState -> MatchResult (m RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where f :: [Char] -> VimState -> MatchResult (m RepeatToken)
f [Char
c] (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) | Char
c Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'o', Char
'O']
              = 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
                  (Visual RegionStyle
style) <- VimState -> VimMode
vsMode (VimState -> VimMode) -> m VimState -> m VimMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
                  BufferM () -> m ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> m ()) -> BufferM () -> m ()
forall a b. (a -> b) -> a -> b
$ do
                      Point
here <- BufferM Point
pointB
                      Point
there <- BufferM Point
getSelectionMarkPointB
                      (Point
here', Point
there') <- case (Char
c, RegionStyle
style) of
                                            (Char
'O', RegionStyle
Block) -> Point -> Point -> BufferM (Point, Point)
flipRectangleB Point
here Point
there
                                            (Char
_, RegionStyle
_) -> (Point, Point) -> BufferM (Point, Point)
forall (m :: * -> *) a. Monad m => a -> m a
return (Point
there, Point
here)
                      Point -> BufferM ()
moveTo Point
here'
                      Point -> BufferM ()
setSelectionMarkPointB Point
there'
                  RepeatToken -> m RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
          f [Char]
_ VimState
_ = MatchResult (m RepeatToken)
forall a. MatchResult a
NoMatch

insertBinding :: VimBinding
insertBinding :: VimBinding
insertBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE ([Char] -> VimState -> MatchResult (EditorM RepeatToken)
f ([Char] -> VimState -> MatchResult (EditorM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where f :: [Char] -> VimState -> MatchResult (EditorM RepeatToken)
f [Char]
evs (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) | [Char]
evs [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char] -> [[Char]]
forall a. Eq a => [a] -> [[a]]
group [Char]
"IA"
            = 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
                  (Visual RegionStyle
style) <- VimState -> VimMode
vsMode (VimState -> VimMode) -> EditorM VimState -> EditorM VimMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
                  Region
region <- BufferM Region -> EditorM Region
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer BufferM Region
regionOfSelectionB
                  [Point]
cursors <- BufferM [Point] -> EditorM [Point]
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM [Point] -> EditorM [Point])
-> BufferM [Point] -> EditorM [Point]
forall a b. (a -> b) -> a -> b
$ case [Char]
evs of
                      [Char]
"I" -> RegionStyle -> Region -> BufferM [Point]
leftEdgesOfRegionB RegionStyle
style Region
region
                      [Char]
"A" -> RegionStyle -> Region -> BufferM [Point]
rightEdgesOfRegionB RegionStyle
style Region
region
                      [Char]
_ -> [Char] -> BufferM [Point]
forall a. HasCallStack => [Char] -> a
error [Char]
"Just silencing ghc's false positive warning."
                  case [Point]
cursors of
                      [] -> [Char] -> EditorM ()
forall a. HasCallStack => [Char] -> a
error [Char]
"No cursor to move to (in Yi.Keymap.Vim.VisualMap.insertBinding)"
                      (Point
mainCursor : [Point]
_) -> BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (Point -> BufferM ()
moveTo Point
mainCursor)
                  (VimState -> VimState) -> EditorM ()
modifyStateE ((VimState -> VimState) -> EditorM ())
-> (VimState -> VimState) -> EditorM ()
forall a b. (a -> b) -> a -> b
$ \VimState
s -> VimState
s { vsSecondaryCursors :: [Point]
vsSecondaryCursors = Int -> [Point] -> [Point]
forall a. Int -> [a] -> [a]
drop Int
1 [Point]
cursors }
                  BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ Bool -> BufferM ()
setVisibleSelection Bool
False
                  VimMode -> EditorM ()
switchModeE (VimMode -> EditorM ()) -> VimMode -> EditorM ()
forall a b. (a -> b) -> a -> b
$ Char -> VimMode
Insert ([Char] -> Char
forall a. [a] -> a
head [Char]
evs)
                  RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
          f [Char]
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch

tagJumpBinding :: VimBinding
tagJumpBinding :: VimBinding
tagJumpBinding = (EventString -> VimState -> MatchResult (YiM RepeatToken))
-> VimBinding
VimBindingY ([Char] -> VimState -> MatchResult (YiM RepeatToken)
forall a.
(Eq a, IsString a) =>
a -> VimState -> MatchResult (YiM RepeatToken)
f ([Char] -> VimState -> MatchResult (YiM RepeatToken))
-> (EventString -> [Char])
-> EventString
-> VimState
-> MatchResult (YiM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack (Text -> [Char]) -> (EventString -> Text) -> EventString -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventString -> Text
_unEv)
    where f :: a -> VimState -> MatchResult (YiM RepeatToken)
f a
"<C-]>" (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) })
            = YiM RepeatToken -> MatchResult (YiM RepeatToken)
forall a. a -> MatchResult a
WholeMatch (YiM RepeatToken -> MatchResult (YiM RepeatToken))
-> YiM RepeatToken -> MatchResult (YiM RepeatToken)
forall a b. (a -> b) -> a -> b
$ do
                 Tag
tag <- Text -> Tag
Tag (Text -> Tag) -> (YiString -> Text) -> YiString -> Tag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. YiString -> Text
R.toText (YiString -> Tag) -> YiM YiString -> YiM Tag
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BufferM YiString -> YiM YiString
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer
                            (BufferM Region
regionOfSelectionB BufferM Region -> (Region -> BufferM YiString) -> BufferM YiString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Region -> BufferM YiString
readRegionB)
                 YiM RepeatToken -> YiM ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (YiM RepeatToken -> YiM ()) -> YiM RepeatToken -> YiM ()
forall a b. (a -> b) -> a -> b
$ EditorM RepeatToken -> YiM RepeatToken
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor EditorM RepeatToken
escAction
                 Tag -> Int -> Maybe ([Char], Int, Int) -> YiM ()
gotoTag Tag
tag Int
0 Maybe ([Char], Int, Int)
forall a. Maybe a
Nothing
                 RepeatToken -> YiM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Finish
          f a
_ VimState
_ = MatchResult (YiM RepeatToken)
forall a. MatchResult a
NoMatch