package module
Version: v0.4.14 Latest Latest

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

Go to latest
Published: Aug 26, 2021 License: MIT Imports: 13 Imported by: 0


GoDoc Go Report Card


go-readline-ny is the readline library used in the command line shell NYAGOS.

  • Emacs-like key-bindings
  • On Windows Terminal
    • Surrogate-pair
    • Emoji (via clipboard)
    • Zero-Width-Joiner (via clipboard)
    • Variation Selector (via clipboard pasted by Ctrl-Y)

Zero-Width-Joiner sample on Windows-Terminal


The most simple sample.

package main

import (


func main() {
    editor := readline.Editor{}
    text, err := editor.ReadLine(context.Background())
    if err != nil {
        fmt.Printf("ERR=%s\n", err.Error())
    } else {
        fmt.Printf("TEXT=%s\n", text)

If the target platform includes Windows, you have to import and use go-colorable like example2.go .


Tiny Shell

package main

import (



func main() {
    history := simplehistory.New()

    editor := readline.Editor{
        Prompt:  func() (int, error) { return fmt.Print("$ ") },
        Writer:  colorable.NewColorableStdout(),
        History: history,
    fmt.Println("Tiny Shell. Type Ctrl-D to quit.")
    for {
        text, err := editor.ReadLine(context.Background())

        if err != nil {
            fmt.Printf("ERR=%s\n", err.Error())

        fields := strings.Fields(text)
        if len(fields) <= 0 {
        cmd := exec.Command(fields[0], fields[1:]...)
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        cmd.Stdin = os.Stdin






View Source
const (
	K_CLEAR          = "CLEAR"
	K_CTRL           = "CTRL"
	K_CTRL_A         = "C_A"
	K_CTRL_B         = "C_B"
	K_CTRL_C         = "C_C"
	K_CTRL_D         = "C_D"
	K_CTRL_E         = "C_E"
	K_CTRL_F         = "C_F"
	K_CTRL_G         = "C_G"
	K_CTRL_H         = "C_H"
	K_CTRL_I         = "C_I"
	K_CTRL_J         = "C_J"
	K_CTRL_K         = "C_K"
	K_CTRL_L         = "C_L"
	K_CTRL_M         = "C_M"
	K_CTRL_N         = "C_N"
	K_CTRL_O         = "C_O"
	K_CTRL_P         = "C_P"
	K_CTRL_Q         = "C_Q"
	K_CTRL_R         = "C_R"
	K_CTRL_S         = "C_S"
	K_CTRL_T         = "C_T"
	K_CTRL_U         = "C_U"
	K_CTRL_V         = "C_V"
	K_CTRL_W         = "C_W"
	K_CTRL_X         = "C_X"
	K_CTRL_Y         = "C_Y"
	K_CTRL_Z         = "C_Z"
	K_CTRL_CARET     = "C_^"
	K_DELETE         = "DEL"
	K_DOWN           = "DOWN"
	K_CTRL_DOWN      = "C_DOWN"
	K_END            = "END"
	K_ENTER          = "ENTER"
	K_ESCAPE         = "ESCAPE"
	K_F1             = "F1"
	K_F10            = "F10"
	K_F11            = "F11"
	K_F12            = "F12"
	K_F13            = "F13"
	K_F14            = "F14"
	K_F15            = "F15"
	K_F16            = "F16"
	K_F17            = "F17"
	K_F18            = "F18"
	K_F19            = "F19"
	K_F2             = "F2"
	K_F20            = "F20"
	K_F21            = "F21"
	K_F22            = "F22"
	K_F23            = "F23"
	K_F24            = "F24"
	K_F3             = "F3"
	K_F4             = "F4"
	K_F5             = "F5"
	K_F6             = "F6"
	K_F7             = "F7"
	K_F8             = "F8"
	K_F9             = "F9"
	K_HOME           = "HOME"
	K_LEFT           = "LEFT"
	K_CTRL_LEFT      = "C_LEFT"
	K_PAGEUP         = "PAGEUP"
	K_PAUSE          = "PAUSE"
	K_RIGHT          = "RIGHT"
	K_SHIFT          = "SHIFT"
	K_UP             = "UP"
	K_CTRL_UP        = "C_UP"
	K_ALT_A          = "M_A"
	K_ALT_B          = "M_B"
	K_ALT_C          = "M_C"
	K_ALT_D          = "M_D"
	K_ALT_E          = "M_E"
	K_ALT_F          = "M_F"
	K_ALT_G          = "M_G"
	K_ALT_H          = "M_H"
	K_ALT_I          = "M_I"
	K_ALT_J          = "M_J"
	K_ALT_K          = "M_K"
	K_ALT_L          = "M_L"
	K_ALT_M          = "M_M"
	K_ALT_N          = "M_N"
	K_ALT_O          = "M_O"
	K_ALT_P          = "M_P"
	K_ALT_Q          = "M_Q"
	K_ALT_R          = "M_R"
	K_ALT_S          = "M_S"
	K_ALT_T          = "M_T"
	K_ALT_U          = "M_U"
	K_ALT_V          = "M_V"
	K_ALT_W          = "M_W"
	K_ALT_X          = "M_X"
	K_ALT_Y          = "M_Y"
	K_ALT_Z          = "M_Z"
	K_ALT_OEM_2      = "M_OEM_2"
View Source
const (
	F_END_OF_LINE          = "END_OF_LINE"
	F_HISTORY_DOWN         = "HISTORY_DOWN" // for compatible
	F_HISTORY_UP           = "HISTORY_UP"   // for compatible
	F_INTR                 = "INTR"
	F_KILL_LINE            = "KILL_LINE"
	F_PASS                 = "PASS"
	F_SWAPCHAR             = "SWAPCHAR"
	F_YANK                 = "YANK"
	F_UNDO                 = "UNDO"


View Source
var (
	// SurrogatePairOk is true when the surrogated pair unicode is supported
	// If it is false, <NNNN> is displayed instead.
	SurrogatePairOk = isWindowsTerminal

	// ZeroWidthJoinSequenceOk is true when ZWJ(U+200D) is supported.
	// If it is false, <NNNN> is displayed instead.
	ZeroWidthJoinSequenceOk = isWindowsTerminal

	// VariationSequenceOk is true when Variation Sequences are supported.
	// If it is false, <NNNN> is displayed instead.
	VariationSequenceOk = isWindowsTerminal

	// ModifierSequenceOk is false, SkinTone sequence are treated as two
	// character
	ModifierSequenceOk = isWindowsTerminal
View Source
var CtrlC = (errors.New("^C"))

CtrlC is the error when Ctrl-C is pressed.

View Source
var Delimiters = "\"'"

Delimiters means the quationmarks. The whitespace enclosed by them are not treat as parameters separator.


func GetKey added in v0.2.2

func GetKey(tty1 KeyGetter) (string, error)

GetKey reads one-key from tty.

func ResetCharWidth

func ResetCharWidth()

ResetCharWidth resets the cache for the width of characters.

func SetCharWidth

func SetCharWidth(c rune, width int)

SetCharWidth sets the width of the character into the cache.


type Buffer

type Buffer struct {
	Buffer []Moji

	ViewStart int
	// contains filtered or unexported fields

Buffer is ReadLine's internal data structure

func (*Buffer) CurrentWord

func (B *Buffer) CurrentWord() (string, int)

CurrentWord returns the current word the cursor exists and word's position

func (*Buffer) CurrentWordTop

func (B *Buffer) CurrentWordTop() (wordTop int)

CurrentWordTop returns the position of the current word the cursor exists

func (*Buffer) Delete

func (B *Buffer) Delete(pos int, n int) WidthT

Delete remove Buffer[pos:pos+n]. It returns the width to clear the end of line. It does not update screen.

func (*Buffer) DrawFromHead

func (buf *Buffer) DrawFromHead()

DrawFromHead draw all text in viewarea and move screen-cursor to the position where it should be.

func (*Buffer) GetKey

func (B *Buffer) GetKey() (string, error)

GetKey reads one-key from tty.

func (*Buffer) GetWidthBetween

func (B *Buffer) GetWidthBetween(from int, to int) WidthT

GetWidthBetween returns the width between start and end

func (*Buffer) GotoHead

func (buf *Buffer) GotoHead()

GotoHead move screen-cursor to the top of the viewarea. It should be called before text is changed.

func (*Buffer) InsertAndRepaint

func (buf *Buffer) InsertAndRepaint(str string)

InsertAndRepaint inserts str and repaint the editline.

func (*Buffer) InsertString

func (B *Buffer) InsertString(pos int, s string) int

InsertString inserts string s at pos (Do not update screen) It returns the count of runes

func (*Buffer) Repaint

func (buf *Buffer) Repaint(pos int, del WidthT)

Repaint buffer[pos:] + " \b"*del but do not rewind cursor position

func (*Buffer) RepaintAfterPrompt

func (buf *Buffer) RepaintAfterPrompt()

RepaintAfterPrompt repaints the all characters in the editline except for prompt.

func (*Buffer) RepaintAll

func (buf *Buffer) RepaintAll()

RepaintAll repaints the all characters in the editline including prompt.

func (*Buffer) ReplaceAndRepaint

func (buf *Buffer) ReplaceAndRepaint(pos int, str string)

ReplaceAndRepaint replaces the string between `pos` and cursor's position to `str`

func (*Buffer) ResetViewStart

func (B *Buffer) ResetViewStart()

ResetViewStart set ViewStart the new value which should be. It does not update screen.

func (Buffer) String

func (B Buffer) String() string

func (*Buffer) SubString

func (B *Buffer) SubString(start, end int) string

SubString returns the readline string between start and end

func (*Buffer) ViewWidth

func (B *Buffer) ViewWidth() WidthT

ViewWidth returns the cell-width screen can show in the one-line.

type Editor

type Editor struct {
	History       IHistory
	Writer        io.Writer
	Out           *bufio.Writer
	Prompt        func() (int, error)
	Default       string
	Cursor        int
	LineFeed      func(Result)
	OpenKeyGetter func() (KeyGetter, error)

Editor is the main class to hold the parameter for ReadLine

func (*Editor) ReadLine

func (editor *Editor) ReadLine(ctx context.Context) (string, error)

ReadLine calls LineEditor - ENTER typed -> returns TEXT and nil - CTRL-C typed -> returns "" and readline.CtrlC - CTRL-D typed -> returns "" and io.EOF

type IHistory

type IHistory interface {
	Len() int
	At(int) string

IHistory is the interface ReadLine can use as container for history. It can be set to Editor.History field

type KeyFuncT

type KeyFuncT interface {
	Call(ctx context.Context, buffer *Buffer) Result

KeyFuncT is the interface for object bound to key-mapping

func GetFunc

func GetFunc(funcName string) (KeyFuncT, error)

GetFunc returns KeyFuncT-object by name

type KeyGetter added in v0.2.7

type KeyGetter interface {
	Raw() (func() error, error)
	ReadRune() (rune, error)
	Buffered() bool
	Close() error
	Size() (int, int, error)

	GetResizeNotifier() func() (int, int, bool)

KeyGetter is the interface from which the ReadLine can read console input

func NewDefaultTty added in v0.3.0

func NewDefaultTty() (KeyGetter, error)

NewDefaultTty returns the instance for KeyGetter, which is the customized version of go-tty.TTY

type KeyGoFuncT

type KeyGoFuncT struct {
	Func func(ctx context.Context, buffer *Buffer) Result
	Name string

KeyGoFuncT is the implement of KeyFuncT which has a name and a function

func (*KeyGoFuncT) Call

func (K *KeyGoFuncT) Call(ctx context.Context, buffer *Buffer) Result

Call calls the function the receiver contains

func (KeyGoFuncT) String

func (K KeyGoFuncT) String() string

String returns KeyGoFuncT's name

type KeyMap

type KeyMap struct {
	KeyMap map[string]KeyFuncT

KeyMap is the class for key-bindings

var GlobalKeyMap KeyMap

GlobalKeyMap is the global keymap for users' customizing

func (*KeyMap) BindKeyClosure

func (editor *KeyMap) BindKeyClosure(name string, f func(context.Context, *Buffer) Result) error

BindKeyClosure binds closure to key by name

func (*KeyMap) BindKeyFunc

func (editor *KeyMap) BindKeyFunc(key string, f KeyFuncT) error

BindKeyFunc binds function to key

func (*KeyMap) BindKeySymbol

func (editor *KeyMap) BindKeySymbol(keyName, funcName string) error

BindKeySymbol assigns function to key by names.

func (*KeyMap) GetBindKey

func (editor *KeyMap) GetBindKey(key string) KeyFuncT

GetBindKey returns the function assigned to given key

type Moji added in v0.2.1

type Moji interface {
	Width() WidthT
	WriteTo(io.Writer) (int64, error)

Moji is the interface for minimum unit to edit in readline

When we make a new implement type of Moji, we have to append the code in the function: string2moji() and KeyFuncInsertSelf().

type Result

type Result int

Result is the type for readline's result.

const (
	// CONTINUE is returned by key-functions to continue the line editor
	CONTINUE Result = iota
	// ENTER is returned by key-functions when Enter key is pressed
	ENTER Result = iota
	// ABORT is returned by key-functions when Ctrl-D is pressed with no command-line
	ABORT Result = iota
	// INTR is returned by key-functions when Ctrl-C is pressed
	INTR Result = iota

func (Result) String

func (R Result) String() string

String makes Result to fmt.Stringer

type WidthT added in v0.2.2

type WidthT int

WidthT means the width type

func GetCharWidth

func GetCharWidth(n rune) WidthT

GetCharWidth returns the width of the character. [Deprecated]

func GetStringWidth

func GetStringWidth(s string) WidthT

GetStringWidth returns the width of the string. [Deprecated]


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL