{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_HADDOCK show-extensions #-}
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 a. a -> EditorM a
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 a b. a -> MatchResult b -> MatchResult a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
Bool -> MatchResult ()
matchFromBool (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
"<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 a. a -> EditorM a
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) -> String -> [VimBinding]
forall a b. (a -> b) -> [a] -> [b]
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
currentState <- EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
case vsCount 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 a. a -> EditorM a
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
Lens' FBuffer 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 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
setMarkBinding :: VimBinding
setMarkBinding :: VimBinding
setMarkBinding = (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
"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
$ String -> BufferM ()
setNamedMarkHereB [Char
c]
RepeatToken -> m RepeatToken
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
f String
_ 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 a. Eq a => 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
currentMode <- (VimState -> VimMode) -> EditorM VimState -> EditorM VimMode
forall a b. (a -> b) -> EditorM a -> EditorM b
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 = case a
evs of
a
"v" -> RegionStyle
Inclusive
a
"V" -> RegionStyle
LineWise
a
"<C-v>" -> RegionStyle
Block
a
_ -> String -> RegionStyle
forall a. HasCallStack => String -> a
error String
"Just silencing false positive warning."
newMode = RegionStyle -> VimMode
Visual RegionStyle
newStyle
if newMode == currentMode
then escAction
else do
modifyStateE $ \VimState
s -> VimState
s { vsMode = newMode }
withCurrentBuffer $ do
putRegionStyle newStyle
rectangleSelectionA .= (Block == newStyle)
setVisibleSelection True
return 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 (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 [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 a. a -> EditorM a
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
f String
_ 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 = Just d }
mutate vs :: VimState
vs@(VimState {vsCount :: VimState -> Maybe Int
vsCount = Just Int
count}) = VimState
vs { vsCount = Just $ count * 10 + 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 (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 -> MatchResult TextObject
stringToTextObject -> MatchResult TextObject
PartialMatch) (VimState {vsMode :: VimState -> VimMode
vsMode = Visual RegionStyle
_}) = MatchResult (m RepeatToken)
forall a. MatchResult a
PartialMatch
f (String -> 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 _ reg <- CountedTextObject -> BufferM StyledRegion
regionOfTextObjectB (Int -> TextObject -> CountedTextObject
CountedTextObject Int
count TextObject
to)
setSelectionMarkPointB (regionStart reg)
moveTo (regionEnd reg -~ 1)
RepeatToken -> m RepeatToken
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
f String
_ 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
start <- BufferM Point
getSelectionMarkPointB
stop <- pointB
return $! mkRegion start stop
operatorBindings :: [VimOperator] -> [VimBinding]
operatorBindings :: [VimOperator] -> [VimBinding]
operatorBindings [VimOperator]
operators = (VimOperator -> VimBinding) -> [VimOperator] -> [VimBinding]
forall a b. (a -> b) -> [a] -> [b]
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 a b. (a -> b) -> [a] -> [b]
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 (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
"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 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
reg <- withCurrentBuffer regionOfSelectionB
case 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
(start, lengths) <- Region -> BufferM (Point, [Int])
shapeOfBlockRegionB Region
reg
moveTo start
startCol <- curCol
forM_ (reverse [0 .. length lengths - 1]) $ \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 a b. (a -> b) -> BufferM a -> BufferM b
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
leftOnEol
RegionStyle
_ -> do
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
reg'' <- withCurrentBuffer $ mkRegionOfStyleB (regionStart reg')
(regionEnd reg' -~ Size 1)
Exclusive
void $ operatorApplyToRegionE opDelete 1 $ StyledRegion LineWise reg''
resetCountE
switchModeE Normal
return 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 a b. a -> MatchResult b -> MatchResult a
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 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 <- withCurrentBuffer regionOfSelectionB
count <- getCountE
token <- operatorApplyToRegionE op count $ StyledRegion style region
resetCountE
clrStatus
withCurrentBuffer $ do
setVisibleSelection False
putRegionStyle Inclusive
return token
replaceBinding :: VimBinding
replaceBinding :: VimBinding
replaceBinding = (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
evs (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) =
case String
evs of
String
"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 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 <- withCurrentBuffer regionOfSelectionB
withCurrentBuffer $ transformCharactersInRegionB (StyledRegion style region)
(\Char
x -> if Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' then Char
x else Char
c)
void escAction
return Finish
String
_ -> MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
f String
_ 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
$c== :: VisualPaste -> VisualPaste -> Bool
== :: VisualPaste -> VisualPaste -> Bool
$c/= :: VisualPaste -> VisualPaste -> Bool
/= :: 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
$ccompare :: VisualPaste -> VisualPaste -> Ordering
compare :: VisualPaste -> VisualPaste -> Ordering
$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
>= :: VisualPaste -> VisualPaste -> Bool
$cmax :: VisualPaste -> VisualPaste -> VisualPaste
max :: VisualPaste -> VisualPaste -> VisualPaste
$cmin :: VisualPaste -> VisualPaste -> VisualPaste
min :: VisualPaste -> VisualPaste -> VisualPaste
Ord, Int -> VisualPaste -> String -> String
[VisualPaste] -> String -> String
VisualPaste -> String
(Int -> VisualPaste -> String -> String)
-> (VisualPaste -> String)
-> ([VisualPaste] -> String -> String)
-> Show VisualPaste
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> VisualPaste -> String -> String
showsPrec :: Int -> VisualPaste -> String -> String
$cshow :: VisualPaste -> String
show :: VisualPaste -> String
$cshowList :: [VisualPaste] -> String -> String
showList :: [VisualPaste] -> String -> String
Show)
pasteBinding :: VimBinding
pasteBinding :: VimBinding
pasteBinding = (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
"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
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
maybe (pure ()) (paste style p) register
void escAction
return 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 <- BufferM Region
regionOfSelectionB
when (p == ReplaceSelection) . void $ deleteRegionWithStyleB region LineWise
insertRopeWithStyleB (addNewLineIfNecessary rope) 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
here <- BufferM Point
pointB
there <- getSelectionMarkPointB
(here', there') <- flipRectangleB here there
reg <- regionOfSelectionB
moveTo (minimum [here, there, here', there'])
when (p == ReplaceSelection) . void $ deleteRegionWithStyleB reg Block
if R.countNewLines rope == 0
then actionOnLeft reg $ maybe (pure ()) (\Point
_ -> YiString -> RegionStyle -> BufferM ()
insertRopeWithStyleB YiString
rope RegionStyle
_style)
else pasteInclusiveB rope _style
where
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
(start, lengths) <- Region -> BufferM (Point, [Int])
shapeOfBlockRegionB Region
reg
moveTo start
forM_ (zip [0..] lengths) $ \(Int
i, Int
l) -> do
p' <- BufferM Point
pointB
moveTo start
void $ lineMoveRel i
action (if l == 0 then Nothing else Just 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 <- BufferM Region
regionOfSelectionB
region' <- convertRegionToStyleB region Inclusive
replaceRegionB region' rope
switchEdgeBinding :: VimBinding
switchEdgeBinding :: VimBinding
switchEdgeBinding = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE (String -> VimState -> MatchResult (EditorM RepeatToken)
forall {m :: * -> *}.
(MonadEditor m, MonadFail 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
c] (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) | Char
c Char -> String -> Bool
forall a. Eq a => a -> [a] -> 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 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
withCurrentBuffer $ do
here <- pointB
there <- getSelectionMarkPointB
(here', there') <- case (c, style) of
(Char
'O', RegionStyle
Block) -> Point -> Point -> BufferM (Point, Point)
flipRectangleB Point
here Point
there
(Char
_, RegionStyle
_) -> (Point, Point) -> BufferM (Point, Point)
forall a. a -> BufferM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Point
there, Point
here)
moveTo here'
setSelectionMarkPointB there'
return Continue
f String
_ VimState
_ = MatchResult (m RepeatToken)
forall a. MatchResult a
NoMatch
insertBinding :: VimBinding
insertBinding :: VimBinding
insertBinding = (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
evs (VimState { vsMode :: VimState -> VimMode
vsMode = (Visual RegionStyle
_) }) | String
evs String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String -> [String]
forall a. Eq a => [a] -> [[a]]
group String
"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 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 <- withCurrentBuffer regionOfSelectionB
cursors <- withCurrentBuffer $ case evs of
String
"I" -> RegionStyle -> Region -> BufferM [Point]
leftEdgesOfRegionB RegionStyle
style Region
region
String
"A" -> RegionStyle -> Region -> BufferM [Point]
rightEdgesOfRegionB RegionStyle
style Region
region
String
_ -> String -> BufferM [Point]
forall a. HasCallStack => String -> a
error String
"Just silencing ghc's false positive warning."
case cursors of
[] -> String -> EditorM ()
forall a. HasCallStack => String -> a
error String
"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)
modifyStateE $ \VimState
s -> VimState
s { vsSecondaryCursors = drop 1 cursors }
withCurrentBuffer $ setVisibleSelection False
switchModeE $ Insert (head evs)
return Continue
f String
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
tagJumpBinding :: VimBinding
tagJumpBinding :: VimBinding
tagJumpBinding = (EventString -> VimState -> MatchResult (YiM RepeatToken))
-> VimBinding
VimBindingY (String -> VimState -> MatchResult (YiM RepeatToken)
forall {a}.
(Eq a, IsString a) =>
a -> VimState -> MatchResult (YiM RepeatToken)
f (String -> VimState -> MatchResult (YiM RepeatToken))
-> (EventString -> String)
-> EventString
-> VimState
-> MatchResult (YiM 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 (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 <- 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 a b. BufferM a -> (a -> BufferM b) -> BufferM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Region -> BufferM YiString
readRegionB)
void $ withEditor escAction
gotoTag tag 0 Nothing
return Finish
f a
_ VimState
_ = MatchResult (YiM RepeatToken)
forall a. MatchResult a
NoMatch