Version: v0.0.0-...-b95dbb3 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Jan 14, 2016 License: MIT, AGPL-3.0 Imports: 15 Imported by: 0



Software License Build Status GoDoc

Readline is A Pure Go Implementation of a libreadline-style Library.
The goal is to be a powerful alternater for GNU-Readline.

WHY: Readline will support most of features which GNU Readline is supported, and provide a pure go environment and a MIT license.



Also works fine in windows

demo windows

You can read the source code in example/main.go.


  • Vi Mode is not completely finish
  • More funny examples
  • Support dumb/eterm-color terminal in emacs


  • Support emacs/vi mode, almost all basic features that GNU-Readline is supported
  • zsh-style backward/forward history search
  • zsh-style completion
  • Readline auto refresh when others write to Stdout while editing (it needs specify the Stdout/Stderr provided by *readline.Instance to others).
  • Support colourful prompt in all platforms.


  • Simplest example
import ""

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

for {
	line, err := rl.Readline()
	if err != nil { // io.EOF
  • Example with durable history
rl, err := readline.NewEx(&readline.Config{
	Prompt: "> ",
	HistoryFile: "/tmp/readline.tmp",
if err != nil {
defer rl.Close()

for {
	line, err := rl.Readline()
	if err != nil { // io.EOF
  • Example with auto refresh
import (

rl, err := readline.New("> ")
if err != nil {
defer rl.Close()
log.SetOutput(l.Stderr()) // let "log" write to l.Stderr instead of os.Stderr

go func() {
	for _ = range time.Tick(time.Second) {

for {
	line, err := rl.Readline()
	if err != nil { // io.EOF
  • Example with auto completion
import (

var completer = readline.NewPrefixCompleter(

rl, err := readline.New(&readline.Config{
	Prompt:       "> ",
	AutoComplete: completer,
if err != nil {
defer rl.Close()

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


Meta+B means press Esc and n separately.
Users can change that in terminal simulator(i.e. iTerm2) to Alt+B
Notice: Meta+B is equals with Alt+B in windows.

  • Shortcut in normal mode
Shortcut Comment
Ctrl+A Beginning of line
Ctrl+B / Backward one character
Meta+B Backward one word
Ctrl+C Send io.EOF
Ctrl+D Delete one character
Meta+D Delete one word
Ctrl+E End of line
Ctrl+F / Forward one character
Meta+F Forward one word
Ctrl+G Cancel
Ctrl+H Delete previous character
Ctrl+I / Tab Command line completion
Ctrl+J Line feed
Ctrl+K Cut text to the end of line
Ctrl+L Clean screen (TODO)
Ctrl+M Same as Enter key
Ctrl+N / Next line (in history)
Ctrl+P / Prev line (in history)
Ctrl+R Search backwards in history
Ctrl+S Search forwards in history
Ctrl+T Transpose characters
Meta+T Transpose words (TODO)
Ctrl+U Cut text to the beginning of line
Ctrl+W Cut previous word
Backspace Delete previous character
Meta+Backspace Cut previous word
Enter Line feed
  • Shortcut in Search Mode (Ctrl+S or Ctrl+r to enter this mode)
Shortcut Comment
Ctrl+S Search forwards in history
Ctrl+R Search backwards in history
Ctrl+C / Ctrl+G Exit Search Mode and revert the history
Backspace Delete previous character
Other Exit Search Mode
  • Shortcut in Complete Select Mode (double Tab to enter this mode)
Shortcut Comment
Ctrl+F Move Forward
Ctrl+B Move Backward
Ctrl+N Move to next line
Ctrl+P Move to previous line
Ctrl+A Move to the first candicate in current line
Ctrl+E Move to the last candicate in current line
Tab / Enter Use the word on cursor to complete
Ctrl+C / Ctrl+G Exit Complete Select Mode
Other Exit Complete Select Mode

Tested with

Environment $TERM
Mac OS X iTerm2 xterm
Mac OS X default xterm
Mac OS X iTerm2 Screen screen
Mac OS X iTerm2 Tmux screen
Ubuntu Server 14.04 LTS linux
Centos 7 linux
Windows 10 -
  • Ctrl+A is not working in screen because it used as a control command by default

If you test it otherwhere, whether it works fine or not, please let me know!


If you have any questions, please submit a github issue and any pull requests is welcomed :)



Readline is a pure go implementation for GNU-Readline kind library.

WHY: Readline will support most of features which GNU Readline is supported, and provide a pure go environment and a MIT license.


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

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



View Source
const (
	CharLineStart = 1
	CharBackward  = 2
	CharInterrupt = 3
	CharDelete    = 4
	CharLineEnd   = 5
	CharForward   = 6
	CharBell      = 7
	CharCtrlH     = 8
	CharTab       = 9
	CharCtrlJ     = 10
	CharKill      = 11
	CharEnter     = 13
	CharNext      = 14
	CharPrev      = 16
	CharBckSearch = 18
	CharFwdSearch = 19
	CharTranspose = 20
	CharCtrlU     = 21
	CharCtrlW     = 23
	CharEsc       = 27
	CharEscapeEx  = 91
	CharBackspace = 127
View Source
const (
	MetaBackward rune = -iota - 1
View Source
const (
View Source
const (
	S_DIR_BCK = iota
View Source
const (
	VIM_NORMAL = iota


View Source
var (
	Stdin  io.ReadCloser  = os.Stdin
	Stdout io.WriteCloser = os.Stdout
	Stderr io.WriteCloser = os.Stderr
View Source
var (
	StdinFd = int(uintptr(syscall.Stdin))


func Debug

func Debug(o ...interface{})

append log info to another file

func GetInt

func GetInt(s []string, def int) int

func IsPrintable

func IsPrintable(key rune) bool

func IsTerminal

func IsTerminal(fd int) bool

IsTerminal returns true if the given file descriptor is a terminal.

func IsWordBreak

func IsWordBreak(i rune) bool

func LineCount

func LineCount(w int) int

calculate how many lines for N character

func MakeRaw

func MakeRaw(fd int) (*terminal.State, error)

func Restore

func Restore(fd int, state *terminal.State) error


type AutoCompleter

type AutoCompleter interface {
	// Readline will pass the whole line and current offset to it
	// Completer need to pass all the candidates, and how long they shared the same characters in line
	// Example:
	//   Do("g", 1) => ["o", "it", "it-shell", "rep"], 1
	//   Do("gi", 2) => ["t", "t-shell"], 1
	//   Do("git", 3) => ["", "-shell"], 0
	Do(line []rune, pos int) (newLine [][]rune, length int)

type Config

type Config struct {
	// prompt supports ANSI escape sequence, so we can color some characters even in windows
	Prompt string

	// readline will persist historys to file where HistoryFile specified
	HistoryFile string
	// specify the max length of historys, it's 500 by default
	HistoryLimit int

	// AutoCompleter will called once user press TAB
	AutoComplete AutoCompleter

	// If VimMode is true, readline will in vim.insert mode by default
	VimMode bool

	Stdout io.Writer
	Stderr io.Writer
	// contains filtered or unexported fields

func (*Config) Init

func (c *Config) Init() error

type Instance

type Instance struct {
	Config    *Config
	Terminal  *Terminal
	Operation *Operation

func New

func New(prompt string) (*Instance, error)

func NewEx

func NewEx(cfg *Config) (*Instance, error)

func (*Instance) Close

func (i *Instance) Close() error

we must make sure that call Close() before process exit.

func (*Instance) IsVimMode

func (i *Instance) IsVimMode() bool

func (*Instance) ReadPassword

func (i *Instance) ReadPassword(prompt string) ([]byte, error)

func (*Instance) ReadSlice

func (i *Instance) ReadSlice() ([]byte, error)

same as readline

func (*Instance) Readline

func (i *Instance) Readline() (string, error)

func (*Instance) SetHistoryPath

func (i *Instance) SetHistoryPath(p string)

change hisotry persistence in runtime

func (*Instance) SetPrompt

func (i *Instance) SetPrompt(s string)

func (*Instance) SetVimMode

func (i *Instance) SetVimMode(on bool)

switch VimMode in runtime

func (*Instance) Stderr

func (i *Instance) Stderr() io.Writer

readline will refresh automatic when write through Stdout()

func (*Instance) Stdout

func (i *Instance) Stdout() io.Writer

readline will refresh automatic when write through Stdout()

type Operation

type Operation struct {
	// contains filtered or unexported fields

func NewOperation

func NewOperation(t *Terminal, cfg *Config) *Operation

func (*Operation) Close

func (o *Operation) Close()

func (Operation) CloseHistory

func (o Operation) CloseHistory()

func (Operation) CompactHistory

func (o Operation) CompactHistory()

func (Operation) CompleteRefresh

func (o Operation) CompleteRefresh()

func (Operation) EnterCompleteMode

func (o Operation) EnterCompleteMode(offset int, candidate [][]rune)

func (Operation) EnterCompleteSelectMode

func (o Operation) EnterCompleteSelectMode()

func (Operation) EnterVimInsertMode

func (o Operation) EnterVimInsertMode()

func (Operation) ExitCompleteMode

func (o Operation) ExitCompleteMode(revent bool)

func (Operation) ExitCompleteSelectMode

func (o Operation) ExitCompleteSelectMode()

func (Operation) ExitSearchMode

func (o Operation) ExitSearchMode(revert bool)

func (Operation) ExitVimInsertMode

func (o Operation) ExitVimInsertMode()

func (Operation) ExitVimMode

func (o Operation) ExitVimMode()

func (Operation) FindHistoryBck

func (o Operation) FindHistoryBck(isNewSearch bool, rs []rune, start int) (int, *list.Element)

func (Operation) FindHistoryFwd

func (o Operation) FindHistoryFwd(isNewSearch bool, rs []rune, start int) (int, *list.Element)

func (Operation) HandleCompleteSelect

func (o Operation) HandleCompleteSelect(r rune) bool

func (Operation) HandleVim

func (o Operation) HandleVim(r rune, readNext func() rune) rune

func (Operation) HandleVimNormal

func (o Operation) HandleVimNormal(r rune, readNext func() rune) (t rune)

func (Operation) HistoryRewrite

func (o Operation) HistoryRewrite()

func (Operation) IsEnableVimMode

func (o Operation) IsEnableVimMode() bool

func (Operation) IsInCompleteMode

func (o Operation) IsInCompleteMode() bool

func (Operation) IsInCompleteSelectMode

func (o Operation) IsInCompleteSelectMode() bool

func (Operation) IsSearchMode

func (o Operation) IsSearchMode() bool

func (Operation) NewHistory

func (o Operation) NewHistory(current []rune)

func (Operation) NextHistory

func (o Operation) NextHistory() ([]rune, bool)

func (Operation) OnComplete

func (o Operation) OnComplete()

func (*Operation) Password

func (o *Operation) Password(prompt string) ([]byte, error)

func (Operation) PrevHistory

func (o Operation) PrevHistory() []rune

func (Operation) PushHistory

func (o Operation) PushHistory(s []rune)

func (*Operation) Runes

func (o *Operation) Runes() ([]rune, error)

func (Operation) SearchBackspace

func (o Operation) SearchBackspace()

func (Operation) SearchChar

func (o Operation) SearchChar(r rune)

func (Operation) SearchMode

func (o Operation) SearchMode(dir int)

func (Operation) SearchRefresh

func (o Operation) SearchRefresh(x int)

func (*Operation) SetHistoryPath

func (o *Operation) SetHistoryPath(path string)

func (*Operation) SetPrompt

func (o *Operation) SetPrompt(s string)

func (*Operation) SetTitle

func (o *Operation) SetTitle(t string)

func (Operation) SetVimMode

func (o Operation) SetVimMode(on bool)

func (*Operation) Slice

func (o *Operation) Slice() ([]byte, error)

func (*Operation) Stderr

func (o *Operation) Stderr() io.Writer

func (*Operation) Stdout

func (o *Operation) Stdout() io.Writer

func (*Operation) String

func (o *Operation) String() (string, error)

func (Operation) UpdateHistory

func (o Operation) UpdateHistory(s []rune, commit bool)

type PrefixCompleter

type PrefixCompleter struct {
	Name     []rune
	Children []*PrefixCompleter

func NewPrefixCompleter

func NewPrefixCompleter(pc ...*PrefixCompleter) *PrefixCompleter

func PcItem

func PcItem(name string, pc ...*PrefixCompleter) *PrefixCompleter

func (*PrefixCompleter) Do

func (p *PrefixCompleter) Do(line []rune, pos int) (newLine [][]rune, offset int)

type RuneBuffer

type RuneBuffer struct {
	// contains filtered or unexported fields

func NewRuneBuffer

func NewRuneBuffer(w io.Writer, prompt string) *RuneBuffer

func (*RuneBuffer) BackEscapeWord

func (r *RuneBuffer) BackEscapeWord()

func (*RuneBuffer) Backspace

func (r *RuneBuffer) Backspace()

func (*RuneBuffer) Backup

func (r *RuneBuffer) Backup()

func (*RuneBuffer) Clean

func (r *RuneBuffer) Clean()

func (*RuneBuffer) CurrentWidth

func (r *RuneBuffer) CurrentWidth(x int) int

func (*RuneBuffer) CursorLineCount

func (r *RuneBuffer) CursorLineCount() int

func (*RuneBuffer) Delete

func (r *RuneBuffer) Delete() (success bool)

func (*RuneBuffer) DeleteWord

func (r *RuneBuffer) DeleteWord()

func (*RuneBuffer) Erase

func (r *RuneBuffer) Erase()

func (*RuneBuffer) IdxLine

func (r *RuneBuffer) IdxLine() int

func (*RuneBuffer) Kill

func (r *RuneBuffer) Kill()

func (*RuneBuffer) KillFront

func (r *RuneBuffer) KillFront()

func (*RuneBuffer) Len

func (r *RuneBuffer) Len() int

func (*RuneBuffer) LineCount

func (r *RuneBuffer) LineCount() int

func (*RuneBuffer) MoveBackward

func (r *RuneBuffer) MoveBackward()

func (*RuneBuffer) MoveForward

func (r *RuneBuffer) MoveForward()

func (*RuneBuffer) MoveTo

func (r *RuneBuffer) MoveTo(ch rune, prevChar, reverse bool) (success bool)

func (*RuneBuffer) MoveToLineEnd

func (r *RuneBuffer) MoveToLineEnd()

func (*RuneBuffer) MoveToLineStart

func (r *RuneBuffer) MoveToLineStart()

func (*RuneBuffer) MoveToNextWord

func (r *RuneBuffer) MoveToNextWord()

func (*RuneBuffer) MoveToPrevWord

func (r *RuneBuffer) MoveToPrevWord() (success bool)

func (*RuneBuffer) Pos

func (r *RuneBuffer) Pos() int

func (*RuneBuffer) PromptLen

func (r *RuneBuffer) PromptLen() int

func (*RuneBuffer) Refresh

func (r *RuneBuffer) Refresh(f func())

func (*RuneBuffer) Reset

func (r *RuneBuffer) Reset() []rune

func (*RuneBuffer) Restore

func (r *RuneBuffer) Restore()

func (*RuneBuffer) RuneSlice

func (r *RuneBuffer) RuneSlice(i int) []rune

func (*RuneBuffer) Runes

func (r *RuneBuffer) Runes() []rune

func (*RuneBuffer) Set

func (r *RuneBuffer) Set(buf []rune)

func (*RuneBuffer) SetPrompt

func (r *RuneBuffer) SetPrompt(prompt string)

func (*RuneBuffer) SetStyle

func (r *RuneBuffer) SetStyle(start, end int, style string)

func (*RuneBuffer) SetWithIdx

func (r *RuneBuffer) SetWithIdx(idx int, buf []rune)

func (*RuneBuffer) Transpose

func (r *RuneBuffer) Transpose()

func (*RuneBuffer) WriteRune

func (r *RuneBuffer) WriteRune(s rune)

func (*RuneBuffer) WriteRunes

func (r *RuneBuffer) WriteRunes(s []rune)

func (*RuneBuffer) WriteString

func (r *RuneBuffer) WriteString(s string)

type Terminal

type Terminal struct {
	// contains filtered or unexported fields

func NewTerminal

func NewTerminal(cfg *Config) (*Terminal, error)

func (*Terminal) Bell

func (t *Terminal) Bell()

func (*Terminal) Close

func (t *Terminal) Close() error

func (*Terminal) IsReading

func (t *Terminal) IsReading() bool

func (*Terminal) KickRead

func (t *Terminal) KickRead()

func (*Terminal) Print

func (t *Terminal) Print(s string)

func (*Terminal) PrintRune

func (t *Terminal) PrintRune(r rune)

func (*Terminal) ReadRune

func (t *Terminal) ReadRune() rune

func (*Terminal) Readline

func (t *Terminal) Readline() *Operation

func (*Terminal) Write

func (t *Terminal) Write(b []byte) (int, error)


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL