Gim/model.go
Hayden Hargreaves 4003f411e0 Forgot this
2026-02-08 23:25:38 -07:00

144 lines
2.6 KiB
Go

package main
import tea "github.com/charmbracelet/bubbletea"
type mode int
const (
NormalMode mode = iota
InsertMode
CommandMode
)
type cursor struct {
x int
y int
}
type model struct {
lines []string
cursor cursor
s_gutter int
mode mode
win_h int
win_w int
command string
input *InputHandler
// Insert repetition
insertCount int
insertKeys []string
insertAction Action
}
func newModel() model {
return model{
lines: []string{
"Hello world",
"line 2",
"line 3",
"line 4",
"line 5",
"line 6",
},
cursor: cursor{
x: 0,
y: 0,
},
s_gutter: 5,
mode: NormalMode,
command: "",
input: NewInputHandler(),
}
}
func (m model) Init() tea.Cmd {
return nil
}
func (m *model) clampCursorX() {
lineLen := len(m.lines[m.cursor.y])
if lineLen == 0 {
m.cursor.x = 0
} else if m.cursor.x >= lineLen {
m.cursor.x = lineLen
}
}
func (m model) getCursorPosition() Position {
return Position{Line: m.cursor.y, Col: m.cursor.x}
}
func (m *model) replayInsert() {
// Replay (count - 1) more times
for i := 1; i < m.insertCount; i++ {
// For 'o' and 'O', we need to create a new line first
switch m.insertAction.(type) {
case OpenLineBelow:
pos := m.cursor.y
m.lines = append(m.lines[:pos+1], append([]string{""}, m.lines[pos+1:]...)...)
m.cursor.y++
m.cursor.x = 0
case OpenLineAbove:
pos := m.cursor.y
m.lines = append(m.lines[:pos], append([]string{""}, m.lines[pos:]...)...)
m.cursor.x = 0
// 'i' and 'a' don't need setup - just replay keys
}
// Replay each recorded keystroke
for _, key := range m.insertKeys {
m.processInsertKey(key)
}
}
}
func (m *model) processInsertKey(key string) {
switch key {
case "enter":
y := m.cursor.y
x := m.cursor.x
// Simple case, at end, just create a line
if x == len(m.lines[y]) {
m.lines = append(m.lines[:y+1], append([]string{""}, m.lines[y+1:]...)...)
// otherwise, splice
} else {
l := m.lines[y]
m.lines[y] = l[:x]
m.lines = append(m.lines[:y+1], append([]string{l[x:]}, m.lines[y+1:]...)...)
}
m.cursor.y++
m.cursor.x = 0
case "backspace":
x := m.cursor.x
y := m.cursor.y
l := m.lines[y]
if x > 0 {
m.lines[y] = l[:x-1] + l[x:]
m.cursor.x--
} else if y > 0 {
newX := len(m.lines[y-1])
m.lines[y-1] = m.lines[y-1] + l
m.lines = append(m.lines[:y], m.lines[y+1:]...)
m.cursor.y--
m.cursor.x = newX
}
default:
// Regular character
x := m.cursor.x
y := m.cursor.y
l := m.lines[y]
if x < len(l) {
m.lines[y] = l[:x] + key + l[x:]
} else {
m.lines[y] = l + key
}
m.cursor.x += len(key)
}
}