yi-0.7.0: src/library/Yi/Keymap/Vim2/StateUtils.hs
module Yi.Keymap.Vim2.StateUtils
( switchMode
, switchModeE
, resetCount
, resetCountE
, setCountE
, modifyStateE
, getMaybeCountE
, getCountE
, accumulateEventE
, accumulateBindingEventE
, accumulateTextObjectEventE
, flushAccumulatorIntoRepeatableActionE
, dropAccumulatorE
, dropBindingAccumulatorE
, dropTextObjectAccumulatorE
, setRegisterE
, getRegisterE
, normalizeCountE
, setStickyEolE
, maybeMult
, updateModeIndicatorE
, saveInsertEventStringE
) where
import Yi.Prelude
import Prelude ()
import qualified Data.HashMap.Strict as HM
import Data.Maybe (fromMaybe)
import qualified Data.Rope as R
import Yi.Buffer.Normal
import Yi.Editor
import Yi.Event
import Yi.Keymap.Vim2.Common
import Yi.Keymap.Vim2.EventUtils
import Yi.Style (defaultStyle)
switchMode :: VimMode -> VimState -> VimState
switchMode mode state = state { vsMode = mode }
switchModeE :: VimMode -> EditorM ()
switchModeE mode = modifyStateE $ switchMode mode
modifyStateE :: (VimState -> VimState) -> EditorM ()
modifyStateE f = do
currentState <- getDynamic
setDynamic $ f currentState
resetCount :: VimState -> VimState
resetCount s = s { vsCount = Nothing }
resetCountE :: EditorM ()
resetCountE = modifyStateE resetCount
getMaybeCountE :: EditorM (Maybe Int)
getMaybeCountE = fmap vsCount getDynamic
getCountE :: EditorM Int
getCountE = do
currentState <- getDynamic
return $! fromMaybe 1 (vsCount currentState)
setCountE :: Int -> EditorM ()
setCountE n = modifyStateE $ \s -> s { vsCount = Just n }
accumulateBindingEventE :: Event -> EditorM ()
accumulateBindingEventE e = modifyStateE $
\s -> s { vsBindingAccumulator = vsBindingAccumulator s ++ eventToString e }
accumulateEventE :: Event -> EditorM ()
accumulateEventE e = modifyStateE $
\s -> s { vsAccumulator = vsAccumulator s ++ eventToString e }
accumulateTextObjectEventE :: EventString -> EditorM ()
accumulateTextObjectEventE evs = modifyStateE $
\s -> s { vsTextObjectAccumulator = vsTextObjectAccumulator s ++ evs }
flushAccumulatorIntoRepeatableActionE :: EditorM ()
flushAccumulatorIntoRepeatableActionE = do
currentState <- getDynamic
let repeatableAction = stringToRepeatableAction $ vsAccumulator currentState
modifyStateE $ \s -> s { vsRepeatableAction = Just repeatableAction
, vsAccumulator = []
}
dropAccumulatorE :: EditorM ()
dropAccumulatorE = modifyStateE $ \s -> s { vsAccumulator = [] }
dropBindingAccumulatorE :: EditorM ()
dropBindingAccumulatorE = modifyStateE $ \s -> s { vsBindingAccumulator = [] }
dropTextObjectAccumulatorE :: EditorM ()
dropTextObjectAccumulatorE = modifyStateE $ \s -> s { vsTextObjectAccumulator = [] }
getRegisterE :: RegisterName -> EditorM (Maybe Register)
getRegisterE name = fmap (HM.lookup name . vsRegisterMap) getDynamic
setRegisterE :: RegisterName -> RegionStyle -> R.Rope -> EditorM ()
setRegisterE name style rope = do
rmap <- fmap vsRegisterMap getDynamic
let rmap' = HM.insert name (Register style rope) rmap
modifyStateE $ \state -> state { vsRegisterMap = rmap' }
normalizeCountE :: Maybe Int -> EditorM ()
normalizeCountE n = do
mcount <- getMaybeCountE
modifyStateE $ \s -> s {
vsCount = maybeMult mcount n
, vsAccumulator = show (fromMaybe 1 (maybeMult mcount n))
++ snd (splitCountedCommand (normalizeCount (vsAccumulator s)))
}
maybeMult :: Num a => Maybe a -> Maybe a -> Maybe a
maybeMult (Just a) (Just b) = Just (a * b)
maybeMult Nothing Nothing = Nothing
maybeMult a Nothing = a
maybeMult Nothing b = b
setStickyEolE :: Bool -> EditorM ()
setStickyEolE b = modifyStateE $ \s -> s { vsStickyEol = b }
updateModeIndicatorE :: VimMode -> EditorM ()
updateModeIndicatorE prevMode = do
currentState <- getDynamic
let mode = vsMode currentState
paste = vsPaste currentState
when (mode /= prevMode) $ do
let modeName = case mode of
Insert _ -> "INSERT" ++ if paste then " (paste) " else ""
InsertNormal -> "(insert)"
InsertVisual -> "(insert) VISUAL"
Replace -> "REPLACE"
Visual Block -> "VISUAL BLOCK"
Visual LineWise -> "VISUAL LINE"
Visual _ -> "VISUAL"
_ -> ""
decoratedModeName = if null modeName then "" else "-- " ++ modeName ++ " --"
setStatus ([decoratedModeName], defaultStyle)
saveInsertEventStringE :: EventString -> EditorM ()
saveInsertEventStringE evs =
modifyStateE $ \s -> s { vsOngoingInsertEvents = vsOngoingInsertEvents s ++ evs }