This question is a sequel to the following question: How to prevent inputs being flushed into output?
Using this program, I observed that Function keys (and some others) are compositions of multiple characters:
'\ESC' -- F1 pressed
'O'
'P'
'\ESC' -- Insert pressed
'['
'2'
'~'
'\ESC' -- Alt+v pressed
'v'
So I wanted to read such keys. Here is my attempt:
import Control.Monad
import System.IO
main :: IO ()
main = forever $ do
hSetEcho stdin False
c <- getChar
cs <- getRemaining
putStrLn $ case c:cs of
"\ESCOP" -> "\\F1"
"\ESCOQ" -> "\\F2"
"\ESCOR" -> "\\F3"
"\ESCOS" -> "\\F4"
"\ESC[15~" -> "\\F5"
"\ESC[17~" -> "\\F6"
"\ESC[18~" -> "\\F7"
"\ESC[19~" -> "\\F8"
"\ESC[20~" -> "\\F9"
"\ESC[24~" -> "\\F12"
"\ESC[2~" -> "\\Insert"
"\ESC[3~" -> "\\Delete"
"\ESC[H" -> "\\Home"
"\ESC[F" -> "\\End"
"\ESC[5~" -> "\\PageUp"
"\ESC[6~" -> "\\PageDown"
"\ESC[A" -> "\\↑"
"\ESC[D" -> "\\←"
"\ESC[B" -> "\\↓"
"\ESC[C" -> "\\→"
"\ESC[E" -> "\\NumPad5"
'\ESC':_ -> "\\Alt" ++ cs
_ -> c:cs
where
getRemaining = do
c <- hReady stdin >>= \r -> if r then pure <$> getChar else return ""
if null c
then return ""
else (c ++) <$> getRemaining
The key idea was to call getChar
until the input buffer becomes empty.
But why this failed and won't accept any input?
EDIT: I expected something like this:
a -- A pressed
A -- Shift+A pressed
\F1 -- F1 pressed
\Insert -- Insert pressed
\Alte -- Alt+E pressed
But I don't see any output. If I don't hSetEcho stdin False
, the only output are echoes.
EDIT 2: I tried:
getRemaining = do
c <- isEOF >>= \r -> if r then return "" else pure <$> getChar
case c of
"" -> return ""
_ -> (c ++) <$> getRemaining
But the problem remains the same.