diff options
author | Spencer Janssen <sjanssen@cse.unl.edu> | 2007-10-16 11:05:52 +0200 |
---|---|---|
committer | Spencer Janssen <sjanssen@cse.unl.edu> | 2007-10-16 11:05:52 +0200 |
commit | 27c2f00b6bd9296024dc7f07e45778709ab30e7a (patch) | |
tree | c1edc8bf77fbf214a9f481920595d88ddd6598b2 /ShellPrompt.hs | |
parent | 47943248fb5959182b9351bf5954f4c8fdbdd1ae (diff) | |
download | XMonadContrib-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 'ShellPrompt.hs')
-rw-r--r-- | ShellPrompt.hs | 52 |
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 |