module Yi.Keymap.Vim.Common
( VimMode(..)
, VimBinding(..)
, GotoCharCommand(..)
, VimState(..)
, Register(..)
, RepeatToken(..)
, RepeatableAction(..)
, MatchResult(..)
, EventString(..), unEv
, OperatorName(..), unOp
, RegisterName
, Substitution(..)
, module Yi.Keymap.Vim.MatchResult
, lookupBestMatch, matchesString
) where
import GHC.Generics (Generic)
import Control.Applicative (Alternative ((<|>)))
import Lens.Micro.Platform (makeLenses)
import Data.Binary (Binary (..))
import Data.Default (Default (..))
import qualified Data.HashMap.Strict as HM (HashMap)
import Data.Monoid ((<>))
import Data.String (IsString (..))
import qualified Data.Text as T (Text, isPrefixOf, pack)
import qualified Data.Text.Encoding as E (decodeUtf8, encodeUtf8)
import Data.Typeable (Typeable)
import Yi.Buffer (Direction, Point, RegionStyle)
import Yi.Editor (EditorM)
import Yi.Keymap (YiM)
import Yi.Keymap.Vim.MatchResult (MatchResult (..))
import Yi.Rope (YiString)
import Yi.Types (YiVariable)
newtype EventString = Ev { _unEv :: T.Text } deriving (Show, Eq, Ord)
instance IsString EventString where
fromString = Ev . T.pack
newtype OperatorName = Op { _unOp :: T.Text } deriving (Show, Eq)
instance IsString OperatorName where
fromString = Op . T.pack
instance Monoid EventString where
mempty = Ev mempty
Ev t `mappend` Ev t' = Ev $ t <> t'
instance Monoid OperatorName where
mempty = Op mempty
Op t `mappend` Op t' = Op $ t <> t'
instance Binary EventString where
get = Ev . E.decodeUtf8 <$> get
put (Ev t) = put $ E.encodeUtf8 t
instance Binary OperatorName where
get = Op . E.decodeUtf8 <$> get
put (Op t) = put $ E.encodeUtf8 t
makeLenses ''EventString
makeLenses ''OperatorName
lookupBestMatch :: EventString -> [(EventString, a)] -> MatchResult a
lookupBestMatch key = foldl go NoMatch
where go m (k, x) = m <|> fmap (const x) (key `matchesString` k)
matchesString :: EventString -> EventString -> MatchResult ()
matchesString (Ev got) (Ev expected)
| expected == got = WholeMatch ()
| got `T.isPrefixOf` expected = PartialMatch
| otherwise = NoMatch
type RegisterName = Char
type MacroName = Char
data RepeatableAction = RepeatableAction
{ raPreviousCount :: !Int
, raActionString :: !EventString
} deriving (Typeable, Eq, Show, Generic)
data Register = Register
{ regRegionStyle :: RegionStyle
, regContent :: YiString
} deriving (Show, Generic)
data VimMode
= Normal
| NormalOperatorPending OperatorName
| Insert Char
| Replace
| ReplaceSingleChar
| InsertNormal
| InsertVisual
| Visual RegionStyle
| Ex
| Search { previousMode :: VimMode, direction :: Direction }
deriving (Typeable, Eq, Show, Generic)
data GotoCharCommand = GotoCharCommand !Char !Direction !RegionStyle
deriving (Generic)
data VimState = VimState
{ vsMode :: !VimMode
, vsCount :: !(Maybe Int)
, vsAccumulator :: !EventString
, vsTextObjectAccumulator :: !EventString
, vsRegisterMap :: !(HM.HashMap RegisterName Register)
, vsActiveRegister :: !RegisterName
, vsRepeatableAction :: !(Maybe RepeatableAction)
, vsStringToEval :: !EventString
, vsOngoingInsertEvents :: !EventString
, vsLastGotoCharCommand :: !(Maybe GotoCharCommand)
, vsBindingAccumulator :: !EventString
, vsSecondaryCursors :: ![Point]
, vsPaste :: !Bool
, vsCurrentMacroRecording :: !(Maybe (MacroName, EventString))
, vsLastSubstitution :: !(Maybe Substitution)
} deriving (Typeable, Generic)
instance Binary RepeatableAction
instance Binary Register
instance Binary GotoCharCommand
instance Default VimMode where
def = Normal
instance Binary VimMode
instance Default VimState where
def = VimState
Normal
Nothing
mempty
mempty
mempty
'\0'
Nothing
mempty
mempty
Nothing
mempty
mempty
False
Nothing
Nothing
instance Binary VimState
instance YiVariable VimState
data RepeatToken = Finish
| Drop
| Continue
deriving Show
data VimBinding
= VimBindingY (EventString -> VimState -> MatchResult (YiM RepeatToken))
| VimBindingE (EventString -> VimState -> MatchResult (EditorM RepeatToken))
data Substitution = Substitution
{ subsFrom :: YiString
, subsTo :: YiString
, subsFlagGlobal :: !Bool
, subsFlagCaseInsensitive :: !Bool
, subsFlagConfirm :: !Bool
} deriving (Generic)
instance Binary Substitution