func (e move) do(ed *Editor, _ io.Writer) (addr, error) { s, err := e.src.where(ed) if err != nil { return addr{}, err } d, err := e.dst.where(ed) if err != nil { return addr{}, err } d.from = d.to if d.from > s.from && d.from < s.to { return addr{}, errors.New("addresses overlap") } if d.from >= s.to { // Moving to after the source. Delete the source first. if err := pend(ed, s, runes.EmptyReader()); err != nil { return addr{}, err } } r := runes.LimitReader(ed.buf.runes.Reader(s.from), s.size()) if err := pend(ed, d, r); err != nil { return addr{}, err } if d.from <= s.from { // Moving to before the source. Delete the source second. if err := pend(ed, s, runes.EmptyReader()); err != nil { return addr{}, err } } return d, nil }
// Data returns the entry's data. func (e entry) data() runes.Reader { if e.err != nil { panic("data called on the end iterator") } from := e.offs + headerRunes return runes.LimitReader(e.l.buf.Reader(from), e.size) }
func (e print) do(ed *Editor, w io.Writer) (addr, error) { at, err := e.a.where(ed) if err != nil { return addr{}, err } r := runes.LimitReader(ed.buf.runes.Reader(at.from), at.size()) if _, err := runes.Copy(runes.UTF8Writer(w), r); err != nil { return addr{}, err } return at, nil }
func (e cpy) do(ed *Editor, _ io.Writer) (addr, error) { s, err := e.src.where(ed) if err != nil { return addr{}, err } d, err := e.dst.where(ed) if err != nil { return addr{}, err } d.from = d.to r := runes.LimitReader(ed.buf.runes.Reader(s.from), s.size()) return d, pend(ed, d, r) }
// Do applies changes to an Editor's Buffer. // // Changes are applied in two phases: // Phase one logs the changes without modifying the Buffer. // Phase two applies the changes to the Buffer. // The two phases occur with the buffer Lock held. // // The f function performs phase one. // It is called with the Editor's pending log cleared. // It will typically append changes to the Editor's pending log // and/or modify the Editor's marks. // In the case of an error, the marks are restored // to their values before any changes were made. // // The f function must return the address // over which changes were computed. // This address is used to compute and set dot // after the changes are applied. func (ed *Editor) do(f func() (addr, error)) error { ed.buf.Lock() defer ed.buf.Unlock() marks0 := make(map[rune]addr, len(ed.marks)) for r, a := range ed.marks { marks0[r] = a } defer func() { ed.marks = marks0 }() if err := ed.pending.clear(); err != nil { return err } at, err := f() if err != nil { return err } if at, err = fixAddrs(at, ed.pending); err != nil { return err } if err := ed.buf.redo.clear(); err != nil { return err } for e := logFirst(ed.pending); !e.end(); e = e.next() { undoAt := addr{from: e.at.from, to: e.at.from + e.size} undoSrc := ed.buf.runes.Reader(e.at.from) undoSrc = runes.LimitReader(undoSrc, e.at.size()) if err := ed.buf.undo.append(ed.buf.seq, undoAt, undoSrc); err != nil { return err } if err := ed.buf.change(e.at, e.data()); err != nil { // TODO(eaburns): Very bad; what should we do? return err } } ed.buf.seq++ ed.marks['.'] = at marks0 = ed.marks return err }
// Undo1 undoes the most recent // sequence of changes. // A sequence of changes is one in which // all changes have the same seq. // It returns the address that covers // all changes in the sequence. // If nothing is undone, dot is returned. func (ed *Editor) undo1() (addr, error) { e := logLast(ed.buf.undo) if e.end() { return ed.marks['.'], nil } for { prev := e.prev() if prev.end() || prev.seq != e.seq { break } e = prev } all := addr{from: ed.buf.size() + 1, to: -1} start := e for !e.end() { redoAt := addr{from: e.at.from, to: e.at.from + e.size} redoSrc := ed.buf.runes.Reader(e.at.from) redoSrc = runes.LimitReader(redoSrc, e.at.size()) if err := ed.buf.redo.append(ed.buf.seq, redoAt, redoSrc); err != nil { return addr{}, err } // There is no need to call all.update, // because changes always apply // in sequence of increasing addresses. if e.at.from < all.from { all.from = e.at.from } if to := e.at.from + e.size; to > all.to { all.to = to } if err := ed.buf.change(e.at, e.data()); err != nil { return addr{}, err } e = e.next() } return all, start.pop() }
func (e pipe) do(ed *Editor, w io.Writer) (addr, error) { at, err := e.a.where(ed) if err != nil { return addr{}, err } cmd := exec.Command(shell(), "-c", e.cmd) cmd.Stderr = w if e.to { r := ed.buf.runes.Reader(at.from) r = runes.LimitReader(r, at.size()) cmd.Stdin = runes.UTF8Reader(r) } if !e.from { cmd.Stdout = w if err := cmd.Run(); err != nil { return addr{}, err } return at, nil } r, err := cmd.StdoutPipe() if err != nil { return addr{}, err } if err := cmd.Start(); err != nil { return addr{}, err } pendErr := pend(ed, at, runes.RunesReader(bufio.NewReader(r))) if err = cmd.Wait(); err != nil { return addr{}, err } if pendErr != nil { return addr{}, pendErr } return at, nil }