Skip to content

Commit f938f62

Browse files
committed
Make isModified reflect actual modified/unmodified state of buffer
Instead of calculating the hash of the buffer every time Modified() is called, do that every time b.isModified is updated (i.e. every time the buffer is modified) and set b.isModified value accordingly. This change means that the hash will be recalculated every time the user types or deletes a character. But that is what already happens anyway, since inserting or deleting characters triggers redrawing the display, in particular redrawing the status line, which triggers Modified() in order to show the up-to-date modified/unmodified status in the status line. And with this change, we will be able to check this status more than once during a single "handle event & redraw" cycle, while still recalculating the hash only once.
1 parent 4ade5cd commit f938f62

File tree

4 files changed

+24
-23
lines changed

4 files changed

+24
-23
lines changed

internal/buffer/backup.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (b *Buffer) ApplyBackup(fsize int64) (bool, bool) {
125125
if choice%3 == 0 {
126126
// recover
127127
b.LineArray = NewLineArray(uint64(fsize), FFAuto, backup)
128-
b.isModified = true
128+
b.setModified()
129129
return true, true
130130
} else if choice%3 == 1 {
131131
// delete

internal/buffer/buffer.go

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -126,20 +126,36 @@ type SharedBuffer struct {
126126
}
127127

128128
func (b *SharedBuffer) insert(pos Loc, value []byte) {
129-
b.isModified = true
130129
b.HasSuggestions = false
131130
b.LineArray.insert(pos, value)
131+
b.setModified()
132132

133133
inslines := bytes.Count(value, []byte{'\n'})
134134
b.MarkModified(pos.Y, pos.Y+inslines)
135135
}
136+
136137
func (b *SharedBuffer) remove(start, end Loc) []byte {
137-
b.isModified = true
138138
b.HasSuggestions = false
139+
defer b.setModified()
139140
defer b.MarkModified(start.Y, end.Y)
140141
return b.LineArray.remove(start, end)
141142
}
142143

144+
func (b *SharedBuffer) setModified() {
145+
if b.Type.Scratch {
146+
return
147+
}
148+
149+
if b.Settings["fastdirty"].(bool) {
150+
b.isModified = true
151+
} else {
152+
var buff [md5.Size]byte
153+
154+
b.calcHash(&buff)
155+
b.isModified = buff != b.origHash
156+
}
157+
}
158+
143159
// calcHash calculates md5 hash of all lines in the buffer
144160
func (b *SharedBuffer) calcHash(out *[md5.Size]byte) {
145161
h := md5.New()
@@ -653,18 +669,7 @@ func (b *Buffer) Shared() bool {
653669
// Modified returns if this buffer has been modified since
654670
// being opened
655671
func (b *Buffer) Modified() bool {
656-
if b.Type.Scratch {
657-
return false
658-
}
659-
660-
if b.Settings["fastdirty"].(bool) {
661-
return b.isModified
662-
}
663-
664-
var buff [md5.Size]byte
665-
666-
b.calcHash(&buff)
667-
return buff != b.origHash
672+
return b.isModified
668673
}
669674

670675
// Size returns the number of bytes in the current buffer
@@ -1233,7 +1238,6 @@ func (b *Buffer) FindMatchingBrace(start Loc) (Loc, bool, bool) {
12331238
func (b *Buffer) Retab() {
12341239
toSpaces := b.Settings["tabstospaces"].(bool)
12351240
tabsize := util.IntOpt(b.Settings["tabsize"])
1236-
dirty := false
12371241

12381242
for i := 0; i < b.LinesNum(); i++ {
12391243
l := b.LineBytes(i)
@@ -1254,10 +1258,9 @@ func (b *Buffer) Retab() {
12541258
b.Unlock()
12551259

12561260
b.MarkModified(i, i)
1257-
dirty = true
12581261
}
12591262

1260-
b.isModified = dirty
1263+
b.setModified()
12611264
}
12621265

12631266
// ParseCursorLocation turns a cursor location like 10:5 (LINE:COL)

internal/buffer/save.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,7 @@ func (b *Buffer) Save() error {
206206

207207
// AutoSave saves the buffer to its default path
208208
func (b *Buffer) AutoSave() error {
209-
// Doing full b.Modified() check every time would be costly, due to the hash
210-
// calculation. So use just isModified even if fastdirty is not set.
211-
if !b.isModified {
209+
if !b.Modified() {
212210
return nil
213211
}
214212
return b.saveToFile(b.Path, false, true)

internal/buffer/settings.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func (b *Buffer) DoSetOptionNative(option string, nativeValue interface{}) {
9191
case "dos":
9292
b.Endings = FFDos
9393
}
94-
b.isModified = true
94+
b.setModified()
9595
} else if option == "syntax" {
9696
if !nativeValue.(bool) {
9797
b.ClearMatches()
@@ -105,7 +105,7 @@ func (b *Buffer) DoSetOptionNative(option string, nativeValue interface{}) {
105105
b.Settings["encoding"] = "utf-8"
106106
}
107107
b.encoding = enc
108-
b.isModified = true
108+
b.setModified()
109109
} else if option == "readonly" && b.Type.Kind == BTDefault.Kind {
110110
b.Type.Readonly = nativeValue.(bool)
111111
} else if option == "hlsearch" {

0 commit comments

Comments
 (0)