readline

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2022 License: MIT Imports: 7 Imported by: 1

README

Readline library

What is it?

Readline is an enhanced user input function for terminal-based programs.

The simplest way of reading user input in Go is something like this:

scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
input := scanner.Text()

But this input method is very limited: you can only type characters and delete the last one using Backspace. Readline adds the following editing functionality:

  • move cursor using arrow keys
  • move one word left or right
  • quickly move to the beginning or to the end of input
  • delete a whole word
  • delete text from the cursor to the beginning or to the end of line
  • in case of sequential inputs: get previously entered commands
  • supports multiple scopes: can have different history for different inputs
  • set history size for each scope
  • (TODO) search for previously entered commands

This package is a simple readline implementation. It supports a limited set of keyboard shortcuts and currently works in Linux environment only.

Demo

(record of xpression command-line tool which uses a readline input)

Supported keys

Keys Function
Left, Ctrl+B Move the cursor to the left
Right, Ctrl+F Move the cursor to the right
Ctrl+Left, Ctrl+Right Move the cursor one word left or right
Home, Ctrl+A Move the cursor to the beginning of line
End, Ctrl+E Move the cursor to the end of line
Backspace Delete symbol before the cursor
Delete Delete symbol after the cursor
Ctrl+W Delete a word before the cursor (words are delimited by spaces)
Ctrl+K Cut text to the end of line
Ctrl+U Cut text to the beginning of line
Up, Ctrl+P Get previous line from history
Down, Ctrl+N Get next line from history

Usage

import (
    "fmt"

    "github.com/bhmj/readline"
)

func main() {
    fmt.Println("Type anything or q to quit")
    readline.HistorySize(20) // history capacity 20 lines max
    for {
        fmt.Print("> ")
        input, err := readline.Read()
        if err != nil {
            fmt.Printf("error: %v\n", err)
            break
        }
        if input == "q" {
            break
        }
        process(input)
    }
}

Test coverage

TODO

Benchmarks

TODO

Changelog

0.1.0 (2022-07-05) -- MVP.

Roadmap

  • save modified history lines within editing session
  • add scope argument to Read() with distinct history for each scope
  • set history size for each scope
  • switch to symbolic escape sequences instead of current dumb state machine
  • Ctrl+K to cut text to the end of line
  • Ctrl+U to cut text to the beginning of line
  • Ctrl+N, Ctrl+P == Up, Down
  • Ctrl+B, Ctrl+F == Left, Right
  • Ctrl+R, Ctrl+S to search in history
  • handle Ctrl+C

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :)

Licence

MIT

Author

Michael Gurov aka BHMJ

Documentation

Index

Constants

View Source
const (
	Escape = 27
)

Variables

This section is empty.

Functions

func HistorySize

func HistorySize(size int, scope ...string)

HistorySize sets the history capacity for the selected scope. If 'scope' is not passed, it is set to 'default'.

func Read

func Read(scope ...string) (string, error)

Read starts interactive user input. The 'scope' parameter selects distinct history for the named scope, so you can have several inputs with different history. Returns entered string or error.

Types

type Term

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

func Open

func Open() *Term

func (*Term) Close

func (t *Term) Close()

func (*Term) ReadRune

func (t *Term) ReadRune() (rune, int, error)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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