Gim/internal/action/change.go
Hayden Hargreaves b1b3edf810 feat: this is huge, and needs some review, but for now its good
The tests are not passing, something to do with view I think.
2026-02-26 23:18:18 -07:00

118 lines
2.5 KiB
Go

package action
import tea "github.com/charmbracelet/bubbletea"
// ChangeToEndOfLine implements Action (C) - changes from cursor to end of line
type ChangeToEndOfLine struct {
Count int
}
func (a ChangeToEndOfLine) Execute(m Model) tea.Cmd {
win := m.ActiveWindow()
buf := m.ActiveBuffer()
pos := win.Cursor.Col
line := buf.Lines[win.Cursor.Line]
// Save deleted text to register
if pos < len(line) {
m.UpdateDefaultRegister(CharwiseRegister, []string{line[pos:]})
}
// Delete to end of line
buf.SetLine(win.Cursor.Line, line[:pos])
// Enter insert mode
m.SetMode(InsertMode)
return nil
}
// Ensure ChangeToEndOfLine implements Repeatable
var _ Repeatable = ChangeToEndOfLine{}
func (a ChangeToEndOfLine) WithCount(n int) Action {
return ChangeToEndOfLine{Count: n}
}
// SubstituteChar implements Action (s) - deletes character and enters insert mode
type SubstituteChar struct {
Count int
}
func (a SubstituteChar) Execute(m Model) tea.Cmd {
win := m.ActiveWindow()
buf := m.ActiveBuffer()
pos := win.Cursor.Col
line := buf.Lines[win.Cursor.Line]
// Calculate how many chars to delete (limited by line length)
count := min(a.Count, len(line)-pos)
if count > 0 {
// Save deleted text to register
m.UpdateDefaultRegister(CharwiseRegister, []string{line[pos : pos+count]})
// Delete the characters
buf.SetLine(win.Cursor.Line, line[:pos]+line[pos+count:])
}
// Enter insert mode
m.SetMode(InsertMode)
return nil
}
// Ensure SubstituteChar implements Repeatable
var _ Repeatable = SubstituteChar{}
func (a SubstituteChar) WithCount(n int) Action {
return SubstituteChar{Count: n}
}
// SubstituteLine implements Action (S) - clears line and enters insert mode
type SubstituteLine struct {
Count int
}
func (a SubstituteLine) Execute(m Model) tea.Cmd {
win := m.ActiveWindow()
buf := m.ActiveBuffer()
y := win.Cursor.Line
// Calculate how many lines to substitute
count := min(a.Count, buf.LineCount()-y)
var lines []string
// Collect and delete lines
for range count {
lines = append(lines, buf.Lines[y])
buf.DeleteLine(y)
}
// Save deleted lines to register
m.UpdateDefaultRegister(LinewiseRegister, lines)
// Insert empty line at original position
insertY := min(y, buf.LineCount())
buf.InsertLine(insertY, "")
// Position cursor
win.SetCursorPos(insertY, 0)
// Enter insert mode
m.SetMode(InsertMode)
return nil
}
// Ensure SubstituteLine implements Repeatable
var _ Repeatable = SubstituteLine{}
func (a SubstituteLine) WithCount(n int) Action {
return SubstituteLine{Count: n}
}