bhmj / readline

Simple readline library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

About

Simple readline library

License:MIT License


Languages

Language:Go 89.4%Language:Makefile 10.6%