2016-11-21 4 views
1

私はHaskellでreadlineを次の行に転送カーソルなしで使用しようとしています。 ハスケルで次の行に転送せずに読み込む方法は?

> 1 2 + . <enter> 
3 

しかし、私は に従う取得する最も簡単な方法を見つけたい:プログラムを起動した後

readEvalPrintLoop :: IO() 
readEvalPrintLoop = do 
    line <- getLine 
    case line of 
      "bye" -> return() 
      line -> do putStrLn $ interpret line 
         readEvalPrintLoop 

例えば、私は、次のコードを書いた

> 1 2 + . <enter> 3 
+0

@Bakuriuはい、それはあなたが言及入力バッファリングする必要があります。このバッファは、Haskellアプリケーションではなく、端末(OSカーネルまたは端末エミュレータのいずれか)に存在することに注意してください。デフォルトでは、端末は各キーをエコーし​​、アプリケーションとのやりとりなしにいつものようにカーソルを移動します。アプリケーションは端末にこのデフォルトの動作を変更するように要求することができ、実際にはncursesがこれを行う一般的な方法です。 – chi

+0

@Bakuriuバッファリングは接線方向にのみ関連しています。ここの本当の問題は反響しています。私の答えでは、バッファリングを止めますが、改行が現れないようにしていません。むしろ、バッファサイズのチャンクではなく、一度にすべてのものを表示できるようにすることです! –

+0

@Andreiあなたが私のような人なら、この問題は、何が起こっているのか、どのような振る舞いが構成可能であるのかを疑問に思うかもしれません。 [The TTY demystified](http://www.linusakesson.net/programming/tty/)でそれについてもっと詳しく読むことができますが、私はあなたに警告します。ただ物事を終わらせたいなら、これはあなたが望むよりも多くの情報を提供します! –

答えて

1

Enterキーを押すと、他のキーを押したときと同じようにy - 画面に印刷されます。あなたがそうするならば、あなたは、これはいくつかの担保ダメージがあるでしょう、しかし

main = do 
    hSetEcho stdin False 
    readEvalPrintLoop 

を:あなたはhSetEchoと、この動作をオフにすることができ、もはやエコーされ入らないし、それが見えますので、どちらも何かあなたは、入力されていませんあなたが入力するすべてのもののように見えない!修正したエコー戦略を手動で実装することでこれを修正できます。 2つのことをする必要があります:hSetBufferingで入力ストリームをバッファなしモードに設定します(行末ではなく入力をすぐに受け取れるように)。受け取ったそれぞれの非入力文字を出力します。だから:

myGetLine :: IO String 
myGetLine = do 
    c <- getChar 
    case c of 
     '\n' -> return "" -- don't echo newlines 
     _ -> do 
      putChar c -- do echo everything else 
      fmap (c:) myGetLine 

readEvalPrintLoop :: IO() 
readEvalPrintLoop = do 
    line <- myGetLine -- getLine changed to myGetLine 
    case line of 
      "bye" -> return() 
      line -> do putStrLn $ interpret line 
         readEvalPrintLoop 

main = do 
    hSetEcho stdin False 
    hSetBuffering stdin NoBuffering 
    readEvalPrintLoop 
+0

N.B.あなたが望む振る舞いによって、 'myGetLine'でEOFをチェックしたいかもしれません。 –

関連する問題