diff options
Diffstat (limited to 'internal/tmuxedit/cursor_agent.go')
| -rw-r--r-- | internal/tmuxedit/cursor_agent.go | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/internal/tmuxedit/cursor_agent.go b/internal/tmuxedit/cursor_agent.go new file mode 100644 index 0000000..1346d05 --- /dev/null +++ b/internal/tmuxedit/cursor_agent.go @@ -0,0 +1,58 @@ +package tmuxedit + +import ( + "regexp" +) + +// cursorAgent handles Cursor's distinctive box-drawing │ → prompt │ UI. +// Cursor uses a text field (not vim), so clearing is done with End + bulk +// backspace. Multi-line prompts are entered with Shift-Enter within the box. +type cursorAgent struct{ baseAgent } + +// newCursorAgent returns a cursorAgent with the default configuration. +// Detect by the box structure or "/ commands" footer. Checked first because +// cursor panes often show model names like "Claude 4.5 Sonnet". +func newCursorAgent() *cursorAgent { + return &cursorAgent{baseAgent{ + name: "cursor", + displayName: "Cursor", + detectPattern: `(│\s*→|/ commands · @ files)`, + promptPat: `(?m)│\s*→?\s*(.+?)\s*│\s*$`, + stripPatterns: []string{"INSERT", "Add a follow-up", "ctrl+c to stop"}, + clearFirst: true, + clearKeys: "End BSpace*200", + newlineKeys: "S-Enter", + submitKeys: "Enter", + }} +} + +// ExtractPrompt extracts the prompt text from the last contiguous │...│ block +// in the pane. This avoids picking up earlier command-review or dialog boxes +// that also use box-drawing characters. +func (c *cursorAgent) ExtractPrompt(paneContent string) string { + if c.promptPat == "" { + return "" + } + re, err := regexp.Compile(c.promptPat) + if err != nil { + return "" + } + allMatches := matchPromptLines(re, paneContent) + if len(allMatches) == 0 { + return "" + } + return joinLastContiguousBlock(allMatches, c.stripPatterns) +} + +// ClearInput sends End + 200 backspaces to clear Cursor's text field. +// Cursor's input is a standard text field, not vim. +func (c *cursorAgent) ClearInput(paneID string) error { + if !c.clearFirst || c.clearKeys == "" { + return nil + } + if err := sendClearSequence(paneID, c.clearKeys); err != nil { + return err + } + sleepAfterClear() + return nil +} |
