A production-grade, zero-dependency, pure Go terminal line editor designed for building interactive command-line interfaces.
It is Linux, macOS, and Windows native, requiring no CGO and no third-party dependencies. It includes native UTF-8 (CJK and zero-width character metrics) support, multi-line line wrapping, full history management with reverse incremental search, dynamic autocompletion, undo/redo, kill ring, password input, and Emacs-style terminal key bindings.
- 📦 Zero Dependencies: Pure Go implementation using OS-specific termios and Win32 console mode system calls.
- ⚡ No CGO: Light binaries, fast builds, and seamless cross-compilation.
- 🪟 Cross-Platform: Full native support for Linux, macOS, and Windows.
- 🔀 Piped & Non-TTY Fallback: Automatically falls back to standard buffered input when stdin/stdout are not terminals.
- 🔍 Reverse Incremental Search (Ctrl+R): Interactive history search with dynamic matching and redisplay (
Ctrl+Rfor older,Ctrl+Sfor newer,Enterto accept,Escto cancel). - 💡 Dynamic Autocompletion: Extensible
Completerinterface with Tab completion, candidate cycling, and terminal-width-aware column grid display. Built-inPrefixCompleterandPathCompleter. - 📋 Bracketed Paste: Atomic insertion of pasted text without triggering premature execution.
- 🔑 Password & Secret Mode:
ReadPasswordfor silent input andReadPasswordWithMaskfor configurable masking. - ⏱️ Context Cancellation:
ReadLineContextreturns on cancellation or timeout; a blocked input read remains attached to the editor and is reused by a later read. - 🔄 Undo & Redo: Multi-level undo stack (
Ctrl+_) and redo support. - ✂️ Kill Ring & Yank: Full kill ring storing deletions from
Ctrl+K,Ctrl+U,Ctrl+W, andAlt+Dwith yank (Ctrl+Y) and yank-pop (Alt+Y). - 🎨 Visual Styling Integration: Features a companion subpackage
formatfor advanced foreground, background, and text decoration setups. - 🇯🇵 Advanced Unicode Metrics: Correctly handles multi-byte UTF-8, zero-width characters (combining marks, zero-width joiners, variation selectors), and CJK wide characters/emojis for visually aligned cursors.
- 🕒 Persistent History: Browsable command history with auto-deduplication, prefix-based search, cross-session file saving/loading, and compaction.
- 📟 Resize Notifications: Terminal size changes update rendering automatically; custom resize callbacks are supported on Linux and macOS (not currently on Windows).
- 🧹 Screen Clearing:
Editor.ClearScreen()clears the terminal viewport and scrollback. - ⌨️ Custom Key Bindings: Extend or replace key actions through
Config.KeyMap.
go get github.com/hitraa/[email protected]Requires Go 1.21 or newer.
Here is a minimal, complete example showing how to initialize the terminal line editor:
package main
import (
"errors"
"fmt"
"io"
"os"
"github.com/hitraa/readline"
)
func main() {
config := readline.Config{
Prompt: "> ",
HistoryFile: os.ExpandEnv("$HOME/.my_app_history"),
MaxHistory: 1000,
EnableSignals: true, // Enable Ctrl+Z/Ctrl+\ POSIX signals on Linux/macOS
Completer: readline.PrefixCompleter("help", "exit", "status", "version"),
}
ed, err := readline.New(config)
if err != nil {
fmt.Fprintf(os.Stderr, "Error initializing editor: %v\n", err)
os.Exit(1)
}
defer ed.Close()
fmt.Println("Interactive Shell. Press Tab for completion, Ctrl+R for search, Ctrl+D to exit.")
for {
line, err := ed.ReadLine()
if err != nil {
if errors.Is(err, io.EOF) {
fmt.Println("\nGoodbye!")
break
}
if errors.Is(err, readline.ErrInterrupt) {
// Ctrl+C pressed; clear prompt and continue
continue
}
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
break
}
if line == "" {
continue
}
fmt.Printf("Received input: %s\n", line)
}
}readline supports native keyboard shortcuts to streamline interactive typing:
- Ctrl + A or Home: Move cursor to start of line.
- Ctrl + E or End: Move cursor to end of line.
- Ctrl + B or Left Arrow: Move cursor backward one character.
- Ctrl + F or Right Arrow: Move cursor forward one character.
- Alt + B or Ctrl + Left: Move cursor backward one word.
- Alt + F or Ctrl + Right: Move cursor forward one word.
- Ctrl + P or Up Arrow: Browse backward through history.
- Ctrl + N or Down Arrow: Browse forward through history.
- Ctrl + R: Start reverse incremental search. Repeated
Ctrl+Rmoves to older matches;Ctrl+Smoves to newer matches;Enteraccepts;EscorCtrl+Gcancels. - Page Up: Search backward in history for entries starting with the current input prefix.
- Page Down: Search forward in history for entries starting with the current input prefix.
- Backspace or Ctrl + H: Delete character before cursor.
- Delete or Ctrl + D (on non-empty line): Delete character at cursor.
- Ctrl + D (on empty line): Send End-Of-File (EOF) to close editor.
- Ctrl + K: Kill all text from cursor to end of line (saved to kill ring).
- Ctrl + U: Kill all text from start of line to cursor (saved to kill ring).
- Ctrl + W or Alt + Backspace: Kill word before cursor (saved to kill ring).
- Alt + D: Kill word after cursor (saved to kill ring).
- Ctrl + Y: Yank (paste) the most recently killed text.
- Alt + Y: Yank-pop: cycle through previous killed texts in the kill ring.
- Ctrl + T: Transpose adjacent characters.
- Ctrl + _: Undo last modification.
- Tab: Trigger autocompletion or cycle through available candidates.
- Shift + Tab: Cycle backward through candidates.
- Ctrl + L: Clear terminal screen and redraw line.
- Ctrl + C: Interrupt current input session.
The library is designed modularly to ensure safety and testability:
- LineBuffer (
buffer.go): Manages the UTF-8 rune buffer, edit cursor, word operations, and visual column width metrics. - Renderer (
render.go): Optimizes terminal redrawing, managing multi-row wrapping, screen clearing, and cursor tracking. - Completer (
complete.go): Provides flexible completion interfaces and adaptive column grid rendering. - Quote Parser (
quote.go): Lexes quotes ("...",'...') and backslash escapes (\) for word tokenization. - SearchMode (
search.go): Manages the reverse incremental history search state machine. - KillRing (
killring.go): Implements an Emacs-style kill ring buffer. - UndoStack (
undo.go): Manages multi-level undo and redo operations. - Terminal Drivers (
terminal_linux.go,terminal_darwin.go,terminal_windows.go): Implements pure Go OS-level raw terminal and console modes with non-TTY fallbacks. - Editor (
editor.go): Coordinates terminal state, events, signal watchers, history, and key dispatching.
The runnable examples cover the main workflows:
go run ./examples/basic: styled prompt, completion, screen clearing, and resize callback.go run ./examples/completion: custom completion candidates.go run ./examples/context: timeout and cancellation.go run ./examples/custom-bindings: custom key actions.go run ./examples/history: persistent command history.go run ./examples/password: silent and masked secret input.
Resize callbacks are delivered on Linux and macOS. Windows resize is not tracked during an active read; terminal dimensions are checked when each read begins.
This project is licensed under the MIT License - see the LICENSE file for details.