package action import ( "fmt" "strings" tea "github.com/charmbracelet/bubbletea" ) // Paste implements Action (p) - pastes after cursor type Paste struct { Count int } func (a Paste) Execute(m Model) tea.Cmd { // Get reg reg, found := m.GetRegister('"') if !found { m.SetCommandError(fmt.Errorf("\"\" register is broken. Uh oh.")) return nil } // Exit if blank if len(reg.Content) == 0 { return nil } switch reg.Type { case LinewiseRegister: { initY := m.CursorY() lines := reg.Content insertPos := initY + 1 // Run count times for range a.Count { for _, line := range lines { m.InsertLine(insertPos, line) insertPos++ } } if m.LineCount() > 1 { m.SetCursorY(initY + 1) } } case CharwiseRegister: { lines := reg.Content // Shouldn't happen, just a check if len(lines) != 1 { m.SetCommandError(fmt.Errorf("Charwise register should only have a single line of content.")) break } x := m.CursorX() y := m.CursorY() cnt := strings.Repeat(lines[0], max(1, a.Count)) curLine := m.Line(y) // Catch edge cases, end of line, start of blank line insertAt := min(x+1, len(curLine)) newLine := curLine[:insertAt] + cnt + curLine[insertAt:] m.SetLine(y, newLine) m.SetCursorX(x + len(cnt)) m.ClampCursorX() } default: m.SetCommandError(fmt.Errorf("Register type is not implemented.")) } return nil } // Ensure Paste implements Repeatable var _ Repeatable = Paste{} func (a Paste) WithCount(n int) Action { return Paste{Count: n} } // PasteBefore implements Action (P) - pastes before cursor type PasteBefore struct { Count int } func (a PasteBefore) Execute(m Model) tea.Cmd { // Get reg reg, found := m.GetRegister('"') if !found { m.SetCommandError(fmt.Errorf("\"\" register is broken. Uh oh.")) return nil } switch reg.Type { case LinewiseRegister: { initY := m.CursorY() lines := reg.Content insertPos := initY // Leave here, this will effectively move the lines below // Run count times for range a.Count { for _, line := range lines { m.InsertLine(insertPos, line) insertPos++ } } } case CharwiseRegister: { lines := reg.Content // Shouldn't happen, just a check if len(lines) != 1 { m.SetCommandError(fmt.Errorf("Charwise register should only have a single line of content.")) break } x := m.CursorX() y := m.CursorY() cnt := strings.Repeat(lines[0], max(1, a.Count)) curLine := m.Line(y) // Catch edge cases, end of line, start of blank line insertAt := min(x, len(curLine)) newLine := curLine[:insertAt] + cnt + curLine[insertAt:] m.SetLine(y, newLine) m.SetCursorX(x + len(cnt)) m.ClampCursorX() } default: m.SetCommandError(fmt.Errorf("Register type is not implemented.")) } return nil } // Ensure PasteBefore implements Repeatable var _ Repeatable = PasteBefore{} func (a PasteBefore) WithCount(n int) Action { return PasteBefore{Count: n} }