终端原始模式不支持Windows上的箭头

0yg35tkg  于 2023-01-31  发布在  Windows
关注(0)|答案(2)|浏览(114)

我试图使我的控制台原始(在Windows上),我使用ssh/终端包:

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)
}

它工作得很好,我可以抓住Ctrl-C和其他特殊的键,但我不能使用箭头键。
我希望箭头键可以移动光标,或者至少调用AutoCompleteCallback,在那里我可以自己移动光标。

iq0todco

iq0todco1#

使用github.com/containerd/console包使终端原始,现在它的工作就像一个魅力。
新代码:

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)
}
kqhtkvqz

kqhtkvqz2#

对于一些想知道为什么containerd/console工作而ssh/terminal不工作的人来说,这可能很有趣:
containerd/console启用ENABLE_VIRTUAL_TERMINAL_INPUT模式,请参阅Github上当前最新版本的代码中的此行。
这样,所有的control character sequences(光标移动,着色,...)都被启用了。微软在High-Level Console Modes中记录了ENABLE_VIRTUAL_TERMINAL_INPUT模式。

相关问题