    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Prompt.Input
    -- Description :  Prompt the user for input and pass it along to some other action.
    -- Copyright   :  (c) 2007 Brent Yorgey
    -- License     :  BSD-style (see LICENSE)
    --
    -- Maintainer  :  <byorgey@gmail.com>
    -- Stability   :  stable
    -- Portability :  unportable
    --
    -- A generic framework for prompting the user for input and passing it
    -- along to some other action.
    --
    -----------------------------------------------------------------------------

    module XMonad.Prompt.Input (
                                -- * Usage
                                -- $usage
                                inputPrompt,
                                inputPromptWithCompl,
                                (?+),
                                InputPrompt,
                               ) where

    import XMonad.Core
    import XMonad.Prompt

    -- $usage
    --
    -- To use this module, import it along with "XMonad.Prompt":
    --
    -- > import XMonad.Prompt
    -- > import XMonad.Prompt.Input
    --
    -- This module provides no useful functionality in isolation, but
    -- is intended for use in building other actions which require user
    -- input.
    --
    -- For example, suppose Mr. Big wants a way to easily fire his
    -- employees. We'll assume that he already has a function
    --
    -- > fireEmployee :: String -> X ()
    --
    -- which takes as input the name of an employee, and fires them.  He
    -- just wants a convenient way to provide the input for this function
    -- from within xmonad.  Here is where the "XMonad.Prompt.Input" module
    -- comes into play.  He can use the 'inputPrompt' function to create a
    -- prompt, and the '?+' operator to compose the prompt with the
    -- @fireEmployee@ action, like so:
    --
    -- > firingPrompt :: X ()
    -- > firingPrompt = inputPrompt def "Fire" ?+ fireEmployee
    --
    -- If @employees@ contains a list of all his employees, he could also
    -- create an autocompleting version, like this:
    --
    -- > firingPrompt' = inputPromptWithCompl def "Fire"
    -- >                     (mkComplFunFromList employees) ?+ fireEmployee
    --
    -- Now all he has to do is add a keybinding to @firingPrompt@ (or
    -- @firingPrompt'@), such as
    --
    -- >  , ((modm .|. controlMask, xK_f),  firingPrompt)
    --
    -- Now when Mr. Big hits mod-ctrl-f, a prompt will pop up saying
    -- \"Fire: \", waiting for him to type the name of someone to fire.
    -- If he thinks better of it after hitting mod-ctrl-f and cancels the
    -- prompt (e.g. by hitting Esc), the @fireEmployee@ action will not be
    -- invoked.
    --
    -- (For detailed instructions on editing your key bindings, see
    -- "XMonad.Doc.Extending#Editing_key_bindings".)
    --
    -- "XMonad.Prompt.Input" is also intended to ease the process of
    -- developing other modules which require user input. For an example
    -- of a module developed using this functionality, see
    -- "XMonad.Prompt.Email", which prompts the user for a recipient,
    -- subject, and one-line body, and sends a quick email.

    newtype InputPrompt = InputPrompt String

    instance XPrompt InputPrompt  where
        showXPrompt :: InputPrompt -> String
    showXPrompt (InputPrompt String
    s) = String
    s String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    ": "

    -- | Given a prompt configuration and some prompt text, create an X
    --   action which pops up a prompt waiting for user input, and returns
    --   whatever they type.  Note that the type of the action is @X
    --   (Maybe String)@, which reflects the fact that the user might
    --   cancel the prompt (resulting in @Nothing@), or enter an input
    --   string @s@ (resulting in @Just s@).
    inputPrompt :: XPConfig -> String -> X (Maybe String)
    inputPrompt :: XPConfig -> String -> X (Maybe String)
    inputPrompt XPConfig
    c String
    p = XPConfig -> String -> ComplFunction -> X (Maybe String)
    inputPromptWithCompl XPConfig
    c String
    p (IO [String] -> ComplFunction
    forall a b. a -> b -> a
    const ([String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []))

    -- | The same as 'inputPrompt', but with a completion function.  The
    --   type @ComplFunction@ is @String -> IO [String]@, as defined in
    --   "XMonad.Prompt".  The 'mkComplFunFromList' utility function, also
    --   defined in "XMonad.Prompt", is useful for creating such a
    --   function from a known list of possibilities.
    inputPromptWithCompl :: XPConfig -> String -> ComplFunction -> X (Maybe String)
    inputPromptWithCompl :: XPConfig -> String -> ComplFunction -> X (Maybe String)
    inputPromptWithCompl XPConfig
    c String
    p ComplFunction
    compl = InputPrompt
    -> XPConfig
    -> ComplFunction
    -> (String -> X String)
    -> X (Maybe String)
    forall p a.
    XPrompt p =>
    p -> XPConfig -> ComplFunction -> (String -> X a) -> X (Maybe a)
    mkXPromptWithReturn (String -> InputPrompt
    InputPrompt String
    p) XPConfig
    c ComplFunction
    compl String -> X String
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return

    infixr 1 ?+

    -- | A combinator for hooking up an input prompt action to a function
    --   which can take the result of the input prompt and produce another
    --   action. If the user cancels the input prompt, the
    --   second function will not be run.
    --
    --   The astute student of types will note that this is actually a
    --   very general combinator and has nothing in particular to do
    --   with input prompts.  If you find a more general use for it and
    --   want to move it to a different module, be my guest.
    (?+) :: (Monad m) => m (Maybe a) -> (a -> m ()) -> m ()
    m (Maybe a)
    x ?+ :: forall (m :: * -> *) a.
    Monad m =>
    m (Maybe a) -> (a -> m ()) -> m ()
    ?+ a -> m ()
    k = m (Maybe a)
    x m (Maybe a) -> (Maybe a -> m ()) -> m ()
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= m () -> (a -> m ()) -> Maybe a -> m ()
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (() -> m ()
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()) a -> m ()
    k