2

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.

Dannyu NDos
  • 2,458
  • 13
  • 32
  • At least I want to know the reason of failure? – Dannyu NDos Aug 13 '19 at 00:04
  • 2
    A bit of advice on the form of your question: you asked "why this failed", but it would also have been good to explain what "failure" means to you. Otherwise people have to guess what you are trying to understand, and risk guessing wrong. There are so many ways things can "not work". A good format of question is **"what I did, what I expected, what I saw"**, and for more subtle problems "why what I saw doesn't match what I expected". – Li-yao Xia Aug 13 '19 at 00:33
  • Sorry, my first answer was too hasty, the function keys do translate to escape sequences. Maybe you're having trouble with the fact that `stdin` is buffered. – Li-yao Xia Aug 13 '19 at 00:43

0 Answers0