Terminal raw mode does not support arrows on Windows

Viewed 1109

I am trying to make my console raw (on Windows), and I'm using ssh/terminal package:

package main

import (
    "fmt"
    "os"

    "golang.org/x/crypto/ssh/terminal"
)

type sh struct{}

func (sh *sh) Read(b []byte) (int, error) {
    return os.Stdin.Read(b)
}

func (sh *sh) Write(b []byte) (int, error) {
    return os.Stdout.Write(b)
}

func main() {
    oldstate, err := terminal.MakeRaw(int(os.Stdin.Fd()))
    if err != nil {
        panic(err)
    }

    defer terminal.Restore(int(os.Stdin.Fd()), oldstate)

    term := terminal.NewTerminal(&sh{}, "")
    term.AutoCompleteCallback = func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
        fmt.Println("callback:", line, pos, key)

        return "", 0, false
    }

    line, err := term.ReadLine()
    fmt.Println("result:", line, err)
}

It works great, and I can catch Ctrl-C and other special keys, but I can't use the arrow keys.

I want the arrow keys to move the cursor or at least invoke AutoCompleteCallback where I can move the cursor my self.

1 Answers

Used github.com/containerd/console package to make the terminal raw and now it works like a charm.

New code:

package main

import (
    "fmt"
    "os"

    "github.com/containerd/console"
    "golang.org/x/crypto/ssh/terminal"
)

func main() {
    current := console.Current()
    defer current.Reset()

    if err := current.SetRaw(); err != nil {
        panic(err)
    }

    term := terminal.NewTerminal(current, "")
    term.AutoCompleteCallback = func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
        // fmt.Println("callback:", line, pos, key)

        return "", 0, false
    }

    line, err := term.ReadLine()
    fmt.Println("result:", line, err)
}

Related