Skip to content

Commit

Permalink
Merge pull request #3291 from dmaluka/diffgutter-cleanup
Browse files Browse the repository at this point in the history
Diffgutter: simplify + fix race
  • Loading branch information
dmaluka committed May 14, 2024
2 parents b70f0eb + 5a159ce commit 9176508
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 31 deletions.
4 changes: 1 addition & 3 deletions internal/action/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1480,9 +1480,7 @@ func (h *BufPane) HalfPageDown() bool {
func (h *BufPane) ToggleDiffGutter() bool {
if !h.Buf.Settings["diffgutter"].(bool) {
h.Buf.Settings["diffgutter"] = true
h.Buf.UpdateDiff(func(synchronous bool) {
screen.Redraw()
})
h.Buf.UpdateDiff()
InfoBar.Message("Enabled diff gutter")
} else {
h.Buf.Settings["diffgutter"] = false
Expand Down
33 changes: 17 additions & 16 deletions internal/buffer/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ func (b *Buffer) Write(bytes []byte) (n int, err error) {
return len(bytes), nil
}

func (b *Buffer) updateDiffSync() {
func (b *Buffer) updateDiff(synchronous bool) {
b.diffLock.Lock()
defer b.diffLock.Unlock()

Expand All @@ -1291,7 +1291,16 @@ func (b *Buffer) updateDiffSync() {
}

differ := dmp.New()
baseRunes, bufferRunes, _ := differ.DiffLinesToRunes(string(b.diffBase), string(b.Bytes()))

if !synchronous {
b.Lock()
}
bytes := b.Bytes()
if !synchronous {
b.Unlock()
}

baseRunes, bufferRunes, _ := differ.DiffLinesToRunes(string(b.diffBase), string(bytes))
diffs := differ.DiffMainRunes(baseRunes, bufferRunes, false)
lineN := 0

Expand Down Expand Up @@ -1320,13 +1329,9 @@ func (b *Buffer) updateDiffSync() {

// UpdateDiff computes the diff between the diff base and the buffer content.
// The update may be performed synchronously or asynchronously.
// UpdateDiff calls the supplied callback when the update is complete.
// The argument passed to the callback is set to true if and only if
// the update was performed synchronously.
// If an asynchronous update is already pending when UpdateDiff is called,
// UpdateDiff does not schedule another update, in which case the callback
// is not called.
func (b *Buffer) UpdateDiff(callback func(bool)) {
// UpdateDiff does not schedule another update.
func (b *Buffer) UpdateDiff() {
if b.updateDiffTimer != nil {
return
}
Expand All @@ -1337,20 +1342,18 @@ func (b *Buffer) UpdateDiff(callback func(bool)) {
}

if lineCount < 1000 {
b.updateDiffSync()
callback(true)
b.updateDiff(true)
} else if lineCount < 30000 {
b.updateDiffTimer = time.AfterFunc(500*time.Millisecond, func() {
b.updateDiffTimer = nil
b.updateDiffSync()
callback(false)
b.updateDiff(false)
screen.Redraw()
})
} else {
// Don't compute diffs for very large files
b.diffLock.Lock()
b.diff = make(map[int]DiffStatus)
b.diffLock.Unlock()
callback(true)
}
}

Expand All @@ -1362,9 +1365,7 @@ func (b *Buffer) SetDiffBase(diffBase []byte) {
} else {
b.diffBaseLineCount = strings.Count(string(diffBase), "\n")
}
b.UpdateDiff(func(synchronous bool) {
screen.Redraw()
})
b.UpdateDiff()
}

// DiffStatus returns the diff status for a line in the buffer
Expand Down
13 changes: 1 addition & 12 deletions internal/display/bufwindow.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,18 +384,7 @@ func (w *BufWindow) displayBuffer() {

if b.ModifiedThisFrame {
if b.Settings["diffgutter"].(bool) {
b.UpdateDiff(func(synchronous bool) {
// If the diff was updated asynchronously, the outer call to
// displayBuffer might already be completed and we need to
// schedule a redraw in order to display the new diff.
// Note that this cannot lead to an infinite recursion
// because the modifications were cleared above so there won't
// be another call to UpdateDiff when displayBuffer is called
// during the redraw.
if !synchronous {
screen.Redraw()
}
})
b.UpdateDiff()
}
b.ModifiedThisFrame = false
}
Expand Down

0 comments on commit 9176508

Please sign in to comment.