module System.Console.ListPrompt
(
Color
, ListPromptOptions(..)
, simpleListPrompt
, Default(..)
)
where
import Control.Monad (forM_)
import Data.Default (Default (..), def)
import System.Console.ANSI
import System.IO (BufferMode (..), stdin)
import System.Console.ListPrompt.Internal
import System.Console.ListPrompt.Types
simpleListPrompt :: ListPromptOptions -> Choices -> IO String
simpleListPrompt options choices = setup $ do
dimensions <- getDimensionsIO numChoices
selection <- waitForSelection dimensions 0
setSGR []
clearScreen
setCursorPosition 0 0
return selection
where
setup = withNoBuffering stdin NoBuffering . withNoCursor . withNoEcho
numChoices = length choices
waitForSelection dimensions currentIdx = do
clearScreen
renderListOptions options dimensions choices currentIdx
i <- getChar
case i of
'\n' -> return $ choices !! currentIdx
'j' -> waitForSelection
dimensions
((currentIdx + 1) `rem` numChoices)
'k' -> waitForSelection
dimensions
currentIdx'
where
currentIdx' = if currentIdx == 0
then length choices 1
else currentIdx 1
_ -> waitForSelection dimensions currentIdx
renderListOptions :: ListPromptOptions
-> ListPromptDimensions
-> Choices
-> Int
-> IO ()
renderListOptions options dimensions choices currentIdx = do
clearScreen
forM_ [0..2] $ drawLine options dimensions
forM_ (zip [2..] choices) $ \(i, t) ->
drawTextLine options dimensions i t (i2 == currentIdx)
forM_ [len + 2..len + 3] $ drawLine options dimensions
where
len = length choices
drawLine :: ListPromptOptions -> ListPromptDimensions -> Int -> IO ()
drawLine options dimensions@ListPromptDimensions{..} n = do
let (_, w) = listPromptSize
drawTextLine options dimensions n (replicate w ' ') False
drawTextLine :: ListPromptOptions -> ListPromptDimensions
-> Int
-> String
-> Bool
-> IO ()
drawTextLine ListPromptOptions{..} ListPromptDimensions{..} n str selected = do
setSGR $ if selected then selectedItemSGR else normalItemSGR
let (y1, x1) = targetCoordinate
setCursorPosition (y1 + n) x1
let (_, w) = listPromptSize
putStrLn $ " " ++ str ++ replicate (w length str) ' '