1- {-# LANGUAGE PatternGuards #-}
1+ {-# LANGUAGE ScopedTypeVariables #-}
22-- Based on the one in xmonad-contrib, original header below
33-----------------------------------------------------------------------------
44-- |
@@ -24,24 +24,21 @@ module Haskell.Ide.Engine.ExtensibleState (
2424 , gets
2525 ) where
2626
27- import Control.Applicative
28- import Data.Typeable (typeOf ,Typeable ,cast )
29- import qualified Data.Map as M
30- import Haskell.Ide.Engine.PluginDescriptor
3127import qualified Control.Monad.State.Strict as State
32- import Data.Maybe (fromMaybe )
33- import Control.Monad
34- import Control.Monad.Trans.Class
28+ import Control.Monad.Trans.Class
29+ import Data.Dynamic
30+ import qualified Data.Map as M
31+ import Haskell.Ide.Engine.PluginDescriptor
3532
3633-- ---------------------------------------------------------------------
3734-- $usage
3835--
39- -- To utilize this feature in a contrib module , create a data type
36+ -- To utilize this feature in a plugin , create a data type
4037-- and make it an instance of ExtensionClass. You can then use
4138-- the functions from this module for storing and retrieving your data:
4239--
4340-- > {-# LANGUAGE DeriveDataTypeable #-}
44- -- > import qualified XMonad.Util .ExtensibleState as XS
41+ -- > import qualified Haskell.Ide.Engine .ExtensibleState as XS
4542-- >
4643-- > data ListStorage = ListStorage [Integer] deriving Typeable
4744-- > instance ExtensionClass ListStorage where
@@ -58,28 +55,19 @@ import Control.Monad.Trans.Class
5855--
5956-- > .. XS.get :: X ListStorage
6057--
61- -- To make your data persistent between restarts, the data type needs to be
62- -- an instance of Read and Show and the instance declaration has to be changed:
63- --
6458-- > data ListStorage = ListStorage [Integer] deriving (Typeable,Read,Show)
6559-- >
6660-- > instance ExtensionClass ListStorage where
6761-- > initialValue = ListStorage []
68- -- > extensionType = PersistentExtension
6962--
70- -- One should take care that the string representation of the chosen type
71- -- is unique among the stored values, otherwise it will be overwritten.
72- -- Normally these string representations contain fully qualified module names
73- -- when automatically deriving Typeable, so
74- -- name collisions should not be a problem in most cases.
7563-- A module should not try to store common datatypes(e.g. a list of Integers)
7664-- without a custom data type as a wrapper to avoid collisions with other modules
7765-- trying to store the same data type without a wrapper.
7866--
7967
8068-- | Modify the map of state extensions by applying the given function.
81- modifyStateExts :: (M. Map String ( Either String StateExtension )
82- -> M. Map String ( Either String StateExtension ) )
69+ modifyStateExts :: (M. Map TypeRep Dynamic
70+ -> M. Map TypeRep Dynamic )
8371 -> IdeM ()
8472modifyStateExts f = lift $ lift $ State. modify $ \ st -> st { extensibleState = f (extensibleState st) }
8573
@@ -92,30 +80,22 @@ modify f = put . f =<< get
9280-- type will be overwritten. (More precisely: A value whose string representation of its type
9381-- is equal to the new one's)
9482put :: ExtensionClass a => a -> IdeM ()
95- put v = modifyStateExts . M. insert (show . typeOf $ v) . Right . extensionType $ v
83+ put v = modifyStateExts . M. insert (typeOf $ v) . toDyn $ v
9684
9785-- | Try to retrieve a value of the requested type, return an initial value if there is no such value.
98- get :: ExtensionClass a => IdeM a
99- get = getState' undefined -- `trick' to avoid needing -XScopedTypeVariables
100- where toValue val = maybe initialValue id $ cast val
101- getState' :: ExtensionClass a => a -> IdeM a
102- getState' k = do
103- v <- lift $ lift $ State. gets $ M. lookup (show . typeOf $ k) . extensibleState
104- case v of
105- Just (Right (StateExtension val)) -> return $ toValue val
106- Just (Right (PersistentExtension val)) -> return $ toValue val
107- Just (Left str) | PersistentExtension x <- extensionType k -> do
108- let val = fromMaybe initialValue $ cast =<< safeRead str `asTypeOf` Just x
109- put (val `asTypeOf` k)
110- return val
111- _ -> return $ initialValue
112- safeRead str = case reads str of
113- [(x," " )] -> Just x
114- _ -> Nothing
86+ get :: forall a . ExtensionClass a => IdeM a
87+ get =
88+ do v <-
89+ lift $
90+ lift $
91+ State. gets $ M. lookup (typeRep $ (Proxy :: Proxy a )) . extensibleState
92+ case v of
93+ Just dyn -> return $ fromDyn dyn initialValue
94+ _ -> return initialValue
11595
11696gets :: ExtensionClass a => (a -> b ) -> IdeM b
11797gets = flip fmap get
11898
11999-- | Remove the value from the extensible state field that has the same type as the supplied argument
120- remove :: ExtensionClass a => a -> IdeM ()
121- remove wit = modifyStateExts $ M. delete (show . typeOf $ wit)
100+ remove :: ExtensionClass a => proxy a -> IdeM ()
101+ remove wit = modifyStateExts $ M. delete (typeRep $ wit)
0 commit comments