ManPrompt.hs: auto-complete explicit paths (those with `/')

Bash's compgen is used for this (like in ShellPrompt.hs).

Enable all GHC warnings.

Improve documentation (slightly).
This commit is contained in:
"Valery V. Vorotyntsev" 2007-11-04 20:20:56 +00:00
parent 3fb0cf1391
commit 92ef6cd811

View File

@ -1,3 +1,4 @@
{-# OPTIONS_GHC -Wall #-}
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- | -- |
-- Module : XMonadContrib.ManPrompt -- Module : XMonadContrib.ManPrompt
@ -6,7 +7,7 @@
-- --
-- Maintainer : valery.vv@gmail.com -- Maintainer : valery.vv@gmail.com
-- Stability : unstable -- Stability : unstable
-- Portability : unportable -- Portability : non-portable (uses \"manpath\" and \"bash\")
-- --
-- A manual page prompt for XMonad window manager. -- A manual page prompt for XMonad window manager.
-- --
@ -15,9 +16,7 @@
-- * narrow completions by section number, if the one is specified -- * narrow completions by section number, if the one is specified
-- (like @\/etc\/bash_completion@ does) -- (like @\/etc\/bash_completion@ does)
-- --
-- * handle explicit paths (e.g., @~\/src\/xmonad\/man\/xmonad.1@) -- * test with QuickCheck
--
-- * quickcheck properties
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module XMonadContrib.ManPrompt ( module XMonadContrib.ManPrompt (
@ -48,7 +47,7 @@ import Data.Maybe
-- --
-- 2. In your keybindings add something like: -- 2. In your keybindings add something like:
-- --
-- > , ((modMask, xK_F1), manPrompt defaultXPConfig) -- > , ((modMask, xK_F1), manPrompt defaultXPConfig) -- mod-f1 %! Query for manual page to be displayed
-- %import XMonadContrib.XPrompt -- %import XMonadContrib.XPrompt
-- %import XMonadContrib.ManPrompt -- %import XMonadContrib.ManPrompt
@ -64,33 +63,36 @@ manPrompt :: XPConfig -> X ()
manPrompt c = mkXPrompt Man c manCompl $ runInTerm . (++) "man " manPrompt c = mkXPrompt Man c manCompl $ runInTerm . (++) "man "
manCompl :: String -> IO [String] manCompl :: String -> IO [String]
manCompl s = getManpages >>= flip mkComplFunFromList s manCompl str | '/' `elem` str = do
-- XXX It may be better to use readline instead of bash's compgen...
-- | Obtain the list of manual pages. lines `fmap` getCommandOutput ("bash -c 'compgen -A file " ++ str ++ "'")
-- | otherwise = do
-- /XXX Code duplication!/ mp <- getCommandOutput "manpath -g 2>/dev/null" `E.catch` \_ -> return []
-- Adopted from 'ShellPrompt.getCommands'. let sects = ["man" ++ show n | n <- [1..9 :: Int]]
getManpages :: IO [String] dirs = [d ++ "/" ++ s | d <- split ':' mp, s <- sects]
getManpages = do stripExt = reverse . drop 1 . dropWhile (/= '.') . reverse
p <- getCommandOutput "manpath -g 2>/dev/null" `E.catch` const (return []) mans <- forM dirs $ \d -> do
let sections = ["man" ++ show n | n <- [1..9 :: Int]] -- XXX "cat1".."cat9"? exists <- doesDirectoryExist d
ds = [d ++ "/" ++ s | d <- split ':' p, s <- sections] if exists
stripSec = reverse . drop 1 . dropWhile (/= '.') . reverse then map (stripExt . stripSuffixes [".gz", ".bz2"]) `fmap`
ms <- forM ds $ \d -> do getDirectoryContents d
exists <- doesDirectoryExist d else return []
if exists mkComplFunFromList (uniqSort $ concat mans) str
then map (stripSec . stripSuffixes [".gz", ".bz2"]) `fmap`
getDirectoryContents d
else return []
return . uniqSort . concat $ ms
-- | Run a command using shell and return its output. -- | Run a command using shell and return its output.
--
-- XXX merge with 'Run.runProcessWithInput'?
--
-- * update documentation of the latter (there is no 'Maybe' in result)
--
-- * ask \"gurus\" whether @evaluate (length ...)@ approach is
-- better\/more idiomatic
getCommandOutput :: String -> IO String getCommandOutput :: String -> IO String
getCommandOutput s = do getCommandOutput s = do
(pin, pout, perr, ph) <- runInteractiveCommand s (pin, pout, perr, ph) <- runInteractiveCommand s
hClose pin hClose pin
output <- hGetContents pout output <- hGetContents pout
E.evaluate (null output) E.evaluate (length output)
hClose perr hClose perr
waitForProcess ph waitForProcess ph
return output return output