{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Yi.Keymap.Vim.Utils
( mkBindingE
, mkBindingY
, mkStringBindingE
, mkStringBindingY
, splitCountedCommand
, selectBinding
, selectPureBinding
, matchFromBool
, mkMotionBinding
, mkChooseRegisterBinding
, pasteInclusiveB
, addNewLineIfNecessary
, indentBlockRegionB
, addVimJumpHereE
, exportRegisterToClipboard
, pasteFromClipboard
) where
import Lens.Micro.Platform ((.=), use)
import Control.Monad (forM_, void, when)
import Data.Char (isSpace)
import Data.Foldable (asum)
import Data.List (group)
import qualified Data.Text as T (unpack)
import Safe (headDef)
import Yi.Buffer hiding (Insert)
import Yi.Editor
import Yi.Event (Event)
import Yi.Keymap (YiM)
import Yi.Keymap.Vim.Common
import Yi.Keymap.Vim.EventUtils (eventToEventString, splitCountedCommand)
import Yi.Keymap.Vim.MatchResult
import Yi.Keymap.Vim.Motion (Move (Move), stringToMove)
import Yi.Keymap.Vim.StateUtils (getMaybeCountE, modifyStateE,
resetCountE, getRegisterE)
import Yi.Monad (whenM)
import Yi.Rope (YiString, countNewLines, last)
import qualified Yi.Rope as R (replicateChar, snoc, toString, fromString)
import Yi.Utils (io)
import System.Hclip (getClipboard, setClipboard)
mkStringBindingE :: VimMode -> RepeatToken
-> (EventString, EditorM (), VimState -> VimState) -> VimBinding
mkStringBindingE :: VimMode
-> RepeatToken
-> (EventString, EditorM (), VimState -> VimState)
-> VimBinding
mkStringBindingE VimMode
mode RepeatToken
rtoken (EventString
eventString, EditorM ()
action, VimState -> VimState
mutate) = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
f
where f :: EventString -> VimState -> MatchResult (EditorM RepeatToken)
f EventString
_ VimState
vs | VimState -> VimMode
vsMode VimState
vs VimMode -> VimMode -> Bool
forall a. Eq a => a -> a -> Bool
/= VimMode
mode = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
f EventString
evs VimState
_ = EditorM ()
-> (VimState -> VimState) -> RepeatToken -> EditorM RepeatToken
forall (m :: * -> *).
MonadEditor m =>
m () -> (VimState -> VimState) -> RepeatToken -> m RepeatToken
combineAction EditorM ()
action VimState -> VimState
mutate RepeatToken
rtoken EditorM RepeatToken
-> MatchResult () -> MatchResult (EditorM RepeatToken)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
EventString
evs EventString -> EventString -> MatchResult ()
`matchesString` EventString
eventString
mkStringBindingY :: VimMode
-> (EventString, YiM (), VimState -> VimState) -> VimBinding
mkStringBindingY :: VimMode
-> (EventString, YiM (), VimState -> VimState) -> VimBinding
mkStringBindingY VimMode
mode (EventString
eventString, YiM ()
action, VimState -> VimState
mutate) = (EventString -> VimState -> MatchResult (YiM RepeatToken))
-> VimBinding
VimBindingY EventString -> VimState -> MatchResult (YiM RepeatToken)
f
where f :: EventString -> VimState -> MatchResult (YiM RepeatToken)
f EventString
_ VimState
vs | VimState -> VimMode
vsMode VimState
vs VimMode -> VimMode -> Bool
forall a. Eq a => a -> a -> Bool
/= VimMode
mode = MatchResult (YiM RepeatToken)
forall a. MatchResult a
NoMatch
f EventString
evs VimState
_ = YiM () -> (VimState -> VimState) -> RepeatToken -> YiM RepeatToken
forall (m :: * -> *).
MonadEditor m =>
m () -> (VimState -> VimState) -> RepeatToken -> m RepeatToken
combineAction YiM ()
action VimState -> VimState
mutate RepeatToken
Drop YiM RepeatToken -> MatchResult () -> MatchResult (YiM RepeatToken)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
EventString
evs EventString -> EventString -> MatchResult ()
`matchesString` EventString
eventString
mkBindingE :: VimMode -> RepeatToken -> (Event, EditorM (), VimState -> VimState) -> VimBinding
mkBindingE :: VimMode
-> RepeatToken
-> (Event, EditorM (), VimState -> VimState)
-> VimBinding
mkBindingE VimMode
mode RepeatToken
rtoken (Event
event, EditorM ()
action, VimState -> VimState
mutate) = (EventString -> VimState -> MatchResult (EditorM RepeatToken))
-> VimBinding
VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
f
where f :: EventString -> VimState -> MatchResult (EditorM RepeatToken)
f EventString
evs VimState
vs = EditorM ()
-> (VimState -> VimState) -> RepeatToken -> EditorM RepeatToken
forall (m :: * -> *).
MonadEditor m =>
m () -> (VimState -> VimState) -> RepeatToken -> m RepeatToken
combineAction EditorM ()
action VimState -> VimState
mutate RepeatToken
rtoken EditorM RepeatToken
-> MatchResult () -> MatchResult (EditorM RepeatToken)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
Bool -> MatchResult ()
matchFromBool (VimState -> VimMode
vsMode VimState
vs VimMode -> VimMode -> Bool
forall a. Eq a => a -> a -> Bool
== VimMode
mode Bool -> Bool -> Bool
&& EventString
evs EventString -> EventString -> Bool
forall a. Eq a => a -> a -> Bool
== Event -> EventString
eventToEventString Event
event)
mkBindingY :: VimMode -> (Event, YiM (), VimState -> VimState) -> VimBinding
mkBindingY :: VimMode -> (Event, YiM (), VimState -> VimState) -> VimBinding
mkBindingY VimMode
mode (Event
event, YiM ()
action, VimState -> VimState
mutate) = (EventString -> VimState -> MatchResult (YiM RepeatToken))
-> VimBinding
VimBindingY EventString -> VimState -> MatchResult (YiM RepeatToken)
f
where f :: EventString -> VimState -> MatchResult (YiM RepeatToken)
f EventString
evs VimState
vs = YiM () -> (VimState -> VimState) -> RepeatToken -> YiM RepeatToken
forall (m :: * -> *).
MonadEditor m =>
m () -> (VimState -> VimState) -> RepeatToken -> m RepeatToken
combineAction YiM ()
action VimState -> VimState
mutate RepeatToken
Drop YiM RepeatToken -> MatchResult () -> MatchResult (YiM RepeatToken)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
Bool -> MatchResult ()
matchFromBool (VimState -> VimMode
vsMode VimState
vs VimMode -> VimMode -> Bool
forall a. Eq a => a -> a -> Bool
== VimMode
mode Bool -> Bool -> Bool
&& EventString
evs EventString -> EventString -> Bool
forall a. Eq a => a -> a -> Bool
== Event -> EventString
eventToEventString Event
event)
combineAction :: MonadEditor m => m () -> (VimState -> VimState) -> RepeatToken -> m RepeatToken
combineAction :: m () -> (VimState -> VimState) -> RepeatToken -> m RepeatToken
combineAction m ()
action VimState -> VimState
mutateState RepeatToken
rtoken = do
m ()
action
EditorM () -> m ()
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor (EditorM () -> m ()) -> EditorM () -> m ()
forall a b. (a -> b) -> a -> b
$ (VimState -> VimState) -> EditorM ()
modifyStateE VimState -> VimState
mutateState
RepeatToken -> m RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
rtoken
selectPureBinding :: EventString -> VimState -> [VimBinding] -> MatchResult (EditorM RepeatToken)
selectPureBinding :: EventString
-> VimState -> [VimBinding] -> MatchResult (EditorM RepeatToken)
selectPureBinding EventString
evs VimState
state = [MatchResult (EditorM RepeatToken)]
-> MatchResult (EditorM RepeatToken)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum ([MatchResult (EditorM RepeatToken)]
-> MatchResult (EditorM RepeatToken))
-> ([VimBinding] -> [MatchResult (EditorM RepeatToken)])
-> [VimBinding]
-> MatchResult (EditorM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VimBinding -> MatchResult (EditorM RepeatToken))
-> [VimBinding] -> [MatchResult (EditorM RepeatToken)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VimBinding -> MatchResult (EditorM RepeatToken)
try
where try :: VimBinding -> MatchResult (EditorM RepeatToken)
try (VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
matcher) = EventString -> VimState -> MatchResult (EditorM RepeatToken)
matcher EventString
evs VimState
state
try (VimBindingY EventString -> VimState -> MatchResult (YiM RepeatToken)
_) = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
selectBinding :: EventString -> VimState -> [VimBinding] -> MatchResult (YiM RepeatToken)
selectBinding :: EventString
-> VimState -> [VimBinding] -> MatchResult (YiM RepeatToken)
selectBinding EventString
input VimState
state = [MatchResult (YiM RepeatToken)] -> MatchResult (YiM RepeatToken)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum ([MatchResult (YiM RepeatToken)] -> MatchResult (YiM RepeatToken))
-> ([VimBinding] -> [MatchResult (YiM RepeatToken)])
-> [VimBinding]
-> MatchResult (YiM RepeatToken)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VimBinding -> MatchResult (YiM RepeatToken))
-> [VimBinding] -> [MatchResult (YiM RepeatToken)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VimBinding -> MatchResult (YiM RepeatToken)
try
where try :: VimBinding -> MatchResult (YiM RepeatToken)
try (VimBindingY EventString -> VimState -> MatchResult (YiM RepeatToken)
matcher) = EventString -> VimState -> MatchResult (YiM RepeatToken)
matcher EventString
input VimState
state
try (VimBindingE EventString -> VimState -> MatchResult (EditorM RepeatToken)
matcher) = (EditorM RepeatToken -> YiM RepeatToken)
-> MatchResult (EditorM RepeatToken)
-> MatchResult (YiM RepeatToken)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap EditorM RepeatToken -> YiM RepeatToken
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor (MatchResult (EditorM RepeatToken)
-> MatchResult (YiM RepeatToken))
-> MatchResult (EditorM RepeatToken)
-> MatchResult (YiM RepeatToken)
forall a b. (a -> b) -> a -> b
$ EventString -> VimState -> MatchResult (EditorM RepeatToken)
matcher EventString
input VimState
state
setUnjumpMarks :: Point -> BufferM ()
setUnjumpMarks :: Point -> BufferM ()
setUnjumpMarks Point
p = do
Point
solP <- Point -> BufferM Point
solPointB Point
p
[(Point, Char)]
lineStream <- Direction -> Point -> BufferM [(Point, Char)]
indexedStreamB Direction
Forward Point
solP
let fstNonBlank :: Point
fstNonBlank =
Point -> [Point] -> Point
forall a. a -> [a] -> a
headDef Point
solP [ Point
p' | (Point
p', Char
ch) <- [(Point, Char)]
lineStream, Bool -> Bool
not (Char -> Bool
isSpace Char
ch) Bool -> Bool -> Bool
|| Char
ch Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' ]
(ASetter FBuffer FBuffer Point Point -> Point -> BufferM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Point
p) (ASetter FBuffer FBuffer Point Point -> BufferM ())
-> (Mark -> ASetter FBuffer FBuffer Point Point)
-> Mark
-> BufferM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mark -> ASetter FBuffer FBuffer Point Point
Mark -> Lens' FBuffer Point
markPointA (Mark -> BufferM ()) -> BufferM Mark -> BufferM ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe String -> BufferM Mark
getMarkB (String -> Maybe String
forall a. a -> Maybe a
Just String
"`")
(ASetter FBuffer FBuffer Point Point -> Point -> BufferM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Point
fstNonBlank) (ASetter FBuffer FBuffer Point Point -> BufferM ())
-> (Mark -> ASetter FBuffer FBuffer Point Point)
-> Mark
-> BufferM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mark -> ASetter FBuffer FBuffer Point Point
Mark -> Lens' FBuffer Point
markPointA (Mark -> BufferM ()) -> BufferM Mark -> BufferM ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe String -> BufferM Mark
getMarkB (String -> Maybe String
forall a. a -> Maybe a
Just String
"'")
addVimJumpAtE :: Point -> EditorM ()
addVimJumpAtE :: Point -> EditorM ()
addVimJumpAtE Point
p = do
BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ Point -> BufferM ()
setUnjumpMarks Point
p
Point -> EditorM ()
addJumpAtE Point
p
addVimJumpHereE :: EditorM ()
addVimJumpHereE :: EditorM ()
addVimJumpHereE = do
BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ Point -> BufferM ()
setUnjumpMarks (Point -> BufferM ()) -> BufferM Point -> BufferM ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< BufferM Point
pointB
EditorM ()
addJumpHereE
mkMotionBinding :: RepeatToken -> (VimMode -> Bool) -> VimBinding
mkMotionBinding :: RepeatToken -> (VimMode -> Bool) -> VimBinding
mkMotionBinding RepeatToken
token VimMode -> Bool
condition = (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
state | VimMode -> Bool
condition (VimState -> VimMode
vsMode VimState
state) =
(Move -> EditorM RepeatToken)
-> MatchResult Move -> MatchResult (EditorM RepeatToken)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Move -> EditorM RepeatToken
go (String -> Move -> EditorM RepeatToken)
-> (EventString -> String)
-> EventString
-> Move
-> 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 (EventString -> Move -> EditorM RepeatToken)
-> EventString -> Move -> EditorM RepeatToken
forall a b. (a -> b) -> a -> b
$ EventString
evs) (EventString -> MatchResult Move
stringToMove EventString
evs)
f EventString
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
go :: String -> Move -> EditorM RepeatToken
go :: String -> Move -> EditorM RepeatToken
go String
evs (Move RegionStyle
_style Bool
isJump Maybe Int -> BufferM ()
move) = do
Maybe Int
count <- EditorM (Maybe Int)
getMaybeCountE
Point
prevPoint <- 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
$ do
Point
p <- BufferM Point
pointB
Maybe Int -> BufferM ()
move Maybe Int
count
BufferM ()
leftOnEol
Point -> BufferM Point
forall (m :: * -> *) a. Monad m => a -> m a
return Point
p
Bool -> EditorM () -> EditorM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
isJump (EditorM () -> EditorM ()) -> EditorM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ Point -> EditorM ()
addVimJumpAtE Point
prevPoint
EditorM ()
resetCountE
Bool
sticky <- BufferM Bool -> EditorM Bool
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM Bool -> EditorM Bool) -> BufferM Bool -> EditorM Bool
forall a b. (a -> b) -> a -> b
$ Getting Bool FBuffer Bool -> BufferM Bool
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting Bool FBuffer Bool
forall c. HasAttributes c => Lens' c Bool
stickyEolA
Bool -> EditorM () -> EditorM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
evs String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"$") (EditorM () -> EditorM ())
-> (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
True
Bool -> EditorM () -> EditorM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
evs String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String -> [String]
forall a. Eq a => [a] -> [[a]]
group String
"jk" Bool -> Bool -> Bool
&& Bool
sticky) (EditorM () -> EditorM ()) -> EditorM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$
BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ BufferM ()
moveToEol BufferM () -> BufferM () -> BufferM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> BufferM ()
moveXorSol Int
1
Bool -> EditorM () -> EditorM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
evs String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` String -> [String]
forall a. Eq a => [a] -> [[a]]
group String
"jk$") (EditorM () -> EditorM ())
-> (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
let m :: Char
m = String -> Char
forall a. [a] -> a
head String
evs
Bool -> EditorM () -> EditorM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
m Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (Char
'f' Char -> String -> String
forall a. a -> [a] -> [a]
: String
"FtT")) (EditorM () -> EditorM ()) -> EditorM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ do
let c :: Char
c = String -> Char
forall a. [a] -> a
Prelude.last String
evs
(Direction
dir, RegionStyle
style) =
case Char
m of
Char
'f' -> (Direction
Forward, RegionStyle
Inclusive)
Char
't' -> (Direction
Forward, RegionStyle
Exclusive)
Char
'F' -> (Direction
Backward, RegionStyle
Inclusive)
Char
'T' -> (Direction
Backward, RegionStyle
Exclusive)
Char
_ -> String -> (Direction, RegionStyle)
forall a. HasCallStack => String -> a
error String
"can't happen"
command :: GotoCharCommand
command = Char -> Direction -> RegionStyle -> GotoCharCommand
GotoCharCommand Char
c Direction
dir RegionStyle
style
(VimState -> VimState) -> EditorM ()
modifyStateE ((VimState -> VimState) -> EditorM ())
-> (VimState -> VimState) -> EditorM ()
forall a b. (a -> b) -> a -> b
$ \VimState
s -> VimState
s { vsLastGotoCharCommand :: Maybe GotoCharCommand
vsLastGotoCharCommand = GotoCharCommand -> Maybe GotoCharCommand
forall a. a -> Maybe a
Just GotoCharCommand
command}
RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
token
mkChooseRegisterBinding :: (VimState -> Bool) -> VimBinding
mkChooseRegisterBinding :: (VimState -> Bool) -> VimBinding
mkChooseRegisterBinding VimState -> Bool
statePredicate = (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
"\"" VimState
s | VimState -> Bool
statePredicate VimState
s = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
PartialMatch
f [Char
'"', Char
c] VimState
s | VimState -> Bool
statePredicate VimState
s = 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) -> EditorM ())
-> (VimState -> VimState) -> EditorM ()
forall a b. (a -> b) -> a -> b
$ \VimState
s' -> VimState
s' { vsActiveRegister :: Char
vsActiveRegister = Char
c }
RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Continue
f String
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch
indentBlockRegionB :: Int -> Region -> BufferM ()
indentBlockRegionB :: Int -> Region -> BufferM ()
indentBlockRegionB Int
count Region
reg = do
IndentSettings
indentSettings <- BufferM IndentSettings
indentSettingsB
(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
1..] [Int]
lengths) (((Int, Int) -> BufferM ()) -> BufferM ())
-> ((Int, Int) -> BufferM ()) -> BufferM ()
forall a b. (a -> b) -> a -> b
$ \(Int
i, Int
_) -> do
BufferM Bool -> BufferM () -> BufferM ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (Bool -> Bool
not (Bool -> Bool) -> BufferM Bool -> BufferM Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BufferM Bool
atEol) (BufferM () -> BufferM ()) -> BufferM () -> BufferM ()
forall a b. (a -> b) -> a -> b
$ do
let w :: Int
w = IndentSettings -> Int
shiftWidth IndentSettings
indentSettings
if Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
then YiString -> BufferM ()
insertN (YiString -> BufferM ()) -> YiString -> BufferM ()
forall a b. (a -> b) -> a -> b
$ Int -> Char -> YiString
R.replicateChar (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
w) Char
' '
else Int -> BufferM ()
forall t. (Eq t, Num t) => t -> BufferM ()
go (Int -> Int
forall a. Num a => a -> a
abs Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
w)
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
Point -> BufferM ()
moveTo Point
start
where
go :: t -> BufferM ()
go t
0 = () -> BufferM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
go t
n = do
Char
c <- BufferM Char
readB
Bool -> BufferM () -> BufferM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') (BufferM () -> BufferM ()) -> BufferM () -> BufferM ()
forall a b. (a -> b) -> a -> b
$
Int -> BufferM ()
deleteN Int
1 BufferM () -> BufferM () -> BufferM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> t -> BufferM ()
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1)
pasteInclusiveB :: YiString -> RegionStyle -> BufferM ()
pasteInclusiveB :: YiString -> RegionStyle -> BufferM ()
pasteInclusiveB YiString
rope RegionStyle
style = do
Point
p0 <- BufferM Point
pointB
YiString -> RegionStyle -> BufferM ()
insertRopeWithStyleB YiString
rope RegionStyle
style
if YiString -> Int
countNewLines YiString
rope Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& RegionStyle
style RegionStyle -> [RegionStyle] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ RegionStyle
Exclusive, RegionStyle
Inclusive ]
then BufferM ()
leftB
else Point -> BufferM ()
moveTo Point
p0
trailingNewline :: YiString -> Bool
trailingNewline :: YiString -> Bool
trailingNewline YiString
t = case YiString -> Maybe Char
Yi.Rope.last YiString
t of
Just Char
'\n' -> Bool
True
Maybe Char
_ -> Bool
False
addNewLineIfNecessary :: YiString -> YiString
addNewLineIfNecessary :: YiString -> YiString
addNewLineIfNecessary YiString
rope =
if YiString -> Bool
trailingNewline YiString
rope then YiString
rope else YiString
rope YiString -> Char -> YiString
`R.snoc` Char
'\n'
pasteFromClipboard :: YiM ()
pasteFromClipboard :: YiM ()
pasteFromClipboard = do
YiString
text <- (String -> YiString) -> YiM String -> YiM YiString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> YiString
R.fromString (YiM String -> YiM YiString) -> YiM String -> YiM YiString
forall a b. (a -> b) -> a -> b
$ IO String -> YiM String
forall (m :: * -> *) a. MonadBase IO m => IO a -> m a
io IO String
getClipboard
BufferM () -> YiM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> YiM ()) -> BufferM () -> YiM ()
forall a b. (a -> b) -> a -> b
$ YiString -> RegionStyle -> BufferM ()
insertRopeWithStyleB YiString
text RegionStyle
Inclusive
exportRegisterToClipboard :: RegisterName -> YiM ()
exportRegisterToClipboard :: Char -> YiM ()
exportRegisterToClipboard Char
name = do
Maybe Register
mbr <- EditorM (Maybe Register) -> YiM (Maybe Register)
forall (m :: * -> *) a. MonadEditor m => EditorM a -> m a
withEditor (EditorM (Maybe Register) -> YiM (Maybe Register))
-> EditorM (Maybe Register) -> YiM (Maybe Register)
forall a b. (a -> b) -> a -> b
$ Char -> EditorM (Maybe Register)
getRegisterE Char
name
IO () -> YiM ()
forall (m :: * -> *) a. MonadBase IO m => IO a -> m a
io (IO () -> YiM ()) -> (String -> IO ()) -> String -> YiM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
setClipboard (String -> YiM ()) -> String -> YiM ()
forall a b. (a -> b) -> a -> b
$ String -> (Register -> String) -> Maybe Register -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" (YiString -> String
R.toString (YiString -> String)
-> (Register -> YiString) -> Register -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Register -> YiString
regContent) Maybe Register
mbr