peterh / liner

Pure Go line editor with history, inspired by linenoise
MIT License
1.04k stars 132 forks source link

os.Stdin.Read only read one character #137

Closed haifenghuang closed 4 years ago

haifenghuang commented 4 years ago

I just made a new program as below:

package main

import (
    "fmt"
    "os"
    "github.com/peterh/liner"
)

func main() {
    l := liner.NewLiner()
    defer l.Close()

    for {
        if line, err := l.Prompt(">>"); err == nil {
            fmt.Printf("%s\n", line)
            buffer := make([]byte, 1024)
            n, _ := os.Stdin.Read(buffer)
            fmt.Printf("n=%d, str=%s\n", n, string(buffer))
            continue
        }
    }
}

On the n, _ := os.Stdion.Read(buffer) line, When I enter a character 'b' , the output is n=1, str=b, please see below output:

C:\demo>main.exe  
>>1234                                 
1234                                   
n=1, str=b

>>                                     

It only accept one character and print the result. What was the problem?

peterh commented 4 years ago

The problem is that you called os.Stdin.Read instead of l.Prompt. Why would you do that?

(If you really really need to bake/unbake the terminal mode and temporarily suspend liner, you can use liner.TerminalMode. But I suggest using liner for everything or nothing.)

haifenghuang commented 4 years ago

Because I designed a language REPL, the language support below statement:

let a;
stdin >> a;   # read standard input into variable 'a'

If above code is in a file, then it's OK, but if in the REPL, it has problem as stated above.