func bodyDiff(win *acme.Win, ffile string) (bool, error) { tf, err := os.Open(ffile) if err != nil { return false, err } defer tf.Close() win.Seek("body", 0, 0) fr := bufio.NewReader(tf) br := bufio.NewReader(&bodyReader{win}) for { fb, errf := fr.ReadByte() if errf != nil && errf != io.EOF { return false, errf } bb, errb := br.ReadByte() if errb != nil && errb != io.EOF { return false, errb } if fb != bb { return true, nil } if errf == io.EOF && errb == io.EOF { return false, nil } } }
func readFilename(win *acme.Win) (string, error) { b, err := win.ReadAll("tag") if err != nil { return "", err } tag := string(b) i := strings.Index(tag, " ") if i == -1 { return "", fmt.Errorf("cannot get filename from tag") } return tag[0:i], nil }
func events(win *acme.Win, rerun chan<- struct{}) { for e := range win.EventChan() { debugPrint("Acme event: %+v\n", e) switch e.C2 { case 'x', 'X': switch string(e.Text) { case "Get": kill() rerun <- struct{}{} case "Del": kill() if err := win.Ctl("delete"); err != nil { log.Fatalln("Failed to delete the window:", err) } default: win.WriteEvent(e) } default: win.WriteEvent(e) } } os.Exit(0) }
// We would use win.ReadAll except for a bug in acme // where it crashes when reading trying to read more // than the negotiated 9P message size. func readBody(win *acme.Win) ([]byte, error) { var body []byte buf := make([]byte, 8000) for { n, err := win.Read("body", buf) if err == io.EOF { break } if err != nil { return nil, err } body = append(body, buf[0:n]...) } return body, nil }
// 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 { buf := make([]byte, 8000) for { n, err := win.Read("body", buf) if err == io.EOF { break } if err != nil { return err } if _, err := w.Write(buf[0:n]); err != nil { return fmt.Errorf("write error: %v", err) } } return nil }
func writeEvents(w *acme.Win, wg *sync.WaitGroup) { defer wg.Done() for { select { case e, ok := <-w.EventChan(): if !ok { return } w.WriteEvent(e) if string(e.Text) == "Del" { return } } } }
func writeData(win *acme.Win, data []byte) error { if len(data) == 0 { _, err := win.Write("data", nil) return err } for len(data) > 0 { d := data if len(d) > 8000 { d = trimIncompleteRune(d[0:8000]) } n, err := win.Write("data", d) if err != nil { return err } data = data[n:] } return nil }
func events(w *acme.Win) <-chan string { c := make(chan string, 10) go func() { for e := range w.EventChan() { switch e.C2 { case 'x', 'X': // execute if string(e.Text) == "Del" { w.Ctl("delete") } w.WriteEvent(e) case 'l', 'L': // look w.Ctl("clean") c <- string(e.Text) } } w.CloseFiles() close(c) }() return c }
func reloadShowAddr(win *acme.Win, off int) error { if err := win.Ctl("get"); err != nil { return err } if err := win.Addr("#%d", off); err != nil { return err } return win.Ctl("dot=addr\nshow") }
func readAddr(win *acme.Win) (q0, q1 int, err error) { if _, _, err := win.ReadAddr(); err != nil { return 0, 0, err } if err := win.Ctl("addr=dot"); err != nil { return 0, 0, err } return win.ReadAddr() }
func readAddr(win *acme.Win) (q0, q1 int, err error) { // This first read is bogus. // Acme zeroes the win's address the first time addr is opened. // So, we need to open it before setting addr=dot, // lest we just read back a zero address. if _, _, err := win.ReadAddr(); err != nil { return 0, 0, err } if err := win.Ctl("addr=dot\n"); err != nil { return 0, 0, err } return win.ReadAddr() }
func writeBody(win *acme.Win, ffile string) error { if err := win.Ctl("nomark"); err != nil { fmt.Fprintf(os.Stderr, "failed to set nomark: %s", err) } defer func() { if err := win.Ctl("mark"); err != nil { fmt.Fprintf(os.Stderr, "failed to set mark: %s", err) } }() tf, err := os.Open(ffile) if err != nil { return err } defer tf.Close() if err := win.Addr("0,$"); err != nil { return err } _, err = io.Copy(dataWriter{win}, tf) return err }
func selection(win *acme.Win, body []byte) (int, int, error) { if _, _, err := win.ReadAddr(); err != nil { return 0, 0, err } if err := win.Ctl("addr=dot"); err != nil { return 0, 0, err } q0, q1, err := win.ReadAddr() if err != nil { return 0, 0, err } off0, err := byteOff(q0, bytes.NewReader(body)) if err != nil { return 0, 0, err } off1, err := byteOff(q1, bytes.NewReader(body)) if err != nil { return 0, 0, err } return off0, off1, nil }
func showAddr(win *acme.Win, q0, q1 int) error { if err := win.Addr("#%d,#%d", q0, q1); err != nil { return err } return win.Ctl("dot=addr\nshow\n") }