module XMonad.Config.Alt.Internal (
module XMonad.Config.Alt.QQ,
runConfig,
runConfig',
set,
add,
modify,
modifyIO,
modifyIO',
insertInto,
LayoutHook(LayoutHook),
FocusFollowsMouse(FocusFollowsMouse),
StartupHook(StartupHook),
LogHook(LogHook),
BorderWidth(BorderWidth),
MouseBindings(MouseBindings),
Keys(Keys),
ModMask(ModMask),
Workspaces(Workspaces),
HandleEventHook(HandleEventHook),
ManageHook(ManageHook),
Terminal(Terminal),
FocusedBorderColor(FocusedBorderColor),
NormalBorderColor(NormalBorderColor),
defaultPrec,
insLt,
insGeq,
Ins2(..),
Ins'(..),
ins,
HCompose(hComp),
Snd(Snd),
HSubtract(hSubtract),
HReplicateF(hReplicateF),
HPred'(hPred'),
Mode(..),
Add(Add),
Set(Set),
Modify(Modify),
ModifyIO(ModifyIO),
Config(..),
test,
module Data.HList,
) where
import Control.Monad.Writer
import Data.Char
import Data.HList
import Language.Haskell.TH
import qualified XMonad as X
import XMonad.Config.Alt.Types
import XMonad.Config.Alt.QQ
class Mode action field e x y | action field e x -> y, action field x y -> e where
m :: action -> field -> e -> X.XConfig x -> Config (X.XConfig y)
data Add = Add
data Set = Set
data Modify = Modify
data ModifyIO = ModifyIO
$(decNat "defaultPrec" 4)
set f v = insertInto Set hFalse defaultPrec f v
add f v = insertInto Add hFalse defaultPrec f v
modify f v = insertInto Modify hFalse defaultPrec f v
modifyIO = modifyIO' hFalse defaultPrec
modifyIO' x = insertInto ModifyIO x
insertInto action hold prec f x = ins' prec hold (m action f x =<<)
data LayoutHook = LayoutHook
instance Mode ModifyIO LayoutHook (l X.Window -> Config (m X.Window)) l m where
m _ _ l c = do
l' <- l $ X.layoutHook c
return $ c { X.layoutHook = l' }
instance (X.LayoutClass l X.Window, X.LayoutClass l' X.Window) =>
Mode Add LayoutHook (l' X.Window) l (X.Choose l' l) where
m _ _ l = \x -> return $ x { X.layoutHook = l X.||| X.layoutHook x }
instance (Read (l X.Window), X.LayoutClass l X.Window,
Read (l' X.Window), X.LayoutClass l' X.Window) =>
Mode Modify LayoutHook (l X.Window -> l' X.Window) l l' where
m _ _ l = \x -> return $ x { X.layoutHook = l (X.layoutHook x) }
instance (X.LayoutClass l' X.Window) =>
Mode Set LayoutHook (l' X.Window) l l' where
m _ _ l = \x -> return $ x { X.layoutHook = l }
data Snd = Snd
instance Apply Snd (a, b) b where
apply _ (_, b) = b
class HCompose l f | l -> f where
hComp :: l -> f
instance HCompose HNil (a -> a) where
hComp _ = id
instance HCompose r (a -> b) => HCompose ((b -> c) :*: r) (a -> c) where
hComp (HCons g r) = g . hComp r
class HSubtract a b c | a b -> c where
hSubtract :: a -> b -> c
instance (HNat a, HNat b, HSubtract a b c) => HSubtract (HSucc a) (HSucc b) c where
hSubtract a b = hSubtract (hPred a) (hPred b)
instance HNat a => HSubtract a HZero a where
hSubtract a _ = a
instance HSubtract HZero b HZero where
hSubtract _ _ = hZero
class HNat n => HReplicateF n e l | n e -> l where
hReplicateF :: n -> e -> l
instance HReplicateF HZero e HNil where
hReplicateF _ _ = HNil
instance (Apply e x y, HReplicateF n e r) => HReplicateF (HSucc n) e ((HFalse, x -> y) :*: r) where
hReplicateF n e = (hFalse, apply e) `HCons` hReplicateF (hPred n) e
class HPred' n n' | n -> n' where
hPred' :: n -> n'
instance HPred' HZero HZero where
hPred' _ = hZero
instance HNat n => HPred' (HSucc n) n where
hPred' = hPred
insLt n hold f l =
l
`hAppend`
(hReplicateF ( n `hSubtract` hLength l) Id)
`hAppend`
((hold,f) `HCons` HNil)
insGeq n a f l =
let (b,g) = hLookupByHNat n l
h = hCond b (b,g) (a,f . g)
in hUpdateAtHNat n h l
class (HBool hold) => Ins2 b n hold f l l' | b n hold f l -> l' where
ins2 :: b -> n -> hold -> f -> l -> l'
instance
(
HLength l n,
HSubtract a1 n a,
HReplicateF a Id l',
HAppend l l' l'',
HAppend l'' (HCons (hold,e) HNil) l''1,
HBool hold) =>
Ins2 HTrue a1 hold e l l''1
where ins2 _ = insLt
instance
(HLookupByHNat n l (t, a -> b),
HUpdateAtHNat n z l l',
HCond t (t, a -> b) (t1, a -> c) z,
HBool t1) =>
Ins2 HFalse n t1 (b -> c) l l'
where ins2 _ = insGeq
class Ins' n hold f l l' | n hold f l -> l' where
ins' :: n -> hold -> f -> l -> l'
instance (HLength l ll, HLt ll n b, Ins2 b n hold f l l') => Ins' n hold f l l' where
ins' = ins2 (undefined :: b)
ins n e = ins' n hFalse (e =<<)
runConfig' defConfig x = do
let Config c = hComp (hMap Snd (hComp (hEnd x) HNil)) (return defConfig)
(a,w) <- runWriterT c
print (w [])
return a
runConfig x = X.xmonad =<< runConfig' X.defaultConfig x
data T1 a = T1 a deriving Show
data T2 a = T2 a deriving Show
data T3 a = T3 a deriving Show
data T3a a = T3a a deriving Show
data RunMWR = RunMWR
instance (Monad m, HCompose l (m () -> Writer w a)) => Apply RunMWR l (a, w) where
apply _ x = runWriter $ hComp x (return ())
data Print = Print
instance Show a => Apply Print a (IO ()) where
apply _ = print
data HHMap a = HHMap a
instance HMap f a b => Apply (HHMap f) a b where
apply (HHMap f) = hMap f
test :: IO ()
test = sequence_ $ hMapM Print $ hMap RunMWR $ hMap (HHMap Snd) $ hEnd $ hBuild
test1_
test2_
test3_
test3a_
where
test1_ = ins (undefined `asTypeOf` hSucc (hSucc (hSucc hZero))) (\x -> tell "3" >> return (T1 x)) hNil
test2_ = ins (hSucc hZero) (\x -> tell "1" >> return (T2 x)) test1_
test3_ = ins (hSucc (hSucc hZero)) (\x -> tell "2" >> return (T3 x)) test2_
test3a_ = ins (hSucc (hSucc hZero)) (\x -> tell "2" >> return (T3a x)) test3_
data Expected a
$(fmap concat $ sequence
[ do
let accessor = "X." ++ (case nameBase d of
x:xs -> toLower x:xs
_ -> [])
acc = mkName accessor
VarI _ (ForallT _ _ (_ `AppT` (return -> ty))) _ _ <- reify acc
l <- fmap varT $ newName "l"
let mkId action tyIn body = instanceD
(return [])
[t| $(conT ''Mode) $(conT action) $(conT d) $(tyIn) $l $l |]
[funD 'm
[clause
[wildP,wildP]
(normalB body
)
[]
]
]
`const` (action, tyIn)
let fallback act = instanceD
(sequence [classP ''Fail [[t| Expected $ty |]]])
[t| $(conT ''Mode) $act $(conT d) $(varT =<< newName "x") $l $l |]
[funD 'm [clause [] (normalB [| error "impossible to satisfy" |]) [] ]]
`const` act
sequence $
[fallback (conT n) | n <- [''ModifyIO, ''Modify, ''Set] ] ++
[dataD (return []) d [] [normalC d []] []
,mkId ''ModifyIO [t| $ty -> Config $ty |]
[| \f c -> do
r <- f ($(varE acc) c)
return $(recUpdE
[| c |]
[fmap (\r' -> (acc,r')) [| r |]])
|]
,mkId ''Modify [t| $ty -> $ty |]
[| \f c -> do
r <- return $ f ($(varE acc) c)
return $(recUpdE
[| c |]
[fmap (\r' -> (acc,r')) [| r |]])
|]
,mkId ''Set [t| $ty |]
[| \f c -> do
return $(recUpdE
[| c |]
[fmap ((,) acc) [| f |]])
|]
]
| d <- map mkName
["NormalBorderColor",
"FocusedBorderColor",
"Terminal",
"ManageHook",
"HandleEventHook",
"Workspaces",
"ModMask",
"Keys",
"MouseBindings",
"BorderWidth",
"LogHook",
"StartupHook",
"FocusFollowsMouse"]
]
)