package action import ( tea "github.com/charmbracelet/bubbletea" ) // Model defines the interface for editor state that actions can modify type Model interface { // Text buffer Lines() []string Line(idx int) string SetLine(idx int, content string) InsertLine(idx int, content string) DeleteLine(idx int) LineCount() int // Cursor CursorX() int CursorY() int SetCursorX(x int) SetCursorY(y int) ClampCursorX() // Window ScrollY() int SetScrollY(y int) WinH() int WinW() int ViewPortH() int // Anchor AnchorX() int AnchorY() int SetAnchorX(x int) SetAnchorY(y int) // Insert InsertKeys() []string SetInsertKeys(keys []string) // Command mode Command() string SetCommand(cmd string) CommandCursor() int SetCommandCursor(cur int) CommandError() error SetCommandError(err error) CommandOutput() string SetCommandOutput(out string) // Settings Settings() Settings SetSettings(s Settings) // Registers Registers() map[rune]Register GetRegister(name rune) (Register, bool) SetRegister(name rune, t RegisterType, cnt []string) error UpdateDefaultRegister(t RegisterType, cnt []string) // Mode Mode() Mode SetMode(mode Mode) // Insert recording (for count replay) SetInsertRecording(count int, action Action) // ExitInsertMode handles replay, cursor step-back, and mode transition on esc ExitInsertMode() } // Position represents a location in the buffer type Position struct { Line, Col int } // MotionType indicates how a motion operates type MotionType int const ( CharwiseExclusive MotionType = iota // w, b, h, l, 0, ^ - end position not included CharwiseInclusive // e, $, f - end position is included Linewise // j, k, G, gg, {, } - operates on whole lines ) // IsCharwise returns true if the motion type is character-based (not linewise) func (mt MotionType) IsCharwise() bool { return mt == CharwiseExclusive || mt == CharwiseInclusive } // Action is the base interface - anything executable type Action interface { Execute(m Model) tea.Cmd } // Motion moves the cursor and returns the range covered type Motion interface { Action Type() MotionType } // Operator acts on a range (delete, yank, change) type Operator interface { Operate(m Model, start, end Position, mtype MotionType) tea.Cmd } // DoublePresser is an optional interface for operators that support double-press (dd, yy, cc) type DoublePresser interface { DoublePress(m Model, count int) tea.Cmd } // Repeatable actions track count type Repeatable interface { WithCount(n int) Action }