6 "github.com/zyedidia/micro/internal/util"
9 // Loc stores a location
14 // LessThan returns true if b is smaller
15 func (l Loc) LessThan(b Loc) bool {
19 return l.Y == b.Y && l.X < b.X
22 // GreaterThan returns true if b is bigger
23 func (l Loc) GreaterThan(b Loc) bool {
27 return l.Y == b.Y && l.X > b.X
30 // GreaterEqual returns true if b is greater than or equal to b
31 func (l Loc) GreaterEqual(b Loc) bool {
35 if l.Y == b.Y && l.X > b.X {
41 // LessEqual returns true if b is less than or equal to b
42 func (l Loc) LessEqual(b Loc) bool {
46 if l.Y == b.Y && l.X < b.X {
52 // The following functions require a buffer to know where newlines are
54 // Diff returns the distance between two locations
55 func DiffLA(a, b Loc, buf *LineArray) int {
63 // Make sure a is guaranteed to be less than b
69 for i := a.Y + 1; i < b.Y; i++ {
70 // + 1 for the newline
71 loc += utf8.RuneCount(buf.LineBytes(i)) + 1
73 loc += utf8.RuneCount(buf.LineBytes(a.Y)) - a.X + b.X + 1
77 // This moves the location one character to the right
78 func (l Loc) right(buf *LineArray) Loc {
80 return Loc{l.X + 1, l.Y}
83 if l.X < utf8.RuneCount(buf.LineBytes(l.Y)) {
84 res = Loc{l.X + 1, l.Y}
91 // This moves the given location one character to the left
92 func (l Loc) left(buf *LineArray) Loc {
94 return Loc{l.X - 1, l.Y}
98 res = Loc{l.X - 1, l.Y}
100 res = Loc{utf8.RuneCount(buf.LineBytes(l.Y - 1)), l.Y - 1}
105 // MoveLA moves the cursor n characters to the left or right
106 // It moves the cursor left if n is negative
107 func (l Loc) MoveLA(n int, buf *LineArray) Loc {
109 for i := 0; i < n; i++ {
114 for i := 0; i < util.Abs(n); i++ {
120 // Diff returns the difference between two locs
121 func (l Loc) Diff(b Loc, buf *Buffer) int {
122 return DiffLA(l, b, buf.LineArray)
125 // Move moves a loc n characters
126 func (l Loc) Move(n int, buf *Buffer) Loc {
127 return l.MoveLA(n, buf.LineArray)
130 // ByteOffset is just like ToCharPos except it counts bytes instead of runes
131 func ByteOffset(pos Loc, buf *Buffer) int {
134 for i := 0; i < y; i++ {
135 // + 1 for the newline
136 loc += len(buf.Line(i)) + 1
138 loc += len(buf.Line(y)[:x])
142 // clamps a loc within a buffer
143 func clamp(pos Loc, la *LineArray) Loc {
144 if pos.GreaterEqual(la.End()) {
146 } else if pos.LessThan(la.Start()) {