From c5cd80b4bed1234152f19d23ddac51d86ba36f0f Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 8 Feb 2026 17:38:07 +0200 Subject: Fix Claude agent clearing to use readline instead of vim commands Claude Code's prompt input field does not support vim commands for clearing. The previous sequence 'Escape gg C-v G d i' resulted in literal text 'gGdijo' appearing in the prompt instead of clearing it. Changed to 'C-a C-k' (Emacs/readline style): - C-a: Move cursor to start of line - C-k: Kill (delete) from cursor to end of line Also added 150ms delay after Escape key in sendClearSequence to ensure mode transitions complete before subsequent keys are sent (though Claude uses readline, this helps other potential vim-based agents). Changes: - internal/tmuxedit/claude_agent.go: clearKeys "C-a C-k" instead of vim - internal/tmuxedit/claude_agent_test.go: Update test expectations - internal/tmuxedit/agentutil.go: Add time import and Escape delay - docs/usage.md: Update claude clear method documentation - docs/tmux.md: Clarify claude uses readline not vim - config.toml.example: Update claude description Integration tested: - Extracted: "final verification test" - Sent: "FINAL REPLACED TEXT NO VIM COMMANDS" - Result: Clean replacement with NO vim command artifacts - All unit tests pass (67/67) - Coverage: 80.9% Co-authored-by: Cursor --- internal/tmuxedit/agentutil.go | 5 +++++ internal/tmuxedit/claude_agent.go | 2 +- internal/tmuxedit/claude_agent_test.go | 10 +++------- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'internal') diff --git a/internal/tmuxedit/agentutil.go b/internal/tmuxedit/agentutil.go index 924a4a8..18ece9b 100644 --- a/internal/tmuxedit/agentutil.go +++ b/internal/tmuxedit/agentutil.go @@ -8,6 +8,7 @@ import ( "regexp" "strconv" "strings" + "time" ) // promptMatch holds a regex match result with its line number in the pane. @@ -117,6 +118,10 @@ func sendClearSequence(paneID, clearKeys string) error { return fmt.Errorf("clear key %q failed: %w", key, err) } } + // Add delay after Escape to let Vim/Claude exit INSERT mode + if key == "Escape" { + time.Sleep(150 * time.Millisecond) + } } return nil } diff --git a/internal/tmuxedit/claude_agent.go b/internal/tmuxedit/claude_agent.go index 72ba107..b84c77e 100644 --- a/internal/tmuxedit/claude_agent.go +++ b/internal/tmuxedit/claude_agent.go @@ -21,7 +21,7 @@ func newClaudeAgent() *claudeAgent { sectionPat: `^─{5,}`, promptPat: `(?m)❯\s*(.+)$`, clearFirst: true, - clearKeys: "Escape gg C-v G d i", + clearKeys: "C-a C-k", newlineKeys: "S-Enter", submitKeys: "Enter", }} diff --git a/internal/tmuxedit/claude_agent_test.go b/internal/tmuxedit/claude_agent_test.go index a373378..1a80433 100644 --- a/internal/tmuxedit/claude_agent_test.go +++ b/internal/tmuxedit/claude_agent_test.go @@ -88,14 +88,10 @@ func TestClaudeAgent_ClearInput(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v", err) } - // "Escape gg C-v G d i" should send each as separate send-keys call + // "C-a C-k" (Emacs/readline style) should send each as separate send-keys call want := []string{ - "send:%3:Escape", - "send:%3:gg", - "send:%3:C-v", - "send:%3:G", - "send:%3:d", - "send:%3:i", + "send:%3:C-a", + "send:%3:C-k", } if len(calls) != len(want) { t.Fatalf("got %d calls, want %d: %v", len(calls), len(want), calls) -- cgit v1.2.3