1module Main (main) where
4import Control.Concurrent
7import qualified Data.Text as T
8import System.Environment
11import System.Process.Typed
14main = getArgs >>= runPrograms
16runPrograms :: [String] -> IO ()
18 exited <- newEmptyMVar
19 processes <- forM (zip progs (prettifyProcesses progs)) $ \(prog, pretty) -> do
21 startProcess . setStderr createPipe
22 . setStdout createPipe
27 putMVar exited (pretty, e)
31 isEmpty <- isEmptyMVar exited
33 forM (zip colors processes) $ \(color, (prog, p)) -> do
35 <$> writeOutput [color] prog (getStdout p)
36 <*> writeOutput [color] prog (getStderr p)
43 else threadDelay 100000
45 (prog, exitCode) <- readMVar exited
46 infoMessage $ T.pack prog <> " exited with " <> (T.pack . show) exitCode
47 forM_ processes (stopProcess . snd)
51colors = cycle [green, blue, magenta, cyan]
53writeOutput :: [String] -> String -> Handle -> IO Bool
54writeOutput color prog h = do
55 inputAvailable <- hReady h
59 putStrLn $ formatWith color (prog <> " | ") <> l
63prettifyProcesses :: [String] -> [String]
64prettifyProcesses ps' =
65 let ps = take 50 <$> ps'
66 maxLen = maximum . fmap length $ ps
67 in ps <&> \p -> p <> replicate (maxLen - length p) ' '
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list