----------------------------------------------------------------------------- -- | -- Module : XMonad.Prompt.DirExec -- Copyright : (C) 2008 Juraj Hercek -- License : BSD3 -- -- Maintainer : juhe_xmonad@hck.sk -- Stability : unstable -- Portability : unportable -- -- A directory file executables prompt for XMonad. This might be useful if you -- don't want to have scripts in your PATH environment variable (same -- executable names, different behavior) - otherwise you might want to use -- "XMonad.Prompt.Shell" instead - but you want to have easy access to these -- executables through the xmonad's prompt. -- ----------------------------------------------------------------------------- module XMonad.Prompt.DirExec ( -- * Usage -- $usage dirExecPrompt , dirExecPromptNamed , DirExec ) where import Control.Exception as E import System.Directory import Control.Monad import Data.List import XMonad import XMonad.Prompt econst :: Monad m => a -> IOException -> m a econst = const . return -- $usage -- 1. In your @~\/.xmonad\/xmonad.hs@: -- -- > import XMonad.Prompt.DirExec -- -- 2. In your keybindings add something like: -- -- > , ("M-C-x", dirExecPrompt defaultXPConfig spawn "/home/joe/.scipts") -- -- or -- -- > , ("M-C-x", dirExecPromptNamed defaultXPConfig spawn -- > "/home/joe/.scripts" "My Scripts: ") -- -- or add this after your default bindings: -- -- > ++ -- > [ ("M-x " ++ key, dirExecPrompt defaultXPConfig fn "/home/joe/.scripts") -- > | (key, fn) <- [ ("x", spawn), ("M-x", runInTerm "-hold") ] -- > ] -- > ++ -- -- The first alternative uses the last element of the directory path for -- a name of prompt. The second alternative uses the provided string -- for the name of the prompt. The third alternative defines 2 key bindings, -- first one spawns the program by shell, second one runs the program in -- terminal -- -- For detailed instruction on editing the key binding see -- "XMonad.Doc.Extending#Editing_key_bindings". data DirExec = DirExec String instance XPrompt DirExec where showXPrompt (DirExec name) = name -- | Function 'dirExecPrompt' starts the prompt with list of all executable -- files in directory specified by 'FilePath'. The name of the prompt is taken -- from the last element of the path. If you specify root directory - @\/@ - as -- the path, name @Root:@ will be used as the name of the prompt instead. The -- 'XPConfig' parameter can be used to customize visuals of the prompt. -- The runner parameter specifies the function used to run the program - see -- usage for more information dirExecPrompt :: XPConfig -> (String -> X ()) -> FilePath -> X () dirExecPrompt cfg runner path = do let name = (++ ": ") . last . (["Root"] ++) -- handling of "/" path parameter . words . map (\x -> if x == '/' then ' ' else x) $ path dirExecPromptNamed cfg runner path name -- | Function 'dirExecPromptNamed' does the same as 'dirExecPrompt' except -- the name of the prompt is specified by 'String' parameter. dirExecPromptNamed :: XPConfig -> (String -> X ()) -> FilePath -> String -> X () dirExecPromptNamed cfg runner path name = do let path' = path ++ "/" cmds <- io $ getDirectoryExecutables path' mkXPrompt (DirExec name) cfg (compList cmds) (runner . (path' ++)) where compList cmds s = return . filter (isInfixOf s) $ cmds getDirectoryExecutables :: FilePath -> IO [String] getDirectoryExecutables path = (getDirectoryContents path >>= filterM (\x -> let x' = path ++ x in liftM2 (&&) (doesFileExist x') (liftM executable (getPermissions x')))) `E.catch` econst []