package action import ( tea "github.com/charmbracelet/bubbletea" ) // Mode constants for editor mode type Mode int const ( NormalMode Mode = iota InsertMode CommandMode VisualMode VisualLineMode VisualBlockMode ) func (m Mode) ToString() string { switch m { case NormalMode: return "NORMAL" case InsertMode: return "INSERT" case CommandMode: return "COMMAND" case VisualMode: return "VISUAL" case VisualLineMode: return "V-LINE" case VisualBlockMode: return "V-BLOCK" default: return "-----" } } func (m Mode) IsVisualMode() bool { return m == VisualMode || m == VisualLineMode || m == VisualBlockMode } // 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) // 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) // Settings Settings() Settings // 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 ( Charwise MotionType = iota // h, l, w, e, f, t - operates on characters Linewise // j, k, G, gg, {, } - operates on whole lines ) // 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 // DoublePress handles dd, yy, cc (line-wise) DoublePress(m Model, count int) tea.Cmd } // Repeatable actions track count type Repeatable interface { WithCount(n int) Action }