Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.

go-prompt

Go Report Card Software License GoDoc tests

A library for building powerful interactive prompts inspired by python-prompt-toolkit, making it easier to build cross-platform command line tools using Go.

package main

import (
	"fmt"
	"github.com/c-bata/go-prompt"
)

func completer(d prompt.Document) []prompt.Suggest {
	s := []prompt.Suggest{
		{Text: "users", Description: "Store the username and age"},
		{Text: "articles", Description: "Store the article text posted by user"},
		{Text: "comments", Description: "Store the text commented to articles"},
	}
	return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}

func main() {
	fmt.Println("Please select table.")
	t := prompt.Input("> ", completer)
	fmt.Println("You selected " + t)
}

Projects using go-prompt

Features

Powerful auto-completion

demo

(This is a GIF animation of kube-prompt.)

Flexible options

go-prompt provides many options. Please check option section of GoDoc for more details.

options

Keyboard Shortcuts

Emacs-like keyboard shortcuts are available by default (these also are the default shortcuts in Bash shell). You can customize and expand these shortcuts.

keyboard shortcuts

Key Binding Description
Ctrl + A Go to the beginning of the line (Home)
Ctrl + E Go to the end of the line (End)
Ctrl + P Previous command (Up arrow)
Ctrl + N Next command (Down arrow)
Ctrl + F Forward one character
Ctrl + B Backward one character
Ctrl + D Delete character under the cursor
Ctrl + H Delete character before the cursor (Backspace)
Ctrl + W Cut the word before the cursor to the clipboard
Ctrl + K Cut the line after the cursor to the clipboard
Ctrl + U Cut the line before the cursor to the clipboard
Ctrl + L Clear the screen

History

You can use Up arrow and Down arrow to walk through the history of commands executed.

History

Multiple platform support

We have confirmed go-prompt works fine in the following terminals:

  • iTerm2 (macOS)
  • Terminal.app (macOS)
  • Command Prompt (Windows)
  • gnome-terminal (Ubuntu)

Links

Author

Masashi Shibata

License

This software is licensed under the MIT license, see LICENSE for more information.

Owner
Masashi SHIBATA
Creator of go-prompt. Optuna committer. Kubeflow/Katib reviewer.
Masashi SHIBATA
Comments
  • Fix test on macOS

    Fix test on macOS

    Characters in Добрый день are actually double-width on macOS terminals (confirmed on Terminal.app and iTerm2.app).

    2018-10-18 19 47 34

    It caused test failure and I fixed it by modifying expected value. (I'm not sure updated expected value is actually what you expect, tho...)

  • Update pkg/term module to latest and use unix.Termios

    Update pkg/term module to latest and use unix.Termios

    Updating pkg/term is necessary to fix #190

    For more background, latest version of pkg/term has a change in argument type of function termios.Tcsetattr. See https://github.com/pkg/term/pull/51 for more details.

    Anyone using go prompt with explicit dependency of pkg/term to latest would encounter with issue #190

  • Problem with key bindings

    Problem with key bindings

    I have some problems adding key bindings in go-prompt. I took the 'echo' example, and tried to add a simple print for the 'Home', 'End' and 'PageUp' keys, but only the 'Home' key bind worked:

    package main
    
    import (
    	"fmt"
    	"github.com/c-bata/go-prompt"
    )
    
    func executor(in string) {
    	fmt.Println("Your input: " + in)
    }
    
    func completer(in prompt.Document) []prompt.Suggest {
    	s := []prompt.Suggest{
    		{Text: "users", Description: "Store the username and age"},
    		{Text: "articles", Description: "Store the article text posted by user"},
    		{Text: "comments", Description: "Store the text commented to articles"},
    		{Text: "groups", Description: "Combine users with specific rules"},
    	}
    	return prompt.FilterHasPrefix(s, in.GetWordBeforeCursor(), true)
    }
    
    func main() {
    	p := prompt.New(
    		executor,
    		completer,
    		prompt.OptionPrefix(">>> "),
    		prompt.OptionTitle("sql-prompt"),
    		prompt.OptionAddKeyBind(prompt.KeyBind{
    			Key: prompt.Home,
    			Fn: func(buf *prompt.Buffer) {
    				fmt.Println("HOME")
    			}}),
    		prompt.OptionAddKeyBind(prompt.KeyBind{
    			Key: prompt.End,
    			Fn: func(buf *prompt.Buffer) {
    				fmt.Println("END")
    			}}),
    		prompt.OptionAddKeyBind(prompt.KeyBind{
    			Key: prompt.PageUp,
    			Fn: func(buf *prompt.Buffer) {
    				fmt.Println("Up")
    			}}),
    	)
    	p.Run()
    }
    

    What's wrong with my code?

    Thanks for your help.

    PS: by the way, the default behaviour of the 'Home' key doesn't take into account the length of the Prefix (here, the ">>>").

  • Added OptionBreakLineCallback, to run a callback every time there's a line break

    Added OptionBreakLineCallback, to run a callback every time there's a line break

    It's sometimes useful to run a function everytime there's a line break -- Enter as well as, for example, ControlC.

    With this PR, a new option is added to assign a callback that gets called every time renderer.BreakLine() is called.

    Added a test that makes sure the renderer doesn't break if the callback is not specified, as well as to check that it runs ok when the callback executes.

    Just to give a bit more of context: in ABS we are trying to implement ControlR (reverse search), and need to clear the search selection every time the user "clears" the console, either by pressing enter or by clearing the current line (eg. ControlC).

  • How to bind ctrl+c to terminate current running command?

    How to bind ctrl+c to terminate current running command?

    Hi, I've been using this lib building a dynamodb prompt, it's all good until I try to kill a query running too long. Ctrl+c seems can't kill what is running in that executor function, so I looked up in the docs, but can't find any useful tips.

    Can someone help me with this, thanks~~

  • [Bug] Errors on installing go-prompt via go get in Ubuntu 18

    [Bug] Errors on installing go-prompt via go get in Ubuntu 18

    Bug reports

    Got the errors in the system terminal on installing the go-prompt package via command go get github.com/c-bata/go-prompt in Ubuntu 18.

    Expected Behavior

    Package has been downloaded and installed, can be used for program build (i.e. via go run, go build).

    Current Behavior and Steps to Reproduce

    On installing via the command go get github.com/c-bata/go-prompt in Ubuntu 18 (and in docker with images golang:1.13 or golang:1.14) got the errors

    ../../c-bata/go-prompt/internal/term/raw.go:27:75: cannot use (*syscall.Termios)(&n) (type *syscall.Termios) as type *unix.Termios in argument to termios.Tcsetattr ../../c-bata/go-prompt/internal/term/term.go:22:40: cannot use &saveTermios (type *syscall.Termios) as type *unix.Termios in argument to termios.Tcgetattr ../../c-bata/go-prompt/internal/term/term.go:33:68: cannot use &o (type *syscall.Termios) as type *unix.Termios in argument to termios.Tcsetattr

    Tried to use go modules, and install a particular release (tag), alike go get -v github.com/c-bata/[email protected] but none of them helps (tried all 6 releases) - no changes, the same errors.

    At the same time, in the Windows WSL with Ubuntu 18 the package is being installed w/o errors and can be used as expected.

    Context

    • Operating System: Ubuntu 18 (Linux 5.0.0-38-generic #41-Ubuntu SMP Tue Dec 3 00:27:35 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux); docker images golang:1.13 or golang:1.14
    • Go version: on Ubuntu 18 - where errors occur: 1.14.1; on Windows WSL / Ubuntu 18: 1.14
    • Terminal Emulator: none (fails on installing step)
    • tag: any release

    Thanks for your help!

  • Detect exit request with CTRL-D in Input

    Detect exit request with CTRL-D in Input

    Feature Request

    Feature Request

    Hi, thank you for the lovely library. I am using it in a project here https://github.com/fortify500/stepsman Would appreciate if you can add me to the list. Currently I am using Input and not Run because I have no apparent way to enter the OptionInitialBufferText on every input (which i need). However, the biggest problem is that in Input I don't know if a CTRL-D was pressed to exit. I tried serval tricks like KeyBind (which is not triggered for some reason) but to no avail.

    Would appreciate it if it was possible to somehow either detect CTRL-D after the Input finished like an err returned in addition to the string or a callback or simply enter "exit" string.

    Thanks!

  • Update pkg/term to 1.2.0

    Update pkg/term to 1.2.0

    This fixes build errors on FreeBSD. Ran go mod tidy to clean up unused dependencies.

    Term package has fixed FreeBSD build errors recently https://github.com/pkg/term/pull/61

  • [Bug] Usage of Ctrl+C binding corrupt STTY settings

    [Bug] Usage of Ctrl+C binding corrupt STTY settings

    Bug reports

    Expected Behavior

    After my program is finished with ControlC binding, I expect that Ctrl+C combination will work in the terminal as it did before the program launch.

    Current Behavior and Steps to Reproduce

    After finished my program by ControlC binding and Ctrl+C combination do nothing.

    p := prompt.New(
    	// ... other options
    	prompt.OptionAddKeyBind(prompt.KeyBind{
    		Key: prompt.ControlC,
    		Fn: func(b *prompt.Buffer) { os.Exit(0) }
    	}),
    )
    
    p.Run()
    

    If I send text command to executor for exit it calls os.Exit(0) too and program finished correctly.

    Program exit if I press Ctrl+C in opened prompt and stty settings is corrupted.

    I got settings before run program with stty -a > stty.before and after finish program by CTRL+C with stty -a > stty.after.

    --- stty.before	2020-05-26 15:30:40.827199004 +0300
    +++ stty.after	2020-05-26 15:30:47.212105711 +0300
    @@ -3,8 +3,8 @@
     eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
     werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
     -parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
    --ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
    +-ignbrk -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff
     -iuclc -ixany imaxbel iutf8
     opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    -isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
    +-isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
     echoctl echoke -flusho -extproc
    

    Disabled this options: -brkint -icrnl -ixon -isig

    Option isig enable interrupt, quit, and suspend special characters.

    More info about stty https://linux.die.net/man/1/stty

    For restore initial behavior need use command reset.

    Context

    • Operating System: Fedora Linux, CentOS
    • Terminal Emulator: gnome-terminal
    • commit revision: d043be07639872dd59e161726523dcf4687959cc
  • Trigger ExitChecker on pressed keys

    Trigger ExitChecker on pressed keys

    #161 allows to exit go-prompt (not the all Go program like an os.Exit(), but just go-prompt) when the user type <return> and select an entry matching a criteria.

    This PR adds the same exit-go-prompt option to each key typed.

    The general goal is to allow for an early exit as soon as a character (or sequence of characters) has been typed, without having to type <enter>.

    Example use-case: a go-prompt with three choices 'yes', 'no', 'cancel'.

    The following example would allow a user to select yes or no, just by typing 'y' or 'n' (no need to type <return>), or 'cancel' by typing ESC. That would not call os.Exit, just exit the go-prompt Run() loop, without executor.

    type choice struct {
    	isCancel bool
    	isYes    bool
    }
    
    func (c *choice) cancel(_ *prompt.Buffer) {
    	c.isCancel = true
    }
    
    func (c *choice) checkIfExit(in string) bool {
    	c.isYes = (in == "y")
    	return in == "y" || in == "n" || c.isCancel
    }
    
    func main() {
    	c := &choice{}
    	exitOnEscape := prompt.KeyBind{
    		Key: prompt.Escape,
    		Fn:  c.cancel,
    	}
    	p := prompt.New(
    		executor,
    		completer,
    		prompt.OptionPrefix(">>> "),
    		prompt.OptionSetExitCheckerOnInput(c.checkIfExit),
    		prompt.OptionCompletionOnDown(),
    		prompt.OptionAddKeyBind(exitOnEscape),
    	)
    	p.Run()
    	fmt.Println("All done")
    	fmt.Printf("Choice '%t', cancelled: '%t'\n", c.isYes, c.isCancel)
    }
    
  • Fix runtime error: index out of range in GetSelectedSuggestion

    Fix runtime error: index out of range in GetSelectedSuggestion

    When I enter [tab] many times, will panic like below: panic: runtime error: index out of range [0] with length 0

    goroutine 1 [running]: github.com/c-bata/go-prompt.(*CompletionManager).GetSelectedSuggestion(0xc0004320f0, 0xc000424c40, 0xc0004320f0, 0x17, 0x6f00000063, 0x6500000072) /root/go/pkg/mod/github.com/c-bata/[email protected]/completion.go:51 +0x13f github.com/c-bata/go-prompt.(*Render).Render(0xc000430f70, 0xc000424c40, 0xc0004320f0) /root/go/pkg/mod/github.com/c-bata/[email protected]/render.go:209 +0x3dd github.com/c-bata/go-prompt.(*Prompt).Run(0xc00044f700) /root/go/pkg/mod/github.com/c-bata/[email protected]/prompt.go:96 +0x6f9 github.com/shipengqi/hawk-eye/app/hectl/cmd.promptCommand.func1(0xc0001faf00, 0x1d61f80, 0x0, 0x0) /root/hawk-eye/app/hectl/cmd/prompt.go:38 +0x39f github.com/spf13/cobra.(*Command).execute(0xc0001faf00, 0x1d61f80, 0x0, 0x0, 0xc0001faf00, 0x1d61f80) /root/go/pkg/mod/github.com/spf13/[email protected]/command.go:830 +0x2aa github.com/spf13/cobra.(*Command).ExecuteC(0xc0001fac80, 0x0, 0x111c640, 0xc000096058) /root/go/pkg/mod/github.com/spf13/[email protected]/command.go:914 +0x2fb github.com/spf13/cobra.(*Command).Execute(...) /root/go/pkg/mod/github.com/spf13/[email protected]/command.go:864 main.main() /root/hawk-eye/app/hectl/main.go:7 +0x28

  • added new InputWithExit api to indicate when an exit was requested

    added new InputWithExit api to indicate when an exit was requested

    The idea here is to allow a bit finer grained control over the Input function without disturbing the current API. When using go-prompt in a custom REPL it's useful to know when something like CTRL+D was pressed so that the loop can terminate, since there's no way to distinguish between empty input "" and an exit request. For your consideration.

  • [Bug] In the v0.2.6 , the icnl attribute of the stty is modified, but the attribute is not restored. v0.2.5 is ok

    [Bug] In the v0.2.6 , the icnl attribute of the stty is modified, but the attribute is not restored. v0.2.5 is ok

    Bug reports

    I use go-prompt to develop my own CLI client program. After exiting the client, press Enter and enter no line break. No command is displayed, but the command is executed. This can be eliminated by entering the stty sane command, so I determined that go-prompt modified the stty attribute. Switch to v0.2.5 and no problem. the icnl attribute of the stty is modified, but the attribute is not restored.

    Expected Behavior

    bug

    Current Behavior and Steps to Reproduce

    That's how I used it: fmt.Printf("openGemini CLI %s (rev-%s)\n", CLIENT_VERSION, "revision") fmt.Println("Please usequit,exitorCtrl-Dto exit this program.") completer := NewCompleter() p := prompt.New( c.executor, completer.completer, prompt.OptionTitle("openGemini: interactive openGemini client"), prompt.OptionPrefix(">>> "), prompt.OptionPrefixTextColor(prompt.DefaultColor), prompt.OptionCompletionWordSeparator(FilePathCompletionSeparator), ) p.Run() return nil

    That's how I find it : bug2

    • Operating System: Linux (CentOS 8.5)
    • Terminal Emulator: XShell
    • tag of go-prompt or commit revision: 0.2.6
  • [Bug] Terminal Colors not reset after application exists

    [Bug] Terminal Colors not reset after application exists

    Bug reports

    Please file a bug report here.

    Expected Behavior

    When go-prompt application is terminated (ctrl^D), terminal color's need to be reset.

    Current Behavior and Steps to Reproduce

    After exiting go-prompt application (ex: simple-echo), the terminal & shell (mac terminal, iterm2, ubuntu bash) are in a state where you cannot see any characters being typed. Restarting the shell resolved the issue, until the next time you run the go-prompt application:

    `vagrant@dev:~/host_user_homedir/go-workspace/src/go-prompt/_example/simple-echo$ go run main.go

    users Your input: users vagrant@dev:~/host_user_homedir/go-workspace/src/go-prompt/_example/simple-echo$ ddddddd: command not found `

    https://user-images.githubusercontent.com/577870/196228129-16339375-7b4f-4499-8cd7-e152257ad35d.mov

    Context

    Mac 11.7 with iTerm2 and terminal Ubuntu 20.04 with default bash shell

  • support meta-{backspace,left,right} key.

    support meta-{backspace,left,right} key.

    Added Alt+ and Alt+ processing to the contents of this pull request.

    For MacOS terminal emulators, Option + delete does not work with the default settings. Therefore, it is necessary to enable the setting to use the Options key as the Meta key in each terminal. This seems to be the same with zsh etc.

  • [Bug] Unexpected behavior of log output

    [Bug] Unexpected behavior of log output

    Bug reports

    [tsh][listeners] >>> start default-http2-listener
    [2022-05-06 20:33:28][INFO] Starting listener default-http2-listener
    [tsh][listeners] >>> [2022-05-06 20:33:28][ERROR] HTTP2Listener default-http2-listener start error: listen tcp 0.0.0.0:8989: bind: address already in use
    

    As the above output shows, the log output coincides with the current command line, is there a way to fix this?

    Expected Behavior

    Logs are automatically output above the command line instead of peers

    Current Behavior and Steps to Reproduce

    The log output is the same as the current command line

    • Operating System: Macos
    • Terminal Emulator: iTerm2
    • tag of go-prompt or commit revision: v0.2.6
Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.
Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.

go-prompt A library for building powerful interactive prompts inspired by python-prompt-toolkit, making it easier to build cross-platform command line

Jan 3, 2023
A golang library for building interactive prompts with full support for windows and posix terminals.
A golang library for building interactive prompts with full support for windows and posix terminals.

Survey A library for building interactive prompts on terminals supporting ANSI escape sequences. package main import ( "fmt" "github.com/Alec

Jan 6, 2023
git-glimpse is a command-line tool that is aimed at generating a git prompt like the one from zsh-vcs-prompt.

Git GoGlimpse git-glimpse is a command-line tool that is aimed at generating a git prompt like the one from zsh-vcs-prompt. The particularity of this

Jan 27, 2022
Provides an interactive prompt to connect to ECS Containers using the ECS ExecuteCommand API.
Provides an interactive prompt to connect to ECS Containers using the ECS ExecuteCommand API.

ecsgo Heavily inspired by incredibly useful gossm, this tool makes use of the new ECS ExecuteCommand API to connect to running ECS tasks. It provides

Dec 12, 2022
Interactive prompt for command-line applications
Interactive prompt for command-line applications

promptui Interactive prompt for command-line applications. We built Promptui because we wanted to make it easy and fun to explore cloud services with

Jan 8, 2023
Interactive prompt to set and push a semver tag
Interactive prompt to set and push a semver tag

cutver For when you know what version to tag, and you want to cut a release in the annotated tag format. Installation go install github.com/roryq/cutv

Nov 15, 2022
A simple CLI based rock-paper-scissors game created in GO with interactive shell prompt.

rock-paper-scissors A simple CLI (Command Line Interface) based rock-paper-scissors game with interactive shell prompt. Language Download Grab a binar

Oct 9, 2022
An easy to use menu structure for cli applications that prompts users to make choices.
An easy to use menu structure for cli applications that prompts users to make choices.

WMenu Package wmenu creates menus for cli programs. It uses wlog for its interface with the command line. It uses os.Stdin, os.Stdout, and os.Stderr w

Dec 26, 2022
Prompts users to enter values for required flags in Cobra CLI applications

Cobra Flag Prompt Cobra Flag Prompt prompts users to enter values for required flags. It is an extension of Cobra, and requires that you use Cobra to

Nov 13, 2021
:key: Idiotproof golang password validation library inspired by Python's passlib

passlib for go Python's passlib is quite an amazing library. I'm not sure there's a password library in existence with more thought put into it, or wi

Dec 30, 2022
:key: Idiotproof golang password validation library inspired by Python's passlib

passlib for go 100% modules-free. Python's passlib is quite an amazing library. I'm not sure there's a password library in existence with more thought

Dec 19, 2022
⛳ A minimal programming language inspired by Ink, JavaScript, and Python.

⛳ Golfcart My blog post: Creating the Golfcart Programming Language Getting Started Scope Rules Usage Building and tests Contributions License Golfcar

Sep 6, 2022
Go-fastapi: a library to quickly build APIs. It is inspired by Python's popular FastAPI
Go-fastapi: a library to quickly build APIs. It is inspired by Python's popular FastAPI

go-fastapi go-fastapi is a library to quickly build APIs. It is inspired by Pyth

Jan 1, 2023
Tpf2-tpnetmap-toolkit - A toolkit to create svg map images from TransportFever2 world data
Tpf2-tpnetmap-toolkit - A toolkit to create svg map images from TransportFever2 world data

tpf2-tpnetmap-toolkit TransportFever2 のワールドデータから svg のマップ画像を作成するツールキットです。 1. 導入方

Feb 17, 2022
Substation is a cloud native toolkit for building modular ingest, transform, and load (ITL) data pipelines

Substation Substation is a cloud native data pipeline toolkit. What is Substation? Substation is a modular ingest, transform, load (ITL) application f

Dec 30, 2022
A Go (golang) package that enhances the standard database/sql package by providing powerful data retrieval methods as well as DB-agnostic query building capabilities.

ozzo-dbx Summary Description Requirements Installation Supported Databases Getting Started Connecting to Database Executing Queries Binding Parameters

Dec 31, 2022
A powerful HTTP router and URL matcher for building Go web servers with 🦍

gorilla/mux https://www.gorillatoolkit.org/pkg/mux Package gorilla/mux implements a request router and dispatcher for matching incoming requests to th

Jan 9, 2023
⚡️ A Go framework for rapidly building powerful graphql services

Thunder is a Go framework for rapidly building powerful graphql servers. Thunder has support for schemas automatically generated from Go types, live q

Dec 24, 2022