Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# binaries
/editinacme

# clutter
.DS_Store
.localized

# Everybody has their own so don't check in by accident.
guide
70 changes: 59 additions & 11 deletions acme/editinacme/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,34 @@
//
// Usage:
//
// editinacme <file>
// editinacme [-nw] <file>
//
// Editinacme uses the plumber to ask acme to open the file,
// waits until the file's acme window is deleted, and exits.
// Editinacme uses the plumber to ask acme to open the file, waits until
// the file's acme window is deleted, and exits. Use the -nw flag to exit
// immediately after opening the file.
package main

import (
"bufio"
"flag"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"

"9fans.net/go/acme"
"9fans.net/go/plan9"
"9fans.net/go/plumb"
)

func main() {
log.SetFlags(0)
log.SetPrefix("editinacme: ")

nowait := flag.Bool("nw", false, "Don't wait for Acme to close the file")

flag.Usage = func() {
fmt.Fprintf(os.Stderr, "usage: editinacme file\n")
os.Exit(2)
Expand All @@ -47,21 +55,61 @@ func main() {
if err != nil {
log.Fatal(err)
}
defer r.Close()

log.Printf("editing %s", file)
filenamechan := make(chan string)
if !*nowait {
fid, err := plumb.Open("edit", plan9.OREAD)
if err != nil {
log.Fatalf("can't open plumber: %v", err)
}
defer fid.Close()
brd := bufio.NewReader(fid)
m := new(plumb.Message)

go func() {
for {
err := m.Recv(brd)
if err != nil {
log.Fatalf("recv: %s", err)
}
if filename, likelymy := likelymyplumbrequest(m, file); likelymy {
filenamechan <- filename
return
}
}
}()
}

log.Printf("editing %s", file)
out, err := exec.Command("plumb", "-d", "edit", file).CombinedOutput()
if err != nil {
log.Fatalf("executing plumb: %v\n%s", err, out)
}

for {
ev, err := r.Read()
if err != nil {
log.Fatalf("reading acme log: %v", err)
}
if ev.Op == "del" && ev.Name == file {
break
if !*nowait {
filename := <-filenamechan
for {
ev, err := r.Read()
if err != nil {
log.Fatalf("reading acme log: %v", err)
}
if ev.Op == "del" && ev.Name == filename {
break
}
}
}
}

// likelymyplumbrequest applies some heuristics to determine if this
// message likely corresponds to the just made plumb edit request and
// returns the filename that the plumber asked Acme to open.
func likelymyplumbrequest(msg *plumb.Message, arg string) (string, bool) {
cwd, err := os.Getwd()
if err != nil {
log.Fatalf("aww shucks! %v", err)
}
plumbedfname := string(msg.Data)
myreq := (msg.Dir == cwd && strings.HasPrefix(arg, plumbedfname))
return plumbedfname, myreq
}