    -- | This module provides 'KeyEvents', a data type for mapping
    -- application-defined abstract events to user-facing names (e.g.
    -- for use in configuration files and documentation). This data
    -- structure gives you a place to define the correspondence between
    -- your application's key events and their names. A 'KeyEvents' also
    -- effectively tells the key binding system about the collection of
    -- possible abstract events that can be handled.
    --
    -- A 'KeyEvents' is used to construct a
    -- 'Brick.Keybindings.KeyConfig.KeyConfig' with
    -- 'Brick.Keybindings.KeyConfig.newKeyConfig'.
    module Brick.Keybindings.KeyEvents
      ( KeyEvents
      , keyEvents
      , keyEventsList
      , lookupKeyEvent
      , keyEventName
      )
    where

    import qualified Data.Bimap as B
    import qualified Data.Text as T

    -- | A bidirectional mapping between events @k@ and their user-readable
    -- names.
    data KeyEvents k = KeyEvents (B.Bimap T.Text k)
                     deriving (KeyEvents k -> KeyEvents k -> Bool
    (KeyEvents k -> KeyEvents k -> Bool)
    -> (KeyEvents k -> KeyEvents k -> Bool) -> Eq (KeyEvents k)
    forall k. Eq k => KeyEvents k -> KeyEvents k -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall k. Eq k => KeyEvents k -> KeyEvents k -> Bool
    == :: KeyEvents k -> KeyEvents k -> Bool
    $c/= :: forall k. Eq k => KeyEvents k -> KeyEvents k -> Bool
    /= :: KeyEvents k -> KeyEvents k -> Bool
    Eq, Int -> KeyEvents k -> ShowS
    [KeyEvents k] -> ShowS
    KeyEvents k -> String
    (Int -> KeyEvents k -> ShowS)
    -> (KeyEvents k -> String)
    -> ([KeyEvents k] -> ShowS)
    -> Show (KeyEvents k)
    forall k. Show k => Int -> KeyEvents k -> ShowS
    forall k. Show k => [KeyEvents k] -> ShowS
    forall k. Show k => KeyEvents k -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall k. Show k => Int -> KeyEvents k -> ShowS
    showsPrec :: Int -> KeyEvents k -> ShowS
    $cshow :: forall k. Show k => KeyEvents k -> String
    show :: KeyEvents k -> String
    $cshowList :: forall k. Show k => [KeyEvents k] -> ShowS
    showList :: [KeyEvents k] -> ShowS
    Show)

    -- | Build a new 'KeyEvents' map from the specified list of events and
    -- names. Key event names are stored in lowercase.
    --
    -- Calls 'error' if any events have the same name (ignoring case) or if
    -- multiple names map to the same event.
    keyEvents :: (Ord k) => [(T.Text, k)] -> KeyEvents k
    keyEvents :: forall k. Ord k => [(Text, k)] -> KeyEvents k
    keyEvents [(Text, k)]
    pairs =
        let m :: Bimap Text k
    m = [(Text, k)] -> Bimap Text k
    forall a b. (Ord a, Ord b) => [(a, b)] -> Bimap a b
    B.fromList [(Text -> Text
    T.strip (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    T.toLower Text
    n, k
    e) | (Text
    n, k
    e) <- [(Text, k)]
    pairs]
        in if Bimap Text k -> Int
    forall a b. Bimap a b -> Int
    B.size Bimap Text k
    m Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= [(Text, k)] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(Text, k)]
    pairs
           then String -> KeyEvents k
    forall a. HasCallStack => String -> a
    error String
    "keyEvents: input list contains duplicates by name or by event value"
           else Bimap Text k -> KeyEvents k
    forall k. Bimap Text k -> KeyEvents k
    KeyEvents (Bimap Text k -> KeyEvents k) -> Bimap Text k -> KeyEvents k
    forall a b. (a -> b) -> a -> b
    $ [(Text, k)] -> Bimap Text k
    forall a b. (Ord a, Ord b) => [(a, b)] -> Bimap a b
    B.fromList [(Text, k)]
    pairs

    -- | Convert the 'KeyEvents' to a list.
    keyEventsList :: KeyEvents k -> [(T.Text, k)]
    keyEventsList :: forall k. KeyEvents k -> [(Text, k)]
    keyEventsList (KeyEvents Bimap Text k
    m) = Bimap Text k -> [(Text, k)]
    forall a b. Bimap a b -> [(a, b)]
    B.toList Bimap Text k
    m

    -- | Look up the specified event name to get its abstract event. The
    -- lookup ignores leading and trailing whitespace as well as case.
    lookupKeyEvent :: (Ord k) => KeyEvents k -> T.Text -> Maybe k
    lookupKeyEvent :: forall k. Ord k => KeyEvents k -> Text -> Maybe k
    lookupKeyEvent (KeyEvents Bimap Text k
    m) Text
    name = Text -> Bimap Text k -> Maybe k
    forall a b (m :: * -> *).
    (Ord a, Ord b, MonadThrow m) =>
    a -> Bimap a b -> m b
    B.lookup (Text -> Text
    T.strip (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    T.toLower Text
    name) Bimap Text k
    m

    -- | Given an abstract event, get its event name.
    keyEventName :: (Ord k) => KeyEvents k -> k -> Maybe T.Text
    keyEventName :: forall k. Ord k => KeyEvents k -> k -> Maybe Text
    keyEventName (KeyEvents Bimap Text k
    m) k
    e = k -> Bimap Text k -> Maybe Text
    forall a b (m :: * -> *).
    (Ord a, Ord b, MonadThrow m) =>
    b -> Bimap a b -> m a
    B.lookupR k
    e Bimap Text k
    m