150 lines
2.9 KiB
Go
150 lines
2.9 KiB
Go
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}
|
|
}
|