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
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :)
Licence
MIT
Author
Michael Gurov aka BHMJ