github.com/jmigpin/editor@v1.6.0/util/iout/iorw/rwundo/rwundo.go (about)

     1  package rwundo
     2  
     3  import (
     4  	"github.com/jmigpin/editor/util/iout/iorw"
     5  	"github.com/jmigpin/editor/util/iout/iorw/rwedit"
     6  )
     7  
     8  type RWUndo struct {
     9  	iorw.ReadWriterAt
    10  	History *History
    11  }
    12  
    13  func NewRWUndo(rw iorw.ReadWriterAt, hist *History) *RWUndo {
    14  	rwu := &RWUndo{ReadWriterAt: rw, History: hist}
    15  	return rwu
    16  }
    17  
    18  //----------
    19  
    20  func (rw *RWUndo) OverwriteAt(i, n int, p []byte) error {
    21  	// don't add to history if the result is equal
    22  	changed := true
    23  	if eq, err := iorw.REqual(rw, i, n, p); err == nil && eq {
    24  		changed = false
    25  	}
    26  
    27  	ur, err := NewUndoRedoOverwrite(rw.ReadWriterAt, i, n, p)
    28  	if err != nil {
    29  		return err
    30  	}
    31  
    32  	if changed {
    33  		edits := &Edits{}
    34  		edits.Append(ur)
    35  		rw.History.Append(edits)
    36  	}
    37  	return nil
    38  }
    39  
    40  //----------
    41  
    42  func (rw *RWUndo) UndoRedo(redo, peek bool) (rwedit.SimpleCursor, bool, error) {
    43  	edits, ok := rw.History.UndoRedo(redo, peek)
    44  	if !ok {
    45  		return rwedit.SimpleCursor{}, false, nil
    46  	}
    47  	c, err := edits.WriteUndoRedo(redo, rw.ReadWriterAt)
    48  	if err != nil {
    49  		// TODO: restore the undo/redo since it was not successful?
    50  		return rwedit.SimpleCursor{}, false, err
    51  	}
    52  	return c, true, nil
    53  }
    54  
    55  //----------
    56  
    57  // used in tests
    58  func (rw *RWUndo) undo() (rwedit.SimpleCursor, bool, error) {
    59  	return rw.UndoRedo(false, false)
    60  }
    61  func (rw *RWUndo) redo() (rwedit.SimpleCursor, bool, error) {
    62  	return rw.UndoRedo(true, false)
    63  }