Readline is a pure go(golang) implementation for GNU-Readline kind library

Comments
  • Dynamic autocompletion

    Dynamic autocompletion

    I implemented dynamic autocompletion mechanism.

    Now there is a new item type "PcItemDynamic" which takes function as parameter.

    When it comes to autocomplete at this position, the function is called, the whole line is given to it (for example if autocompletion depend on previous autocompleted field) and functio should return possible strings how to continue.

    Example usage:

    • listing some dynamic key-value storage
    • listing files in directory
  • Tab-selection of completions looks wrong when options span multiple lines

    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.

  • Recursive dynamic completer?

    Recursive dynamic completer?

    Is it possible for dynamic completers to be called 'recursively' to build up a path?

    To clarify by referring to listFiles() in the example code - if the first listFiles() returned a directory, could it indicate it should be called again with the chosen completion as the input, so that it could then list files in that directory, and so on, until a complete path was formed?

  • No carriage return after command line

    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.

  • Checking password strength

    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.

  • AIX support

    AIX support

    This commit adds support for AIX operating system.

    • move term_solaris.go to term_nosyscall6.go. AIX like solaris doesn't provide syscall.Syscall6 and must rely on x/sys/unix in order to perform syscalls.

    • This patch won't work with versions prior to 1.13 because it needs some constants added by https://go-review.googlesource.com/c/go/+/171339.

  • Fix panic for ReadPassword

    Fix panic for ReadPassword

    An issue on ishell https://github.com/abiosoft/ishell/issues/64 made me dig into this. I realized the panic is due to nil Painter for Config generated during ReadPassword.

  • Race condition between SetPrompt and ioloop

    Race condition between SetPrompt and ioloop

    Found in https://teamcity.cockroachdb.com/viewLog.html?buildId=20052#334279584_2_20052_problem:

     github.com/chzyer/readline.(*RuneBuffer).PromptLen()
          /go/src/github.com/chzyer/readline/runebuf.go:78 +0x5c
    
    vs.
    
     github.com/cockroachdb/cockroach/cli.runInteractive()  // where SetPrompt() is called
         /go/src/github.com/cockroachdb/cockroach/cli/sql.go:283 +0x2b9
    

    The SetPrompt method should protect the prompt variable with a mutex.

  • "Home" and "End" keys not working

    As documented in the Changelog this features was supposed to be implemented in https://github.com/chzyer/readline/pull/12 but I don't see any code handling HOME and END (only DEL in this PR).

    Does HOME and END works for anyone?

  • Add ClearScreen operation on Ctrl+L

    Add ClearScreen operation on Ctrl+L

    Regarding issue #55, I implemented clear screen and bound it to Ctrl+L. I have tested it on Linux , but not on Windows as I have no access to a Windows machine atm.

  • add SetChildren for prefix completer interface

    add SetChildren for prefix completer interface

    In my case, I need update prefix completer in background, so I need this SetChildren method for prefix completer interface.

    See the codes below, I need get server list first and then update the completer:

    func updateServerList() {
        svrList, err := getServers()
        if err != nil {
            fmt.Fprintf(tty.Stderr(), "\r\nconnect to %s err: %s\r\n",
                color.Bold(framer), err)
        }
        if svrList == nil {
            return
        }
    
        updateCompleter(svrList)
    }
    
    func updateCompleter(svrList []string) {
        var tcServersCompleter []readline.PrefixCompleterInterface
        for _, host := range svrList {
            tcServersCompleter = append(tcServersCompleter, readline.PcItem(host))
        }
        for _, child := range completer.GetChildren() {
            childName := string(child.GetName())
            switch childName {
            case "setmaster ",
                "serveradd ",
                "serverstat ",
                "serverdel ",
                "serveroffline ",
                child.SetChildren(tcServersCompleter)
            default:
                continue
            }
        }
    }
    
  • change of color (ANSI color code unchaged) when calling `log.SetOutput(l.Stderr())`

    change of color (ANSI color code unchaged) when calling `log.SetOutput(l.Stderr())`

    example code:

    package main
    
    import (
    	"fmt"
    	"io"
    	"log"
    	"os"
    	"time"
    
    	"github.com/chzyer/readline"
    )
    
    const (
    	COLOR_RESET = "\033[0m"
    	COLOR_GREEN = "\033[32m"
    )
    
    func main() {
    	go logger()
    
    	time.Sleep(2 * time.Second)
    
    	fmt.Println("calling log.SetOutput() inside GetInput() which changes color")
    	go GetInput()
    
    	time.Sleep(time.Hour)
    }
    
    func logger() {
    	for {
    		log.Printf("%scolor%s\n", COLOR_GREEN, COLOR_RESET)
    		time.Sleep(500 * time.Millisecond)
    	}
    }
    
    // GetInput is used to read input from user.
    // [goroutine]
    func GetInput() {
    	l, err := readline.NewEx(
    		&readline.Config{
    			Prompt: "» ",
    			AutoComplete: readline.NewPrefixCompleter(
    				readline.PcItem("msh",
    					readline.PcItem("start"),
    					readline.PcItem("freeze"),
    					readline.PcItem("exit"),
    				),
    				readline.PcItem("mine"),
    			),
    			FuncFilterInputRune: func(r rune) (rune, bool) {
    				switch r {
    				case readline.CharCtrlZ: // block CtrlZ feature
    					return r, false
    				}
    				return r, true
    			},
    		})
    	if err != nil {
    		fmt.Println("error while starting readline: %s", err.Error())
    		return
    	}
    	defer l.Close()
    
    	log.SetOutput(l.Stderr()) // autorefresh prompt line
    	for {
    		line, err := l.Readline()
    		switch err {
    		case nil:
    		case io.EOF, readline.ErrInterrupt:
    			os.Exit(1)
    		default:
    			fmt.Println(err.Error())
    			continue
    		}
    
    		fmt.Println("user input: %s", line)
    	}
    }
    

    powershell && cmd

    first 4 are dark green, last 4 are light green

    2022/12/26 19:00:32 color
    2022/12/26 19:00:32 color
    2022/12/26 19:00:33 color
    2022/12/26 19:00:34 color
    calling log.SetOutput() inside GetInput() which changes color
    2022/12/26 19:00:34 color
    2022/12/26 19:00:35 color
    2022/12/26 19:00:35 color
    2022/12/26 19:00:36 color
    

    git bash

    2022/12/26 19:05:44 ←[32mcolor←[0m
    2022/12/26 19:05:45 ←[32mcolor←[0m
    2022/12/26 19:05:45 ←[32mcolor←[0m
    2022/12/26 19:05:46 ←[32mcolor←[0m
    calling log.SetOutput() inside GetInput() which changes color
    2022/12/26 19:05:46 color
    2022/12/26 19:05:47 color
    2022/12/26 19:05:47 color
    2022/12/26 19:05:48 color
    

    specs

    • windows 10
    • amd64
    • using vscode

    question

    • what can I use instead of log.SetOutput(l.Stderr()) to autorefresh the prompt line and having it always at the bottom?
    • is it correct to use log.SetOutput(l.Stdout())?
    • what can I do to avoid the unwanted color change?
  • the serial terminal key is invalid or stuck

    the serial terminal key is invalid or stuck

    When the tty is /dev/ttyS0, readline gets the term width as 0 (stty size output is 0 0), resulting in invalid tab and infinite loop of arrow keys

    w return is 0 https://github.com/chzyer/readline/blob/7f93d88cd5ffa0e805d58d2f9fc3191be15ec668/utils_unix.go#L39-L45

  • data race warning

    data race warning

    WARNING: DATA RACE Write at 0x00c0000ce1f0 by goroutine 35: github.com/chzyer/readline.(*opSearch).OnWidthChange() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/search.go:46 +0xc9 github.com/chzyer/readline.NewOperation.func1() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/operation.go:85 +0x9d github.com/chzyer/readline.DefaultOnWidthChanged.func1.1() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/utils_unix.go:79 +0x41

    Previous write at 0x00c0000ce1f0 by goroutine 132: github.com/chzyer/readline.newOpSearch() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/search.go:36 +0x3f7 github.com/chzyer/readline.(*Operation).SetConfig() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/operation.go:477 +0x34c github.com/chzyer/readline.NewOperation() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/operation.go:78 +0x315 github.com/chzyer/readline.(*Terminal).Readline() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/terminal.go:95 +0x5b github.com/chzyer/readline.NewEx() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/readline.go:169 +0x41 github.com/chzyer/readline.New() /home/archie/go/pkg/mod/github.com/chzyer/[email protected]/readline.go:181 +0xee jasmgo/app.handleReadLine()

  • Support multi-line edit

    Support multi-line edit

    Would be useful to implementing something similar to how quotes works in sh/bash. That is to be able to open a quote, write some lines and then close to quote. This currently work but once you go back in history to edit a multi-line input things go wrong.

    The behaviour can be reproduced using the multiline example and this patch:

    diff --git a/example/readline-multiline/readline-multiline.go b/example/readline-multiline/readline-multiline.go
    index 2192cf6..090753f 100644
    --- a/example/readline-multiline/readline-multiline.go
    +++ b/example/readline-multiline/readline-multiline.go
    @@ -32,7 +32,7 @@ func main() {
                            rl.SetPrompt(">>> ")
                            continue
                    }
    -               cmd := strings.Join(cmds, " ")
    +               cmd := strings.Join(cmds, "\n")
                    cmds = cmds[:0]
                    rl.SetPrompt("> ")
                    rl.SaveHistory(cmd)
    

    And then run:

    $ go run example/readline-multiline/readline-multiline.go
    > line1
    >>> line2
    >>> line3;
    line1
    line2
    line3;
    # press arrow up and you get multiple lines as input
    # press arrow left to try to go back into the multiline input
    # the lines start to scroll up
    

    Related to this is also #85

  • Tab Completion Candidate Pager for when candidates don't fit on a single page

    Tab Completion Candidate Pager for when candidates don't fit on a single page

    NB: This PR includes PR202 (https://github.com/chzyer/readline/pull/202) which is not yet merged. PR202 addressed various redraw issues with wide characters, edge of screen, multiple lines, masking etc. The main feature of the pager builds on these changes and redraw code so, I had to include them in this PR.

    Main Features:

    • If there are too many candidates returned by the completer, completeMode and completeSelectMode did not work properly. Similar to the bash completion pager, list candidates and offer "--More--" on the end of each page. User can select " ", "y" or "Y" to keep listing or "q", "Q", "n", "N" to stop listing. When paging completes, we also exit out of completionMode.
    • Added aggregate completion when entering completeSelectMode where the candidates dwindle down sharing a larger common prefix. This makes typing a little faster than having to select. It's a more bash-like behaviour.

    Other Fixes:

    • Fix various crashes where candidates are too wide for the width of the screen and causes division by zero.
    • Fix crash with wide (Asian characters) in completion.
    • Streamline redrawing as CompleteRefresh was called too often.
    • Fix crashes around ctrl-a and ctrl-e in select mode when candidates don't fit on a line
    • Fix prev/next candidates in select mode when candidates don't fit on a line
    • Fix crash when ctrl-k was pressed in select mode. This caused us to exit completeSelectMode which cleaned up all the data but left us in completeMode such that if CompleteRefresh was called directly, the data was not initialised.
    • Fix complete and select mode redraw issues when candidates did not fit on one line.
    • Fix cursor position issues after CompleteRefresh especially if the prompt and buffer also went over 1 line.
    • Fix redraw issue where exiting completion mode using certain key presses leaves candidates on the screen.

    Fixes for Windows:

    • Use window size for visible height/width instead of buffer size
    • Adjust for Window's EOL behaviour.

    Notes:

    • Added Height info to different structures as the decision to page or not required height information.
    • Added OnSizeChange(). Didn't know if I could get rid of the OnWidthChange()? Would be nice to remove the Width stuff and just have Size (width + height info).

    I tested this patch on Linux and Window and it seems to work well.

Drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags.

Description pflag is a drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags. pflag is compatible with the GNU extensions to

Dec 30, 2022
Dependency-free replacement for GNU parallel, perfect fit for usage in an initramfs.

coshell v0.2.5 A no-frills dependency-free replacement for GNU parallel, perfect for initramfs usage. Licensed under GNU/GPL v2. How it works An sh -c

Dec 19, 2022
GNU coreutils remade in Go for RosetteOS

Rosebush GNU and POSIX coreutils remade in Go for RosetteOS Build To compile the Rosebush, simply make -B This will compile all the utils one by one.

Oct 4, 2021
GDScript Syntax Highlighting in GNU Nano

nano-gdscript GDScript Syntax Highlighting in GNU Nano. Updated regularly every minor updates. Contributions are welcomed Installation This is 100% fr

Dec 20, 2022
A rich tool for parsing flags and values in pure Golang

A rich tool for parsing flags and values in pure Golang. No additional library is required and you can use everywhere.

Jan 25, 2022
Pure Go line editor with history, inspired by linenoise

Liner Liner is a command line editor with history. It was inspired by linenoise; everything Unix-like is a VT100 (or is trying very hard to be). If yo

Jan 3, 2023
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go

Sloc Cloc and Code (scc) A tool similar to cloc, sloccount and tokei. For counting physical the lines of code, blank lines, comment lines, and physica

Jan 8, 2023
Source code editor in pure Go.
Source code editor in pure Go.

Editor Source code editor in pure Go. About This is a simple but advanced source code editor As the editor is being developed, the rules of how the UI

Dec 25, 2022
A command line http test tool. Maintain the case via git and pure text
A command line http test tool. Maintain the case via git and pure text

httptest A command line http test tool Maintain the api test cases via git and pure text We want to test the APIs via http requests and assert the res

Dec 16, 2022
APFS parser written in pure Go

[WIP] go-apfs ?? APFS parser written in pure Go Originally from this ipsw branch Install go get github.com/blacktop/go-apfs apfs cli Install go instal

Dec 24, 2022
Pure Go command line prompt with history, kill-ring, and tab completion

Prompt Prompt is a command line prompt editor with history, kill-ring, and tab completion. It was inspired by linenoise and derivatives which eschew u

Nov 20, 2021
Rule engine implementation in Golang
Rule engine implementation in Golang

"Gopher Holds The Rules" Grule-Rule-Engine import "github.com/hyperjumptech/grule-rule-engine" Rule Engine for Go Grule is a Rule Engine library for t

Jan 3, 2023
Simple trie based auto-completion engine implementation in golang.
Simple trie based auto-completion engine implementation in golang.

Simple auto-complete engine implementation in golang. Quick start $ git clone https://github.com/benbarron/trie-auto-completion-engine $ cd trie-auto-

Jul 12, 2022
Golang implementation of the research by @jonaslyk and the drafted PoC from @LloydLabs

Doge-SelfDelete Golang implementation of the research by @jonaslyk and the drafted PoC from @LloydLabs Golang 实现的文件自删除,来自@jonaslyk和@LloydLabs etc add

Oct 2, 2022
Golang implementation of Reflective load PE from memory

?? Frog For Automatic Scan ?? Doge For Defense Evasion & Offensive Security Doge-MemX Golang implementation of Reflective load PE from memory Only Sup

Dec 6, 2022
Nano API Implementation in Golang

nanoapi Nano API Implementation in GO TL;DR The idea is to create a very simple

Jan 9, 2022
An implementation of the Nano cryptocurrency protocol in golang

Go Nano An implementation of the Nano protocol written from scratch in Go (golang). About the Project A crypto currency has to be resilient to survive

Dec 7, 2022
Golisp-wtf - A lisp interpreter (still just a parser) implementation in golang. You may yell "What the fuck!?.." when you see the shitty code.

R6RS Scheme Lisp dialect interpreter This is an implementation of a subset of R6RS Scheme Lisp dialect in golang. The work is still in progress. At th

Jan 7, 2022
Doge-AddSSP - Load ssp dll golang implementation

Doge-AddSSP Load ssp dll golang implementation Administrator/System Privilege Us

Nov 9, 2022