-----------------------------------------------------------------------------
-- |
-- Module      :  XMonad.Prompt.AppLauncher
-- Description :  A prompt for launch applications that receive command line parameters.
-- Copyright   :  (C) 2008 Luis Cabellos
-- License     :  BSD3
--
-- Maintainer  :  zhen.sydow@gmail.com
-- Stability   :  unstable
-- Portability :  unportable
--
-- A module for launch applicationes that receive parameters in the command
-- line. The launcher call a prompt to get the parameters.
--
-----------------------------------------------------------------------------
module XMonad.Prompt.AppLauncher ( -- * Usage
                                    -- $usage
                                    launchApp
                                   ,module XMonad.Prompt
                                  -- * Use case: launching gimp with file
                                  -- $tip

                                  -- * Types
                                   ,Application, AppPrompt,
                                  ) where

import XMonad (X(),MonadIO)
import XMonad.Core (spawn)
import XMonad.Prompt (XPrompt(showXPrompt), mkXPrompt, XPConfig(searchPredicate))
import XMonad.Prompt.Shell (getShellCompl)

{- $usage
   This module is intended to allow the launch of the same application
   but changing the parameters using the user response. For example, when
   you want to open a image in gimp program, you can open gimp and then use
   the File Menu to open the image or you can use this module to select
   the image in the command line.

   We use Prompt to get the user command line. This also allow to autoexpand
   the names of the files when we are writing the command line.
 -}

{- $tip

First, you need to import necessary modules. Prompt is used to get the promp
configuration and the AppLauncher module itself.

> import XMonad.Prompt
> import XMonad.Prompt.AppLauncher as AL

Then you can add the bindings to the applications.

> ...
> , ((modm, xK_g), AL.launchApp def "gimp" )
> , ((modm, xK_g), AL.launchApp def "evince" )
> ...

 -}

-- A customized prompt
newtype AppPrompt = AppPrompt String
instance XPrompt AppPrompt where
    showXPrompt :: AppPrompt -> String
showXPrompt (AppPrompt String
n) = String
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" "

type Application = String
type Parameters = String

{- | Given an application and its parameters, launch the application. -}
launch :: MonadIO m => Application -> Parameters -> m ()
launch :: forall (m :: * -> *). MonadIO m => String -> String -> m ()
launch String
app String
params = String -> m ()
forall (m :: * -> *). MonadIO m => String -> m ()
spawn ( String
app String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
params )


{- | Get the user's response to a prompt an launch an application using the
   input as command parameters of the application.-}
launchApp :: XPConfig -> Application -> X ()
launchApp :: XPConfig -> String -> X ()
launchApp XPConfig
config String
app = AppPrompt -> XPConfig -> ComplFunction -> (String -> X ()) -> X ()
forall p.
XPrompt p =>
p -> XPConfig -> ComplFunction -> (String -> X ()) -> X ()
mkXPrompt (String -> AppPrompt
AppPrompt String
app) XPConfig
config ([String] -> Predicate -> ComplFunction
getShellCompl [] (Predicate -> ComplFunction) -> Predicate -> ComplFunction
forall a b. (a -> b) -> a -> b
$ XPConfig -> Predicate
searchPredicate XPConfig
config) ((String -> X ()) -> X ()) -> (String -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ String -> String -> X ()
forall (m :: * -> *). MonadIO m => String -> String -> m ()
launch String
app