Giter Site home page Giter Site logo

readline's Introduction

readline's People

Contributors

abiosoft avatar antekresic avatar bbrowning avatar bdarnell avatar buaazp avatar chessman avatar chzyer avatar derickr avatar dvrkps avatar edwardbetts avatar funrollloops avatar fxaguessy avatar gfrey avatar helflym avatar ilius avatar jamesnetherton avatar jcramb avatar jelmersnoeck avatar jordanlewis avatar kenshaw avatar lunixbochs avatar mehrdadrad avatar michalpristas avatar mrsinham avatar nvanbenschoten avatar paultag avatar rreuvekamp avatar sahib avatar setnicka avatar xdamman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

readline's Issues

Instance not closing properly

Instance doesn't appear to be closing properly. When I attempt to close the instance it returns "errno 0" and doesn't release the terminal. Attached is a simple application which demonstrates the issue:

package main

import (
    "fmt"

    "github.com/chzyer/readline"
)

func main() {
    rl, err := readline.NewEx(&readline.Config{
        Prompt: "rl# ",
    })
    if err != nil {
        fmt.Printf("Failed to create readline: %v\n", err)
        return
    }
    fmt.Printf("enter 2 lines of stuff\n")
    for i := 0; i < 2; i++ {
        line, err := rl.Readline()
        if err != nil {
            fmt.Printf("ERR: %v\n", err)
            return
        }
        fmt.Fprintf(rl.Stderr(), "you said: %v\n", line)
    }
    if err := rl.Close(); err != nil {
        fmt.Printf("Failed to close readline instance: %v\n", err);
    }

    var input string
    if _, err := fmt.Scanf("Input stuff: %s", &input); err != nil {
        fmt.Printf("simple input: %v\n", input)
    }
}

After attempting to close (I can attempt to close a few times, 2nd one seems to not return an error) the readline Instance is still consuming input. If I am not using it correctly, let me know.

"Home" and "End" keys not working

As documented in the Changelog this features was supposed to be implemented in #12 but I don't see any code handling HOME and END (only DEL in this PR).

Does HOME and END works for anyone?

Panic on deleting first char in select mode

There is a specific case when you delete the first character in select mode, library panics out:

`> panic: runtime error: integer divide by zero
[signal 0x8 code=0x7 addr=0x5958e pc=0x5958e]

goroutine 6 [running]:
panic(0x1306a0, 0xc82000a0b0)
/usr/local/Cellar/go/1.6.2/libexec/src/runtime/panic.go:481 +0x3e6
gopkg.in/readline%2ev1.(_opCompleter).doSelect(0xc820084080)
/go/src/gopkg.in/readline.v1/complete.go:49 +0xee
gopkg.in/readline%2ev1.(_opCompleter).OnComplete(0xc820084080)
/go/src/gopkg.in/readline.v1/complete.go:72 +0x1e6
gopkg.in/readline%2ev1.(*Operation).ioloop(0xc820060300)
/go/src/gopkg.in/readline.v1/operation.go:172 +0x1439
created by gopkg.in/readline%2ev1.NewOperation
/go/src/gopkg.in/readline.v1/operation.go:67 +0x42a`

Here is a gist of what I'm using to test this:
https://gist.github.com/antekresic/283106411e826f53799fa4565e90f094

Steps to reproduce: press 's', Tab, Tab, Backspace

Issue seems to be caused by entering OnComplete for an empty input rune buffer. My fix suggestion is to add a check for the empty buffer here:
https://github.com/chzyer/readline/blob/master/complete.go#L69

Let me know if you want a PR.

Thanks!

Deadlock issues

I have a problem where occasionally readline will deadlock. I'm using readline in a couple of different simple CLI tools. There's nothing too unusual or fancy about the usage. I can't share the code, but maybe the information I've got would be useful.

The most recent time the problem happened, my program got stuck calling (*Instance).ReadLine(). Nothing I typed caused that ReadLine call to return.

Here are a couple of the goroutines from the stack trace that I obtained with SIGQUIT:

goroutine 1 [select]:
xxx/vendor/github.com/chzyer/readline.(*Operation).Runes(0xc820317560, 0x0, 0x0, 0x0, 0x0, 0x0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/operation.go:340 +0x369
xxx/vendor/github.com/chzyer/readline.(*Operation).String(0xc820317560, 0x0, 0x0, 0x0, 0x0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/operation.go:327 +0x40
xxx/vendor/github.com/chzyer/readline.(*Instance).Readline(0xc820309400, 0x0, 0x0, 0x0, 0x0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/readline.go:216 +0x3d
main.main()
        /gopath/src/xxx/tool/tool.go:113 +0x1740 // this is where my code calls (*Instance).ReadLine()

goroutine 45 [select]:
xxx/vendor/github.com/chzyer/readline.(*Terminal).ioloop(0xc820304f40)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/terminal.go:108 +0x441
created by xxx/vendor/github.com/chzyer/readline.NewTerminal
        /gopath/src/xxx/vendor/github.com/chzyer/readline/terminal.go:33 +0x186

goroutine 47 [chan receive]:
xxx/vendor/github.com/chzyer/readline.DefaultOnWidthChanged.func1.1(0xc8203175c0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/utils_unix.go:72 +0x43
created by xxx/vendor/github.com/chzyer/readline.DefaultOnWidthChanged.func1
        /gopath/src/xxx/vendor/github.com/chzyer/readline/utils_unix.go:78 +0x13f

goroutine 48 [chan receive]:
xxx/vendor/github.com/chzyer/readline.(*Operation).ioloop(0xc820317560)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/operation.go:98 +0x5b
created by xxx/vendor/github.com/chzyer/readline.NewOperation
        /gopath/src/xxx/vendor/github.com/chzyer/readline/operation.go:82 +0x4a6

Cleaning up when the app exits

Hello - I'm having a hard time figuring out how to cleanly restore the tty state to cooked mode when my application exits. I can use a defer.Close() in the goroutine where rl.ReadLine() is running, but the problem is that sometimes my application must quit programmatically (or panics). In these cases, the program exists and leaves the terminal in a very confusing raw/noecho mode.

The only workaround I can think of is to open a pipe to a child process, which then waits for its input to close before it runs stty sane (but this won't be portable to Windows, as far as I know). And it feels like a hack...

Is there a standard idiom for this? Or some example code, perhaps?

Panic on windows when completing

You simple example wrapped into a binary panics on windows, when pressing the tab key.
This happens on windows 7 and windows 8.1.

package main

import "github.com/chzyer/readline"

func main() {
        rl, err := readline.New("> ")
        if err != nil {
                panic(err)
        }
        defer rl.Close()

        for {
                line, err := rl.Readline()
                if err != nil { // io.EOF
                        break
                }
                println(line)
        }

}
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x43d363]

goroutine 8 [running]:
github.com/chzyer/readline.(*opCompleter).OnComplete(0xc082050000)
    c:/test/go/src/github.com/chzyer/readline/complete.go:76 +0x2e3
github.com/chzyer/readline.(*Operation).ioloop(0xc082008280)
    c:/test/go/src/github.com/chzyer/readline/operation.go:118 +0x877
created by github.com/chzyer/readline.NewOperation
    c:/test/go/src/github.com/chzyer/readline/operation.go:64 +0x491

goroutine 1 [chan receive]:
github.com/chzyer/readline.(*Operation).Runes(0xc082008280, 0x0, 0x0, 0x0, 0x0, 0x0)
    c:/test/go/src/github.com/chzyer/readline/operation.go:258 +0xbe
github.com/chzyer/readline.(*Operation).String(0xc082008280, 0x0, 0x0, 0x0, 0x0)
    c:/test/go/src/github.com/chzyer/readline/operation.go:248 +0x56
github.com/chzyer/readline.(*Instance).Readline(0xc08200a410, 0x0, 0x0, 0x0, 0x0)
    c:/test/go/src/github.com/chzyer/readline/readline.go:76 +0x57
main.main()
    c:/test/go/src/rltest/main.go:13 +0xaf

goroutine 5 [chan receive]:
github.com/chzyer/readline.(*ANSIWriter).ioloop(0xc0820041c0)
    c:/test/go/src/github.com/chzyer/readline/ansi_windows.go:101 +0x139
created by github.com/chzyer/readline.NewANSIWriter
    c:/test/go/src/github.com/chzyer/readline/ansi_windows.go:64 +0xd7

goroutine 6 [chan receive]:
github.com/chzyer/readline.(*ANSIWriter).ioloop(0xc082004240)
    c:/test/go/src/github.com/chzyer/readline/ansi_windows.go:101 +0x139
created by github.com/chzyer/readline.NewANSIWriter
    c:/test/go/src/github.com/chzyer/readline/ansi_windows.go:64 +0xd7

goroutine 7 [syscall, locked to thread]:
github.com/chzyer/readline.func·021(0xc0820069a0, 0x4, 0x4, 0x0, 0x0)
    c:/test/go/src/github.com/chzyer/readline/windows_api.go:120 +0x40b
github.com/chzyer/readline.(*RawReader).Read(0xc08200a3d0, 0xc08205b000, 0x1000, 0x1000, 0x4, 0x0, 0x0)
    c:/test/go/src/github.com/chzyer/readline/rawreader_windows.go:46 +0x131
bufio.(*Reader).fill(0xc082042480)
    c:/go/src/bufio/bufio.go:97 +0x1d5
bufio.(*Reader).ReadRune(0xc082042480, 0xc082042300, 0xc082049f14, 0x0, 0x0)
    c:/go/src/bufio/bufio.go:227 +0xde
github.com/chzyer/readline.(*Terminal).ioloop(0xc082008230)
    c:/test/go/src/github.com/chzyer/readline/terminal.go:95 +0x1c3
created by github.com/chzyer/readline.NewTerminal
    c:/test/go/src/github.com/chzyer/readline/terminal.go:39 +0x279
exit status 2

iTerm2 cursor application mode

When using iTerm2, the arrow keys are generating escape O sequences which are being printed out to screen instead of scrolling back in history of moving between characters. Is there any intention of supporting the escape O sequences in addition to the escape [ sequences?

For reference, the iTerm FAQ talks about the escape sequences under "Why my arrow/HOME/END keys are not working?"

Missing many common vi mode commands

This library is missing many common vi mode commands that are implemented in readline/libedit.

Here are the ones that stood out most to me as I tried using a simple command prompt:

  • c<motion>, d<motion> (change, delete)
  • x (delete character)
  • r (replace character)

gopkg does not work with sub-packages

This is not an issue with readline itself, but impacts uses of it via gopkg. See niemeyer/gopkg#9 for details.

Basically, gopkg only works correctly with single-package repositories. Because gopokg.in/chzyer/readline.v1 imports github.com/chzyer/readline/runes, both repositories will be pulled in, but the latter be at HEAD on master.

I don't have a solution to this unfortunately, I just noticed it when pulling in readline via otto.

Readline doesn't compile on Solaris

We're gearing up to use this library for Terraform and we target Solaris and have users using that OS. This library unfortunately doesn't compile there due to missing the State struct there.

We've built around it with build tags for now to simply not support our interactive console feature there but it'd be fantastic if this was supported.

Readline unnecessarily redraws the last line in the terminal

At CockroachDB we are now using expect to test the SQL shell and this shows all the characters sent by the program to the terminal. In our expect traces we see things like this:

send: sending "select 1;\r" to { exp6 }                                                                                                                                                                                                                                                                                                                
expect: does ":26257>  \u0008" (spawn_id exp6) match glob pattern "1 row"? no
root@:26257> se
expect: does ":26257>  \u0008\u001b[J\u001b[2K\rroot@:26257> s\u001b[J\u001b[2K\rroot@:26257> se" (spawn_id exp6) match glob pattern "1 row"? no                                                                                                                                                                                                      root@:26257> selec
expect: does ":26257>  \u0008\u001b[J\u001b[2K\rroot@:26257> s\u001b[J\u001b[2K\rroot@:26257> se\u001b[J\u001b[2K\rroot@:26257> sel\u001b[J\u001b[2K\rroot@:26257> sele\u001b[J\u001b[2K\rroot@:26257> selec" (spawn_id exp6) match glob pattern "1 row"? no
root@:26257> select 1;
expect: does ":26257>  \u0008\u001b[J\u001b[2K\rroot@:26257> s\u001b[J\u001b[2K\rroot@:26257> se\u001b[J\u001b[2K\rroot@:26257> sel\u001b[J\u001b[2K\rroot@:26257> sele\u001b[J\u001b[2K\rroot@:26257> selec\u001b[J\u001b[2K\rroot@:26257> select\u001b[J\u001b[2K\rroot@:26257> select \u001b[J\u001b[2K\rroot@:26257> select 1\u001b[J\u001b[2K\rro
ot@:26257> select 1;" (spawn_id exp6) match glob pattern "1 row"? no
root@:26257> select 1;

What is happening here, is that after every character typed by the user (received by readline from the terminal), readline issues \033[J\033[2K\r to the terminal then redraws (re-outputs) the prompt and all the characters typed so far.

This is sub-optimal: a redraw should only be necessary when characters previously present in the readline buffer are modified (e.g. when using left-arrow, up-arrow etc). During normal input of non-special characters, this redraw is unnecessary.

Also on slow terminals (like over slow ssh connections) this redraw becomes clearly noticeable to the user for very long inputs.

search crashes the whole program

It's the cockroach project that uses your readline library, but when I tried to back search (using Ctrl+R), it just crashes, the backtrace is as follows:

Please help fix this. Thanks!

# Welcome to the cockroach SQL interface.
# All statements must be terminated by a semicolon.
# To exit: CTRL + D.
root@:15432> panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0xb8 pc=0x42e0c96]

goroutine 12 [running]:
github.com/chzyer/readline.(*opSearch).SearchRefresh(0xc8202925b0, 0xd)
    /Users/q/go/src/github.com/chzyer/readline/search.go:127 +0xc6
github.com/chzyer/readline.(*opSearch).SearchMode(0xc8202925b0, 0x0)
    /Users/q/go/src/github.com/chzyer/readline/search.go:100 +0x78
github.com/chzyer/readline.(*Operation).ioloop(0xc820261440)
    /Users/q/go/src/github.com/chzyer/readline/operation.go:140 +0x2112
created by github.com/chzyer/readline.NewOperation
    /Users/q/go/src/github.com/chzyer/readline/operation.go:70 +0x428

goroutine 1 [select]:
github.com/chzyer/readline.(*Operation).Runes(0xc820261440, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/q/go/src/github.com/chzyer/readline/operation.go:316 +0x2d5
github.com/chzyer/readline.(*Operation).String(0xc820261440, 0x0, 0x0, 0x0, 0x0)
    /Users/q/go/src/github.com/chzyer/readline/operation.go:300 +0x40
github.com/chzyer/readline.(*Instance).Readline(0xc82027ed80, 0x0, 0x0, 0x0, 0x0)
    /Users/q/go/src/github.com/chzyer/readline/readline.go:184 +0x3d
github.com/chzyer/readline.Line(0xc82028d700, 0xd, 0x0, 0x0, 0x0, 0x0)
    /Users/q/go/src/github.com/chzyer/readline/std.go:44 +0xf6
github.com/cockroachdb/cockroach/cli.runInteractive(0xc8202943c0, 0xc820205e60, 0x28, 0x0, 0x0)
    /Users/q/go/src/github.com/cockroachdb/cockroach/cli/sql.go:173 +0x450
github.com/cockroachdb/cockroach/cli.runTerm(0x5c13320, 0xc82028d600, 0x0, 0x1, 0x0, 0x0)
    /Users/q/go/src/github.com/cockroachdb/cockroach/cli/sql.go:271 +0x151
github.com/spf13/cobra.(*Command).execute(0x5c13320, 0xc82028d5a0, 0x1, 0x1, 0x0, 0x0)
    /Users/q/go/src/github.com/spf13/cobra/command.go:565 +0x63b
github.com/spf13/cobra.(*Command).ExecuteC(0x5c10320, 0x5c13320, 0x0, 0x0)
    /Users/q/go/src/github.com/spf13/cobra/command.go:656 +0x56b
github.com/spf13/cobra.(*Command).Execute(0x5c10320, 0x0, 0x0)
    /Users/q/go/src/github.com/spf13/cobra/command.go:615 +0x2d
github.com/cockroachdb/cockroach/cli.Run(0xc82000a190, 0x2, 0x2, 0x0, 0x0)
    /Users/q/go/src/github.com/cockroachdb/cockroach/cli/cli.go:85 +0x7c
main.main()
    /Users/q/go/src/github.com/cockroachdb/cockroach/main.go:37 +0xe6

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/Cellar/go/1.5.3/libexec/src/runtime/asm_amd64.s:1721 +0x1

goroutine 7 [chan receive]:
github.com/cockroachdb/cockroach/util/log.(*loggingT).flushDaemon(0x5c23740)
    /Users/q/go/src/github.com/cockroachdb/cockroach/util/log/clog.go:1030 +0x64
created by github.com/cockroachdb/cockroach/util/log.init.1
    /Users/q/go/src/github.com/cockroachdb/cockroach/util/log/clog.go:610 +0xbc

goroutine 9 [syscall]:
os/signal.loop()
    /usr/local/Cellar/go/1.5.3/libexec/src/os/signal/signal_unix.go:22 +0x18
created by os/signal.init.1
    /usr/local/Cellar/go/1.5.3/libexec/src/os/signal/signal_unix.go:28 +0x37

goroutine 10 [chan receive]:
database/sql.(*DB).connectionOpener(0xc8202943c0)
    /usr/local/Cellar/go/1.5.3/libexec/src/database/sql/sql.go:634 +0x45
created by database/sql.Open
    /usr/local/Cellar/go/1.5.3/libexec/src/database/sql/sql.go:481 +0x336

goroutine 11 [syscall]:
syscall.Syscall(0x3, 0x0, 0xc8202ac000, 0x1000, 0x1, 0x0, 0x0)
    /usr/local/Cellar/go/1.5.3/libexec/src/syscall/asm_darwin_amd64.s:16 +0x5
syscall.read(0x0, 0xc8202ac000, 0x1000, 0x1000, 0x1, 0x0, 0x0)
    /usr/local/Cellar/go/1.5.3/libexec/src/syscall/zsyscall_darwin_amd64.go:972 +0x5f
syscall.Read(0x0, 0xc8202ac000, 0x1000, 0x1000, 0x1, 0x0, 0x0)
    /usr/local/Cellar/go/1.5.3/libexec/src/syscall/syscall_unix.go:160 +0x4d
os.(*File).read(0xc82002c008, 0xc8202ac000, 0x1000, 0x1000, 0xc8202612b8, 0x0, 0x0)
    /usr/local/Cellar/go/1.5.3/libexec/src/os/file_unix.go:211 +0x75
os.(*File).Read(0xc82002c008, 0xc8202ac000, 0x1000, 0x1000, 0x1, 0x0, 0x0)
    /usr/local/Cellar/go/1.5.3/libexec/src/os/file.go:95 +0x8a
bufio.(*Reader).fill(0xc82002be70)
    /usr/local/Cellar/go/1.5.3/libexec/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).ReadRune(0xc82002be70, 0xc820261260, 0xc82002bddc, 0x0, 0x0)
    /usr/local/Cellar/go/1.5.3/libexec/src/bufio/bufio.go:260 +0xc8
github.com/chzyer/readline.(*Terminal).ioloop(0xc8202904b0)
    /Users/q/go/src/github.com/chzyer/readline/terminal.go:111 +0x24b
created by github.com/chzyer/readline.NewTerminal
    /Users/q/go/src/github.com/chzyer/readline/terminal.go:34 +0x189

x/crypto/ssh support

Currently stdin an isatty are not configureable which makes using this package with x/crypto/ssh impossible.

screen clears when starting

I'm running the simplest example under screen and the terminal is getting cleared at startup. It shouldn't be clearing the screen.

If I capture a screen log I get the following

$ hexdump -C screenlog.14
00000000  67 6f 20 72 75 6e 20 74  65 73 74 2e 67 6f 20 0d  |go run test.go .|
00000010  0a 1b 5b 4a 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |..[J.[2K...[2K..|
00000020  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000030  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
00000040  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
00000050  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000060  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
00000070  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
00000080  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000090  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
000000a0  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
000000b0  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
000000c0  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
000000d0  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
000000e0  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
000000f0  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
00000100  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
00000110  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000120  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
00000130  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
00000140  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000150  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
00000160  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
00000170  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000180  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
00000190  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
000001a0  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
000001b0  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
000001c0  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
000001d0  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
000001e0  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
000001f0  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
00000200  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000210  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
00000220  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
00000230  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000240  0d 08 1b 5b 32 4b 0d 08  1b 5b 32 4b 0d 08 1b 5b  |...[2K...[2K...[|
00000250  32 4b 0d 08 1b 5b 32 4b  0d 08 1b 5b 32 4b 0d 08  |2K...[2K...[2K..|
00000260  1b 5b 32 4b 0d 08 1b 5b  32 4b 0d 08 1b 5b 32 4b  |.[2K...[2K...[2K|
00000270  0d 08 3e 20                                       |..> |

take the simplest example code from the main github page

package main

import "github.com/chzyer/readline"

func main() {

        rl, err := readline.New("> ")
        if err != nil {
                panic(err)
        }
        defer rl.Close()

        for {
                line, err := rl.Readline()
                if err != nil { // io.EOF
                        break
                }
                println(line)
        }
}

Why complete helper stop when arguments on cmd

Hello,

I'm working on a tool that emulate an terminal online.
I have a simple dynamic function that list directory dynamically.

Example:
If user write "ls" without anything.
It will print (with autocompleter) the current directory in help.

But if the user writes : ls ..
The action blocks.

I have notice that the problem comes with the line 160 in the file complete_helper.go :
return doInternal(lineCompleter, tmpLine, len(tmpLine), origLine)

When I comment this line, it prints well the directory with new scope "..".
Why this return is here ?

My function =

func (k *Kernel) ListLocalFiles() func(string) []string {
	return func(line string) []string {
		names := make([]string, 0)
		dir, err := filepath.Abs(filepath.Dir(os.Args[0]))

		if err != nil {
			return names
		}

		arr := strings.Fields(line)
		if len(arr) > 1 {
			dir = arr[1]
		}

		files, _ := ioutil.ReadDir(dir)
		for _, f := range files {
			names = append(names, f.Name())
		}

		return names
	}
}

liner compatibility

It would be nice to be compatible with liner, at least for the basic usages.
One idea is, to create a subpackage:
github.com/chzyer/readline/liner
which translates the liner interface to readline.
In this case, only the import path needs to be changed and it's very easy to compare the libraries.

What do you think?

Can ctrl-c be captured?

Hello,

I'm using readline in a terminal emulation setting - in this context, it would be nice to capture ctrl-c and send a remote reset instead of quitting the application (ctrl-d can be used for that). Is this possible? Can a custome Listener be used for this?

With many thanks for creating such a nice utility,
-jcw

Version tagging

I'm going to use your package in my project, but it would be really nice if it also had stable versions tagged so I could use it through gopkg.in! :)

Tab-selection of completions looks wrong when options span multiple lines

If the suggested completions are long enough to take up more than one terminal line, pressing tab to move the highlight causes more lines to be printed. Here some example code:

package main

import "github.com/chzyer/readline"

var completer = readline.NewPrefixCompleter(
    readline.PcItem("all_these_options"),
    readline.PcItem("take_up_more_than"),
    readline.PcItem("one_terminal_line"),
    readline.PcItem("so_the_highlights"),
    readline.PcItem("do_not_work_right"))

func main() {
    rl, err := readline.NewEx(&readline.Config{
        Prompt:       "> ",
        AutoComplete: completer,
    })
    if err != nil {
        panic(err)
    }
    defer rl.Close()

    for {
        line, err := rl.Readline()
        if err != nil {
            break
        }
        println(line)
    }
}

If I run this snippet and press Tab five times, this is what I see:
result

It looks like only the current line is being redrawn, and since there are two lines drawn it keeps moving down each time. The re-draw process should redraw all the lines, not just the last.
With shorter option texts, this doesn't happen.

This definitely happens in a windows 7 command prompt, I haven't tried it out on any other terminals yet.

feature request: case-insensitive history

in CockroachDB if a user enters "SELECT" ... it would be nice to be able to do Ctrl+R then "sel..." in lowercase and see the SELECT come back from history.

Currently the history search is case sensitive so this does not work.

Ideally the behavior would be configurable.

Need help about create a press space to next page app.

I want to create a cli app which can print next page by press space key. Just like less or more command. But when i try to call ReadRune from readline, the program stucked. Can you fix this program? Or Can you create more example about how to use readline?

here is my code

package main

import (
    "strings"
    "github.com/chzyer/readline"
    "io"
    "fmt"
)

func main() {
    cfg := &readline.Config{
        Prompt:              " \033[31m$\033[0m ",
        HistoryFile:         "/tmp/readline.tmp",
        InterruptPrompt:     "\nInterrupt, Press Ctrl+D to exit",
        EOFPrompt:           "exit",
    }

    l, err := readline.NewEx(cfg)
    if err != nil {
        panic(err)
    }
    for {
        line, err := l.Readline()
        if err == io.EOF {
            break
        }
        line = strings.TrimSpace(line)
        // 退出指令
        lineLower := strings.ToLower(line)
        if lineLower == "exit" || lineLower == "quit" || lineLower == "bye" {
            l.Stdout().Write([]byte("exit...\n"))
            break;
        }
        handleLine(l, line)
    }
}

func handleLine(l *readline.Instance, line string) {

    p := 1
    printPage(l.Stdout(), p)
    fmt.Fprintln(l.Stdout(), "hello, this is readline demo page 1, press space to view next page, ESC to quit.")

    for {
        ru := l.Terminal.ReadRune()
        if ru == 27 {
            fmt.Fprintln(l.Stdout(), "ESC pressed quiting...")
            break;
        }else if ru == 32 {
            fmt.Fprintln(l.Stdout(), "space pressed. print next page.")
            p += 1
            printPage(l.Stdout(), p)
        }
    }
}

func printPage(writer io.Writer, page int) {
    fmt.Fprintln(writer, "this is page:%d", page)
}

Checking password strength

Hello @chzyer, thanks for this nifty library.

I hit a little problem when using it though: I want a user to enter a password (in plaintext) and check it's strength using the zxcvbn library. Depending on the strength I would color the Password: prompt in a friendlier color. For this I modified the Autorefresh example of yours, so that the refresh would fetch the current input, check the strength and do a fitting SetPrompt().

However, when using rl.Operation.Runes() directly all sort of weird behaviour appears.
This appears due to the fact that it does not only fetch the current runes, but also does some IO. For testing I exposed the buf *RuneBuffer in readline.Operation to the outside and used it's Runes() method directly.

Despite being an awful hack, it seems to work - am I doing something awfully wrong, or would the addition of another method that just fetches the current buffer contents appropiate?

Here's my current (working) attempt:
https://gist.github.com/sahib/2ee21e8d636c98876a83

Thanks.

Goroutine leak with latest "cancelable stdin" changes

See: https://circleci.com/gh/cockroachdb/cockroach/22259

This prevents us at CockroachDB from upgrading to the latest readline.

The problem is that the global var Stdin is set to a CancelableStdin object but this object is never closed, so there is a goroutine remaining when the program using readline terminates. This makes leak checkers unhappy.

The better solution would be to create an API for readline to "initialize" and "finalize" the entire library. The CancelableStdin object would be created in "initialize" and closed in "finalize". This way, if a program (like cockroach) merely imports the readline package but does not actually use it, there will be no goroutine created.

Ctrl-Y (yank) feature missing

Is there a plan for implementing yank? Not necessarily the whole kill ring, just a way of yanking back your previous kill.

Completer fault

Hi I noticed a malfunction when having PcItems with same prefix
Using this completer:

var completer = readline.NewPrefixCompleter(
        readline.PcItem("simple",
            readline.PcItem("rule",
                readline.PcItem("-name"),
                readline.PcItem("-name2"),
                readline.PcItem("-name23"),
            ),
        ),
    )

A will get following completion tree
.simple
......rule
............-name (as it is common prefix for all)
..................-name-name (this is not so good)
..................-name2
..................-name23

I would look at it on my own but I'm not sure where to look.
it works fine for
var completer = readline.NewPrefixCompleter(
readline.PcItem("simple",
readline.PcItem("rule",
readline.PcItem("-abc"),
readline.PcItem("-def"),
readline.PcItem("-qwe"),
),
),
)

prefix of agrs is not common

Clear strange behaviour

Hi, when pressing ctrl+L to clear the screen, it instead inserts a new line and misplace the pompt (see here).
That is after pressing ctrl+L 3 times. This is on Linux in termite, but also happens in terminator and xterm.

[Question] Prevent readline to print.

I'm currently working on a CLI client for a chat application and I really like how this library manipulates the log output. There is currently besides this library no Go library available that refreshes the stdout without including all kinds of lay-outing I do not need.

But I have a question: Is it possible to prevent Readline() from printing to the terminal output?
Currently my output looks like this

(INSERT) > test
2016/02/14 15:59:07 > Rivalo > test

Where (INSERT) > is the prompt for reading the line, and the next line simply returns the sent message inside the chat channel.
I want to prevent the User's message from displaying twice but keep the consistency with the messages from others, which means that after a \n readline() shouldn't print its just received line to the stdout.

Is there currently an option or workaround for this I'm overlooking in the documentation?
(Please, in future, add comments above exported functions, it makes the godoc documentation easier to read)

History buf

Sometimes when I use history using up/down arrows the output get broken.
Command is printed out but not to current line.
It will get printed to a new line and I will get another line for input. Hard to explain hard to reproduce.

Example will be the best:

For expected history
command one
command two
command three
command four

Initial state (enter command is propmt message, _ is current cursos):
enter command: _

after playing with history I got output like this
enter command: command three _

(after pressing up arrow)

enter command:
command two
_

(then I press up arrow again [enter key is not pressed] and output is like this)

enter command:
command two
enter command: command one _

I hope it is a bit clear with this example. I'm not really sure where to look at

(*Instance) Close function call blocks until line is received

Hello,
I have the following scenario in a program I'm writing.

Connection to one or more servers in their own go routines, with a sync.WaitGroup that will terminate the program if all servers are disconnected. Signal monitoring, which also monitors a boolean quit channel, so if a quit command is entered in the terminal window, the program will quit. Checks on the readline instance to determine if an interrupt of any kind is received, which will also quit the program. Entering the quot command in the terminal, or CTRL+C for interrupts shuts the program down cleanly, but trying to kill the program by sending it a signal will not terminate the program until enter is pressed, or likely, some other signal interrupt received.

Briefly, here is how I believe this could be reproduced.

  1. Write a short program with a sync.WaitGroup, and create the following go routines. A go routine monitoring signals sent to the process by the operating system, and a go routine monitoring the input received by the user, using a variable containing a readline instance, and the Line function for receiving data and error checking. Error checking should quit the input monitoring routine, and send to the signal monitoring routine on a different channel to close the program.
  2. Attempt to kill the program by sending one of the monitored signals. The program will not end until a new line is received.

My question is this. Is the Close() function call supposed to block like this? Or, could I read input in another way that would return an error immediately after the readline instance is closed, and not block on the readline instance Close() method? I could then completely end the program without the need for an extra step of entering a blank newline or otherwise.

Blake

No carriage return after command line

When autocompleting or after completing command (after hitting enter), the next line after command line is indented. It starts on the same position as the old one ends, ilustration:

» say 
      hello   bye 

or

» test test
           2016/07/21 09:55:19 you said: "test test"

Tested on two Linux machines, one of them was Debian 5.4.0-6 (Linux version 4.6.0-1-amd64) with pure installation of Go:

sudo apt install golang
export GOPATH=$HOME/go
go get github.com/chzyer/readline
go run go/src/github.com/chzyer/readline/example/readline-demo/readline-demo.go

This bug is probably caused by some changes in external packages, because when I was using older version of all packages (e.q. one month), all works as expected.

UniqueEditLine botches previous line

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

multi-line entries in history cause erroneous behavior

Found with the following:

  1. enter a multi-line entry in the history (e.g. AddHistory("foo\nbar"))
  2. recall the multi-line entry. The cursor is positioned (correctly) at the end of the last line.
  3. try to navigate backwards with left-arrow: the display is messed up.

Ctrl+Z on Windows completely breaks readline.

Pretty simple. If I type Ctrl+Z at a Readline() on Windows, the line I was working on disappears along with the prompt and no keyboard input has any effect anymore aside from Ctrl+C, which kills the program and barfs whatever I typed in after hitting Ctrl+Z to the command prompt.

Windows: Alt-Tab makes the `Alt` modifier sticky.

In a simple app, using Alt tab seems to send the alt signal to readline, which switches to "Esc" mode.. but hitting Alt+Tab to switch, prevents the key release event to go through. So when we come back to the app, hitting d for example, calls DeleteWord or something.

Is there any way we could make sure to depress the alt, or release it after a given amount of time, or anything that wouldn't put the readline lib into an "always alt+" mode ?

Breaking scroll buffer

The current line is splitted into multiple lines based on terminal width. Splitting is actually precalculated inside functions SplitByMultiLine and SplitByLine. Then, when printing a line, '\n' are sent to terminal after each precalculated line (lines that are a product of splitting). All of this rely on the fact that most terminals will do the same on window width change. They will wrap all lines from history and current editing line around new width boundary. Line printing, cleaining, and on width change logic relys on this idea of splitting.

First thing

I believe there is a problem when you have a line that needs to be splitted in more than two lines. The code doesn't perform well in some cases. For example, when you need to split a very long line into 5 new ones. This would be a dirty fix for such scenario:

func SplitByMultiLine(start, oldWidth, newWidth int, rs []rune) []string {
    var ret []string
    buf := bytes.NewBuffer(nil)
    currentWidth := start
    for _, r := range rs {
        w := runes.Width(r)
        currentWidth += w
        buf.WriteRune(r)
        if currentWidth%newWidth == 0 {
            ret = append(ret, buf.String())
            buf.Reset()
            if currentWidth == oldWidth {
                currentWidth = 0
            }
            continue
        }
        if currentWidth >= oldWidth {
            ret = append(ret, buf.String())
            buf.Reset()
            currentWidth = 0
        }
    }
    if buf.Len() > 0 {
        ret = append(ret, buf.String())
    }
    return ret
}

Second thing

Adding NL after each split, gives terminal application 'a permission' to send some parts of original line beyond top of window screen, which taints scroll buffer. Every line that ends with '\n' becomes a part of history. So basically, complete line splitting logic that is used in printing and cleaning inside runebuf, that is relying on prediction of how many new lines will show on screen after line wrapping (done by terminal application automatically), can affect scrollbuffer badly. Once that a line (born after splitting) goes into scroll buffer, it might be gone from the screen as well. That breaks line cleaning logic from runebuf that sends "\033[2K\r\033[A" for every line, and moving cursor beyond top of the screen just doesn't work. Expecting that every splitted line will be always on screen is just not a good prediction. I suggest to replace the whole logic behind it. Adding NL artifically is just bad for scroll buffer and it breaks behaviour of terminal application in some cases.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.