{-# OPTIONS_HADDOCK show-extensions #-}
module Yi.Keymap.Vim.ReplaceSingleCharMap
( defReplaceSingleMap
) where
import Control.Monad (replicateM_, when)
import Data.Maybe (fromMaybe)
import qualified Data.Text as T (unpack)
import Yi.Buffer
import Yi.Editor (getEditorDyn, withCurrentBuffer)
import Yi.Keymap.Keys (Key (KEsc), spec)
import Yi.Keymap.Vim.Common
import Yi.Keymap.Vim.StateUtils (resetCount, resetCountE, switchMode, switchModeE)
import Yi.Keymap.Vim.Utils (mkBindingE)
import Yi.Utils (SemiNum ((~-)))
defReplaceSingleMap :: [VimBinding]
defReplaceSingleMap :: [VimBinding]
defReplaceSingleMap = [VimBinding
escBinding, VimBinding
actualReplaceBinding]
escBinding :: VimBinding
escBinding :: VimBinding
escBinding = VimMode
-> RepeatToken
-> (Event, EditorM (), VimState -> VimState)
-> VimBinding
mkBindingE VimMode
ReplaceSingleChar RepeatToken
Drop (Key -> Event
spec Key
KEsc, () -> EditorM ()
forall (m :: * -> *) a. Monad m => a -> m a
return (), VimState -> VimState
resetCount (VimState -> VimState)
-> (VimState -> VimState) -> VimState -> VimState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VimMode -> VimState -> VimState
switchMode VimMode
Normal)
actualReplaceBinding :: VimBinding
actualReplaceBinding :: VimBinding
actualReplaceBinding = (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
s | VimMode
ReplaceSingleChar VimMode -> VimMode -> Bool
forall a. Eq a => a -> a -> Bool
== VimState -> VimMode
vsMode 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
currentState <- EditorM VimState
forall (m :: * -> *) a.
(MonadEditor m, YiVariable a, Default a, Functor m) =>
m a
getEditorDyn
let count :: Int
count = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ VimState -> Maybe Int
vsCount VimState
currentState
let replacer :: BufferM ()
replacer = case [Char]
evs of
(c:[]) -> Char -> BufferM ()
replaceCharB Char
c
[Char]
"<lt>" -> Char -> BufferM ()
replaceCharB Char
'<'
[Char]
"<C-e>" -> BufferM ()
replaceCharWithBelowB
[Char]
"<C-y>" -> BufferM ()
replaceCharWithAboveB
[Char]
_ -> () -> BufferM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
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
BufferM ()
moveToEol
Point
eol <- BufferM Point
pointB
Point -> BufferM ()
moveTo Point
here
let effectiveCount :: Int
effectiveCount = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
count (Size -> Int
fromSize (Size -> Int) -> Size -> Int
forall a b. (a -> b) -> a -> b
$ Point
eol Point -> Point -> Size
forall absolute relative.
SemiNum absolute relative =>
absolute -> absolute -> relative
~- Point
here)
Bool -> BufferM () -> BufferM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
effectiveCount Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (BufferM () -> BufferM ()) -> BufferM () -> BufferM ()
forall a b. (a -> b) -> a -> b
$ do
Int -> BufferM () -> BufferM ()
forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ Int
effectiveCount (BufferM () -> BufferM ()) -> BufferM () -> BufferM ()
forall a b. (a -> b) -> a -> b
$ BufferM ()
replacer BufferM () -> BufferM () -> BufferM ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BufferM ()
rightB
BufferM ()
leftB
EditorM ()
resetCountE
VimMode -> EditorM ()
switchModeE VimMode
Normal
RepeatToken -> EditorM RepeatToken
forall (m :: * -> *) a. Monad m => a -> m a
return RepeatToken
Finish
f [Char]
_ VimState
_ = MatchResult (EditorM RepeatToken)
forall a. MatchResult a
NoMatch