| Safe Haskell | Safe-Infered |
|---|
Yi.Hooks
Description
This module provides assistance in implementing "hooks" in Yi. This module provides no major new functionality -- only assistance in using YiConfigVariables more easily to implement hooks.
We consider a simple example. Suppose we have a function
promptForFile :: Maybe FilePath -> YiM FilePath
which prompts the user to select a file from their file system, starting with the provided directory (if actually provided).
Since this is a frequent task in Yi, it is important for it to be as user-friendly as possible. If opinions vary on the
meaning of "user-friendly", then we would really like to provide multiple implementations of promptForFile, and allow
users to select which implementation to use in their config files.
A way to achieve this is using hooks, as follows:
-- create a new type
newtype FilePrompter = FilePrompter { runFilePrompter :: Maybe FilePath -> YiM FilePath }
deriving(Typeable)
$(nameDeriveAccessors ''FilePrompter (n -> Just (n ++ "A")))
-- give some implementations
filePrompter1, filePrompter2, filePrompter3 :: FilePrompter
...
-- declare FilePrompter as a YiConfigVariable (so it can go in the Config)
instance YiConfigVariable FilePrompter
-- specify the default FilePrompter
instance Initializable FilePrompter where
initial = filePrompter1
-- replace the old promptForFile function with a shim
promptForFile :: Maybe FilePath -> YiM FilePath
promptForFile = runHook runFilePrompter
-- provide a custom-named Field for Yi.Config.Simple (not strictly necessary, but user-friendly)
filePrompter :: Field FilePrompter
filePrompter = customVariable
The user can write
...
filePrompter %= filePrompter2
...
in their config file, and calls to promptForFile will now use the different prompter. Library code which
called promptForFile does not need to be changed, but it gets the new filePrompter2 behaviour automatically.
See Yi.Eval for a real example of hooks.
- runHook :: (HookType ty, YiConfigVariable var) => (var -> ty) -> ty
- class HookType ty
- customVariable :: YiConfigVariable a => Field a
- type Field a = Accessor Config a
Convenience function runHook
runHook :: (HookType ty, YiConfigVariable var) => (var -> ty) -> tySource
Re-exports from Yi.Config.Simple
customVariable :: YiConfigVariable a => Field aSource
Accessor for any YiConfigVariable, to be used by modules defining
YiConfigVariables. Such modules should provide a custom-named field.
For instance, take the following hypothetical YiConfigVariable:
newtype UserName = UserName { unUserName :: String }
deriving(Typeable, Binary, Initializable)
instance YiConfigVariable UserName
$(nameDeriveAccessors ''UserName (n -> Just (n ++ "A")))
userName :: Field String
userName = unUserNameA . customVariableHere, the hypothetical library would provide the field userName to be used in preference to customVariable.