]> git.lizzy.rs Git - micro.git/blobdiff - internal/buffer/line_array.go
Share hash across equivalent buffers for fastdirty=off
[micro.git] / internal / buffer / line_array.go
index dcbf2e43bc87b6b3da73eaa8335d44a2abcdf5c7..3aae47ba86b7e711ae7facf76215eaf1d976324a 100644 (file)
@@ -3,6 +3,7 @@ package buffer
 import (
        "bufio"
        "io"
+       "sync"
        "unicode/utf8"
 
        "github.com/zyedidia/micro/pkg/highlight"
@@ -38,6 +39,7 @@ type Line struct {
        state       highlight.State
        match       highlight.LineMatch
        rehighlight bool
+       lock        sync.Mutex
 }
 
 const (
@@ -124,12 +126,22 @@ func NewLineArray(size uint64, endings FileFormat, reader io.Reader) *LineArray
 
                if err != nil {
                        if err == io.EOF {
-                               la.lines = Append(la.lines, Line{data[:], nil, nil, false})
+                               la.lines = Append(la.lines, Line{
+                                       data:        data[:],
+                                       state:       nil,
+                                       match:       nil,
+                                       rehighlight: false,
+                               })
                        }
                        // Last line was read
                        break
                } else {
-                       la.lines = Append(la.lines, Line{data[:dlen-1], nil, nil, false})
+                       la.lines = Append(la.lines, Line{
+                               data:        data[:dlen-1],
+                               state:       nil,
+                               match:       nil,
+                               rehighlight: false,
+                       })
                }
                n++
        }
@@ -155,9 +167,19 @@ func (la *LineArray) Bytes() []byte {
 
 // newlineBelow adds a newline below the given line number
 func (la *LineArray) newlineBelow(y int) {
-       la.lines = append(la.lines, Line{[]byte{' '}, nil, nil, false})
+       la.lines = append(la.lines, Line{
+               data:        []byte{' '},
+               state:       nil,
+               match:       nil,
+               rehighlight: false,
+       })
        copy(la.lines[y+2:], la.lines[y+1:])
-       la.lines[y+1] = Line{[]byte{}, la.lines[y].state, nil, false}
+       la.lines[y+1] = Line{
+               data:        []byte{},
+               state:       la.lines[y].state,
+               match:       nil,
+               rehighlight: false,
+       }
 }
 
 // Inserts a byte array at a given location
@@ -208,9 +230,7 @@ func (la *LineArray) remove(start, end Loc) []byte {
        if start.Y == end.Y {
                la.lines[start.Y].data = append(la.lines[start.Y].data[:startX], la.lines[start.Y].data[endX:]...)
        } else {
-               for i := start.Y + 1; i <= end.Y-1; i++ {
-                       la.deleteLine(start.Y + 1)
-               }
+               la.deleteLines(start.Y+1, end.Y-1)
                la.deleteToEnd(Loc{startX, start.Y})
                la.deleteFromStart(Loc{endX - 1, start.Y + 1})
                la.joinLines(start.Y, start.Y+1)
@@ -233,6 +253,10 @@ func (la *LineArray) deleteLine(y int) {
        la.lines = la.lines[:y+copy(la.lines[y:], la.lines[y+1:])]
 }
 
+func (la *LineArray) deleteLines(y1, y2 int) {
+       la.lines = la.lines[:y1+copy(la.lines[y1:], la.lines[y2+1:])]
+}
+
 // DeleteByte deletes the byte at a position
 func (la *LineArray) deleteByte(pos Loc) {
        la.lines[pos.Y].data = la.lines[pos.Y].data[:pos.X+copy(la.lines[pos.Y].data[pos.X:], la.lines[pos.Y].data[pos.X+1:])]
@@ -285,28 +309,40 @@ func (la *LineArray) LineBytes(n int) []byte {
 
 // State gets the highlight state for the given line number
 func (la *LineArray) State(lineN int) highlight.State {
+       la.lines[lineN].lock.Lock()
+       defer la.lines[lineN].lock.Unlock()
        return la.lines[lineN].state
 }
 
 // SetState sets the highlight state at the given line number
 func (la *LineArray) SetState(lineN int, s highlight.State) {
+       la.lines[lineN].lock.Lock()
+       defer la.lines[lineN].lock.Unlock()
        la.lines[lineN].state = s
 }
 
 // SetMatch sets the match at the given line number
 func (la *LineArray) SetMatch(lineN int, m highlight.LineMatch) {
+       la.lines[lineN].lock.Lock()
+       defer la.lines[lineN].lock.Unlock()
        la.lines[lineN].match = m
 }
 
 // Match retrieves the match for the given line number
 func (la *LineArray) Match(lineN int) highlight.LineMatch {
+       la.lines[lineN].lock.Lock()
+       defer la.lines[lineN].lock.Unlock()
        return la.lines[lineN].match
 }
 
 func (la *LineArray) Rehighlight(lineN int) bool {
+       la.lines[lineN].lock.Lock()
+       defer la.lines[lineN].lock.Unlock()
        return la.lines[lineN].rehighlight
 }
 
 func (la *LineArray) SetRehighlight(lineN int, on bool) {
+       la.lines[lineN].lock.Lock()
+       defer la.lines[lineN].lock.Unlock()
        la.lines[lineN].rehighlight = on
 }