mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-05 06:30:28 +09:00
Allow changes from external programs to be undone
We use a diff to be able to transform the buffer into an arbitrary string (usually when we reread the file after an external program such as gofmt has changed it) and still preserve undo/redo. Fixes #136
This commit is contained in:
@@ -155,11 +155,7 @@ func (b *Buffer) ReOpen() {
|
||||
messenger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
if txt == "" {
|
||||
b.r = new(rope.Rope)
|
||||
} else {
|
||||
b.r = rope.New(txt)
|
||||
}
|
||||
b.EventHandler.ApplyDiff(txt)
|
||||
|
||||
b.ModTime, _ = GetModTime(b.Path)
|
||||
b.IsModified = false
|
||||
|
||||
@@ -2,6 +2,8 @@ package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
dmp "github.com/sergi/go-diff/diffmatchpatch"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -55,6 +57,25 @@ func NewEventHandler(buf *Buffer) *EventHandler {
|
||||
return eh
|
||||
}
|
||||
|
||||
// ApplyDiff takes a string and runs the necessary insertion and deletion events to make
|
||||
// the buffer equal to that string
|
||||
// This means that we can transform the buffer into any string and still preserve undo/redo
|
||||
// through insert and delete events
|
||||
func (eh *EventHandler) ApplyDiff(new string) {
|
||||
messenger.Message("Applying diff")
|
||||
differ := dmp.New()
|
||||
diff := differ.DiffMain(eh.buf.String(), new, false)
|
||||
var charNum int
|
||||
for _, d := range diff {
|
||||
if d.Type == dmp.DiffInsert {
|
||||
eh.Insert(charNum, d.Text)
|
||||
} else if d.Type == dmp.DiffDelete {
|
||||
eh.Remove(charNum, charNum+Count(d.Text))
|
||||
}
|
||||
charNum += Count(d.Text)
|
||||
}
|
||||
}
|
||||
|
||||
// Insert creates an insert text event and executes it
|
||||
func (eh *EventHandler) Insert(start int, text string) {
|
||||
e := &TextEvent{
|
||||
|
||||
Reference in New Issue
Block a user