diff options
Diffstat (limited to 'internal/tmuxedit/send.go')
| -rw-r--r-- | internal/tmuxedit/send.go | 103 |
1 files changed, 15 insertions, 88 deletions
diff --git a/internal/tmuxedit/send.go b/internal/tmuxedit/send.go index ea63057..7a6bce2 100644 --- a/internal/tmuxedit/send.go +++ b/internal/tmuxedit/send.go @@ -17,83 +17,6 @@ var sendKeys = func(paneID string, keys ...string) error { return nil } -// deduplicateText compares the original (pre-filled) text with what the user -// returned from the editor. Returns empty string if unchanged (no-op), or -// the full edited text if anything changed. The caller is responsible for -// clearing existing pane input before sending the result, so we always return -// the complete text rather than stripping the original prefix. -func deduplicateText(original, edited string) string { - original = strings.TrimSpace(original) - edited = strings.TrimSpace(edited) - if edited == "" || edited == original { - return "" - } - return edited -} - -// sendTextToPane sends the given text to the target pane. It optionally -// clears existing input first (using the agent's ClearKeys sequence), then -// sends text line-by-line using the agent's NewlineKeys between lines. -// ClearKeys is space-separated; tokens like "BSpace*200" repeat a key N times -// via tmux send-keys -N. Example: "End BSpace*200" moves to end then -// sends 200 backspaces to clear the entire prompt buffer. -func sendTextToPane(paneID, text string, agent AgentConfig) error { - if strings.TrimSpace(text) == "" { - return nil - } - // Clear existing input using the key sequence (space-separated). - // Each token is sent as a separate tmux send-keys call. - // A short pause after clearing lets the TUI process all queued - // keystrokes (e.g. 200 backspaces) before new text arrives. - if agent.ClearFirst && agent.ClearKeys != "" { - if err := sendClearSequence(paneID, agent.ClearKeys); err != nil { - return err - } - sleepAfterClear() - } - // Send text line-by-line, inserting newline keys between lines - lines := strings.Split(text, "\n") - for i, line := range lines { - if err := sendKeys(paneID, line); err != nil { - return fmt.Errorf("send line %d failed: %w", i, err) - } - // Insert inter-line newline (except after the last line) - if i < len(lines)-1 { - nlKey := agent.NewlineKeys - if nlKey == "" { - nlKey = "Enter" // fallback for agents without shift-enter - } - if err := sendKeys(paneID, nlKey); err != nil { - return fmt.Errorf("newline after line %d failed: %w", i, err) - } - } - } - return nil -} - -// sleepAfterClear pauses to let the TUI drain queued keystrokes (like bulk -// backspaces) before new text is sent. Override in tests to avoid delays. -var sleepAfterClear = func() { time.Sleep(300 * time.Millisecond) } - -// sendClearSequence parses a space-separated key sequence and sends each -// token individually. Tokens with a "*N" suffix (e.g. "BSpace*200") are -// sent N times using tmux send-keys -N for efficient bulk repeats. -func sendClearSequence(paneID, clearKeys string) error { - for _, token := range strings.Fields(clearKeys) { - key, count := parseKeyRepeat(token) - if count > 1 { - if err := sendRepeatedKey(paneID, key, count); err != nil { - return fmt.Errorf("clear key %q*%d failed: %w", key, count, err) - } - } else { - if err := sendKeys(paneID, key); err != nil { - return fmt.Errorf("clear key %q failed: %w", key, err) - } - } - } - return nil -} - // sendRepeatedKey is the seam for `tmux send-keys -N <count>`. Override in // tests. Uses -N for efficient bulk key repeats (e.g. 200 backspaces). var sendRepeatedKey = func(paneID, key string, count int) error { @@ -105,16 +28,20 @@ var sendRepeatedKey = func(paneID, key string, count int) error { return nil } -// parseKeyRepeat splits "Key*N" into (Key, N). Returns (token, 1) if no -// repeat suffix is present or the suffix is invalid. -func parseKeyRepeat(token string) (string, int) { - idx := strings.LastIndex(token, "*") - if idx < 1 || idx >= len(token)-1 { - return token, 1 - } - n, err := strconv.Atoi(token[idx+1:]) - if err != nil || n < 1 { - return token, 1 +// sleepAfterClear pauses to let the TUI drain queued keystrokes (like bulk +// backspaces) before new text is sent. Override in tests to avoid delays. +var sleepAfterClear = func() { time.Sleep(300 * time.Millisecond) } + +// deduplicateText compares the original (pre-filled) text with what the user +// returned from the editor. Returns empty string if unchanged (no-op), or +// the full edited text if anything changed. The caller is responsible for +// clearing existing pane input before sending the result, so we always return +// the complete text rather than stripping the original prefix. +func deduplicateText(original, edited string) string { + original = strings.TrimSpace(original) + edited = strings.TrimSpace(edited) + if edited == "" || edited == original { + return "" } - return token[:idx], n + return edited } |
