function similar to getchar

前端 未结 6 697
终归单人心
终归单人心 2020-12-04 19:18

Is there a Go function similar to C\'s getchar able to handle tab press in console? I want to make some sort of completion in my console app.

6条回答
  •  我在风中等你
    2020-12-04 20:00

    Other answers here suggest such things as:

    • Using cgo

      • inefficient
      • "cgo is not Go"
    • os.Exec of stty

      • not portable
      • inefficient
      • error prone
    • using code that uses /dev/tty

      • not portable
    • using a GNU readline package

      • inefficient if it's a wrapper to C readline or if implemented using one of the above techniques
      • otherwise okay

    However, for the simple case this is easy just using a package from the Go Project's Sub-repositories.

    Basically, use terminal.MakeRaw and terminal.Restore to set standard input to raw mode (checking for errors, e.g. if stdin is not a terminal); then you can either read bytes directly from os.Stdin, or more likely, via a bufio.Reader (for better efficiency).

    For example, something like this:

    package main
    
    import (
        "bufio"
        "fmt"
        "log"
        "os"
    
        "golang.org/x/crypto/ssh/terminal"
    )
    
    func main() {
        // fd 0 is stdin
        state, err := terminal.MakeRaw(0)
        if err != nil {
            log.Fatalln("setting stdin to raw:", err)
        }
        defer func() {
            if err := terminal.Restore(0, state); err != nil {
                log.Println("warning, failed to restore terminal:", err)
            }
        }()
    
        in := bufio.NewReader(os.Stdin)
        for {
            r, _, err := in.ReadRune()
            if err != nil {
                log.Println("stdin:", err)
                break
            }
            fmt.Printf("read rune %q\r\n", r)
            if r == 'q' {
                break
            }
        }
    }
    
    

提交回复
热议问题