### Real-time Input Validation with Listener (Go) Source: https://context7.com/chzyer/readline/llms.txt Implements real-time input validation for a Go console application using the readline library's SetListener functionality. This example specifically filters input to allow only numeric characters, periods, and hyphens. The listener callback receives the current input buffer and a key event, returning the modified buffer, cursor position, and a flag indicating if a change occurred. Dependencies include the `unicode` package for character classification and the `readline` library. ```Go package main import ( "io" "strings" "unicode" "github.com/chzyer/readline" ) func main() { cfg := &readline.Config{ Prompt: "number> ", } // Listener that only allows numeric input cfg.SetListener(func(line []rune, pos int, key rune) ([]rune, int, bool) { if key == 0 { return nil, 0, false // Initialization call } // Filter out non-numeric characters newLine := make([]rune, 0, len(line)) for _, r := range line { if unicode.IsDigit(r) || r == '.' || r == '-' { newLine = append(newLine, r) } } if len(newLine) != len(line) { // Input was filtered, update line return newLine, len(newLine), true } return nil, 0, false // No change }) rl, err := readline.NewEx(cfg) if err != nil { panic(err) } defer rl.Close() for { line, err := rl.Readline() if err == io.EOF { break } println("Valid number entered:", line) } } ``` -------------------------------- ### Prefill Input Buffer with Default Text in Go Source: https://context7.com/chzyer/readline/llms.txt Demonstrates how to set default text in the input buffer before the user starts typing using Readline's ReadlineWithDefault and WriteStdin functions. Handles io.EOF for end-of-file conditions. ```go package main import ( "fmt" "io" "strings" "github.com/chzyer/readline" ) func main() { rl, err := readline.New("> ") if err != nil { panic(err) } defer rl.Close() // Pre-fill the buffer with default text defaultCommand := "echo hello world" line, err := rl.ReadlineWithDefault(defaultCommand) if err == io.EOF { return } fmt.Printf("Executed: %s\n", line) // Alternative: use WriteStdin to prefill next read rl.WriteStdin([]byte("ls -la")) line2, err := rl.Readline() if err == io.EOF { return } fmt.Printf("Executed: %s\n", strings.TrimSpace(line2)) } ``` -------------------------------- ### Use Global Convenience Functions for Readline Source: https://context7.com/chzyer/readline/llms.txt Demonstrates the use of global convenience functions in the readline library for simpler interactions without explicit instance management. This includes setting a global history file, configuring a global auto-completer, reading lines, reading masked passwords, and manually adding history entries. It uses functions like `readline.SetHistoryPath`, `readline.SetAutoComplete`, `readline.Line`, `readline.Password`, and `readline.AddHistory`. ```go package main import ( "fmt" "github.com/chzyer/readline" ) func main() { // Set global history file readline.SetHistoryPath("/tmp/global_history.txt") // Set global auto-completer completer := readline.NewPrefixCompleter( readline.PcItem("start"), readline.PcItem("stop"), readline.PcItem("restart"), ) readline.SetAutoComplete(completer) // Read username username, err := readline.Line("Username: ") if err != nil { panic(err) } // Read password with masking password, err := readline.Password("Password: ") if err != nil { panic(err) } fmt.Printf("User: %s (password length: %d)\n", username, len(password)) // Manually add to history readline.AddHistory(fmt.Sprintf("login:%s", username)) // Read command with configured completer cmd, err := readline.Line("> ") if err != nil { panic(err) } fmt.Printf("Command: %s\n", cmd) } ``` -------------------------------- ### Configure Readline with NewEx for Advanced Options Source: https://context7.com/chzyer/readline/llms.txt Initializes a readline instance using `NewEx` with extensive configuration options. This includes setting a custom prompt with ANSI colors, configuring history file and limits, enabling case-insensitive history search, defining auto-completion logic, and customizing input filtering. It also demonstrates graceful handling of termination signals. ```go package main import ( "fmt" "io" "log" "github.com/chzyer/readline" ) // Define auto-completion structure var completer = readline.NewPrefixCompleter( readline.PcItem("help"), readline.PcItem("exit"), readline.PcItem("set", readline.PcItem("verbose"), readline.PcItem("quiet"), ), readline.PcItem("get", readline.PcItem("status"), readline.PcItem("config"), ), ) func filterInput(r rune) (rune, bool) { // Block Ctrl+Z to prevent suspension if r == readline.CharCtrlZ { return r, false } return r, true } func main() { rl, err := readline.NewEx(&readline.Config{ Prompt: "\033[31m»\033[0m ", // Red prompt with ANSI colors HistoryFile: "/tmp/myapp_history.txt", HistoryLimit: 500, HistorySearchFold: true, // Case-insensitive history search AutoComplete: completer, InterruptPrompt: "^C", EOFPrompt: "exit", VimMode: false, // Use emacs mode by default FuncFilterInputRune: filterInput, DisableAutoSaveHistory: false, }) if err != nil { panic(err) } defer rl.Close() // Gracefully handle termination signals rl.CaptureExitSignal() log.SetOutput(rl.Stderr()) for { line, err := rl.Readline() if err == readline.ErrInterrupt { continue } else if err == io.EOF { break } log.Printf("Command received: %s", line) } } ``` -------------------------------- ### Dynamic Auto-Completion with File Listing (Go) Source: https://context7.com/chzyer/readline/llms.txt Implements context-aware auto-completion for file and directory names using Go. It utilizes `readline.PcItemDynamic` to dynamically list files in the current directory or only directories when a specific command is invoked. Dependencies include the `os` package for file system operations and the `readline` library. ```Go package main import ( "io" "os" "github.com/chzyer/readline" ) // Dynamic file completion function func listFiles(path string) func(string) []string { return func(line string) []string { names := make([]string, 0) files, err := os.ReadDir(path) if err != nil { return names } for _, f := range files { names = append(names, f.Name()) } return names } } var completer = readline.NewPrefixCompleter( readline.PcItem("open", // Dynamically list files in current directory readline.PcItemDynamic(listFiles("./")), ), readline.PcItem("cd", readline.PcItemDynamic(func(line string) []string { // List only directories dirs := make([]string, 0) files, _ := os.ReadDir("./") for _, f := range files { if f.IsDir() { dirs = append(dirs, f.Name()) } } return dirs }), ), readline.PcItem("help"), ) func main() { rl, err := readline.NewEx(&readline.Config{ Prompt: "file> ", AutoComplete: completer, }) if err != nil { panic(err) } defer rl.Close() for { line, err := rl.Readline() if err == io.EOF { break } println("Command:", line) } } ``` -------------------------------- ### Initialize Readline Instance with Basic Prompt Source: https://context7.com/chzyer/readline/llms.txt Creates a basic readline instance with a simple prompt string. It then enters a loop to read lines from standard input until interrupted by Ctrl+C or Ctrl+D (EOF). Handles interrupt and EOF signals for graceful exit or line clearing. ```go package main import ( "fmt" "io" "github.com/chzyer/readline" ) func main() { rl, err := readline.New("> ") if err != nil { panic(err) } defer rl.Close() for { line, err := rl.Readline() if err == readline.ErrInterrupt { if len(line) == 0 { break // Ctrl+C on empty line exits } continue // Ctrl+C with text clears line } else if err == io.EOF { break // Ctrl+D exits } fmt.Printf("You entered: %s\n", line) } } ``` -------------------------------- ### Read Password Input with Masking Source: https://context7.com/chzyer/readline/llms.txt Demonstrates reading sensitive input like passwords using `ReadPassword` and `ReadPasswordEx`. The basic `ReadPassword` masks input with default characters. `ReadPasswordEx` allows for a custom listener to dynamically update the prompt, for instance, to show the current length of the entered password. ```go package main import ( "fmt" "github.com/chzyer/readline" ) func main() { rl, err := readline.New("> ") if err != nil { panic(err) } defer rl.Close() // Simple password input with default masking password, err := rl.ReadPassword("Enter password: ") if err != nil { panic(err) } fmt.Printf("Password length: %d\n", len(password)) // Advanced password input with custom listener pswd, err := rl.ReadPasswordEx("Enter new password: ", readline.FuncListener(func(line []rune, pos int, key rune) ([]rune, int, bool) { // Update prompt to show password length dynamically rl.SetPrompt(fmt.Sprintf("Password (%d chars): ", len(line))) rl.Refresh() return nil, 0, false })) if err != nil { panic(err) } fmt.Printf("New password set: %d characters\n", len(pswd)) } ``` -------------------------------- ### Toggle Vim and Emacs Editing Modes at Runtime Source: https://context7.com/chzyer/readline/llms.txt Demonstrates how to switch between Vim and Emacs editing modes dynamically within a readline session. This allows users to choose their preferred input method. It uses the `readline.NewEx` function to initialize the readline instance and `rl.SetVimMode` and `rl.IsVimMode` for mode management. ```go package main import ( "io" "strings" "github.com/chzyer/readline" ) func main() { rl, err := readline.NewEx(&readline.Config{ Prompt: "edit> ", VimMode: false, // Start in emacs mode }) if err != nil { panic(err) } defer rl.Close() for { line, err := rl.Readline() if err == io.EOF { break } line = strings.TrimSpace(line) switch { case line == "mode vim": rl.SetVimMode(true) println("Switched to vim mode") case line == "mode emacs": rl.SetVimMode(false) println("Switched to emacs mode") case line == "mode": if rl.IsVimMode() { println("Current mode: vim") } else { println("Current mode: emacs") } default: println("Input:", line) } } } ``` -------------------------------- ### Create a Remote Readline Terminal Server Source: https://context7.com/chzyer/readline/llms.txt Implements a network-based terminal server using `readline.ListenRemote`. This allows multiple clients to connect remotely and interact with a readline session over TCP. It handles client connections, reads input, and echoes responses. Errors during listening or connection are logged. ```go package main import ( "fmt" "io" "log" "net" "strings" "github.com/chzyer/readline" ) func main() { config := readline.Config{ Prompt: "remote> ", } // Start listening for remote connections err := readline.ListenRemote("tcp", ":5555", &config, func(rl *readline.Instance) { defer rl.Close() log.Println("Client connected") for { line, err := rl.Readline() if err == io.EOF { log.Println("Client disconnected") break } line = strings.TrimSpace(line) if line == "quit" { fmt.Fprintln(rl, "Goodbye!") break } // Echo back to client fmt.Fprintf(rl, "Received: %s\n", line) } }, func(ln net.Listener) error { log.Printf("Server listening on %s", ln.Addr().String()) return nil }) if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Programmatic Command History Management (Go) Source: https://context7.com/chzyer/readline/llms.txt Demonstrates how to manage command history programmatically in a Go application using the readline library. This includes enabling/disabling history, clearing it, manually adding entries, and changing the history file path at runtime. The primary input is user commands via the console, and the output is console messages indicating history status or executed commands. ```Go package main import ( "fmt" "strings" "github.com/chzyer/readline" ) func main() { rl, err := readline.NewEx(&readline.Config{ Prompt: "cmd> ", HistoryFile: "/tmp/myapp.history", }) if err != nil { panic(err) } defer rl.Close() for { line, err := rl.Readline() if err != nil { break } line = strings.TrimSpace(line) switch { case line == "history off": rl.HistoryDisable() fmt.Println("History disabled") case line == "history on": rl.HistoryEnable() fmt.Println("History enabled") case line == "history clear": rl.ResetHistory() fmt.Println("History cleared") case strings.HasPrefix(line, "history add "): // Manually add entry to history content := line[12:] if err := rl.SaveHistory(content); err != nil { fmt.Printf("Error saving to history: %v\n", err) } case line == "history path": // Change history file at runtime rl.SetHistoryPath("/tmp/newhistory.txt") fmt.Println("History path updated") default: fmt.Printf("Executed: %s\n", line) } } } ``` -------------------------------- ### Dynamically Update Readline Prompt Source: https://context7.com/chzyer/readline/llms.txt Shows how to change the command-line prompt dynamically during runtime based on various conditions, such as displaying timestamps, command counts, or using ANSI color codes. This enhances user feedback and application state visibility. It utilizes `rl.SetPrompt` for prompt manipulation. ```go package main import ( "fmt" "io" "strings" "time" "github.com/chzyer/readline" ) func main() { rl, err := readline.New("> ") if err != nil { panic(err) } defer rl.Close() counter := 0 for { line, err := rl.Readline() if err == io.EOF { break } counter++ line = strings.TrimSpace(line) switch { case line == "time": // Update prompt to show timestamp timestamp := time.Now().Format("15:04:05") rl.SetPrompt(fmt.Sprintf("[%s]> ", timestamp)) case line == "count": // Update prompt to show command count rl.SetPrompt(fmt.Sprintf("[%d]> ", counter)) case line == "color": // Use ANSI colors in prompt rl.SetPrompt("\033[32m✓\033[0m ") case line == "reset": rl.SetPrompt("> ") default: fmt.Printf("Command #%d: %s\n", counter, line) } } } ``` -------------------------------- ### Connect to a Remote Readline Terminal Client Source: https://context7.com/chzyer/readline/llms.txt Provides the client-side implementation to connect to a remote readline server created with `readline.ListenRemote`. It uses `readline.DialRemote` to establish a connection to the specified address. Any connection errors are logged. ```go package main import ( "log" "github.com/chzyer/readline" ) func main() { // Connect to remote readline server err := readline.DialRemote("tcp", "localhost:5555") if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Thread-Safe Output During Input in Go Source: https://context7.com/chzyer/readline/llms.txt Shows how to write to stdout/stderr without disrupting the current input line using readline's Stdout() method. Includes a background goroutine for status updates and a loop to process user input. ```go package main import ( "fmt" "io" "time" "github.com/chzyer/readline" ) func main() { rl, err := readline.New("> ") if err != nil { panic(err) } defer rl.Close() // Background goroutine writing status updates go func() { ticker := time.NewTicker(3 * time.Second) defer ticker.Stop() for range ticker.C { // Use readline's Stdout() for thread-safe output // This preserves the input line and refreshes display fmt.Fprintln(rl.Stdout(), "[Status] Background task running...") } }() for { line, err := rl.Readline() if err == io.EOF { break } // Use rl.Write() or rl.Stdout().Write() for output fmt.Fprintf(rl.Stdout(), "You entered: %s\n", line) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.