All checks were successful
Run Test Suite / test (push) Successful in 56s
Not sure if this is perfect, but it seems to be working
127 lines
3.1 KiB
Go
127 lines
3.1 KiB
Go
package action
|
|
|
|
import (
|
|
"git.gophernest.net/azpect/TextEditor/internal/core"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
)
|
|
|
|
// ChangeToEndOfLine implements Action (C) - changes from cursor to end of line
|
|
type ChangeToEndOfLine struct {
|
|
Count int
|
|
}
|
|
|
|
// ChangeToEndOfLine.Execute: Changes from cursor to end of line and enters insert mode (C key).
|
|
func (a ChangeToEndOfLine) Execute(m Model) tea.Cmd {
|
|
win := m.ActiveWindow()
|
|
buf := m.ActiveBuffer()
|
|
|
|
pos := win.Cursor.Col
|
|
line := buf.Line(win.Cursor.Line)
|
|
|
|
// Save deleted text to register
|
|
if pos < len(line) {
|
|
m.UpdateDefaultRegister(core.CharwiseRegister, []string{line[pos:]})
|
|
}
|
|
|
|
// Delete to end of line
|
|
buf.SetLine(win.Cursor.Line, line[:pos])
|
|
|
|
// Enter insert mode
|
|
m.SetMode(core.InsertMode)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Ensure ChangeToEndOfLine implements Repeatable
|
|
var _ Repeatable = ChangeToEndOfLine{}
|
|
|
|
// ChangeToEndOfLine.WithCount: Returns a new ChangeToEndOfLine with the given count.
|
|
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
|
|
}
|
|
|
|
// SubstituteChar.Execute: Deletes Count characters and enters insert mode (s key).
|
|
func (a SubstituteChar) Execute(m Model) tea.Cmd {
|
|
win := m.ActiveWindow()
|
|
buf := m.ActiveBuffer()
|
|
|
|
pos := win.Cursor.Col
|
|
line := buf.Line(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(core.CharwiseRegister, []string{line[pos : pos+count]})
|
|
|
|
// Delete the characters
|
|
buf.SetLine(win.Cursor.Line, line[:pos]+line[pos+count:])
|
|
}
|
|
|
|
// Enter insert mode
|
|
m.SetMode(core.InsertMode)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Ensure SubstituteChar implements Repeatable
|
|
var _ Repeatable = SubstituteChar{}
|
|
|
|
// SubstituteChar.WithCount: Returns a new SubstituteChar with the given count.
|
|
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
|
|
}
|
|
|
|
// SubstituteLine.Execute: Clears Count lines and enters insert mode (S key).
|
|
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.Line(y))
|
|
buf.DeleteLine(y)
|
|
}
|
|
|
|
// Save deleted lines to register
|
|
m.UpdateDefaultRegister(core.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(core.InsertMode)
|
|
|
|
return nil
|
|
}
|
|
|
|
// Ensure SubstituteLine implements Repeatable
|
|
var _ Repeatable = SubstituteLine{}
|
|
|
|
// SubstituteLine.WithCount: Returns a new SubstituteLine with the given count.
|
|
func (a SubstituteLine) WithCount(n int) Action {
|
|
return SubstituteLine{Count: n}
|
|
}
|