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.Adjusted
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 = [escBinding, actualReplaceBinding]
escBinding :: VimBinding
escBinding = mkBindingE ReplaceSingleChar Drop (spec KEsc, return (), resetCount . switchMode Normal)
actualReplaceBinding :: VimBinding
actualReplaceBinding = VimBindingE (f . T.unpack . _unEv)
where
f evs s | ReplaceSingleChar == vsMode s = WholeMatch $ do
currentState <- getEditorDyn
let count = fromMaybe 1 $ vsCount currentState
let replacer = case evs of
(c:[]) -> replaceCharB c
"<lt>" -> replaceCharB '<'
"<C-e>" -> replaceCharWithBelowB
"<C-y>" -> replaceCharWithAboveB
_ -> return ()
withCurrentBuffer $ do
here <- pointB
moveToEol
eol <- pointB
moveTo here
let effectiveCount = min count (fromSize $ eol ~- here)
when (effectiveCount > 0) $ do
replicateM_ effectiveCount $ replacer >> rightB
leftB
resetCountE
switchModeE Normal
return Finish
f _ _ = NoMatch