diff --git a/main.go b/main.go index e5fe0d0..f1fe0aa 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( + "bufio" "bytes" "encoding/json" "fmt" @@ -235,15 +236,32 @@ func (c *KVSClient) handleGet(args []string) { } func (c *KVSClient) handlePut(args []string) { - if len(args) < 2 { + if len(args) < 1 { fmt.Println(red("Usage: put ")) + fmt.Println("Or: put (then paste JSON on next line)") return } + var jsonStr string + if len(args) == 1 { + // Multiline mode - read from next input + fmt.Println(yellow("Enter JSON (Ctrl+D when done):")) + scanner := bufio.NewScanner(os.Stdin) + var lines []string + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + jsonStr = strings.Join(lines, "\n") + } else { + // Single line mode + jsonStr = strings.Join(args[1:], " ") + } + // Parse JSON data var data json.RawMessage - if err := json.Unmarshal([]byte(args[1]), &data); err != nil { + if err := json.Unmarshal([]byte(jsonStr), &data); err != nil { fmt.Println(red("Invalid JSON:"), err) + fmt.Println("Tip: Use proper JSON format with escaped quotes") return } @@ -527,25 +545,35 @@ var completer = readline.NewPrefixCompleter( func parseCommand(line string) []string { var parts []string var current strings.Builder - inQuotes := false + var quoteChar rune = 0 // Use a rune to store the active quote character (' or ") - for i := 0; i < len(line); i++ { - ch := line[i] - switch ch { - case '"': - inQuotes = !inQuotes - case ' ', '\t': - if inQuotes { - current.WriteByte(ch) - } else if current.Len() > 0 { + for _, ch := range line { + switch { + // If we see a quote character + case ch == '\'' || ch == '"': + if quoteChar == 0 { + // Not currently inside a quoted string, so start one + quoteChar = ch + } else if quoteChar == ch { + // Inside a quoted string and found the matching quote, so end it + quoteChar = 0 + } else { + // Inside a quoted string but found the *other* type of quote, treat it as a literal character + current.WriteRune(ch) + } + // If we see a space or tab and are NOT inside a quoted string + case (ch == ' ' || ch == '\t') && quoteChar == 0: + if current.Len() > 0 { parts = append(parts, current.String()) current.Reset() } + // Any other character default: - current.WriteByte(ch) + current.WriteRune(ch) } } + // Add the last part if it exists if current.Len() > 0 { parts = append(parts, current.String()) }