From 3426cb2d4a8214aad997f376a6ffc33edb598ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Bohusl=C3=A1vek?= Date: Fri, 11 Aug 2023 12:03:24 +0200 Subject: [PATCH 1/2] add support for body where last line does not end with \n --- acme.go | 19 ++++++++++++++----- apply.go | 12 ++++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/acme.go b/acme.go index fdc48a7..c224cda 100644 --- a/acme.go +++ b/acme.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "fmt" "io" "os" @@ -11,10 +12,12 @@ import ( "9fans.net/go/acme" ) +var nl = []byte("\n") + // We would use io.Copy except for a bug in acme // where it crashes when reading trying to read more // than the negotiated 9P message size. -func copyBody(w io.Writer, win *acme.Win) error { +func copyBody(w io.Writer, win *acme.Win) (endsWithNL bool, err error) { buf := make([]byte, 8000) for { n, err := win.Read("body", buf) @@ -22,13 +25,19 @@ func copyBody(w io.Writer, win *acme.Win) error { break } if err != nil { - return err + return false, err } - if _, err := w.Write(buf[0:n]); err != nil { - return fmt.Errorf("write error: %v", err) + if _, err := w.Write(buf[:n]); err != nil { + return false, fmt.Errorf("write error: %v", err) } + endsWithNL = bytes.HasSuffix(buf[:n], nl) } - return nil + if !endsWithNL { + if _, err := w.Write(nl); err != nil { + return false, fmt.Errorf("write error: %v", err) + } + } + return endsWithNL, nil } func acmeCurrentWin() (*acme.Win, error) { diff --git a/apply.go b/apply.go index d5ada7a..7d0e29d 100644 --- a/apply.go +++ b/apply.go @@ -46,7 +46,8 @@ func Main() error { if err != nil { return err } - if err := copyBody(bodyFile, win); err != nil { + endsWithNL, err := copyBody(bodyFile, win) + if err != nil { return err } bodyFile.Seek(0, 0) @@ -76,7 +77,7 @@ func Main() error { // return err // } // defer win.Write("ctl", []byte("mark")) - err = apply(diffOut, func(addr string, data []byte) error { + edit := func(addr string, data []byte) error { if _, err := win.Write("addr", []byte(addr)); err != nil { return fmt.Errorf("cannot set address %q: %v", addr, err) } @@ -84,10 +85,13 @@ func Main() error { return fmt.Errorf("cannot write data: %v", err) } return nil - }) - if err != nil { + } + if err := apply(diffOut, edit); err != nil { return err } + if !endsWithNL { + return edit(`$-/\n/`, nil) + } return nil } From d8256cb9f1278f87d68f487a4042a623cef301ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Bohusl=C3=A1vek?= Date: Fri, 11 Aug 2023 12:21:48 +0200 Subject: [PATCH 2/2] mark before nomark Still not perfect. It seems one has to Undo twice to have an effect. But it does undo it all at once. --- apply.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apply.go b/apply.go index 7d0e29d..580fc22 100644 --- a/apply.go +++ b/apply.go @@ -71,12 +71,13 @@ func Main() error { if err := pcmd.Start(); err != nil { return fmt.Errorf("cannot start %q: %v", cmdArgs[0], err) } - // TODO this doesn't appear to have the desired effect - - // changes made after "nomark" don't seem to be undoable. - // if _, err := win.Write("ctl", []byte("nomark")); err != nil { - // return err - // } - // defer win.Write("ctl", []byte("mark")) + if _, err := win.Write("ctl", []byte("mark")); err != nil { + return err + } + if _, err := win.Write("ctl", []byte("nomark")); err != nil { + return err + } + defer win.Write("ctl", []byte("mark")) edit := func(addr string, data []byte) error { if _, err := win.Write("addr", []byte(addr)); err != nil { return fmt.Errorf("cannot set address %q: %v", addr, err)