### Initialize Readline and View Keyboard Shortcuts in Go Source: https://context7.com/wjqserver/readline/llms.txt Demonstrates the basic initialization of a readline instance and lists the supported keyboard shortcuts for line editing and navigation. The example uses the NewInstance method to configure the prompt and provides a reference for user interaction. ```Go package main import ( "fmt" "github.com/WJQSERVER/readline" ) func main() { rl, _ := readline.NewInstance(&readline.Config{ Prompt: "> ", }) defer rl.Close() fmt.Println("Keyboard shortcuts available:") fmt.Println(" Ctrl+A / Home - Move to line start") fmt.Println(" Ctrl+E / End - Move to line end") fmt.Println(" Ctrl+B / Left - Move cursor left") fmt.Println(" Ctrl+F / Right - Move cursor right") fmt.Println(" Ctrl+Left - Move word left") fmt.Println(" Ctrl+Right - Move word right") fmt.Println(" Ctrl+K - Delete to end of line") fmt.Println(" Ctrl+U - Delete to start of line") fmt.Println(" Ctrl+W - Delete word backward") fmt.Println(" Ctrl+L - Refresh line") fmt.Println(" Up/Down - Navigate history") fmt.Println(" Tab - Auto-complete") fmt.Println(" Ctrl+C - Interrupt (returns ErrInterrupt)") fmt.Println(" Ctrl+D - EOF when empty (returns io.EOF)") rl.Readline() } ``` -------------------------------- ### Implement a Complete CLI Application in Go Source: https://context7.com/wjqserver/readline/llms.txt A comprehensive example showing how to build an interactive CLI with tab completion, command parsing, and error handling. It demonstrates the use of PrefixCompleter for suggestions and a main loop to process user input until an exit command or EOF is received. ```Go package main import ( "fmt" "io" "strings" "github.com/WJQSERVER/readline" ) func main() { completer := &readline.PrefixCompleter{ Candidates: []string{ "help", "version", "status", "get users", "get orders", "get config", "set debug on", "set debug off", "clear", "exit", "quit", }, } rl, err := readline.NewInstance(&readline.Config{ Prompt: "\033[36mcli\033[0m> ", // Cyan prompt Completer: completer, }) if err != nil { panic(err) } defer rl.Close() fmt.Println("Welcome to CLI (type 'help' for commands, 'exit' to quit)") for { line, err := rl.Readline() if err != nil { if err == readline.ErrInterrupt { fmt.Println("^C (use 'exit' to quit)") continue } if err == io.EOF { fmt.Println("\nBye!") return } fmt.Printf("Error: %v\n", err) return } line = strings.TrimSpace(line) if line == "" { continue } switch { case line == "help": fmt.Println("Commands: help, version, status, get , set debug , clear, exit") case line == "version": fmt.Println("CLI v1.0.0") case line == "status": fmt.Println("Status: OK") case strings.HasPrefix(line, "get "): fmt.Printf("Fetching: %s\n", line[4:]) case strings.HasPrefix(line, "set "): fmt.Printf("Setting: %s\n", line[4:]) case line == "clear": fmt.Print("\033[2J\033[H") // Clear screen case line == "exit" || line == "quit": fmt.Println("Goodbye!") return default: fmt.Printf("Unknown command: %s\n", line) } } } ``` -------------------------------- ### Create Readline Instance with Configuration Source: https://context7.com/wjqserver/readline/llms.txt Initializes a new readline instance using the provided configuration. The `Config` struct allows customization of the prompt, tab completion, history, and I/O streams. If `Config` is nil, default settings (os.Stdin, os.Stdout, in-memory history) are applied. ```go package main import ( "fmt" "io" "github.com/WJQSERVER/readline" ) func main() { rl, err := readline.NewInstance(&readline.Config{ Prompt: "\033[32m>>>\033[0m ", // Green prompt with ANSI colors Completer: &readline.PrefixCompleter{ Candidates: []string{"help", "exit", "list", "show"}, }, }) if err != nil { panic(err) } defer rl.Close() fmt.Println("Readline initialized successfully") // Instance ready for use with rl.Readline() } ``` -------------------------------- ### Implement Tab Completion with PrefixCompleter Source: https://context7.com/wjqserver/readline/llms.txt Demonstrates the use of `PrefixCompleter` for basic tab completion. This completer matches user input against a predefined list of `Candidates`. If the input prefix uniquely matches a candidate, it auto-completes; otherwise, it presents a list of possible matches when the Tab key is pressed. ```go package main import ( "fmt" "io" "github.com/WJQSERVER/readline" ) func main() { completer := &readline.PrefixCompleter{ Candidates: []string{ "help", "history", "exit", "list", "load", "save", "connect", "config", "status", "stop", "start", }, } rl, _ := readline.NewInstance(&readline.Config{ Prompt: "cmd> ", Completer: completer, }) defer rl.Close() for { line, err := rl.Readline() if err == io.EOF { break } fmt.Printf("Command: %s\n", line) } } // Usage: Type "he" then press Tab -> completes to "help" // Usage: Type "st" then press Tab -> shows "status", "stop", "start" options ``` -------------------------------- ### Dynamically Update Prompt String After Instance Creation in Go Source: https://context7.com/wjqserver/readline/llms.txt Illustrates how to change the command prompt dynamically after the readline instance has been created using the SetPrompt method. This is useful for reflecting changes in application state, such as user login status or current directory. ```go package main import ( "fmt" "io" "os" "github.com/WJQSERVER/readline" ) func main() { rl, _ := readline.NewInstance(&readline.Config{ Prompt: "guest> ", }) defer rl.Close() currentUser := "guest" for { line, err := rl.Readline() if err == io.EOF { break } if line == "login admin" { currentUser = "admin" rl.SetPrompt("\033[31madmin#\033[0m ") // Red prompt for admin fmt.Println("Logged in as admin") } else if line == "logout" { currentUser = "guest" rl.SetPrompt("guest> ") fmt.Println("Logged out") } else if line == "pwd" { dir, _ := os.Getwd() rl.SetPrompt(fmt.Sprintf("[%s@%s]$ ", currentUser, dir)) } } } ``` -------------------------------- ### Implement Custom Tab Completion with Completer Interface in Go Source: https://context7.com/wjqserver/readline/llms.txt Demonstrates how to implement the Completer interface to provide custom tab completion logic. The Do method analyzes the current input line and cursor position to suggest matching commands or resources. It handles different completion scenarios based on the input. ```go package main import ( "strings" "github.com/WJQSERVER/readline" ) type CommandCompleter struct { commands []string resources []string } func (c *CommandCompleter) Do(line []rune, pos int) ([][]rune, int) { currentLine := string(line[:pos]) words := strings.Fields(currentLine) // Complete commands for first word if len(words) == 0 || (len(words) == 1 && !strings.HasSuffix(currentLine, " ")) { prefix := "" if len(words) == 1 { prefix = words[0] } var matches [][]rune for _, cmd := range c.commands { if strings.HasPrefix(cmd, prefix) { matches = append(matches, []rune(cmd)) } } return matches, len(prefix) } // Complete resources for "get" and "delete" commands if words[0] == "get" || words[0] == "delete" { prefix := "" if !strings.HasSuffix(currentLine, " ") && len(words) > 1 { prefix = words[len(words)-1] } var matches [][]rune for _, res := range c.resources { if strings.HasPrefix(res, prefix) { matches = append(matches, []rune(res)) } } return matches, len(prefix) } return nil, 0 } func main() { completer := &CommandCompleter{ commands: []string{"get", "set", "delete", "list", "help", "exit"}, resources: []string{"users", "orders", "products", "config"}, } rl, _ := readline.NewInstance(&readline.Config{ Prompt: "api> ", Completer: completer, }) defer rl.Close() rl.Readline() } // Usage: "get us" -> completes to "get users" // Usage: "del" -> completes to "delete" ``` -------------------------------- ### Implement Persistent Command History in Go Source: https://context7.com/wjqserver/readline/llms.txt Shows how to implement a custom History interface for persistent command history. The PersistentHistory struct saves commands to a file and loads them on startup, ensuring history is maintained across sessions. It uses a mutex for thread-safe access. ```go package main import ( "os" "strings" "sync" "github.com/WJQSERVER/readline" ) // PersistentHistory saves history to a file type PersistentHistory struct { lines []string filepath string mu sync.RWMutex } func NewPersistentHistory(path string) *PersistentHistory { h := &PersistentHistory{filepath: path, lines: []string{}} // Load existing history if data, err := os.ReadFile(path); err == nil { for _, line := range strings.Split(string(data), "\n") { if line != "" { h.lines = append(h.lines, line) } } } return h } func (h *PersistentHistory) Append(line string) { h.mu.Lock() defer h.mu.Unlock() if line == "" || (len(h.lines) > 0 && h.lines[len(h.lines)-1] == line) { return } h.lines = append(h.lines, line) // Persist to file f, _ := os.OpenFile(h.filepath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) defer f.Close() f.WriteString(line + "\n") } func (h *PersistentHistory) Get(index int) (string, bool) { h.mu.RLock() defer h.mu.RUnlock() if index < 0 || index >= len(h.lines) { return "", false } return h.lines[index], true } func (h *PersistentHistory) Len() int { h.mu.RLock() defer h.mu.RUnlock() return len(h.lines) } func main() { rl, _ := readline.NewInstance(&readline.Config{ Prompt: "$ ", History: NewPersistentHistory("/tmp/shell_history"), }) defer rl.Close() rl.Readline() // History persists across sessions } ``` -------------------------------- ### Configure Readline Behavior Source: https://context7.com/wjqserver/readline/llms.txt Defines the `Config` struct used to customize the readline library's behavior. Options include setting the prompt string (with ANSI color support), defining a `Completer` for tab completion, specifying a custom `History` implementation, and overriding default `Stdin` and `Stdout` streams. ```go package main import ( "os" "github.com/WJQSERVER/readline" ) func main() { cfg := &readline.Config{ // Prompt displayed before each input line (supports ANSI escape codes) Prompt: "\033[34mshell>\033[0m ", // Custom completer for tab completion Completer: &readline.PrefixCompleter{ Candidates: []string{"connect", "disconnect", "status", "quit"}, }, // Custom History implementation (optional, defaults to in-memory) History: readline.NewHistory(), // Custom I/O (optional, defaults to os.Stdin/os.Stdout) Stdin: os.Stdin, Stdout: os.Stdout, } rl, _ := readline.NewInstance(cfg) defer rl.Close() // Use rl.Readline() for input } ``` -------------------------------- ### Read User Input with Line Editing Source: https://context7.com/wjqserver/readline/llms.txt The primary method for reading a line of text from the terminal with full editing capabilities. It handles keyboard input, updates the display in real-time, and returns the entered line upon pressing Enter. It also handles specific error conditions like `ErrInterrupt` (Ctrl+C) and `io.EOF` (Ctrl+D). ```go package main import ( "fmt" "io" "github.com/WJQSERVER/readline" ) func main() { rl, _ := readline.NewInstance(&readline.Config{ Prompt: "> ", }) defer rl.Close() for { line, err := rl.Readline() if err != nil { if err == readline.ErrInterrupt { fmt.Println("^C") continue // User pressed Ctrl+C, continue loop } if err == io.EOF { fmt.Println("\nGoodbye!") break // User pressed Ctrl+D, exit } fmt.Printf("Error: %v\n", err) break } fmt.Printf("You entered: %s\n", line) if line == "exit" { break } } } // Output: // > hello world // You entered: hello world // > exit // You entered: exit ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.