123 lines
3.7 KiB
Go
123 lines
3.7 KiB
Go
package action
|
|
|
|
import (
|
|
"git.gophernest.net/azpect/TextEditor/internal/core"
|
|
"git.gophernest.net/azpect/TextEditor/internal/style"
|
|
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)
|
|
|
|
// ==================================================
|
|
// Editor-wide State
|
|
// ==================================================
|
|
Mode() core.Mode
|
|
SetMode(mode core.Mode)
|
|
|
|
Settings() core.EditorSettings
|
|
SetSettings(s core.EditorSettings)
|
|
Styles() style.Styles
|
|
SetStyles(s style.Styles)
|
|
|
|
// ==================================================
|
|
// 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)
|
|
}
|