func cmd_cursor_type_pkg(c *rpc.Client) { var args, reply int var err error args = 0 err = c.Call("RPC.RPC_setid", &args, &reply) compl_id = reply compl_win, err = acme.Open(compl_id, nil) if err != nil { compl_win, _ = acme.New() args = compl_win.GetId() err = c.Call("RPC.RPC_setid", &args, &reply) } //for acme var src []byte var searchpos int var fname string if afile, err = acmeCurrentFile(); err != nil { fmt.Printf("%v", err) } fname, src, searchpos = afile.name, afile.body, afile.offset //for acme typ, pkg := client_cursor_type_pkg(c, src, fname, searchpos) fmt.Printf("%s,,%s\n", typ, pkg) }
func cmd_auto_complete(c *rpc.Client) { var env gocode_env env.get() var args, reply int var err error args = 0 err = c.Call("RPC.RPC_setid", &args, &reply) compl_id = reply compl_win, err = acme.Open(compl_id, nil) if err != nil { compl_win, _ = acme.New() args = compl_win.GetId() err = c.Call("RPC.RPC_setid", &args, &reply) } //for acme var src []byte var searchpos int var fname string if afile, err = acmeCurrentFile(); err != nil { fmt.Printf("%v", err) } fname, src, searchpos = afile.name, afile.body, afile.offset compl_win.Name("%v+completions", fname) compl_win.Addr(",") compl_win.Write("data", nil) //for acme write_candidates(client_auto_complete(c, src, fname, searchpos, env)) }
func main() { flag.Usage = show_usage flag.Parse() var retval int if *g_is_server { retval = do_server() os.Exit(retval) } else { retval = do_client() if needinsert { carrent_win.Addr("#%v,#%v", q0exp, q1exp) carrent_win.Write("data", insertfirst) _, q1exp, _ = carrent_win.ReadAddr() for e := range compl_win.EventChan() { if e.C1 == 'K' { inp := e.Text // compl_win.CloseFiles() ctl := carrent_win.Getctl() carrent_win, _ = acme.Open(77, ctl) carrent_win.Addr("#%v,#%v", q1exp, q1exp) carrent_win.Write("data", inp) carrent_win.Ctl("dot=addr") os.Exit(retval) } switch e.C2 { case 'x': // execute if string(e.Text) == "Del" { compl_win.Ctl("delete") } case 'L': insert := e.Text carrent_win.Addr("#%v,#%v", q0exp, q1exp) carrent_win.Write("data", insert) _, q1exp, _ = carrent_win.ReadAddr() } compl_win.WriteEvent(e) if e.C2 == 'D' { compl_win.WriteEvent(e) os.Exit(retval) } } } os.Exit(retval) } }
func acmeCurrentWin() (*acme.Win, error) { winid := os.Getenv("winid") if winid == "" { return nil, fmt.Errorf("$winid not set - not running inside acme?") } id, err := strconv.Atoi(winid) if err != nil { return nil, fmt.Errorf("invalid $winid %q", winid) } if err := setNameSpace(); err != nil { return nil, err } win, err := acme.Open(id, nil) if err != nil { return nil, fmt.Errorf("cannot open acme window: %v", err) } return win, nil }
func main() { log.SetFlags(0) log.SetPrefix("Run: ") file := os.Getenv("samfile") if file == "" { log.Fatal("not running in acme") } id, _ := strconv.Atoi(os.Getenv("winid")) wfile, err := acme.Open(id, nil) if err != nil { log.Fatal(err) } wfile.Ctl("put") wfile.CloseFiles() wname := "/go/run/" + strings.TrimSuffix(path.Base(file), ".go") windows, _ := acme.Windows() var w *acme.Win for _, info := range windows { if info.Name == wname { ww, err := acme.Open(info.ID, nil) if err != nil { log.Fatal(err) } ww.Addr(",") ww.Write("data", nil) w = ww break } } if w == nil { ww, err := acme.New() if err != nil { log.Fatal(err) } ww.Name(wname) w = ww } w.Ctl("clean") defer w.Ctl("clean") cmd := exec.Command("go", append([]string{"run", os.Getenv("samfile")}, os.Args[1:]...)...) cmd.Stdout = bodyWriter{w} cmd.Stderr = cmd.Stdout cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} err = cmd.Start() if err != nil { w.Fprintf("body", "error starting command: %v\n", err) return } //stop := blinker(w) w.Ctl("cleartag") w.Fprintf("tag", " Kill Stack") done := make(chan bool) go func() { err := cmd.Wait() if err != nil { w.Fprintf("body", "\nerror running command: %v\n", err) } //stop <- true done <- true }() deleted := make(chan bool, 1) go func() { for e := range w.EventChan() { if e.C2 == 'x' || e.C2 == 'X' { switch string(e.Text) { case "Del": select { case deleted <- true: default: } syscall.Kill(-cmd.Process.Pid, 2) continue case "Kill": syscall.Kill(-cmd.Process.Pid, 2) continue case "Stack": syscall.Kill(-cmd.Process.Pid, 3) continue } w.WriteEvent(e) } } }() <-done w.Ctl("cleartag") select { case <-deleted: w.Ctl("delete") default: } }
func reformat(id int, name string) { w, err := acme.Open(id, nil) if err != nil { log.Print(err) return } defer w.CloseFiles() old, err := ioutil.ReadFile(name) if err != nil { //log.Print(err) return } new, err := exec.Command("goimports", name).CombinedOutput() if err != nil { // Probably a syntax error, use the compiler for better message. // For now use 'go build file.go' and strip the package header. // We run it in /var/run so that paths do not get shortened // (assuming /var/run exists and no one is editing go files under that path). // A better fix to both would be to use go tool 6g, but we don't know // whether 6g is the right architecture. Could parse 'go env' output. // Or maybe the go command should have 'go tool compile' and 'go tool link'. cmd := exec.Command("go", "build", name) cmd.Dir = "/var/run" out, _ := cmd.CombinedOutput() start := []byte("# command-line-arguments\n") if !bytes.HasPrefix(out, start) { fmt.Fprintf(os.Stderr, "goimports %s: %v\n%s", name, err, new) return } fmt.Fprintf(os.Stderr, "%s", out) return } if bytes.Equal(old, new) { return } if !*gofmt { oldTop, err := readImports(bytes.NewReader(old), true) if err != nil { //log.Print(err) return } newTop, err := readImports(bytes.NewReader(new), true) if err != nil { //log.Print(err) return } if bytes.Equal(oldTop, newTop) { return } w.Addr("0,#%d", utf8.RuneCount(oldTop)) w.Write("data", newTop) return } f, err := ioutil.TempFile("", "acmego") if err != nil { log.Print(err) return } if _, err := f.Write(new); err != nil { log.Print(err) return } tmp := f.Name() f.Close() defer os.Remove(tmp) diff, _ := exec.Command("9", "diff", name, tmp).CombinedOutput() w.Write("ctl", []byte("mark")) w.Write("ctl", []byte("nomark")) diffLines := strings.Split(string(diff), "\n") for i := len(diffLines) - 1; i >= 0; i-- { line := diffLines[i] if line == "" { continue } if line[0] == '<' || line[0] == '-' || line[0] == '>' { continue } j := 0 for j < len(line) && line[j] != 'a' && line[j] != 'c' && line[j] != 'd' { j++ } if j >= len(line) { log.Printf("cannot parse diff line: %q", line) break } oldStart, oldEnd := parseSpan(line[:j]) newStart, newEnd := parseSpan(line[j+1:]) if oldStart == 0 || newStart == 0 { continue } switch line[j] { case 'a': err := w.Addr("%d+#0", oldStart) if err != nil { log.Print(err) break } w.Write("data", findLines(new, newStart, newEnd)) case 'c': err := w.Addr("%d,%d", oldStart, oldEnd) if err != nil { log.Print(err) break } w.Write("data", findLines(new, newStart, newEnd)) case 'd': err := w.Addr("%d,%d", oldStart, oldEnd) if err != nil { log.Print(err) break } w.Write("data", nil) } } }