module Network.Yogurt.IO
( writeToTTY, splitAtPrompt
, maybeInput
, hGetImpatientLine
) where
import System.IO
import System.Console.Readline
import Control.Monad (when)
import Data.List (elemIndices)
writeToTTY :: String -> IO ()
writeToTTY msg = do
let (prePrompt, prompt) = splitAtPrompt msg
buf <- getLineBuffer
pt <- getPoint
setLineBuffer ""
setPoint 0
redisplay
when (prePrompt /= "") $ do
putStr prePrompt
onNewLine
message prompt
insertText buf
setPoint pt
redisplay
splitAtPrompt :: String -> (String, String)
splitAtPrompt cs = case elemIndices '\n' cs of
[] -> ("", cs)
is -> splitAt (last is + 1) cs
maybeInput :: IO String -> IO (Maybe String)
maybeInput input = fmap Just input `catch` const (return Nothing)
hGetImpatientLine :: Handle -> Int -> IO String
hGetImpatientLine h patience = rec where
rec = do
c <- hGetChar h
if c == '\n'
then return [c]
else do
b <- hWaitForInput h patience
if b
then rec >>= return . (c:)
else return [c]