module FortyTwo.Utils where
import System.Console.ANSI (cursorUpLine, clearFromCursorToScreenEnd)
import System.IO (hSetBuffering, hFlush, hSetEcho, hReady, stdin, stdout, BufferMode(..))
import Data.List (findIndex, findIndices, elemIndex, intercalate)
import Control.Monad (when)
import Data.Maybe (fromJust)
import FortyTwo.Types(Option(..), Options)
import FortyTwo.Constants (emptyString)
noBuffering :: IO()
noBuffering = do
hSetBuffering stdin NoBuffering
hSetBuffering stdout NoBuffering
restoreBuffering :: IO()
restoreBuffering = do
hSetBuffering stdin LineBuffering
hSetBuffering stdout LineBuffering
noEcho :: IO ()
noEcho = hSetEcho stdin False
restoreEcho :: IO ()
restoreEcho = hSetEcho stdin True
clearLines :: Int -> IO()
clearLines lines' = do
cursorUpLine lines'
clearFromCursorToScreenEnd
map' :: (Int -> a -> b) -> [a] -> [b]
map' f = zipWith f [0..]
filter' :: Eq a => (Int -> a -> Bool) -> [a] -> [a]
filter' f xs = [x | x <- xs, f (fromJust (elemIndex x xs)) x]
getKey :: IO String
getKey = reverse <$> getKey' emptyString
where
getKey' chars = do
char <- getChar
more <- hReady stdin
(if more then getKey' else return) (char:chars)
flush :: IO()
flush = hFlush stdout
getOptionsMeta :: Options -> (Int, Int, Maybe Int)
getOptionsMeta options = (0, length options 1, getFocusedOptionIndex options)
stringsToOptions :: [String] -> Options
stringsToOptions options = [
Option { value = o, isFocused = False, isSelected = False } | o <- options
]
focusOption :: Int -> Options -> Options
focusOption focusedIndex = map' $ \ i o ->
Option {
value = getOptionValue o,
isSelected = getOptionIsSelected o,
isFocused = focusedIndex == i
}
toggleFocusedOption :: Int -> Options -> Options
toggleFocusedOption focusedIndex = map' $ \ i o ->
Option {
value = getOptionValue o,
isFocused = focusedIndex == i,
isSelected = if focusedIndex == i then
not $ getOptionIsSelected o
else getOptionIsSelected o
}
toCommaSeparatedString :: [String] -> String
toCommaSeparatedString = intercalate ", "
getOptionValue :: Option -> String
getOptionValue Option { value } = value
getOptionIsFocused :: Option -> Bool
getOptionIsFocused Option { isFocused } = isFocused
getOptionIsSelected :: Option -> Bool
getOptionIsSelected Option { isSelected } = isSelected
getFocusedOptionIndex :: Options -> Maybe Int
getFocusedOptionIndex = findIndex getOptionIsFocused
getSelecteOptionsIndexes :: Options -> [Int]
getSelecteOptionsIndexes = findIndices getOptionIsSelected