content: -----------------------------------------------------------------------------
  -- |
  -- Module      :  XMonad.Prompt.Input
  -- 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 defaultXPConfig \"Fire\" ?+ fireEmployee
  --
  -- If @employees@ contains a list of all his employees, he could also
  -- create an autocompleting version, like this:
  --
  -- > firingPrompt' = inputPromptWithCompl defaultXPConfig \"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.
  
  data InputPrompt = InputPrompt String
  
  instance XPrompt InputPrompt  where
      showXPrompt (InputPrompt s) = s ++ ": "
  
  -- | 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 c p = inputPromptWithCompl c p (const (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 c p compl = mkXPromptWithReturn (InputPrompt p) c compl 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 ()
  x ?+ k = x >>= maybe (return ()) k