stack-run 0.1.1.2 → 0.1.1.3
raw patch · 4 files changed
+193/−1 lines, 4 files
Files
- src/System/Console/Questioner/Autocomplete.hs +2/−0
- src/System/Console/Questioner/ProgressIndicators.hs +139/−0
- src/System/Console/Questioner/Util.hs +48/−0
- stack-run.cabal +4/−1
+ src/System/Console/Questioner/Autocomplete.hs view
@@ -0,0 +1,2 @@+module System.Console.Questioner.Autocomplete+ where
+ src/System/Console/Questioner/ProgressIndicators.hs view
@@ -0,0 +1,139 @@+-- |+-- Module : System.Console.Questioner.ProgressIndicators+-- Description : Provides progress indicators and spinners+-- Copyright : (c) Pedro Yamada+-- License : MIT+--+-- Maintainer : Pedro Yamada <tacla.yamada@gmail.com>+-- Stability : stable+-- Portability : non-portable (not tested on multiple environments)+--+-- Shamefully steals ideas from modules like `Inquirer.js` and `go-spin`.+module System.Console.Questioner.ProgressIndicators+ where++import Control.Applicative ((<$>))+import Control.Concurrent -- (MVar, ThreadId, forkIO, killThread, modifyMVar_,+ -- newMVar, tryTakeMVar, threadDelay)+import Control.Monad (forever)+import Data.Maybe (fromMaybe)+import System.Console.ANSI (clearLine, setCursorColumn)+import System.Console.Terminal.Size (size, Window(..))+import System.IO (BufferMode(NoBuffering), stdout)++import System.Console.Questioner.Util++-- ProgressIndicator type and utilities+-------------------------------------------------------------------------------++data ProgressIndicator = BarIndicator ThreadId (MVar Double)+ | SpinnerIndicator ThreadId++stopIndicator :: ProgressIndicator -> IO ()+stopIndicator i = case i of+ (BarIndicator tid _) -> stopProgressIndicator' tid+ (SpinnerIndicator tid) -> stopProgressIndicator' tid+ where+ stopProgressIndicator' tid = do+ killThread tid+ clearLine+ setCursorColumn 0++updateIndicator :: ProgressIndicator -> Double -> IO ()+updateIndicator (BarIndicator _ c) i = putMVar c i+updateIndicator _ _ = return ()++-- ProgressBars+-------------------------------------------------------------------------------++newtype ProgressBarTheme = ProgressBarTheme (Double -> IO ())++progressBar :: ProgressBarTheme -> IO ProgressIndicator+progressBar (ProgressBarTheme render) = do+ mi <- newEmptyMVar+ render 0+ tid <- forkIO $ hWithBufferMode stdout NoBuffering $ forever $ do+ i <- takeMVar mi+ clearLine+ setCursorColumn 0+ render i+ putMVar mi 0+ return $ BarIndicator tid mi++-- Spinners+-------------------------------------------------------------------------------++type SpinnerTheme = String++spinner :: SpinnerTheme -> Int -> String -> IO ProgressIndicator+spinner theme interval prompt = SpinnerIndicator <$> forkIO (setup $ loop 0)+ where+ setup = hWithBufferMode stdout NoBuffering++ loop i = do+ clearLine+ setCursorColumn 0+ putStr $ ' ' : spinnerState i : ' ' : prompt+ threadDelay interval+ loop $ i + 1++ -- TODO - parameterize+ themeLen = length theme+ spinnerState i = theme !! (i `mod` themeLen)++-- Boilerplate for easier usage (TODO - generate this with TH)+-------------------------------------------------------------------------------++simple1SpinnerTheme, simple2SpinnerTheme, simple3SpinnerTheme,+ simple4SpinnerTheme, simple5SpinnerTheme, simple6SpinnerTheme,+ simple7SpinnerTheme, simple8SpinnerTheme, simple9SpinnerTheme,+ dots1SpinnerTheme, dots2SpinnerTheme, dots3SpinnerTheme, dots4SpinnerTheme,+ dots5SpinnerTheme, dots6SpinnerTheme, dots7SpinnerTheme :: SpinnerTheme++simple1Spinner, simple2Spinner, simple3Spinner, simple4Spinner, simple5Spinner,+ simple6Spinner, simple7Spinner, simple8Spinner, simple9Spinner, dots1Spinner,+ dots2Spinner, dots3Spinner, dots4Spinner, dots5Spinner, dots6Spinner,+ dots7Spinner :: Int -> String -> IO ProgressIndicator++simple1SpinnerTheme = "|/-\\"+simple2SpinnerTheme = "◴◷◶◵"+simple3SpinnerTheme = "◰◳◲◱"+simple4SpinnerTheme = "◐◓◑◒"+simple5SpinnerTheme = "▉▊▋▌▍▎▏▎▍▌▋▊▉"+simple6SpinnerTheme = "▌▄▐▀"+simple7SpinnerTheme = "╫╪"+simple8SpinnerTheme = "■□▪▫"+simple9SpinnerTheme = "←↑→↓"+simple1Spinner = spinner simple1SpinnerTheme+simple2Spinner = spinner simple2SpinnerTheme+simple3Spinner = spinner simple3SpinnerTheme+simple4Spinner = spinner simple4SpinnerTheme+simple5Spinner = spinner simple5SpinnerTheme+simple6Spinner = spinner simple6SpinnerTheme+simple7Spinner = spinner simple7SpinnerTheme+simple8Spinner = spinner simple8SpinnerTheme+simple9Spinner = spinner simple9SpinnerTheme++dots1SpinnerTheme = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"+dots2SpinnerTheme = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"+dots3SpinnerTheme = "⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆"+dots4SpinnerTheme = "⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋"+dots5SpinnerTheme = "⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁"+dots6SpinnerTheme = "⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈"+dots7SpinnerTheme = "⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈"+dots1Spinner = spinner dots1SpinnerTheme+dots2Spinner = spinner dots2SpinnerTheme+dots3Spinner = spinner dots3SpinnerTheme+dots4Spinner = spinner dots4SpinnerTheme+dots5Spinner = spinner dots5SpinnerTheme+dots6Spinner = spinner dots6SpinnerTheme+dots7Spinner = spinner dots7SpinnerTheme++simpleProgressBarTheme :: ProgressBarTheme+simpleProgressBarTheme = ProgressBarTheme $ \i -> do+ w <- fromMaybe (45 :: Int) <$> (fmap width <$> size)+ let blocks = floor ((fromIntegral w :: Double) * i) - 3+ putStr (replicate blocks '▉')++simpleProgressBar :: IO ProgressIndicator+simpleProgressBar = progressBar simpleProgressBarTheme
+ src/System/Console/Questioner/Util.hs view
@@ -0,0 +1,48 @@+module System.Console.Questioner.Util+ where++import Control.Exception (bracket_)+import System.Console.ANSI (clearLine, cursorDownLine, cursorUpLine,+ hideCursor, showCursor)+import System.IO (BufferMode(..), Handle, hGetBuffering, hSetBuffering,+ hSetEcho, stdin)++-- |+-- Performs an IO action with some buffer mode on a handle+hWithBufferMode :: Handle -> BufferMode -> IO a -> IO a+hWithBufferMode handle bufferMode action = do+ originalBuffering <- hGetBuffering handle+ bracket_+ (hSetBuffering handle bufferMode)+ (hSetBuffering handle originalBuffering)+ action++-- |+-- Performs an IO action with NoBuffering on a handle+hWithNoBuffering :: Handle -> IO a -> IO a+hWithNoBuffering handle = hWithBufferMode handle NoBuffering++-- |+-- Performs an IO action with the console cursor hidden+withNoCursor :: IO a -> IO a+withNoCursor = bracket_ hideCursor showCursor++-- |+-- Performs an IO action with console "echoing" supressed+withNoEcho :: IO a -> IO a+withNoEcho = bracket_ (hSetEcho stdin False) (hSetEcho stdin True)++-- |+-- Clears the screen from the cursor's current position until `n` lines+-- above it+clearFromCursorTo :: Int -> IO ()+clearFromCursorTo nlines = do+ cursorUpLine nlines+ loop nlines+ cursorUpLine nlines+ where+ loop 0 = return ()+ loop n = do+ clearLine+ cursorDownLine 1+ loop (n - 1)
stack-run.cabal view
@@ -1,5 +1,5 @@ name: stack-run-version: 0.1.1.2+version: 0.1.1.3 synopsis: An equivalent to cabal run for stack. description: Finds the project root, compiles your code and runs the first or set default executable. It's a shorthand for@@ -21,6 +21,9 @@ executable stack-run main-is: Main.hs other-modules: System.Console.Questioner+ , System.Console.Questioner.Autocomplete+ , System.Console.Questioner.ProgressIndicators+ , System.Console.Questioner.Util build-depends: Cabal , terminal-size , vty