3 // FromCharPos converts from a character position to an x, y position
4 func FromCharPos(loc int, buf *Buffer) Loc {
8 lineLen := Count(buf.Line(y)) + 1
9 for charNum+lineLen <= loc {
12 lineLen = Count(buf.Line(y)) + 1
19 // ToCharPos converts from an x, y position to a character position
20 func ToCharPos(start Loc, buf *Buffer) int {
21 x, y := start.X, start.Y
23 for i := 0; i < y; i++ {
24 // + 1 for the newline
25 loc += Count(buf.Line(i)) + 1
31 // InBounds returns whether the given location is a valid character position in the given buffer
32 func InBounds(pos Loc, buf *Buffer) bool {
33 if pos.Y < 0 || pos.Y >= buf.NumLines || pos.X < 0 || pos.X > Count(buf.Line(pos.Y)) {
40 // ByteOffset is just like ToCharPos except it counts bytes instead of runes
41 func ByteOffset(pos Loc, buf *Buffer) int {
44 for i := 0; i < y; i++ {
45 // + 1 for the newline
46 loc += len(buf.Line(i)) + 1
48 loc += len(buf.Line(y)[:x])
52 // Loc stores a location
57 // Diff returns the distance between two locations
58 func Diff(a, b Loc, buf *Buffer) int {
66 // Make sure a is guaranteed to be less than b
72 for i := a.Y + 1; i < b.Y; i++ {
73 // + 1 for the newline
74 loc += Count(buf.Line(i)) + 1
76 loc += Count(buf.Line(a.Y)) - a.X + b.X + 1
80 // LessThan returns true if b is smaller
81 func (l Loc) LessThan(b Loc) bool {
85 if l.Y == b.Y && l.X < b.X {
91 // GreaterThan returns true if b is bigger
92 func (l Loc) GreaterThan(b Loc) bool {
96 if l.Y == b.Y && l.X > b.X {
102 // GreaterEqual returns true if b is greater than or equal to b
103 func (l Loc) GreaterEqual(b Loc) bool {
107 if l.Y == b.Y && l.X > b.X {
116 // LessEqual returns true if b is less than or equal to b
117 func (l Loc) LessEqual(b Loc) bool {
121 if l.Y == b.Y && l.X < b.X {
130 // This moves the location one character to the right
131 func (l Loc) right(buf *Buffer) Loc {
133 return Loc{l.X + 1, l.Y}
136 if l.X < Count(buf.Line(l.Y)) {
137 res = Loc{l.X + 1, l.Y}
139 res = Loc{0, l.Y + 1}
144 // This moves the given location one character to the left
145 func (l Loc) left(buf *Buffer) Loc {
146 if l == buf.Start() {
147 return Loc{l.X - 1, l.Y}
151 res = Loc{l.X - 1, l.Y}
153 res = Loc{Count(buf.Line(l.Y - 1)), l.Y - 1}
158 // Move moves the cursor n characters to the left or right
159 // It moves the cursor left if n is negative
160 func (l Loc) Move(n int, buf *Buffer) Loc {
162 for i := 0; i < n; i++ {
167 for i := 0; i < Abs(n); i++ {