/
copy.go
75 lines (62 loc) 路 1.4 KB
/
copy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package replay
import (
"github.com/cfoust/cy/pkg/geom"
"github.com/cfoust/cy/pkg/taro"
tea "github.com/charmbracelet/bubbletea"
"github.com/mattn/go-runewidth"
)
func normalizeRange(start, end geom.Vec2) (newStart, newEnd geom.Vec2) {
if end.R < start.R || (end.R == start.R && end.C < start.C) {
intermediate := start
start = end
end = intermediate
}
return start, end
}
// Read a starting from `start` to `end`, inclusive.
func (r *Replay) readString(start, end geom.Vec2) (result string) {
start, end = normalizeRange(start, end)
var char rune
var startCol, endCol, lastChar int
for row := start.R; row <= end.R; row++ {
line := r.getLine(row)
startCol = 0
if row == start.R {
startCol = start.C
}
_, lastChar = getNonWhitespace(line)
endCol = lastChar
if row == end.R {
endCol = geom.Min(end.C, endCol)
}
for col := startCol; col <= endCol; col++ {
char = line[col].Char
result += string(char)
w := runewidth.RuneWidth(char)
for i := 1; i < w; i++ {
col++
}
}
if row != end.R && endCol == lastChar {
result += "\n"
}
}
return
}
func (r *Replay) handleCopy() (taro.Model, tea.Cmd) {
if !r.isCopyMode() || !r.isSelecting {
return r, nil
}
r.isSelecting = false
text := r.readString(
r.selectStart,
r.viewportToTerm(r.cursor),
)
return r, func() tea.Msg {
return taro.PublishMsg{
Msg: CopyEvent{
Text: text,
},
}
}
}