module XMonad.Prompt.Man (
manPrompt
, getCommandOutput
, Man
) where
import XMonad
import XMonad.Prelude
import XMonad.Prompt
import XMonad.Util.Run
import XMonad.Prompt.Shell (split)
import System.Directory
import System.FilePath (dropExtensions, (</>))
import System.IO
import System.Process
import qualified Control.Exception as E
data Man = Man
instance XPrompt Man where
showXPrompt :: Man -> String
showXPrompt Man
Man = String
"Manual page: "
manPrompt :: XPConfig -> X ()
manPrompt :: XPConfig -> X ()
manPrompt XPConfig
c = do
[String]
mans <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
io IO [String]
getMans
forall p.
XPrompt p =>
p -> XPConfig -> ComplFunction -> (String -> X ()) -> X ()
mkXPrompt Man
Man XPConfig
c (XPConfig -> [String] -> ComplFunction
manCompl XPConfig
c [String]
mans) forall a b. (a -> b) -> a -> b
$ String -> String -> X ()
runInTerm String
"" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a] -> [a]
(++) String
"man "
getMans :: IO [String]
getMans :: IO [String]
getMans = do
String
paths <- do
let getout :: String -> IO String
getout String
cmd = String -> IO String
getCommandOutput String
cmd forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`E.catch` \E.SomeException{} -> forall (m :: * -> *) a. Monad m => a -> m a
return String
""
String
p1 <- String -> IO String
getout String
"manpath -g 2>/dev/null"
String
p2 <- String -> IO String
getout String
"manpath 2>/dev/null"
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [[a]] -> [a]
intercalate String
":" forall a b. (a -> b) -> a -> b
$ String -> [String]
lines forall a b. (a -> b) -> a -> b
$ String
p1 forall a. [a] -> [a] -> [a]
++ String
p2
let sects :: [String]
sects = [String
"man" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
n | Int
n <- [Int
1..Int
9 :: Int]]
dirs :: [String]
dirs = [String
d String -> String -> String
</> String
s | String
d <- forall a. Eq a => a -> [a] -> [[a]]
split Char
':' String
paths, String
s <- [String]
sects]
[[String]]
mans <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (forall a. Eq a => [a] -> [a]
nub [String]
dirs) forall a b. (a -> b) -> a -> b
$ \String
d -> do
Bool
exists <- String -> IO Bool
doesDirectoryExist String
d
if Bool
exists
then forall a b. (a -> b) -> [a] -> [b]
map String -> String
dropExtensions forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ComplFunction
getDirectoryContents String
d
else forall (m :: * -> *) a. Monad m => a -> m a
return []
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Ord a => [a] -> [a]
uniqSort forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[String]]
mans
manCompl :: XPConfig -> [String] -> String -> IO [String]
manCompl :: XPConfig -> [String] -> ComplFunction
manCompl XPConfig
c [String]
mans String
s | String
s forall a. Eq a => a -> a -> Bool
== String
"" Bool -> Bool -> Bool
|| forall a. [a] -> a
last String
s forall a. Eq a => a -> a -> Bool
== Char
' ' = forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise = do
[String]
f <- String -> [String]
lines forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
getCommandOutput (String
"bash -c 'compgen -A file " forall a. [a] -> [a] -> [a]
++ String
s forall a. [a] -> [a] -> [a]
++ String
"'")
XPConfig -> [String] -> ComplFunction
mkComplFunFromList XPConfig
c ([String]
f forall a. [a] -> [a] -> [a]
++ [String]
mans) String
s
getCommandOutput :: String -> IO String
getCommandOutput :: String -> IO String
getCommandOutput String
s = do
(Handle
pin, Handle
pout, Handle
perr, ProcessHandle
_) <- String -> IO (Handle, Handle, Handle, ProcessHandle)
runInteractiveCommand String
s
Handle -> IO ()
hClose Handle
pin
String
output <- Handle -> IO String
hGetContents Handle
pout
forall a. a -> IO a
E.evaluate (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
output)
Handle -> IO ()
hClose Handle
perr
forall (m :: * -> *) a. Monad m => a -> m a
return String
output