-
Notifications
You must be signed in to change notification settings - Fork 1
/
selection.go
51 lines (44 loc) · 1.01 KB
/
selection.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
package main
import (
"bytes"
"fmt"
)
type position struct {
line, col int
}
type selection struct {
start, end position
}
// parseSelection parses a selection like "startLine.startCol-endLine.endCol".
func parseSelection(str string) (s selection, err error) {
_, err = fmt.Sscanf(str, "%d.%d-%d.%d",
&s.start.line, &s.start.col,
&s.end.line, &s.end.col)
return s, err
}
// byteOffsetsIn converts a selection to "startByte:endByte".
func (s selection) byteOffsetsIn(b []byte) string {
return fmt.Sprintf("%d:%d",
s.start.byteOffsetIn(b),
s.end.byteOffsetIn(b)+1)
}
func (p position) byteOffsetIn(b []byte) int {
return nthIndexByte(b, '\n', p.line-1) + p.col
}
// nthIndexByte returns the index of the nth instance of c in s,
// or -1 if no such instance is present in s.
func nthIndexByte(s []byte, c byte, n int) int {
var count, idx int
for count = 0; count < n; count++ {
i := bytes.IndexByte(s, c) + 1
idx += i
if i == 0 {
break
}
s = s[i:]
}
if count == n {
return idx - 1
}
return -1
}