readline icon indicating copy to clipboard operation
readline copied to clipboard

UniqueEditLine botches previous line

Open jcw opened this issue 7 years ago • 0 comments

I'd like to use readline as a front end for a microcontroller attached over serial, to provide command history and searching. The basic idea is: enter a line, the line is sent out, gets echoed and processed by the microcontroller, and so on.

It works fine for normal use. The line is cleared when I hit return, and the echoed results show up in its place - just as intended. One special detail is that the returned line may contain more information than what was entered, appended to the end (i.e. results of a command are shown on the same line).

When I hit up/down arrow, I can access command history, and everything still works splendidly.

But when I hit ctrl-r, the text bck-i-search: is printed and the cursor then moves up. This then destroys what was reported in the last output line.

Furthermore, when hitting a key repeatedly, if there is no matching history entry, the cursor will continue to be moved up, with below it the text failing bck-i-search: .... Hitting x repeatedly will gradually clear the entire screen while moving the cursor up.

Am I using this package wrong? Is there a way to work around this? Have I hit a bug in readline?

Attached the entire code I'm using. I can test further and provide more information - please just let me know. I'm using the latest version of readline from GitHub as of Oct 16th.

Cheers, -jcw

PS. I'm on macOS 10.12, the above happens with both Terminal and iTerm2.

package main

import (
    "os"
    "bytes"

    "github.com/chzyer/readline"
    "github.com/pkg/term"
)

func main() {
    tty, _ := term.Open("/dev/cu.usbmodemD5D4C5E3",
        term.Speed(115200), term.RawMode)

    rl, _ := readline.NewEx(&readline.Config{
        UniqueEditLine: true,
    })
    defer rl.Close()

    go func() {
        for {
            line := make([]byte, 100)
            n, _ := tty.Read(line)
            line = bytes.Replace(line[:n], []byte("\n"), []byte("\r\n"), -1)
            os.Stdout.Write(line)
        }
    }()

    for {
        line, err := rl.Readline()
        if err != nil {
            break
        }
        tty.Write([]byte(line + "\r"))
    }
}

jcw avatar Oct 17 '16 08:10 jcw