]> git.lizzy.rs Git - micro.git/blobdiff - cmd/micro/loc.go
Code optimisation (#1117)
[micro.git] / cmd / micro / loc.go
index 36ed605a0d95d3b4a3fb272575345aa3f8b7d7ff..a3806e548d24e179b8ac07393b6e772ecebc3a5f 100644 (file)
@@ -28,11 +28,55 @@ func ToCharPos(start Loc, buf *Buffer) int {
        return loc
 }
 
+// InBounds returns whether the given location is a valid character position in the given buffer
+func InBounds(pos Loc, buf *Buffer) bool {
+       if pos.Y < 0 || pos.Y >= buf.NumLines || pos.X < 0 || pos.X > Count(buf.Line(pos.Y)) {
+               return false
+       }
+
+       return true
+}
+
+// ByteOffset is just like ToCharPos except it counts bytes instead of runes
+func ByteOffset(pos Loc, buf *Buffer) int {
+       x, y := pos.X, pos.Y
+       loc := 0
+       for i := 0; i < y; i++ {
+               // + 1 for the newline
+               loc += len(buf.Line(i)) + 1
+       }
+       loc += len(buf.Line(y)[:x])
+       return loc
+}
+
 // Loc stores a location
 type Loc struct {
        X, Y int
 }
 
+// Diff returns the distance between two locations
+func Diff(a, b Loc, buf *Buffer) int {
+       if a.Y == b.Y {
+               if a.X > b.X {
+                       return a.X - b.X
+               }
+               return b.X - a.X
+       }
+
+       // Make sure a is guaranteed to be less than b
+       if b.LessThan(a) {
+               a, b = b, a
+       }
+
+       loc := 0
+       for i := a.Y + 1; i < b.Y; i++ {
+               // + 1 for the newline
+               loc += Count(buf.Line(i)) + 1
+       }
+       loc += Count(buf.Line(a.Y)) - a.X + b.X + 1
+       return loc
+}
+
 // LessThan returns true if b is smaller
 func (l Loc) LessThan(b Loc) bool {
        if l.Y < b.Y {
@@ -83,9 +127,10 @@ func (l Loc) LessEqual(b Loc) bool {
        return false
 }
 
+// This moves the location one character to the right
 func (l Loc) right(buf *Buffer) Loc {
        if l == buf.End() {
-               return l
+               return Loc{l.X + 1, l.Y}
        }
        var res Loc
        if l.X < Count(buf.Line(l.Y)) {
@@ -95,9 +140,11 @@ func (l Loc) right(buf *Buffer) Loc {
        }
        return res
 }
+
+// This moves the given location one character to the left
 func (l Loc) left(buf *Buffer) Loc {
        if l == buf.Start() {
-               return l
+               return Loc{l.X - 1, l.Y}
        }
        var res Loc
        if l.X > 0 {
@@ -108,6 +155,8 @@ func (l Loc) left(buf *Buffer) Loc {
        return res
 }
 
+// Move moves the cursor n characters to the left or right
+// It moves the cursor left if n is negative
 func (l Loc) Move(n int, buf *Buffer) Loc {
        if n > 0 {
                for i := 0; i < n; i++ {
@@ -115,12 +164,8 @@ func (l Loc) Move(n int, buf *Buffer) Loc {
                }
                return l
        }
-       for i := 0; i < n; i++ {
-               return l.left(buf)
+       for i := 0; i < Abs(n); i++ {
+               l = l.left(buf)
        }
        return l
 }
-
-// func (l Loc) DistanceTo(b Loc, buf *Buffer) int {
-//
-// }