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} }