summaryrefslogtreecommitdiff
path: root/internal/tmuxedit/cursor_agent.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/tmuxedit/cursor_agent.go')
-rw-r--r--internal/tmuxedit/cursor_agent.go58
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
+}