mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-24 00:13:47 -07:00
ShellPrompt: check for executables and better error handling
Code contributed by Spencer (basically I just removed FilePath depenency).
This commit is contained in:
@@ -16,7 +16,6 @@ module XMonadContrib.ShellPrompt (
|
|||||||
-- * Usage
|
-- * Usage
|
||||||
-- $usage
|
-- $usage
|
||||||
shellPrompt
|
shellPrompt
|
||||||
, rmPath
|
|
||||||
, split
|
, split
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@@ -62,26 +61,29 @@ getShellCompl s
|
|||||||
f <- fmap (lines . fromMaybe "") $ runProcessWithInput "/bin/bash" [] ("compgen -A file " ++ s ++ "\n")
|
f <- fmap (lines . fromMaybe "") $ runProcessWithInput "/bin/bash" [] ("compgen -A file " ++ s ++ "\n")
|
||||||
c <- commandCompletionFunction s
|
c <- commandCompletionFunction s
|
||||||
hPutStrLn stdout s
|
hPutStrLn stdout s
|
||||||
return $ map escape . sort . nub $ f ++ c
|
return . map escape . sort . nub $ f ++ c
|
||||||
| otherwise = return []
|
| otherwise = return []
|
||||||
|
|
||||||
commandCompletionFunction :: String -> IO [String]
|
commandCompletionFunction :: String -> IO [String]
|
||||||
commandCompletionFunction str
|
commandCompletionFunction str
|
||||||
| '/' `elem` str = return []
|
| '/' `elem` str = return []
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
p <- getEnv "PATH"
|
p <- getEnv "PATH" `catch` const (return [])
|
||||||
cl p
|
let ds = split ':' p
|
||||||
where
|
fp d f = d ++ "/" ++ f
|
||||||
cl = liftM (nub . rmPath . concat) . mapM cmpl . split ':'
|
es <- forM ds $ \d -> do
|
||||||
cmpl s = filter (isPrefixOf str) `fmap` getFileNames s
|
exists <- doesDirectoryExist d
|
||||||
|
if exists
|
||||||
|
then getDirectoryContents d >>= filterM (isExecutable . fp d)
|
||||||
|
else return []
|
||||||
|
return . filter (isPrefixOf str) . concat $ es
|
||||||
|
|
||||||
getFileNames :: FilePath -> IO [FilePath]
|
isExecutable :: FilePath ->IO Bool
|
||||||
getFileNames fp =
|
isExecutable f = do
|
||||||
getDirectoryContents fp `catch` \_ -> return []
|
fe <- doesFileExist f
|
||||||
|
if fe
|
||||||
rmPath :: [String] -> [String]
|
then fmap executable $ getPermissions f
|
||||||
rmPath s =
|
else return False
|
||||||
map (reverse . fst . break (=='/') . reverse) s
|
|
||||||
|
|
||||||
split :: Eq a => a -> [a] -> [[a]]
|
split :: Eq a => a -> [a] -> [[a]]
|
||||||
split _ [] = []
|
split _ [] = []
|
||||||
@@ -89,7 +91,7 @@ split e l =
|
|||||||
f : split e (rest ls)
|
f : split e (rest ls)
|
||||||
where
|
where
|
||||||
(f,ls) = span (/=e) l
|
(f,ls) = span (/=e) l
|
||||||
rest s | s == [] = []
|
rest s | s == [] = []
|
||||||
| otherwise = tail s
|
| otherwise = tail s
|
||||||
|
|
||||||
escape :: String -> String
|
escape :: String -> String
|
||||||
@@ -97,7 +99,7 @@ escape [] = ""
|
|||||||
escape (' ':xs) = "\\ " ++ escape xs
|
escape (' ':xs) = "\\ " ++ escape xs
|
||||||
escape (x:xs)
|
escape (x:xs)
|
||||||
| isSpecialChar x = '\\' : x : escape xs
|
| isSpecialChar x = '\\' : x : escape xs
|
||||||
| otherwise = x : escape xs
|
| otherwise = x : escape xs
|
||||||
|
|
||||||
isSpecialChar :: Char -> Bool
|
isSpecialChar :: Char -> Bool
|
||||||
isSpecialChar = flip elem "\\@\"'#?$*()[]{};"
|
isSpecialChar = flip elem "\\@\"'#?$*()[]{};"
|
||||||
|
Reference in New Issue
Block a user