{-# LANGUAGE OverloadedStrings #-}
module Swarm.TUI.Model.KeyBindings (
initKeyHandlingState,
KeybindingPrint (..),
showKeybindings,
handlerNameKeysDescription,
) where
import Brick
import Brick.Keybindings as BK
import Control.Carrier.Lift (runM)
import Control.Carrier.Throw.Either (runThrow)
import Control.Effect.Accum
import Control.Effect.Lift
import Control.Effect.Throw
import Control.Lens hiding (from, (<.>))
import Data.Bifunctor (second)
import Data.Maybe (fromMaybe, mapMaybe)
import Data.Text (Text)
import Data.Text qualified as T
import Swarm.Failure (Asset (..), LoadingFailure (..), SystemFailure (..))
import Swarm.Pretty (prettyText)
import Swarm.ResourceLoading (getSwarmConfigIniFile)
import Swarm.TUI.Controller.EventHandlers
import Swarm.TUI.Model
import Swarm.TUI.Model.Event (SwarmEvent, defaultSwarmBindings, swarmEvents)
loadKeybindingConfig ::
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m [(SwarmEvent, BindingState)]
loadKeybindingConfig :: forall (sig :: (* -> *) -> * -> *) (m :: * -> *).
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m [(SwarmEvent, BindingState)]
loadKeybindingConfig = do
(Bool
iniExists, FilePath
ini) <- IO (Bool, FilePath) -> m (Bool, FilePath)
forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has (Lift IO) sig m =>
IO a -> m a
sendIO (IO (Bool, FilePath) -> m (Bool, FilePath))
-> IO (Bool, FilePath) -> m (Bool, FilePath)
forall a b. (a -> b) -> a -> b
$ Bool -> IO (Bool, FilePath)
getSwarmConfigIniFile Bool
False
if Bool -> Bool
not Bool
iniExists
then [(SwarmEvent, BindingState)] -> m [(SwarmEvent, BindingState)]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
else do
Either FilePath (Maybe [(SwarmEvent, BindingState)])
loadedCustomBindings <- IO (Either FilePath (Maybe [(SwarmEvent, BindingState)]))
-> m (Either FilePath (Maybe [(SwarmEvent, BindingState)]))
forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has (Lift IO) sig m =>
IO a -> m a
sendIO (IO (Either FilePath (Maybe [(SwarmEvent, BindingState)]))
-> m (Either FilePath (Maybe [(SwarmEvent, BindingState)])))
-> IO (Either FilePath (Maybe [(SwarmEvent, BindingState)]))
-> m (Either FilePath (Maybe [(SwarmEvent, BindingState)]))
forall a b. (a -> b) -> a -> b
$ KeyEvents SwarmEvent
-> Text
-> FilePath
-> IO (Either FilePath (Maybe [(SwarmEvent, BindingState)]))
forall k.
KeyEvents k
-> Text
-> FilePath
-> IO (Either FilePath (Maybe [(k, BindingState)]))
keybindingsFromFile KeyEvents SwarmEvent
swarmEvents Text
"keybindings" FilePath
ini
case Either FilePath (Maybe [(SwarmEvent, BindingState)])
loadedCustomBindings of
Left FilePath
e -> SystemFailure -> m [(SwarmEvent, BindingState)]
forall e (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has (Throw e) sig m =>
e -> m a
throwError (SystemFailure -> m [(SwarmEvent, BindingState)])
-> SystemFailure -> m [(SwarmEvent, BindingState)]
forall a b. (a -> b) -> a -> b
$ Asset -> FilePath -> LoadingFailure -> SystemFailure
AssetNotLoaded Asset
Keybindings FilePath
ini (SystemFailure -> LoadingFailure
SystemFailure (SystemFailure -> LoadingFailure)
-> (Text -> SystemFailure) -> Text -> LoadingFailure
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> SystemFailure
CustomFailure (Text -> LoadingFailure) -> Text -> LoadingFailure
forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack FilePath
e)
Right Maybe [(SwarmEvent, BindingState)]
bs -> [(SwarmEvent, BindingState)] -> m [(SwarmEvent, BindingState)]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(SwarmEvent, BindingState)] -> m [(SwarmEvent, BindingState)])
-> [(SwarmEvent, BindingState)] -> m [(SwarmEvent, BindingState)]
forall a b. (a -> b) -> a -> b
$ [(SwarmEvent, BindingState)]
-> Maybe [(SwarmEvent, BindingState)]
-> [(SwarmEvent, BindingState)]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [(SwarmEvent, BindingState)]
bs
initKeyHandlingState ::
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m KeyEventHandlingState
initKeyHandlingState :: forall (sig :: (* -> *) -> * -> *) (m :: * -> *).
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m KeyEventHandlingState
initKeyHandlingState = do
[(SwarmEvent, BindingState)]
customBindings <- m [(SwarmEvent, BindingState)]
forall (sig :: (* -> *) -> * -> *) (m :: * -> *).
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m [(SwarmEvent, BindingState)]
loadKeybindingConfig
let cfg :: KeyConfig SwarmEvent
cfg = KeyEvents SwarmEvent
-> [(SwarmEvent, [Binding])]
-> [(SwarmEvent, BindingState)]
-> KeyConfig SwarmEvent
forall k.
Ord k =>
KeyEvents k
-> [(k, [Binding])] -> [(k, BindingState)] -> KeyConfig k
newKeyConfig KeyEvents SwarmEvent
swarmEvents [(SwarmEvent, [Binding])]
defaultSwarmBindings [(SwarmEvent, BindingState)]
customBindings
SwarmKeyDispatchers
dispatchers <- KeyConfig SwarmEvent -> m SwarmKeyDispatchers
forall (sig :: (* -> *) -> * -> *) (m :: * -> *).
Has (Throw SystemFailure) sig m =>
KeyConfig SwarmEvent -> m SwarmKeyDispatchers
createKeyDispatchers KeyConfig SwarmEvent
cfg
KeyEventHandlingState -> m KeyEventHandlingState
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (KeyEventHandlingState -> m KeyEventHandlingState)
-> KeyEventHandlingState -> m KeyEventHandlingState
forall a b. (a -> b) -> a -> b
$ KeyConfig SwarmEvent
-> SwarmKeyDispatchers -> KeyEventHandlingState
KeyEventHandlingState KeyConfig SwarmEvent
cfg SwarmKeyDispatchers
dispatchers
data KeybindingPrint = MarkdownPrint | TextPrint | IniPrint
deriving (KeybindingPrint -> KeybindingPrint -> Bool
(KeybindingPrint -> KeybindingPrint -> Bool)
-> (KeybindingPrint -> KeybindingPrint -> Bool)
-> Eq KeybindingPrint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: KeybindingPrint -> KeybindingPrint -> Bool
== :: KeybindingPrint -> KeybindingPrint -> Bool
$c/= :: KeybindingPrint -> KeybindingPrint -> Bool
/= :: KeybindingPrint -> KeybindingPrint -> Bool
Eq, Eq KeybindingPrint
Eq KeybindingPrint =>
(KeybindingPrint -> KeybindingPrint -> Ordering)
-> (KeybindingPrint -> KeybindingPrint -> Bool)
-> (KeybindingPrint -> KeybindingPrint -> Bool)
-> (KeybindingPrint -> KeybindingPrint -> Bool)
-> (KeybindingPrint -> KeybindingPrint -> Bool)
-> (KeybindingPrint -> KeybindingPrint -> KeybindingPrint)
-> (KeybindingPrint -> KeybindingPrint -> KeybindingPrint)
-> Ord KeybindingPrint
KeybindingPrint -> KeybindingPrint -> Bool
KeybindingPrint -> KeybindingPrint -> Ordering
KeybindingPrint -> KeybindingPrint -> KeybindingPrint
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
$ccompare :: KeybindingPrint -> KeybindingPrint -> Ordering
compare :: KeybindingPrint -> KeybindingPrint -> Ordering
$c< :: KeybindingPrint -> KeybindingPrint -> Bool
< :: KeybindingPrint -> KeybindingPrint -> Bool
$c<= :: KeybindingPrint -> KeybindingPrint -> Bool
<= :: KeybindingPrint -> KeybindingPrint -> Bool
$c> :: KeybindingPrint -> KeybindingPrint -> Bool
> :: KeybindingPrint -> KeybindingPrint -> Bool
$c>= :: KeybindingPrint -> KeybindingPrint -> Bool
>= :: KeybindingPrint -> KeybindingPrint -> Bool
$cmax :: KeybindingPrint -> KeybindingPrint -> KeybindingPrint
max :: KeybindingPrint -> KeybindingPrint -> KeybindingPrint
$cmin :: KeybindingPrint -> KeybindingPrint -> KeybindingPrint
min :: KeybindingPrint -> KeybindingPrint -> KeybindingPrint
Ord, Int -> KeybindingPrint -> ShowS
[KeybindingPrint] -> ShowS
KeybindingPrint -> FilePath
(Int -> KeybindingPrint -> ShowS)
-> (KeybindingPrint -> FilePath)
-> ([KeybindingPrint] -> ShowS)
-> Show KeybindingPrint
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeybindingPrint -> ShowS
showsPrec :: Int -> KeybindingPrint -> ShowS
$cshow :: KeybindingPrint -> FilePath
show :: KeybindingPrint -> FilePath
$cshowList :: [KeybindingPrint] -> ShowS
showList :: [KeybindingPrint] -> ShowS
Show)
showKeybindings :: KeybindingPrint -> IO Text
showKeybindings :: KeybindingPrint -> IO Text
showKeybindings KeybindingPrint
kPrint = do
Either SystemFailure KeyEventHandlingState
bindings <- LiftC IO (Either SystemFailure KeyEventHandlingState)
-> IO (Either SystemFailure KeyEventHandlingState)
forall (m :: * -> *) a. LiftC m a -> m a
runM (LiftC IO (Either SystemFailure KeyEventHandlingState)
-> IO (Either SystemFailure KeyEventHandlingState))
-> LiftC IO (Either SystemFailure KeyEventHandlingState)
-> IO (Either SystemFailure KeyEventHandlingState)
forall a b. (a -> b) -> a -> b
$ forall e (m :: * -> *) a. ThrowC e m a -> m (Either e a)
runThrow @SystemFailure ThrowC SystemFailure (LiftC IO) KeyEventHandlingState
forall (sig :: (* -> *) -> * -> *) (m :: * -> *).
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m KeyEventHandlingState
initKeyHandlingState
Text -> IO Text
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> IO Text) -> Text -> IO Text
forall a b. (a -> b) -> a -> b
$ case Either SystemFailure KeyEventHandlingState
bindings of
Left SystemFailure
e -> SystemFailure -> Text
forall a. PrettyPrec a => a -> Text
prettyText SystemFailure
e
Right KeyEventHandlingState
bs -> KeybindingPrint
-> KeyConfig SwarmEvent
-> [(Text, [KeyEventHandler SwarmEvent (EventM Name AppState)])]
-> Text
forall {m :: * -> *}.
KeybindingPrint
-> KeyConfig SwarmEvent
-> [(Text, [KeyEventHandler SwarmEvent m])]
-> Text
showTable KeybindingPrint
kPrint (KeyEventHandlingState
bs KeyEventHandlingState
-> Getting
(KeyConfig SwarmEvent) KeyEventHandlingState (KeyConfig SwarmEvent)
-> KeyConfig SwarmEvent
forall s a. s -> Getting a s a -> a
^. Getting
(KeyConfig SwarmEvent) KeyEventHandlingState (KeyConfig SwarmEvent)
Lens' KeyEventHandlingState (KeyConfig SwarmEvent)
keyConfig) [(Text, [KeyEventHandler SwarmEvent (EventM Name AppState)])]
keySections
where
showTable :: KeybindingPrint
-> KeyConfig SwarmEvent
-> [(Text, [KeyEventHandler SwarmEvent m])]
-> Text
showTable = \case
KeybindingPrint
MarkdownPrint -> KeyConfig SwarmEvent
-> [(Text, [KeyEventHandler SwarmEvent m])] -> Text
forall k (m :: * -> *).
Ord k =>
KeyConfig k -> [(Text, [KeyEventHandler k m])] -> Text
keybindingMarkdownTable
KeybindingPrint
TextPrint -> KeyConfig SwarmEvent
-> [(Text, [KeyEventHandler SwarmEvent m])] -> Text
forall k (m :: * -> *).
Ord k =>
KeyConfig k -> [(Text, [KeyEventHandler k m])] -> Text
keybindingTextTable
KeybindingPrint
IniPrint -> KeyConfig SwarmEvent
-> [(Text, [KeyEventHandler SwarmEvent m])] -> Text
forall k (m :: * -> *).
Ord k =>
KeyConfig k -> [(Text, [KeyEventHandler k m])] -> Text
keybindingINI
keySections :: [(Text, [KeyEventHandler SwarmEvent (EventM Name AppState)])]
keySections :: [(Text, [KeyEventHandler SwarmEvent (EventM Name AppState)])]
keySections =
[ (Text
"Main game (always active)", [KeyEventHandler SwarmEvent (EventM Name AppState)]
mainEventHandlers)
, (Text
"REPL panel", [KeyEventHandler SwarmEvent (EventM Name AppState)]
replEventHandlers)
, (Text
"World view panel", [KeyEventHandler SwarmEvent (EventM Name AppState)]
worldEventHandlers)
, (Text
"Robot inventory panel", [KeyEventHandler SwarmEvent (EventM Name AppState)]
robotEventHandlers)
]
keybindingINI :: Ord k => KeyConfig k -> [(Text, [KeyEventHandler k m])] -> Text
keybindingINI :: forall k (m :: * -> *).
Ord k =>
KeyConfig k -> [(Text, [KeyEventHandler k m])] -> Text
keybindingINI KeyConfig k
kc [(Text, [KeyEventHandler k m])]
sections =
Text -> [Text] -> Text
T.intercalate Text
"\n" ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
Text
"[keybindings]\n"
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Text
"; Uncomment the assignment and set comma separated list"
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Text
"; of keybindings or \"unbound\" on the right. See:"
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Text
"; https://hackage.haskell.org/package/brick/docs/Brick-Keybindings-Parse.html#v:parseBinding\n"
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: ((Text, [(k, Text)]) -> [Text]) -> [(Text, [(k, Text)])] -> [Text]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Text, [(k, Text)]) -> [Text]
sectionsINI [(Text, [(k, Text)])]
handlersData
where
handlersData :: [(Text, [(k, Text)])]
handlersData = ((Text, [KeyEventHandler k m]) -> (Text, [(k, Text)]))
-> [(Text, [KeyEventHandler k m])] -> [(Text, [(k, Text)])]
forall a b. (a -> b) -> [a] -> [b]
map (([KeyEventHandler k m] -> [(k, Text)])
-> (Text, [KeyEventHandler k m]) -> (Text, [(k, Text)])
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (([KeyEventHandler k m] -> [(k, Text)])
-> (Text, [KeyEventHandler k m]) -> (Text, [(k, Text)]))
-> ([KeyEventHandler k m] -> [(k, Text)])
-> (Text, [KeyEventHandler k m])
-> (Text, [(k, Text)])
forall a b. (a -> b) -> a -> b
$ (KeyEventHandler k m -> Maybe (k, Text))
-> [KeyEventHandler k m] -> [(k, Text)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe KeyEventHandler k m -> Maybe (k, Text)
forall {k} {m :: * -> *}. KeyEventHandler k m -> Maybe (k, Text)
handlerData) [(Text, [KeyEventHandler k m])]
sections
handlerData :: KeyEventHandler k m -> Maybe (k, Text)
handlerData KeyEventHandler k m
h = case KeyEventHandler k m -> EventTrigger k
forall k (m :: * -> *). KeyEventHandler k m -> EventTrigger k
kehEventTrigger KeyEventHandler k m
h of
ByKey Binding
_ -> Maybe (k, Text)
forall a. Maybe a
Nothing
ByEvent k
k -> (k, Text) -> Maybe (k, Text)
forall a. a -> Maybe a
Just (k
k, Handler m -> Text
forall (m :: * -> *). Handler m -> Text
handlerDescription (Handler m -> Text) -> Handler m -> Text
forall a b. (a -> b) -> a -> b
$ KeyEventHandler k m -> Handler m
forall k (m :: * -> *). KeyEventHandler k m -> Handler m
kehHandler KeyEventHandler k m
h)
section :: a -> a
section a
s = a
"\n;;;; " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
s a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
"\n"
sectionsINI :: (Text, [(k, Text)]) -> [Text]
sectionsINI (Text
s, [(k, Text)]
hs) = Text -> Text
forall {a}. (Semigroup a, IsString a) => a -> a
section Text
s Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: ((k, Text) -> Text) -> [(k, Text)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (KeyConfig k -> (k, Text) -> Text
forall k. Ord k => KeyConfig k -> (k, Text) -> Text
keyBindingEventINI KeyConfig k
kc) [(k, Text)]
hs
keyBindingEventINI :: Ord k => KeyConfig k -> (k, Text) -> Text
keyBindingEventINI :: forall k. Ord k => KeyConfig k -> (k, Text) -> Text
keyBindingEventINI KeyConfig k
kc (k
ev, Text
description) =
[Text] -> Text
T.unlines
[ Text
";; " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
description
, Text
commentDefault Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" = " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
bindingList
]
where
commentDefault :: Text
commentDefault = if Bool
custom then Text
"" else Text
"; "
(Bool
custom, Text
bindingList) = case KeyConfig k -> k -> Maybe BindingState
forall k. Ord k => KeyConfig k -> k -> Maybe BindingState
lookupKeyConfigBindings KeyConfig k
kc k
ev of
Just BindingState
Unbound -> (Bool
True, Text
"unbound")
Just (BindingList [Binding]
bs) -> (Bool
True, [Binding] -> Text
listBindings [Binding]
bs)
Maybe BindingState
Nothing ->
( Bool
False
, if [Binding] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (KeyConfig k -> k -> [Binding]
forall k. Ord k => KeyConfig k -> k -> [Binding]
allDefaultBindings KeyConfig k
kc k
ev)
then Text
"unbound"
else [Binding] -> Text
listBindings ([Binding] -> Text) -> [Binding] -> Text
forall a b. (a -> b) -> a -> b
$ KeyConfig k -> k -> [Binding]
forall k. Ord k => KeyConfig k -> k -> [Binding]
allDefaultBindings KeyConfig k
kc k
ev
)
listBindings :: [Binding] -> Text
listBindings = Text -> [Text] -> Text
T.intercalate Text
"," ([Text] -> Text) -> ([Binding] -> [Text]) -> [Binding] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Binding -> Text) -> [Binding] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Binding -> Text
ppBinding
name :: Text
name = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"(unnamed)" (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ KeyEvents k -> k -> Maybe Text
forall k. Ord k => KeyEvents k -> k -> Maybe Text
keyEventName (KeyConfig k -> KeyEvents k
forall k. KeyConfig k -> KeyEvents k
keyConfigEvents KeyConfig k
kc) k
ev
handlerNameKeysDescription :: Ord k => KeyConfig k -> KeyEventHandler k m -> (Text, Text, Text)
handlerNameKeysDescription :: forall k (m :: * -> *).
Ord k =>
KeyConfig k -> KeyEventHandler k m -> (Text, Text, Text)
handlerNameKeysDescription KeyConfig k
kc KeyEventHandler k m
keh = (Text
name, Text
keys, Text
desc)
where
desc :: Text
desc = Handler m -> Text
forall (m :: * -> *). Handler m -> Text
handlerDescription (Handler m -> Text) -> Handler m -> Text
forall a b. (a -> b) -> a -> b
$ KeyEventHandler k m -> Handler m
forall k (m :: * -> *). KeyEventHandler k m -> Handler m
kehHandler KeyEventHandler k m
keh
(Text
name, Text
keys) = case KeyEventHandler k m -> EventTrigger k
forall k (m :: * -> *). KeyEventHandler k m -> EventTrigger k
kehEventTrigger KeyEventHandler k m
keh of
ByKey Binding
b -> (Text
"(non-customizable key)", Binding -> Text
ppBinding Binding
b)
ByEvent k
ev ->
let name' :: Text
name' = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"(unnamed)" (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ KeyEvents k -> k -> Maybe Text
forall k. Ord k => KeyEvents k -> k -> Maybe Text
keyEventName (KeyConfig k -> KeyEvents k
forall k. KeyConfig k -> KeyEvents k
keyConfigEvents KeyConfig k
kc) k
ev
in case KeyConfig k -> k -> Maybe BindingState
forall k. Ord k => KeyConfig k -> k -> Maybe BindingState
lookupKeyConfigBindings KeyConfig k
kc k
ev of
Maybe BindingState
Nothing ->
if Bool -> Bool
not ([Binding] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (KeyConfig k -> k -> [Binding]
forall k. Ord k => KeyConfig k -> k -> [Binding]
allDefaultBindings KeyConfig k
kc k
ev))
then (Text
name', Text -> [Text] -> Text
T.intercalate Text
"," ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Binding -> Text
ppBinding (Binding -> Text) -> [Binding] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> KeyConfig k -> k -> [Binding]
forall k. Ord k => KeyConfig k -> k -> [Binding]
allDefaultBindings KeyConfig k
kc k
ev)
else (Text
name', Text
"unbound")
Just BindingState
Unbound ->
(Text
name', Text
"unbound")
Just (BindingList [Binding]
bs) ->
let result :: Text
result =
if Bool -> Bool
not ([Binding] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Binding]
bs)
then Text -> [Text] -> Text
T.intercalate Text
"," ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ Binding -> Text
ppBinding (Binding -> Text) -> [Binding] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Binding]
bs
else Text
"unbound"
in (Text
name', Text
result)