Permalink
Browse files

Emacs flymake-mode for golang

  • Loading branch information...
0 parents commit 30826f97eed14bc703f5683a6e4eb023a3b57008 @dougm committed Aug 8, 2012
Showing with 118 additions and 0 deletions.
  1. +32 −0 README.md
  2. +31 −0 go-flymake.el
  3. +55 −0 main.go
@@ -0,0 +1,32 @@
+## Emacs flymake-mode for the Go programming language
+
+The `goflymake` program is a wrapper around the `go` tool to provide
+Emacs flymake style syntax checking for golang source files within
+multi-file packages and _test.go files. Support for os/arch specific
+*cgo* files is included thanks to the standard *go/build* package.
+
+### Setup
+
+ 1. If needed, update your **$PATH** to include go installed binaries, for example:
+
+ `export PATH=$PATH:$GOPATH/bin`
+
+ 2. Install goflymake:
+
+ `go get -u github.com/dougm/goflymake`
+
+### Emacs setup
+
+ 1. Install go-mode.el if you haven't already
+
+ 2. Add these lines to your **.emacs** or similar:
+
+ (add-to-list 'load-path "~/gocode/src/github.com/dougm/goflymake")
+ (require 'go-flymake)
+
+### ToDo
+
+We probably shouldn't need the `goflymake` program, the `go` tool could
+be tweaked to support the flymake style of syntax checking.
+Maybe there is already a better way, but I couldn't find one.
+
@@ -0,0 +1,31 @@
+(eval-when-compile
+ (require 'go-mode)
+ (require 'flymake))
+
+;; flymake.el's flymake-create-temp-inplace appends a
+;; '_flymake' suffix to file-name.
+;; this version prepends a 'flymake_' prefix, since the go tools look
+;; at suffix for '_test', '_$goos', etc.
+(defun goflymake-create-temp-inplace (file-name prefix)
+ (unless (stringp file-name)
+ (error "Invalid file-name"))
+ (or prefix
+ (setq prefix "flymake"))
+ (let* ((temp-name (concat (file-name-directory file-name)
+ prefix "_" (file-name-nondirectory file-name))))
+ (flymake-log 3 "create-temp-inplace: file=%s temp=%s" file-name temp-name)
+ temp-name))
+
+(defun goflymake-init ()
+ (let* ((temp-file (flymake-init-create-temp-buffer-copy
+ 'goflymake-create-temp-inplace))
+ (local-file (file-relative-name
+ temp-file
+ (file-name-directory buffer-file-name))))
+ (list "goflymake" (list temp-file))))
+
+(push '(".+\\.go$" goflymake-init) flymake-allowed-file-name-masks)
+
+(add-hook 'go-mode-hook 'flymake-mode)
+
+(provide 'go-flymake)
55 main.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+ "fmt"
+ "go/build"
+ "os"
+ "os/exec"
+ "path"
+ "strings"
+)
+
+const prefix = "flymake_"
+
+func main() {
+ file := os.Args[len(os.Args)-1]
+ sdir := path.Dir(file)
+ base := path.Base(file)
+ orig := base[len(prefix):]
+
+ isTest := false
+ var args []string
+
+ if strings.HasSuffix(orig, "_test.go") {
+ isTest = true
+ // shame there is no '-o' option
+ args = append(args, "test", "-c")
+ } else {
+ args = append(args, "build", "-o", "/dev/null")
+ }
+
+ pkg, err := build.ImportDir(sdir, build.AllowBinary)
+
+ if err != nil {
+ args = append(args, file)
+ } else {
+ var files []string
+ files = append(files, pkg.GoFiles...)
+ files = append(files, pkg.CgoFiles...)
+ if isTest {
+ files = append(files, pkg.TestGoFiles...)
+ }
+
+ for _, f := range files {
+ if f == orig {
+ continue
+ }
+ args = append(args, f)
+ }
+ }
+
+ cmd := exec.Command("go", args...)
+ out, _ := cmd.CombinedOutput()
+
+ fmt.Print(string(out))
+}

0 comments on commit 30826f9

Please sign in to comment.