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 = reverse <$> getKey' emptyString
where
getKey' chars = do
char <- getChar
more <- hReady stdin
(if more then getKey' else return) (char:chars)
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 ", "
flush :: IO()
flush = hFlush stdout
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