module Brick.Keybindings.KeyConfig
( KeyConfig
, newKeyConfig
, BindingState(..)
, Binding(..)
, ToBinding(..)
, binding
, fn
, meta
, ctrl
, shift
, firstDefaultBinding
, firstActiveBinding
, allDefaultBindings
, allActiveBindings
, keyEventMappings
, keyConfigEvents
, lookupKeyConfigBindings
)
where
import Data.List (nub)
import qualified Data.Map.Strict as M
#if !(MIN_VERSION_base(4,11,0))
import Data.Monoid ((<>))
#endif
import qualified Data.Set as S
import Data.Maybe (fromMaybe, listToMaybe, catMaybes)
import qualified Graphics.Vty as Vty
import Brick.Keybindings.KeyEvents
data Binding =
Binding { Binding -> Key
kbKey :: Vty.Key
, Binding -> Set Modifier
kbMods :: S.Set Vty.Modifier
} deriving (Binding -> Binding -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Binding -> Binding -> Bool
$c/= :: Binding -> Binding -> Bool
== :: Binding -> Binding -> Bool
$c== :: Binding -> Binding -> Bool
Eq, Int -> Binding -> ShowS
[Binding] -> ShowS
Binding -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Binding] -> ShowS
$cshowList :: [Binding] -> ShowS
show :: Binding -> String
$cshow :: Binding -> String
showsPrec :: Int -> Binding -> ShowS
$cshowsPrec :: Int -> Binding -> ShowS
Show, Eq Binding
Binding -> Binding -> Bool
Binding -> Binding -> Ordering
Binding -> Binding -> Binding
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Binding -> Binding -> Binding
$cmin :: Binding -> Binding -> Binding
max :: Binding -> Binding -> Binding
$cmax :: Binding -> Binding -> Binding
>= :: Binding -> Binding -> Bool
$c>= :: Binding -> Binding -> Bool
> :: Binding -> Binding -> Bool
$c> :: Binding -> Binding -> Bool
<= :: Binding -> Binding -> Bool
$c<= :: Binding -> Binding -> Bool
< :: Binding -> Binding -> Bool
$c< :: Binding -> Binding -> Bool
compare :: Binding -> Binding -> Ordering
$ccompare :: Binding -> Binding -> Ordering
Ord)
binding :: Vty.Key -> [Vty.Modifier] -> Binding
binding :: Key -> [Modifier] -> Binding
binding Key
k [Modifier]
mods =
Binding { kbKey :: Key
kbKey = Key
k
, kbMods :: Set Modifier
kbMods = forall a. Ord a => [a] -> Set a
S.fromList [Modifier]
mods
}
data BindingState =
BindingList [Binding]
| Unbound
deriving (Int -> BindingState -> ShowS
[BindingState] -> ShowS
BindingState -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BindingState] -> ShowS
$cshowList :: [BindingState] -> ShowS
show :: BindingState -> String
$cshow :: BindingState -> String
showsPrec :: Int -> BindingState -> ShowS
$cshowsPrec :: Int -> BindingState -> ShowS
Show, BindingState -> BindingState -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BindingState -> BindingState -> Bool
$c/= :: BindingState -> BindingState -> Bool
== :: BindingState -> BindingState -> Bool
$c== :: BindingState -> BindingState -> Bool
Eq, Eq BindingState
BindingState -> BindingState -> Bool
BindingState -> BindingState -> Ordering
BindingState -> BindingState -> BindingState
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: BindingState -> BindingState -> BindingState
$cmin :: BindingState -> BindingState -> BindingState
max :: BindingState -> BindingState -> BindingState
$cmax :: BindingState -> BindingState -> BindingState
>= :: BindingState -> BindingState -> Bool
$c>= :: BindingState -> BindingState -> Bool
> :: BindingState -> BindingState -> Bool
$c> :: BindingState -> BindingState -> Bool
<= :: BindingState -> BindingState -> Bool
$c<= :: BindingState -> BindingState -> Bool
< :: BindingState -> BindingState -> Bool
$c< :: BindingState -> BindingState -> Bool
compare :: BindingState -> BindingState -> Ordering
$ccompare :: BindingState -> BindingState -> Ordering
Ord)
data KeyConfig k =
KeyConfig { forall k. KeyConfig k -> [(k, BindingState)]
keyConfigCustomBindings :: [(k, BindingState)]
, forall k. KeyConfig k -> KeyEvents k
keyConfigEvents :: KeyEvents k
, forall k. KeyConfig k -> Map k [Binding]
keyConfigDefaultBindings :: M.Map k [Binding]
}
deriving (Int -> KeyConfig k -> ShowS
forall k. Show k => Int -> KeyConfig k -> ShowS
forall k. Show k => [KeyConfig k] -> ShowS
forall k. Show k => KeyConfig k -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KeyConfig k] -> ShowS
$cshowList :: forall k. Show k => [KeyConfig k] -> ShowS
show :: KeyConfig k -> String
$cshow :: forall k. Show k => KeyConfig k -> String
showsPrec :: Int -> KeyConfig k -> ShowS
$cshowsPrec :: forall k. Show k => Int -> KeyConfig k -> ShowS
Show, KeyConfig k -> KeyConfig k -> Bool
forall k. Eq k => KeyConfig k -> KeyConfig k -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KeyConfig k -> KeyConfig k -> Bool
$c/= :: forall k. Eq k => KeyConfig k -> KeyConfig k -> Bool
== :: KeyConfig k -> KeyConfig k -> Bool
$c== :: forall k. Eq k => KeyConfig k -> KeyConfig k -> Bool
Eq)
newKeyConfig :: (Ord k)
=> KeyEvents k
-> [(k, [Binding])]
-> [(k, BindingState)]
-> KeyConfig k
newKeyConfig :: forall k.
Ord k =>
KeyEvents k
-> [(k, [Binding])] -> [(k, BindingState)] -> KeyConfig k
newKeyConfig KeyEvents k
evs [(k, [Binding])]
defaults [(k, BindingState)]
bindings =
KeyConfig { keyConfigCustomBindings :: [(k, BindingState)]
keyConfigCustomBindings = [(k, BindingState)]
bindings
, keyConfigEvents :: KeyEvents k
keyConfigEvents = KeyEvents k
evs
, keyConfigDefaultBindings :: Map k [Binding]
keyConfigDefaultBindings = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(k, [Binding])]
defaults
}
keyEventMappings :: (Ord k, Eq k) => KeyConfig k -> [(Binding, S.Set k)]
keyEventMappings :: forall k. (Ord k, Eq k) => KeyConfig k -> [(Binding, Set k)]
keyEventMappings KeyConfig k
kc = forall k a. Map k a -> [(k, a)]
M.toList Map Binding (Set k)
resultMap
where
defaultBindings :: [(k, [Binding])]
defaultBindings = forall k a. Map k a -> [(k, a)]
M.toList forall a b. (a -> b) -> a -> b
$ forall k. KeyConfig k -> Map k [Binding]
keyConfigDefaultBindings KeyConfig k
kc
explicitlyUnboundEvents :: [k]
explicitlyUnboundEvents = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter ((forall a. Eq a => a -> a -> Bool
== BindingState
Unbound) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$ forall k. KeyConfig k -> [(k, BindingState)]
keyConfigCustomBindings KeyConfig k
kc
defaultBindingsWithoutUnbound :: [(k, [Binding])]
defaultBindingsWithoutUnbound = forall a. (a -> Bool) -> [a] -> [a]
filter ((forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [k]
explicitlyUnboundEvents) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(k, [Binding])]
defaultBindings
customizedKeybindingLists :: [(k, [Binding])]
customizedKeybindingLists = forall a. [Maybe a] -> [a]
catMaybes forall a b. (a -> b) -> a -> b
$ (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (forall k. KeyConfig k -> [(k, BindingState)]
keyConfigCustomBindings KeyConfig k
kc) forall a b. (a -> b) -> a -> b
$ \(k
k, BindingState
bState) -> do
case BindingState
bState of
BindingState
Unbound -> forall a. Maybe a
Nothing
BindingList [Binding]
bs -> forall a. a -> Maybe a
Just (k
k, [Binding]
bs)
allPairs :: [(k, [Binding])]
allPairs = [(k, [Binding])]
defaultBindingsWithoutUnbound forall a. Semigroup a => a -> a -> a
<>
[(k, [Binding])]
customizedKeybindingLists
addBindings :: Map k (Set a) -> (a, [k]) -> Map k (Set a)
addBindings Map k (Set a)
m (a
ev, [k]
bs) =
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
M.unionWith forall a. Ord a => Set a -> Set a -> Set a
S.union Map k (Set a)
m forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(k
b, forall a. a -> Set a
S.singleton a
ev) | k
b <- [k]
bs]
resultMap :: Map Binding (Set k)
resultMap = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl forall {k} {a}.
(Ord k, Ord a) =>
Map k (Set a) -> (a, [k]) -> Map k (Set a)
addBindings forall a. Monoid a => a
mempty [(k, [Binding])]
allPairs
lookupKeyConfigBindings :: (Ord k) => KeyConfig k -> k -> Maybe BindingState
lookupKeyConfigBindings :: forall k. Ord k => KeyConfig k -> k -> Maybe BindingState
lookupKeyConfigBindings KeyConfig k
kc k
e = forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup k
e forall a b. (a -> b) -> a -> b
$ forall k. KeyConfig k -> [(k, BindingState)]
keyConfigCustomBindings KeyConfig k
kc
firstDefaultBinding :: (Show k, Ord k) => KeyConfig k -> k -> Maybe Binding
firstDefaultBinding :: forall k. (Show k, Ord k) => KeyConfig k -> k -> Maybe Binding
firstDefaultBinding KeyConfig k
kc k
ev = do
[Binding]
bs <- forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup k
ev (forall k. KeyConfig k -> Map k [Binding]
keyConfigDefaultBindings KeyConfig k
kc)
case [Binding]
bs of
(Binding
b:[Binding]
_) -> forall a. a -> Maybe a
Just Binding
b
[Binding]
_ -> forall a. Maybe a
Nothing
allDefaultBindings :: (Ord k) => KeyConfig k -> k -> [Binding]
allDefaultBindings :: forall k. Ord k => KeyConfig k -> k -> [Binding]
allDefaultBindings KeyConfig k
kc k
ev =
forall a. a -> Maybe a -> a
fromMaybe [] forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup k
ev (forall k. KeyConfig k -> Map k [Binding]
keyConfigDefaultBindings KeyConfig k
kc)
firstActiveBinding :: (Show k, Ord k) => KeyConfig k -> k -> Maybe Binding
firstActiveBinding :: forall k. (Show k, Ord k) => KeyConfig k -> k -> Maybe Binding
firstActiveBinding KeyConfig k
kc k
ev = forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall k. (Show k, Ord k) => KeyConfig k -> k -> [Binding]
allActiveBindings KeyConfig k
kc k
ev
allActiveBindings :: (Show k, Ord k) => KeyConfig k -> k -> [Binding]
allActiveBindings :: forall k. (Show k, Ord k) => KeyConfig k -> k -> [Binding]
allActiveBindings KeyConfig k
kc k
ev = forall a. Eq a => [a] -> [a]
nub [Binding]
foundBindings
where
defaultBindings :: [Binding]
defaultBindings = forall k. Ord k => KeyConfig k -> k -> [Binding]
allDefaultBindings KeyConfig k
kc k
ev
foundBindings :: [Binding]
foundBindings = case forall k. Ord k => KeyConfig k -> k -> Maybe BindingState
lookupKeyConfigBindings KeyConfig k
kc k
ev of
Just (BindingList [Binding]
bs) -> [Binding]
bs
Just BindingState
Unbound -> []
Maybe BindingState
Nothing -> [Binding]
defaultBindings
class ToBinding a where
bind :: a -> Binding
instance ToBinding Vty.Key where
bind :: Key -> Binding
bind Key
k = Binding { kbMods :: Set Modifier
kbMods = forall a. Monoid a => a
mempty, kbKey :: Key
kbKey = Key
k }
instance ToBinding Char where
bind :: Char -> Binding
bind = forall a. ToBinding a => a -> Binding
bind forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Key
Vty.KChar
instance ToBinding Binding where
bind :: Binding -> Binding
bind = forall a. a -> a
id
addModifier :: (ToBinding a) => Vty.Modifier -> a -> Binding
addModifier :: forall a. ToBinding a => Modifier -> a -> Binding
addModifier Modifier
m a
val =
let b :: Binding
b = forall a. ToBinding a => a -> Binding
bind a
val
in Binding
b { kbMods :: Set Modifier
kbMods = forall a. Ord a => a -> Set a -> Set a
S.insert Modifier
m (Binding -> Set Modifier
kbMods Binding
b) }
meta :: (ToBinding a) => a -> Binding
meta :: forall a. ToBinding a => a -> Binding
meta = forall a. ToBinding a => Modifier -> a -> Binding
addModifier Modifier
Vty.MMeta
ctrl :: (ToBinding a) => a -> Binding
ctrl :: forall a. ToBinding a => a -> Binding
ctrl = forall a. ToBinding a => Modifier -> a -> Binding
addModifier Modifier
Vty.MCtrl
shift :: (ToBinding a) => a -> Binding
shift :: forall a. ToBinding a => a -> Binding
shift = forall a. ToBinding a => Modifier -> a -> Binding
addModifier Modifier
Vty.MShift
fn :: Int -> Binding
fn :: Int -> Binding
fn = forall a. ToBinding a => a -> Binding
bind forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Key
Vty.KFun