aboutsummaryrefslogtreecommitdiffstats
path: root/ShellPrompt.hs
diff options
context:
space:
mode:
authorSpencer Janssen <sjanssen@cse.unl.edu>2007-10-16 11:05:52 +0200
committerSpencer Janssen <sjanssen@cse.unl.edu>2007-10-16 11:05:52 +0200
commit27c2f00b6bd9296024dc7f07e45778709ab30e7a (patch)
treec1edc8bf77fbf214a9f481920595d88ddd6598b2 /ShellPrompt.hs
parent47943248fb5959182b9351bf5954f4c8fdbdd1ae (diff)
downloadXMonadContrib-27c2f00b6bd9296024dc7f07e45778709ab30e7a.tar.gz
XMonadContrib-27c2f00b6bd9296024dc7f07e45778709ab30e7a.tar.xz
XMonadContrib-27c2f00b6bd9296024dc7f07e45778709ab30e7a.zip
ShellPrompt: traverse $PATH once per invocation. Major speed improvement
darcs-hash:20071016090552-a5988-eed1d245021b0284bcd5b90f1fdc93d59eb2dd7f.gz
Diffstat (limited to '')
-rw-r--r--ShellPrompt.hs52
1 files changed, 28 insertions, 24 deletions
diff --git a/ShellPrompt.hs b/ShellPrompt.hs
index 9ff06c3..5dfb445 100644
--- a/ShellPrompt.hs
+++ b/ShellPrompt.hs
@@ -52,31 +52,35 @@ data Shell = Shell
instance XPrompt Shell where
showXPrompt Shell = "Run: "
-
shellPrompt :: XPConfig -> X ()
-shellPrompt c = mkXPrompt Shell c getShellCompl spawn
-
-getShellCompl :: String -> IO [String]
-getShellCompl s
- | s /= "" && last s /= ' ' = do
- f <- fmap lines $ runProcessWithInput "/bin/bash" [] ("compgen -A file " ++ s ++ "\n")
- c <- commandCompletionFunction s
- return . map escape . sort . (toList . fromList) $ f ++ c
- | otherwise = return []
-
-commandCompletionFunction :: String -> IO [String]
-commandCompletionFunction str
- | '/' `elem` str = return []
- | otherwise = do
- p <- getEnv "PATH" `catch` const (return [])
- let ds = split ':' p
- fp d f = d ++ "/" ++ f
- es <- forM ds $ \d -> do
- exists <- doesDirectoryExist d
- if exists
- then getDirectoryContents d >>= filterM (isExecutable . fp d)
- else return []
- return . filter (isPrefixOf str) . concat $ es
+shellPrompt c = do
+ cmds <- io $ getCommands
+ mkXPrompt Shell c (getShellCompl cmds) spawn
+
+getShellCompl :: [String] -> String -> IO [String]
+getShellCompl cmds s | s == "" || last s == ' ' = return []
+ | otherwise = do
+ f <- fmap lines $ runProcessWithInput "/bin/bash" [] ("compgen -A file " ++ s ++ "\n")
+ return . map escape . uniqSort $ f ++ commandCompletionFunction cmds s
+
+uniqSort :: Ord a => [a] -> [a]
+uniqSort = toList . fromList
+
+commandCompletionFunction :: [String] -> String -> [String]
+commandCompletionFunction cmds str | '/' `elem` str = []
+ | otherwise = filter (isPrefixOf str) cmds
+
+getCommands :: IO [String]
+getCommands = do
+ p <- getEnv "PATH" `catch` const (return [])
+ let ds = split ':' p
+ fp d f = d ++ "/" ++ f
+ es <- forM ds $ \d -> do
+ exists <- doesDirectoryExist d
+ if exists
+ then getDirectoryContents d >>= filterM (isExecutable . fp d)
+ else return []
+ return . uniqSort . concat $ es
isExecutable :: FilePath ->IO Bool
isExecutable f = do