readline

package module
v1.3.1 Latest Latest
Warning

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

Go to latest
Published: Apr 20, 2024 License: MIT Imports: 15 Imported by: 19

README

Go Reference Go Report Card Wiki License

The New Yet another Readline for Go (go-readline-ny)

The New Yet another Readline for Go (go-readline-ny) is a one-line input library for CUI applications written in Go that is extensible for different needs. It has been running inside the command line shell "NYAGOS" for a long time.

  • Emacs-like key-bindings
  • History
  • Word Completion (file names, command names, or any names in given array)
  • Syntax Highlighting
  • Supported OS: Windows and Linux
  • Suported Unicode (UTF8)
    • Surrogate-pair
    • Emoji (via clipboard)
    • Zero-Width-Joiner (via clipboard)
    • Variation Selector (via clipboard pasted by Ctrl-Y)
  • Add-Ons:
  • MIT License

Zero-Width-Joiner sample on Windows-Terminal

example1.go

The most simple sample.

package main

import (
    "context"
    "fmt"

    "github.com/nyaosorg/go-readline-ny"
)

func main() {
    var 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 .

example2.go

Tiny Shell. This is a sample of prompt change, colorization, filename completion and history browsing.

package main

import (
    "context"
    "fmt"
    "io"
    "os"
    "os/exec"
    "strings"

    "github.com/mattn/go-colorable"

    "github.com/nyaosorg/go-readline-ny"
    "github.com/nyaosorg/go-readline-ny/coloring"
    "github.com/nyaosorg/go-readline-ny/completion"
    "github.com/nyaosorg/go-readline-ny/keys"
    "github.com/nyaosorg/go-readline-ny/simplehistory"
)

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

    editor := &readline.Editor{
        PromptWriter: func(w io.Writer) (int, error) {
            return io.WriteString(w, "\x1B[1;36m$ \x1B[0m") // print `$ ` with cyan
        },
        Writer:         colorable.NewColorableStdout(),
        History:        history,
        Coloring:       &coloring.VimBatch{},
        HistoryCycling: true,
    }

    editor.BindKey(keys.CtrlI, completion.CmdCompletionOrList{
        Completion: completion.File{},
        Postfix:    " ",
    })
    // If you do not want to list files with double-tab-key,
    // use `CmdCompletion` instead of `CmdCompletionOrList`

    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())
            return
        }

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

        cmd.Run()

        history.Add(text)
    }
}

example3.go

This is a sample to change key-bindings to diamond cursor.

example4.go

This is a sample that implements the function to start the text editor defined by the environment variable EDITOR and import the edited contents when the ESCAPE key is pressed.

Documentation

Index

Constants

View Source
const (
	CursorPositionDummyRune = '\uE000'
)

Variables

View Source
var CmdAcceptLine = NewGoCommand("ACCEPT_LINE", cmdAcceptLine)

CmdAcceptLine is the command that ends the editing successfully (for Ctrl-M) Then the method `(*Editor) ReadLine()` returns nil as error.

View Source
var CmdBackwardChar = NewGoCommand("BACKWARD_CHAR", cmdBackwardChar)

CmdBackwardChar is the command that moves cursor to the previous character (for Ctrl-B)

View Source
var CmdBackwardDeleteChar = NewGoCommand("BACKWARD_DELETE_CHAR", cmdBackwardDeleteChar)

CmdBackwardDeleteChar is the command that deletes a character on the leftside of cursor (for Backspace)

View Source
var CmdBackwardWord = NewGoCommand("BACKWARD_WORD", cmdBackwardWord)

CmdBackwardWord is the command that moves cursor to the top of the previous word (for M-B)

View Source
var CmdBeginningOfLine = NewGoCommand("BEGINNING_OF_LINE", cmdBeginningOfLine)

CmdBeginningOfLine is the command that moves cursor to the top of line (for Ctrl-A)

View Source
var CmdClearScreen = NewGoCommand("CLEAR_SCREEN", cmdClearScreen)

CmdClearScreen is the command that clears the screen and repaints the line (for Ctrl-L)

View Source
var CmdDeleteChar = NewGoCommand("DELETE_CHAR", cmdDeleteChar)

CmdDeleteChar is the command that delete a character on the cursor (for Del)

View Source
var CmdDeleteOrAbort = NewGoCommand("DELETE_OR_ABORT", cmdDeleteOrAbort)

CmdDeleteOrAbort is the command that deletes a character on the cursor when the line has any characters. Otherwise quit the editing (for Ctrl-D)

View Source
var CmdEndOfLine = NewGoCommand("END_OF_LINE", cmdEndOfLine)

CmdEndOfLine is the command that moves cursor to the end of the line (for Ctrl-E)

View Source
var CmdForwardChar = NewGoCommand("FORWARD_CHAR", cmdForwardChar)

CmdForwardChar is the command that moves cursor to the next character (for Ctrl-F)

View Source
var CmdForwardWord = NewGoCommand("FORWARD_WORD", cmdForwardWord)

CmdForwardWord is the command that move cursor to the top of the next word (for M-F)

View Source
var CmdISearchBackward = NewGoCommand("ISEARCH_BACKWARD", cmdISearchBackward)

CmdISearchBackward is the command that enters incremental-search-mode. (Ctrl-I)

View Source
var CmdInterrupt = NewGoCommand("INTR", cmdInterrupt)

CmdInterrupt is the command that aborts the editing (for Ctrl-C) Then the method `(*Editor) ReadLine()` returns `readline.CtrlC` as error.

View Source
var CmdKillLine = NewGoCommand("KILL_LINE", cmdKillLine)

CmdKillLine is the command that removes text from cursor to the end of the line (for Ctrl-K)

View Source
var CmdKillWholeLine = NewGoCommand("KILL_WHOLE_LINE", cmdKillWholeLine)

CmdKillWholeLine is the command that removes the whole characters of the line.

View Source
var CmdNextHistory = NewGoCommand("NEXT_HISTORY", cmdNextHistory)

CmdNextHistory is the command that replaces the line to the next entry of the history. (Ctrl-N)

View Source
var CmdPreviousHistory = NewGoCommand("PREVIOUS_HISTORY", cmdPreviousHistory)

CmdPreviousHistory is the command that replaces the line to the previous entry in the history (Ctrl-P)

View Source
var CmdQuotedInsert = NewGoCommand("QUOTED_INSERT", cmdQuotedInsert)

CmdQuotedInsert is the command that inserts the next typed character itself even if it is a control-character (for Ctrl-V or Ctrl-Q)

View Source
var CmdRepaintOnNewline = NewGoCommand("REPAINT_ON_NEWLINE", cmdRepaintOnNewline)
View Source
var CmdSwapChar = NewGoCommand("SWAPCHAR", cmdSwapChar)

CmdSwapChar is the command that swaps the character on the cursor and on on the leftside of the cursor (for Ctrl-T)

View Source
var CmdUndo = NewGoCommand("UNDO", cmdUndo)

CmdUndo is the command that executes undo (for Ctrl-U)

View Source
var CmdUnixLineDiscard = NewGoCommand("UNIX_LINE_DISCARD", cmdUnixLineDiscard)

CmdUnixLineDiscard is the command that removes from the top of the line until cursor. (for Ctrl-U)

View Source
var CmdUnixWordRubout = NewGoCommand("UNIX_WORD_RUBOUT", cmdUnixWordRubout)

CmdUnixWordRubout is the command that removes the current word (for Ctrl-W)

View Source
var CmdYank = NewGoCommand("YANK", cmdYank)

CmdYank is the command that inserts the string in the clipboard (for Ctrl-Y)

View Source
var CmdYankWithQuote = NewGoCommand("YANK_WITH_QUOTE", cmdYankWithQuote)

CmdYankWithQuote is the command that inserts the string in the clipboard and enclose it with double quoatations.

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.

GlobalKeyMap is the global keymap for users' customizing

View Source
var NameToFunc = map[string]Command{}

Functions

func EnableSurrogatePair added in v0.11.0

func EnableSurrogatePair(value bool)

func GetKey

func GetKey(tty XTty) (string, error)

GetKey reads one-key from *tty*. The *tty* object must have Raw(),ReadRune(), and Buffered() method.

func IsSurrogatePairEnabled added in v0.11.0

func IsSurrogatePairEnabled() bool

func MojiCountInString added in v0.11.6

func MojiCountInString(s string) int

func ResetCharWidth

func ResetCharWidth()

func SetCharWidth

func SetCharWidth(c rune, width int)

Types

type AnonymousCommand added in v0.11.2

type AnonymousCommand func(context.Context, *Buffer) Result

func (AnonymousCommand) Call added in v0.11.2

func (f AnonymousCommand) Call(ctx context.Context, B *Buffer) Result

func (AnonymousCommand) String added in v0.11.2

func (f AnonymousCommand) String() string

type Buffer

type Buffer struct {
	*Editor
	Buffer    []Cell
	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 (B *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 (B *Buffer) GotoHead()

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

func (*Buffer) InsertAndRepaint

func (B *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) RepaintAfterPrompt

func (B *Buffer) RepaintAfterPrompt()

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

func (*Buffer) RepaintAll

func (B *Buffer) RepaintAll()

RepaintAll repaints the all characters in the editline including prompt.

func (*Buffer) RepaintLastLine added in v0.14.0

func (B *Buffer) RepaintLastLine()

RepaintLastLine repaints the last line of the prompt and input-line. IMPORTANT: This method requires setting valid Editor.PromptWriter

func (*Buffer) ReplaceAndRepaint

func (B *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 Cell added in v0.9.0

type Cell struct {
	Moji Moji
	// contains filtered or unexported fields
}

func (Cell) String added in v0.11.7

func (C Cell) String() string

type ColorSequence added in v0.10.0

type ColorSequence int64
const (
	Black ColorSequence = 3 | ((30 + iota) << colorCodeBitSize) | (49 << (colorCodeBitSize * 2)) | (1 << (colorCodeBitSize * 3))
	Red
	Green
	Yellow
	Blue
	Magenta
	Cyan
	White

	DefaultForeGroundColor
)
const (
	DarkGray ColorSequence = 3 | ((30 + iota) << colorCodeBitSize) | (22 << (colorCodeBitSize * 2)) | (49 << (colorCodeBitSize * 3))
	DarkRed
	DarkGree
	DarkYellow
	DarkBlue
	DarkMagenta
	DarkCyan
	DarkWhite

	DarkDefaultForeGroundColor
)
const (
	ColorReset ColorSequence = 1
)

func SGR1 added in v0.6.3

func SGR1(n1 int) ColorSequence

func SGR2 added in v0.6.3

func SGR2(n1, n2 int) ColorSequence

func SGR3 added in v0.6.3

func SGR3(n1, n2, n3 int) ColorSequence

func SGR4 added in v0.6.3

func SGR4(n1, n2, n3, n4 int) ColorSequence

func (ColorSequence) Add added in v0.15.1

func (c ColorSequence) Add(value int) ColorSequence

func (ColorSequence) Chain added in v0.15.2

func (c ColorSequence) Chain(value ColorSequence) ColorSequence

func (ColorSequence) WriteTo added in v0.10.0

func (c ColorSequence) WriteTo(w io.Writer) (int64, error)

type Coloring added in v0.6.0

type Coloring interface {
	// Reset has to initialize receiver's fields and return default color.
	Init() ColorSequence
	// Next has to return color for the given rune.
	Next(rune) ColorSequence
}

type Command added in v0.11.1

type Command interface {
	String() string
	Call(ctx context.Context, buffer *Buffer) Result
}

Command is the interface for object bound to key-mapping

type Editor

type Editor struct {
	KeyMap
	History        IHistory
	Writer         io.Writer
	Out            *bufio.Writer
	PromptWriter   func(io.Writer) (int, error)
	Default        string
	Cursor         int
	LineFeedWriter func(Result, io.Writer) (int, error)
	Tty            ITty
	Coloring       Coloring
	HistoryCycling bool
	// contains filtered or unexported fields
}

Editor is the main class to hold the parameter for ReadLine

func (*Editor) Init added in v0.12.3

func (editor *Editor) Init()

Init replaces nil fields to default values. When we refer them before calling Readline, We have to call Init explicitly.

func (*Editor) LookupCommand added in v0.11.7

func (editor *Editor) LookupCommand(key string) Command

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 GoCommand added in v0.11.1

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

GoCommand is the implement of Command which has a name and a function

func NewGoCommand added in v0.11.1

func NewGoCommand(name string, f func(context.Context, *Buffer) Result) *GoCommand

NewGoCommand creates an instance of GoCommand with a name and an function.

func (*GoCommand) Call added in v0.11.1

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

Call calls the function the receiver contains

func (GoCommand) String added in v0.11.1

func (K GoCommand) String() string

String returns GoCommand's name

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 ITty added in v0.11.0

type ITty interface {
	Open(onSize func(int)) error
	GetKey() (string, error)
	Size() (int, int, error)
	Close() error
}

type KeyMap

type KeyMap struct {
	// contains filtered or unexported fields
}

KeyMap is the class for key-bindings

func (*KeyMap) BindKey added in v0.11.1

func (km *KeyMap) BindKey(key keys.Code, f Command)

func (*KeyMap) Lookup added in v0.13.1

func (km *KeyMap) Lookup(key keys.Code) (Command, bool)

type Moji

type Moji = moji.Moji

func StringToMoji added in v0.9.0

func StringToMoji(s string) []Moji

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
)

type SelfInserter added in v0.11.2

type SelfInserter string

func (SelfInserter) Call added in v0.11.2

func (s SelfInserter) Call(ctx context.Context, this *Buffer) Result

func (SelfInserter) String added in v0.11.2

func (s SelfInserter) String() string

type WidthT

type WidthT = moji.WidthT

func GetStringWidth

func GetStringWidth(s string) WidthT

type XTty added in v0.14.1

type XTty interface {
	Raw() (func() error, error)
	ReadRune() (rune, error)
	Buffered() bool
}

XTty is the interface of tty to use GetKey function.

Jump to

Keyboard shortcuts

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