Gim/internal/action/interface.go
2026-04-09 14:36:18 -07:00

135 lines
4.1 KiB
Go

package action
import (
"git.gophernest.net/azpect/TextEditor/internal/core"
"git.gophernest.net/azpect/TextEditor/internal/theme"
tea "github.com/charmbracelet/bubbletea"
)
// Model defines the interface for editor state that actions can modify
type Model interface {
// ==================================================
// Core Data Access
// ==================================================
Windows() []*core.Window
ActiveWindow() *core.Window
Buffers() []*core.Buffer
SetBuffers(bufs []*core.Buffer)
ActiveBuffer() *core.Buffer
// ==================================================
// Insert Mode State
// ==================================================
InsertKeys() []string
SetInsertKeys(keys []string)
// Insert recording (for count replay)
SetInsertRecording(count int, action Action)
SetLastFind(char string, forward, inclusive bool)
GetLastFind() *core.LastFindCommand
// ExitInsertMode handles replay, cursor step-back, and mode transition on esc
ExitInsertMode()
// ==================================================
// Command Mode State
// ==================================================
Command() string
SetCommand(cmd string)
CommandCursor() int
SetCommandCursor(cur int)
CommandOutput() *core.CommandOutput
// DO NOT FORGET TO CALL SetMode()
SetCommandOutput(out *core.CommandOutput)
CommandHistory() []string
SetCommandHistory(history []string)
CommandHistoryCursor() int
SetCommandHistoryCursor(cur int)
// ==================================================
// Search Mode State
// ==================================================
SearchState() core.SearchState
SetSearchState(s core.SearchState)
// ==================================================
// Editor-wide State
// ==================================================
Mode() core.Mode
SetMode(mode core.Mode)
Settings() core.EditorSettings
SetSettings(s core.EditorSettings)
// ==================================================
// Themes
// ==================================================
Theme() (string, theme.EditorTheme)
SetTheme(name string)
Themes() map[string]theme.EditorTheme
SetThemes(t map[string]theme.EditorTheme)
// ==================================================
// Registers
// ==================================================
Registers() map[rune]core.Register
GetRegister(name rune) (core.Register, bool)
SetRegister(name rune, t core.RegisterType, cnt []string) error
UpdateDefaultRegister(t core.RegisterType, cnt []string)
// Dot operator - accumulate keys for repeat
SetLastChangeKeys(keys []string)
LastChangeKeys() []string
ClearLastChangeKeys()
HandleKey(key string) tea.Cmd
}
// 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() core.MotionType
}
// Operator acts on a range (delete, yank, change)
type Operator interface {
Operate(m Model, start, end core.Position, mtype core.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
}
// CharMotion is a motion that requires a character argument (f/t/F/T)
// The state machine will call WithChar to set the character before executing
type CharMotion interface {
Motion
WithChar(char string) Motion
}
// Resolvable is an optional interface for motions that need to consult the
// model to fully determine their behaviour (e.g. RepeatFind must look up the
// last find to know whether it is inclusive or exclusive). The FSM calls
// Resolve(m) first and uses the returned Motion in place of the original, so
// that the subsequent Type() call returns the correct value.
type Resolvable interface {
Motion
Resolve(m Model) Motion
}
type TextObject interface {
// GetRange calculates both endpoints for the text object
// modifier: "i" (inner) or "a" (around)
GetRange(m Model, cursor core.Position, modifier string) (start, end core.Position, mtype core.MotionType)
}