{-# LANGUAGE CPP #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ScopedTypeVariables #-}
module XMonad.Util.EZConfig (
additionalKeys, additionalKeysP,
remapKeysP,
removeKeys, removeKeysP,
additionalMouseBindings, removeMouseBindings,
mkKeymap, checkKeymap,
mkNamedKeymap,
parseKey,
parseKeyCombo,
parseKeySequence, readKeySequence,
#ifdef TESTING
parseModifier,
#endif
) where
import XMonad
import XMonad.Actions.Submap
import XMonad.Prelude
import XMonad.Util.NamedActions
import XMonad.Util.Parser
import Control.Arrow (first, (&&&))
import qualified Data.List.NonEmpty as NE
import qualified Data.Map as M
import Data.Ord (comparing)
import Data.List.NonEmpty (nonEmpty)
additionalKeys :: XConfig a -> [((KeyMask, KeySym), X ())] -> XConfig a
additionalKeys :: forall (a :: * -> *).
XConfig a -> [((KeyMask, KeySym), X ())] -> XConfig a
additionalKeys XConfig a
conf [((KeyMask, KeySym), X ())]
keyList =
XConfig a
conf { keys = M.union (M.fromList keyList) . keys conf }
infixl 4 `additionalKeys`
additionalKeysP :: XConfig l -> [(String, X ())] -> XConfig l
additionalKeysP :: forall (l :: * -> *). XConfig l -> [(String, X ())] -> XConfig l
additionalKeysP XConfig l
conf [(String, X ())]
keyList =
XConfig l
conf { keys = \XConfig Layout
cnf -> Map (KeyMask, KeySym) (X ())
-> Map (KeyMask, KeySym) (X ()) -> Map (KeyMask, KeySym) (X ())
forall k a. Ord k => Map k a -> Map k a -> Map k a
M.union (XConfig Layout -> [(String, X ())] -> Map (KeyMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> [(String, X ())] -> Map (KeyMask, KeySym) (X ())
mkKeymap XConfig Layout
cnf [(String, X ())]
keyList) (XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
keys XConfig l
conf XConfig Layout
cnf) }
infixl 4 `additionalKeysP`
remapKeysP :: XConfig l -> [(String, String)] -> XConfig l
remapKeysP :: forall (l :: * -> *). XConfig l -> [(String, String)] -> XConfig l
remapKeysP XConfig l
conf [(String, String)]
keyList =
XConfig l
conf { keys = \XConfig Layout
cnf -> XConfig Layout -> [(String, X ())] -> Map (KeyMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> [(String, X ())] -> Map (KeyMask, KeySym) (X ())
mkKeymap XConfig Layout
cnf (XConfig Layout -> [(String, X ())]
keyList' XConfig Layout
cnf) Map (KeyMask, KeySym) (X ())
-> Map (KeyMask, KeySym) (X ()) -> Map (KeyMask, KeySym) (X ())
forall a. Semigroup a => a -> a -> a
<> XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
keys XConfig l
conf XConfig Layout
cnf }
where
keyList' :: XConfig Layout -> [(String, X ())]
keyList' :: XConfig Layout -> [(String, X ())]
keyList' XConfig Layout
cnf =
((String, String) -> Maybe (String, X ()))
-> [(String, String)] -> [(String, X ())]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((String -> Maybe (X ()))
-> (String, String) -> Maybe (String, X ())
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> (String, a) -> f (String, b)
traverse (\String
s -> case XConfig Layout -> String -> Maybe (NonEmpty (KeyMask, KeySym))
forall (l :: * -> *).
XConfig l -> String -> Maybe (NonEmpty (KeyMask, KeySym))
readKeySequence XConfig Layout
cnf String
s of
Just ((KeyMask, KeySym)
ks :| []) -> XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
keys XConfig l
conf XConfig Layout
cnf Map (KeyMask, KeySym) (X ()) -> (KeyMask, KeySym) -> Maybe (X ())
forall k a. Ord k => Map k a -> k -> Maybe a
M.!? (KeyMask, KeySym)
ks
Maybe (NonEmpty (KeyMask, KeySym))
_ -> Maybe (X ())
forall a. Maybe a
Nothing))
[(String, String)]
keyList
infixl 4 `remapKeysP`
removeKeys :: XConfig a -> [(KeyMask, KeySym)] -> XConfig a
removeKeys :: forall (a :: * -> *). XConfig a -> [(KeyMask, KeySym)] -> XConfig a
removeKeys XConfig a
conf [(KeyMask, KeySym)]
keyList =
XConfig a
conf { keys = \XConfig Layout
cnf -> ((KeyMask, KeySym)
-> Map (KeyMask, KeySym) (X ()) -> Map (KeyMask, KeySym) (X ()))
-> Map (KeyMask, KeySym) (X ())
-> [(KeyMask, KeySym)]
-> Map (KeyMask, KeySym) (X ())
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (KeyMask, KeySym)
-> Map (KeyMask, KeySym) (X ()) -> Map (KeyMask, KeySym) (X ())
forall k a. Ord k => k -> Map k a -> Map k a
M.delete (XConfig a -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
keys XConfig a
conf XConfig Layout
cnf) [(KeyMask, KeySym)]
keyList }
infixl 4 `removeKeys`
removeKeysP :: XConfig l -> [String] -> XConfig l
removeKeysP :: forall (l :: * -> *). XConfig l -> [String] -> XConfig l
removeKeysP XConfig l
conf [String]
keyList =
XConfig l
conf { keys = \XConfig Layout
cnf -> XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> XConfig Layout -> Map (KeyMask, KeySym) (X ())
keys XConfig l
conf XConfig Layout
cnf Map (KeyMask, KeySym) (X ())
-> Map (KeyMask, KeySym) (X ()) -> Map (KeyMask, KeySym) (X ())
forall k a b. Ord k => Map k a -> Map k b -> Map k a
`M.difference` XConfig Layout -> [(String, X ())] -> Map (KeyMask, KeySym) (X ())
forall (l :: * -> *).
XConfig l -> [(String, X ())] -> Map (KeyMask, KeySym) (X ())
mkKeymap XConfig Layout
cnf ((String -> (String, X ())) -> [String] -> [(String, X ())]
forall a b. (a -> b) -> [a] -> [b]
map (, () -> X ()
forall a. a -> X a
forall (m :: * -> *) a. Monad m => a -> m a
return ()) [String]
keyList) }
infixl 4 `removeKeysP`
additionalMouseBindings :: XConfig a -> [((ButtonMask, Button), Window -> X ())] -> XConfig a
additionalMouseBindings :: forall (a :: * -> *).
XConfig a -> [((KeyMask, Button), KeySym -> X ())] -> XConfig a
additionalMouseBindings XConfig a
conf [((KeyMask, Button), KeySym -> X ())]
mouseBindingsList =
XConfig a
conf { mouseBindings = M.union (M.fromList mouseBindingsList) . mouseBindings conf }
infixl 4 `additionalMouseBindings`
removeMouseBindings :: XConfig a -> [(ButtonMask, Button)] -> XConfig a
removeMouseBindings :: forall (a :: * -> *). XConfig a -> [(KeyMask, Button)] -> XConfig a
removeMouseBindings XConfig a
conf [(KeyMask, Button)]
mouseBindingList =
XConfig a
conf { mouseBindings = \XConfig Layout
cnf -> ((KeyMask, Button)
-> Map (KeyMask, Button) (KeySym -> X ())
-> Map (KeyMask, Button) (KeySym -> X ()))
-> Map (KeyMask, Button) (KeySym -> X ())
-> [(KeyMask, Button)]
-> Map (KeyMask, Button) (KeySym -> X ())
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (KeyMask, Button)
-> Map (KeyMask, Button) (KeySym -> X ())
-> Map (KeyMask, Button) (KeySym -> X ())
forall k a. Ord k => k -> Map k a -> Map k a
M.delete (XConfig a
-> XConfig Layout -> Map (KeyMask, Button) (KeySym -> X ())
forall (l :: * -> *).
XConfig l
-> XConfig Layout -> Map (KeyMask, Button) (KeySym -> X ())
mouseBindings XConfig a
conf XConfig Layout
cnf) [(KeyMask, Button)]
mouseBindingList }
infixl 4 `removeMouseBindings`
mkKeymap :: XConfig l -> [(String, X ())] -> M.Map (KeyMask, KeySym) (X ())
mkKeymap :: forall (l :: * -> *).
XConfig l -> [(String, X ())] -> Map (KeyMask, KeySym) (X ())
mkKeymap XConfig l
c = [((KeyMask, KeySym), X ())] -> Map (KeyMask, KeySym) (X ())
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([((KeyMask, KeySym), X ())] -> Map (KeyMask, KeySym) (X ()))
-> ([(String, X ())] -> [((KeyMask, KeySym), X ())])
-> [(String, X ())]
-> Map (KeyMask, KeySym) (X ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(NonEmpty (KeyMask, KeySym), X ())] -> [((KeyMask, KeySym), X ())]
mkSubmaps ([(NonEmpty (KeyMask, KeySym), X ())]
-> [((KeyMask, KeySym), X ())])
-> ([(String, X ())] -> [(NonEmpty (KeyMask, KeySym), X ())])
-> [(String, X ())]
-> [((KeyMask, KeySym), X ())]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XConfig l
-> [(String, X ())] -> [(NonEmpty (KeyMask, KeySym), X ())]
forall (l :: * -> *) t.
XConfig l -> [(String, t)] -> [(NonEmpty (KeyMask, KeySym), t)]
readKeymap XConfig l
c
mkNamedKeymap :: XConfig l -> [(String, NamedAction)] -> [((KeyMask, KeySym), NamedAction)]
mkNamedKeymap :: forall (l :: * -> *).
XConfig l
-> [(String, NamedAction)] -> [((KeyMask, KeySym), NamedAction)]
mkNamedKeymap XConfig l
c = [(NonEmpty (KeyMask, KeySym), NamedAction)]
-> [((KeyMask, KeySym), NamedAction)]
mkNamedSubmaps ([(NonEmpty (KeyMask, KeySym), NamedAction)]
-> [((KeyMask, KeySym), NamedAction)])
-> ([(String, NamedAction)]
-> [(NonEmpty (KeyMask, KeySym), NamedAction)])
-> [(String, NamedAction)]
-> [((KeyMask, KeySym), NamedAction)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XConfig l
-> [(String, NamedAction)]
-> [(NonEmpty (KeyMask, KeySym), NamedAction)]
forall (l :: * -> *) t.
XConfig l -> [(String, t)] -> [(NonEmpty (KeyMask, KeySym), t)]
readKeymap XConfig l
c
mkNamedSubmaps :: [(NonEmpty (KeyMask, KeySym), NamedAction)] -> [((KeyMask, KeySym), NamedAction)]
mkNamedSubmaps :: [(NonEmpty (KeyMask, KeySym), NamedAction)]
-> [((KeyMask, KeySym), NamedAction)]
mkNamedSubmaps = ([((KeyMask, KeySym), NamedAction)] -> NamedAction)
-> [(NonEmpty (KeyMask, KeySym), NamedAction)]
-> [((KeyMask, KeySym), NamedAction)]
forall a b.
Ord a =>
([(a, b)] -> b) -> [(NonEmpty a, b)] -> [(a, b)]
mkSubmaps' [((KeyMask, KeySym), NamedAction)] -> NamedAction
forall a. HasName a => [((KeyMask, KeySym), a)] -> NamedAction
submapName
mkSubmaps :: [ (NonEmpty (KeyMask, KeySym), X ()) ] -> [((KeyMask, KeySym), X ())]
mkSubmaps :: [(NonEmpty (KeyMask, KeySym), X ())] -> [((KeyMask, KeySym), X ())]
mkSubmaps = ([((KeyMask, KeySym), X ())] -> X ())
-> [(NonEmpty (KeyMask, KeySym), X ())]
-> [((KeyMask, KeySym), X ())]
forall a b.
Ord a =>
([(a, b)] -> b) -> [(NonEmpty a, b)] -> [(a, b)]
mkSubmaps' (([((KeyMask, KeySym), X ())] -> X ())
-> [(NonEmpty (KeyMask, KeySym), X ())]
-> [((KeyMask, KeySym), X ())])
-> ([((KeyMask, KeySym), X ())] -> X ())
-> [(NonEmpty (KeyMask, KeySym), X ())]
-> [((KeyMask, KeySym), X ())]
forall a b. (a -> b) -> a -> b
$ Map (KeyMask, KeySym) (X ()) -> X ()
submap (Map (KeyMask, KeySym) (X ()) -> X ())
-> ([((KeyMask, KeySym), X ())] -> Map (KeyMask, KeySym) (X ()))
-> [((KeyMask, KeySym), X ())]
-> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [((KeyMask, KeySym), X ())] -> Map (KeyMask, KeySym) (X ())
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
mkSubmaps' :: forall a b. (Ord a) => ([(a, b)] -> b) -> [(NonEmpty a, b)] -> [(a, b)]
mkSubmaps' :: forall a b.
Ord a =>
([(a, b)] -> b) -> [(NonEmpty a, b)] -> [(a, b)]
mkSubmaps' [(a, b)] -> b
subm [(NonEmpty a, b)]
binds = ([(NonEmpty a, b)] -> (a, b)) -> [[(NonEmpty a, b)]] -> [(a, b)]
forall a b. (a -> b) -> [a] -> [b]
map [(NonEmpty a, b)] -> (a, b)
combine [[(NonEmpty a, b)]]
gathered
where
gathered :: [[(NonEmpty a, b)]]
gathered :: [[(NonEmpty a, b)]]
gathered = ((NonEmpty a, b) -> (NonEmpty a, b) -> Bool)
-> [(NonEmpty a, b)] -> [[(NonEmpty a, b)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (NonEmpty a, b) -> (NonEmpty a, b) -> Bool
fstKey ([(NonEmpty a, b)] -> [[(NonEmpty a, b)]])
-> ([(NonEmpty a, b)] -> [(NonEmpty a, b)])
-> [(NonEmpty a, b)]
-> [[(NonEmpty a, b)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((NonEmpty a, b) -> (NonEmpty a, b) -> Ordering)
-> [(NonEmpty a, b)] -> [(NonEmpty a, b)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((NonEmpty a, b) -> NonEmpty a)
-> (NonEmpty a, b) -> (NonEmpty a, b) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (NonEmpty a, b) -> NonEmpty a
forall a b. (a, b) -> a
fst) ([(NonEmpty a, b)] -> [[(NonEmpty a, b)]])
-> [(NonEmpty a, b)] -> [[(NonEmpty a, b)]]
forall a b. (a -> b) -> a -> b
$ [(NonEmpty a, b)]
binds
combine :: [(NonEmpty a, b)] -> (a, b)
combine :: [(NonEmpty a, b)] -> (a, b)
combine [(a
k :| [], b
act)] = (a
k, b
act)
combine [(NonEmpty a, b)]
ks = ( NonEmpty a -> a
forall a. NonEmpty a -> a
NE.head (NonEmpty a -> a)
-> ([(NonEmpty a, b)] -> NonEmpty a) -> [(NonEmpty a, b)] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty a, b) -> NonEmpty a
forall a b. (a, b) -> a
fst ((NonEmpty a, b) -> NonEmpty a)
-> ([(NonEmpty a, b)] -> (NonEmpty a, b))
-> [(NonEmpty a, b)]
-> NonEmpty a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (NonEmpty a, b) -> (NonEmpty a, b)
forall a. NonEmpty a -> a
NE.head (NonEmpty (NonEmpty a, b) -> (NonEmpty a, b))
-> ([(NonEmpty a, b)] -> NonEmpty (NonEmpty a, b))
-> [(NonEmpty a, b)]
-> (NonEmpty a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(NonEmpty a, b)] -> NonEmpty (NonEmpty a, b)
forall a. HasCallStack => [a] -> NonEmpty a
notEmpty ([(NonEmpty a, b)] -> a) -> [(NonEmpty a, b)] -> a
forall a b. (a -> b) -> a -> b
$ [(NonEmpty a, b)]
ks
, [(a, b)] -> b
subm ([(a, b)] -> b)
-> ([(NonEmpty a, b)] -> [(a, b)]) -> [(NonEmpty a, b)] -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(a, b)] -> b) -> [(NonEmpty a, b)] -> [(a, b)]
forall a b.
Ord a =>
([(a, b)] -> b) -> [(NonEmpty a, b)] -> [(a, b)]
mkSubmaps' [(a, b)] -> b
subm ([(NonEmpty a, b)] -> b) -> [(NonEmpty a, b)] -> b
forall a b. (a -> b) -> a -> b
$ ((NonEmpty a, b) -> (NonEmpty a, b))
-> [(NonEmpty a, b)] -> [(NonEmpty a, b)]
forall a b. (a -> b) -> [a] -> [b]
map ((NonEmpty a -> NonEmpty a) -> (NonEmpty a, b) -> (NonEmpty a, b)
forall b c d. (b -> c) -> (b, d) -> (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first ([a] -> NonEmpty a
forall a. HasCallStack => [a] -> NonEmpty a
notEmpty ([a] -> NonEmpty a)
-> (NonEmpty a -> [a]) -> NonEmpty a -> NonEmpty a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> NonEmpty a -> [a]
forall a. Int -> NonEmpty a -> [a]
NE.drop Int
1)) [(NonEmpty a, b)]
ks
)
fstKey :: (NonEmpty a, b) -> (NonEmpty a, b) -> Bool
fstKey :: (NonEmpty a, b) -> (NonEmpty a, b) -> Bool
fstKey = a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==) (a -> a -> Bool)
-> ((NonEmpty a, b) -> a)
-> (NonEmpty a, b)
-> (NonEmpty a, b)
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (NonEmpty a -> a
forall a. NonEmpty a -> a
NE.head (NonEmpty a -> a)
-> ((NonEmpty a, b) -> NonEmpty a) -> (NonEmpty a, b) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty a, b) -> NonEmpty a
forall a b. (a, b) -> a
fst)
readKeymap :: XConfig l -> [(String, t)] -> [(NonEmpty (KeyMask, KeySym), t)]
readKeymap :: forall (l :: * -> *) t.
XConfig l -> [(String, t)] -> [(NonEmpty (KeyMask, KeySym), t)]
readKeymap XConfig l
c = ((String, t) -> Maybe (NonEmpty (KeyMask, KeySym), t))
-> [(String, t)] -> [(NonEmpty (KeyMask, KeySym), t)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((Maybe (NonEmpty (KeyMask, KeySym)), t)
-> Maybe (NonEmpty (KeyMask, KeySym), t)
forall {a} {b}. (Maybe a, b) -> Maybe (a, b)
maybeKeys ((Maybe (NonEmpty (KeyMask, KeySym)), t)
-> Maybe (NonEmpty (KeyMask, KeySym), t))
-> ((String, t) -> (Maybe (NonEmpty (KeyMask, KeySym)), t))
-> (String, t)
-> Maybe (NonEmpty (KeyMask, KeySym), t)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Maybe (NonEmpty (KeyMask, KeySym)))
-> (String, t) -> (Maybe (NonEmpty (KeyMask, KeySym)), t)
forall b c d. (b -> c) -> (b, d) -> (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (XConfig l -> String -> Maybe (NonEmpty (KeyMask, KeySym))
forall (l :: * -> *).
XConfig l -> String -> Maybe (NonEmpty (KeyMask, KeySym))
readKeySequence XConfig l
c))
where maybeKeys :: (Maybe a, b) -> Maybe (a, b)
maybeKeys (Maybe a
Nothing,b
_) = Maybe (a, b)
forall a. Maybe a
Nothing
maybeKeys (Just a
k, b
act) = (a, b) -> Maybe (a, b)
forall a. a -> Maybe a
Just (a
k, b
act)
readKeySequence :: XConfig l -> String -> Maybe (NonEmpty (KeyMask, KeySym))
readKeySequence :: forall (l :: * -> *).
XConfig l -> String -> Maybe (NonEmpty (KeyMask, KeySym))
readKeySequence XConfig l
c = [(KeyMask, KeySym)] -> Maybe (NonEmpty (KeyMask, KeySym))
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty ([(KeyMask, KeySym)] -> Maybe (NonEmpty (KeyMask, KeySym)))
-> (String -> Maybe [(KeyMask, KeySym)])
-> String
-> Maybe (NonEmpty (KeyMask, KeySym))
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Parser [(KeyMask, KeySym)] -> String -> Maybe [(KeyMask, KeySym)]
forall a. Parser a -> String -> Maybe a
runParser (XConfig l -> Parser [(KeyMask, KeySym)]
forall (l :: * -> *). XConfig l -> Parser [(KeyMask, KeySym)]
parseKeySequence XConfig l
c Parser [(KeyMask, KeySym)]
-> Parser () -> Parser [(KeyMask, KeySym)]
forall a b. Parser a -> Parser b -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ()
eof)
parseKeySequence :: XConfig l -> Parser [(KeyMask, KeySym)]
parseKeySequence :: forall (l :: * -> *). XConfig l -> Parser [(KeyMask, KeySym)]
parseKeySequence XConfig l
c = XConfig l -> Parser (KeyMask, KeySym)
forall (l :: * -> *). XConfig l -> Parser (KeyMask, KeySym)
parseKeyCombo XConfig l
c Parser (KeyMask, KeySym)
-> Parser String -> Parser [(KeyMask, KeySym)]
forall a sep. Parser a -> Parser sep -> Parser [a]
`sepBy1` Parser Char -> Parser String
forall a. Parser a -> Parser [a]
many1 (Char -> Parser Char
char Char
' ')
parseKeyCombo :: XConfig l -> Parser (KeyMask, KeySym)
parseKeyCombo :: forall (l :: * -> *). XConfig l -> Parser (KeyMask, KeySym)
parseKeyCombo XConfig l
c = do [KeyMask]
mods <- Parser KeyMask -> Parser [KeyMask]
forall a. Parser a -> Parser [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (XConfig l -> Parser KeyMask
forall (l :: * -> *). XConfig l -> Parser KeyMask
parseModifier XConfig l
c)
KeySym
k <- Parser KeySym
parseKey
(KeyMask, KeySym) -> Parser (KeyMask, KeySym)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return ((KeyMask -> KeyMask -> KeyMask) -> KeyMask -> [KeyMask] -> KeyMask
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' KeyMask -> KeyMask -> KeyMask
forall a. Bits a => a -> a -> a
(.|.) KeyMask
0 [KeyMask]
mods, KeySym
k)
parseModifier :: XConfig l -> Parser KeyMask
parseModifier :: forall (l :: * -> *). XConfig l -> Parser KeyMask
parseModifier XConfig l
c = (String -> Parser String
string String
"M-" Parser String -> KeyMask -> Parser KeyMask
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> XConfig l -> KeyMask
forall (l :: * -> *). XConfig l -> KeyMask
modMask XConfig l
c)
Parser KeyMask -> Parser KeyMask -> Parser KeyMask
forall a. Semigroup a => a -> a -> a
<> (String -> Parser String
string String
"C-" Parser String -> KeyMask -> Parser KeyMask
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> KeyMask
controlMask)
Parser KeyMask -> Parser KeyMask -> Parser KeyMask
forall a. Semigroup a => a -> a -> a
<> (String -> Parser String
string String
"S-" Parser String -> KeyMask -> Parser KeyMask
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> KeyMask
shiftMask)
Parser KeyMask -> Parser KeyMask -> Parser KeyMask
forall a. Semigroup a => a -> a -> a
<> do Char
_ <- Char -> Parser Char
char Char
'M'
Char
n <- (Char -> Bool) -> Parser Char
satisfy (Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'1'..Char
'5'])
Char
_ <- Char -> Parser Char
char Char
'-'
KeyMask -> Parser KeyMask
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (KeyMask -> Parser KeyMask) -> KeyMask -> Parser KeyMask
forall a b. (a -> b) -> a -> b
$ Int -> KeyMask
indexMod (String -> Int
forall a. Read a => String -> a
read [Char
n] Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
where indexMod :: Int -> KeyMask
indexMod = [KeyMask] -> Int -> KeyMask
forall a. HasCallStack => [a] -> Int -> a
(!!) [KeyMask
mod1Mask,KeyMask
mod2Mask,KeyMask
mod3Mask,KeyMask
mod4Mask,KeyMask
mod5Mask]
parseKey :: Parser KeySym
parseKey :: Parser KeySym
parseKey = Parser KeySym
parseSpecial Parser KeySym -> Parser KeySym -> Parser KeySym
forall a. Semigroup a => a -> a -> a
<> Parser KeySym
parseRegular
parseRegular :: Parser KeySym
parseRegular :: Parser KeySym
parseRegular = [Parser KeySym] -> Parser KeySym
forall a. [Parser a] -> Parser a
choice [ String -> Parser String
string String
s Parser String -> KeySym -> Parser KeySym
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> KeySym
k | (String
s, KeySym
k) <- [(String, KeySym)]
regularKeys ]
parseSpecial :: Parser KeySym
parseSpecial :: Parser KeySym
parseSpecial = do Char
_ <- Char -> Parser Char
char Char
'<'
[Parser KeySym] -> Parser KeySym
forall a. [Parser a] -> Parser a
choice [ KeySym
k KeySym -> Parser String -> Parser KeySym
forall a b. a -> Parser b -> Parser a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String
string String
name Parser KeySym -> Parser Char -> Parser KeySym
forall a b. Parser a -> Parser b -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> Parser Char
char Char
'>'
| (String
name, KeySym
k) <- [(String, KeySym)]
allSpecialKeys
]
checkKeymap :: XConfig l -> [(String, a)] -> X ()
checkKeymap :: forall (l :: * -> *) a. XConfig l -> [(String, a)] -> X ()
checkKeymap XConfig l
conf [(String, a)]
km = ([String], [String]) -> X ()
forall {m :: * -> *}. MonadIO m => ([String], [String]) -> m ()
warn (XConfig l -> [(String, a)] -> ([String], [String])
forall (l :: * -> *) a.
XConfig l -> [(String, a)] -> ([String], [String])
doKeymapCheck XConfig l
conf [(String, a)]
km)
where warn :: ([String], [String]) -> m ()
warn ([],[]) = () -> m ()
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
warn ([String]
bad,[String]
dup) = String -> m ()
forall (m :: * -> *). MonadIO m => String -> m ()
xmessage (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Warning:\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
msg String
"bad" [String]
bad String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
msg String
"duplicate" [String]
dup
msg :: String -> [String] -> String
msg String
_ [] = String
""
msg String
m [String]
xs = String
m String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" keybindings detected: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [String] -> String
showBindings [String]
xs
showBindings :: [String] -> String
showBindings = [String] -> String
unwords ([String] -> String)
-> ([String] -> [String]) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((String
"\""String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
forall a. [a] -> [a] -> [a]
++String
"\""))
doKeymapCheck :: XConfig l -> [(String,a)] -> ([String], [String])
doKeymapCheck :: forall (l :: * -> *) a.
XConfig l -> [(String, a)] -> ([String], [String])
doKeymapCheck XConfig l
conf [(String, a)]
km = ([String]
bad,[String]
dups)
where ks :: [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
ks = ((String, a) -> (Maybe (NonEmpty (KeyMask, KeySym)), String))
-> [(String, a)] -> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
forall a b. (a -> b) -> [a] -> [b]
map ((XConfig l -> String -> Maybe (NonEmpty (KeyMask, KeySym))
forall (l :: * -> *).
XConfig l -> String -> Maybe (NonEmpty (KeyMask, KeySym))
readKeySequence XConfig l
conf (String -> Maybe (NonEmpty (KeyMask, KeySym)))
-> (String -> String)
-> String
-> (Maybe (NonEmpty (KeyMask, KeySym)), String)
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& String -> String
forall a. a -> a
id) (String -> (Maybe (NonEmpty (KeyMask, KeySym)), String))
-> ((String, a) -> String)
-> (String, a)
-> (Maybe (NonEmpty (KeyMask, KeySym)), String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, a) -> String
forall a b. (a, b) -> a
fst) [(String, a)]
km
bad :: [String]
bad = [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String])
-> ([(Maybe (NonEmpty (KeyMask, KeySym)), String)] -> [String])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Maybe (NonEmpty (KeyMask, KeySym)), String) -> String)
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Maybe (NonEmpty (KeyMask, KeySym)), String) -> String
forall a b. (a, b) -> b
snd ([(Maybe (NonEmpty (KeyMask, KeySym)), String)] -> [String])
-> ([(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Maybe (NonEmpty (KeyMask, KeySym)), String) -> Bool)
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Maybe (NonEmpty (KeyMask, KeySym)) -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe (NonEmpty (KeyMask, KeySym)) -> Bool)
-> ((Maybe (NonEmpty (KeyMask, KeySym)), String)
-> Maybe (NonEmpty (KeyMask, KeySym)))
-> (Maybe (NonEmpty (KeyMask, KeySym)), String)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe (NonEmpty (KeyMask, KeySym)), String)
-> Maybe (NonEmpty (KeyMask, KeySym))
forall a b. (a, b) -> a
fst) ([(Maybe (NonEmpty (KeyMask, KeySym)), String)] -> [String])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)] -> [String]
forall a b. (a -> b) -> a -> b
$ [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
ks
dups :: [String]
dups = ([(NonEmpty (KeyMask, KeySym), String)] -> String)
-> [[(NonEmpty (KeyMask, KeySym), String)]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((NonEmpty (KeyMask, KeySym), String) -> String
forall a b. (a, b) -> b
snd ((NonEmpty (KeyMask, KeySym), String) -> String)
-> ([(NonEmpty (KeyMask, KeySym), String)]
-> (NonEmpty (KeyMask, KeySym), String))
-> [(NonEmpty (KeyMask, KeySym), String)]
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (NonEmpty (KeyMask, KeySym), String)
-> (NonEmpty (KeyMask, KeySym), String)
forall a. NonEmpty a -> a
NE.head (NonEmpty (NonEmpty (KeyMask, KeySym), String)
-> (NonEmpty (KeyMask, KeySym), String))
-> ([(NonEmpty (KeyMask, KeySym), String)]
-> NonEmpty (NonEmpty (KeyMask, KeySym), String))
-> [(NonEmpty (KeyMask, KeySym), String)]
-> (NonEmpty (KeyMask, KeySym), String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(NonEmpty (KeyMask, KeySym), String)]
-> NonEmpty (NonEmpty (KeyMask, KeySym), String)
forall a. HasCallStack => [a] -> NonEmpty a
notEmpty)
([[(NonEmpty (KeyMask, KeySym), String)]] -> [String])
-> ([(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [[(NonEmpty (KeyMask, KeySym), String)]])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(NonEmpty (KeyMask, KeySym), String)] -> Bool)
-> [[(NonEmpty (KeyMask, KeySym), String)]]
-> [[(NonEmpty (KeyMask, KeySym), String)]]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
1) (Int -> Bool)
-> ([(NonEmpty (KeyMask, KeySym), String)] -> Int)
-> [(NonEmpty (KeyMask, KeySym), String)]
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(NonEmpty (KeyMask, KeySym), String)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length)
([[(NonEmpty (KeyMask, KeySym), String)]]
-> [[(NonEmpty (KeyMask, KeySym), String)]])
-> ([(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [[(NonEmpty (KeyMask, KeySym), String)]])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [[(NonEmpty (KeyMask, KeySym), String)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((NonEmpty (KeyMask, KeySym), String)
-> (NonEmpty (KeyMask, KeySym), String) -> Bool)
-> [(NonEmpty (KeyMask, KeySym), String)]
-> [[(NonEmpty (KeyMask, KeySym), String)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (NonEmpty (KeyMask, KeySym) -> NonEmpty (KeyMask, KeySym) -> Bool
forall a. Eq a => a -> a -> Bool
(==) (NonEmpty (KeyMask, KeySym) -> NonEmpty (KeyMask, KeySym) -> Bool)
-> ((NonEmpty (KeyMask, KeySym), String)
-> NonEmpty (KeyMask, KeySym))
-> (NonEmpty (KeyMask, KeySym), String)
-> (NonEmpty (KeyMask, KeySym), String)
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (NonEmpty (KeyMask, KeySym), String) -> NonEmpty (KeyMask, KeySym)
forall a b. (a, b) -> a
fst)
([(NonEmpty (KeyMask, KeySym), String)]
-> [[(NonEmpty (KeyMask, KeySym), String)]])
-> ([(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(NonEmpty (KeyMask, KeySym), String)])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [[(NonEmpty (KeyMask, KeySym), String)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((NonEmpty (KeyMask, KeySym), String)
-> (NonEmpty (KeyMask, KeySym), String) -> Ordering)
-> [(NonEmpty (KeyMask, KeySym), String)]
-> [(NonEmpty (KeyMask, KeySym), String)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((NonEmpty (KeyMask, KeySym), String)
-> NonEmpty (KeyMask, KeySym))
-> (NonEmpty (KeyMask, KeySym), String)
-> (NonEmpty (KeyMask, KeySym), String)
-> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (NonEmpty (KeyMask, KeySym), String) -> NonEmpty (KeyMask, KeySym)
forall a b. (a, b) -> a
fst)
([(NonEmpty (KeyMask, KeySym), String)]
-> [(NonEmpty (KeyMask, KeySym), String)])
-> ([(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(NonEmpty (KeyMask, KeySym), String)])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(NonEmpty (KeyMask, KeySym), String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Maybe (NonEmpty (KeyMask, KeySym)), String)
-> (NonEmpty (KeyMask, KeySym), String))
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(NonEmpty (KeyMask, KeySym), String)]
forall a b. (a -> b) -> [a] -> [b]
map ((Maybe (NonEmpty (KeyMask, KeySym)) -> NonEmpty (KeyMask, KeySym))
-> (Maybe (NonEmpty (KeyMask, KeySym)), String)
-> (NonEmpty (KeyMask, KeySym), String)
forall b c d. (b -> c) -> (b, d) -> (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Maybe (NonEmpty (KeyMask, KeySym)) -> NonEmpty (KeyMask, KeySym)
forall a. HasCallStack => Maybe a -> a
fromJust)
([(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(NonEmpty (KeyMask, KeySym), String)])
-> ([(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(NonEmpty (KeyMask, KeySym), String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Maybe (NonEmpty (KeyMask, KeySym)), String) -> Bool)
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Maybe (NonEmpty (KeyMask, KeySym)) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (NonEmpty (KeyMask, KeySym)) -> Bool)
-> ((Maybe (NonEmpty (KeyMask, KeySym)), String)
-> Maybe (NonEmpty (KeyMask, KeySym)))
-> (Maybe (NonEmpty (KeyMask, KeySym)), String)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe (NonEmpty (KeyMask, KeySym)), String)
-> Maybe (NonEmpty (KeyMask, KeySym))
forall a b. (a, b) -> a
fst)
([(Maybe (NonEmpty (KeyMask, KeySym)), String)] -> [String])
-> [(Maybe (NonEmpty (KeyMask, KeySym)), String)] -> [String]
forall a b. (a -> b) -> a -> b
$ [(Maybe (NonEmpty (KeyMask, KeySym)), String)]
ks