1{-# LANGUAGE RecordWildCards #-}
7import Control.Applicative
8import Control.Concurrent
9import Control.Exception
12import System.Console.ANSI
17defaultConfig :: Config
22 , configSticky = False
27 -> (((Config -> Config) -> IO ()) -> IO a)
29withSpinner spec fn = do
31 configIORef <- newIORef defaultConfig
32 threadId <- forkIO $ tick spec configIORef 0
33 finally (fn (modifyIORef configIORef)) (cleanup threadId configIORef)
35cleanup :: ThreadId -> IORef Config -> IO ()
36cleanup threadId configIORef = do
37 throwTo threadId ThreadKilled
39 finalLine <- renderFinal <$> readIORef configIORef
41 Just line -> putStrLn line
53tick :: Spec -> IORef Config -> Int -> IO ()
54tick spec@Spec{..} configIORef i = do
55 config <- readIORef configIORef
56 putStr $ renderTick spec i config
58 threadDelay $ usInMs * specInterval
60 tick spec configIORef $ i + 1
62renderTick :: Spec -> Int -> Config -> String
63renderTick Spec{..} i Config{..} = unwords $ catMaybes
64 [ emptyMaybe configPrefix
65 , emptyMaybe configSymbol <|> (emptyMaybe $ cycle specFrames !! i)
66 , emptyMaybe configMessage
69renderFinal :: Config -> Maybe String
70renderFinal Config{..} =
72 True -> Just $ unwords $ mapMaybe emptyMaybe
79emptyMaybe :: [a] -> Maybe [a]
80emptyMaybe [] = Nothing
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