Giter Site home page Giter Site logo

go-mode.el's Introduction

This is go-mode, the Emacs mode for editing Go code.

It is a complete rewrite of the go-mode that shipped with Go 1.0.3 and before, and was part of Go 1.1 until Go 1.3. Beginning with Go 1.4, editor integration will not be part of the Go distribution anymore, making this repository the canonical place for go-mode.

Features

In addition to normal features, such as fontification and indentation, and close integration with familiar Emacs functionality (for example syntax-based navigation like beginning-of-defun), go-mode comes with the following extra features to provide an improved experience:

  • Integration with gofmt by providing a command of the same name, and gofmt-before-save, which can be used in a hook to format Go buffers before saving them.

    • Setting the gofmt-command variable also allows using goimports.
    • Setting the gofmt-args variable with a list of arguments allows using e.g. gofmt -s.
  • Integration with godoc via the functions godoc and godoc-at-point.

  • Integration with the Playground

    • go-play-buffer and go-play-region to send code to the Playground
    • go-download-play to download a Playground entry into a new buffer
  • Managing imports

    • A function for jumping to the file's imports (go-goto-imports - C-c C-f i)
    • A function for adding imports, including tab completion (go-import-add, bound to C-c C-a)
    • It is recommended that you use goimports or the organize-imports feature of gopls to manage adding/removing/organizing imports automatically.
  • Integration with godef

    • godef-describe (C-c C-d) to describe expressions
    • godef-jump (C-c C-j) and godef-jump-other-window (C-x 4 C-c C-j) to jump to declarations
    • This requires you to install godef via go install github.com/rogpeppe/godef@latest.
  • Basic support for imenu (functions and variables)

  • Built-in support for displaying code coverage as calculated by go test (go-coverage)

  • Several functions for jumping to and manipulating the individual parts of function signatures. These functions support anonymous functions, but are smart enough to skip them when required (e.g. when jumping to a method receiver or docstring.)

    • Jump to the argument list (go-goto-arguments - C-c C-f a)
    • Jump to the docstring, create it if it does not exist yet (go-goto-docstring - C-c C-f d).
    • Jump to the function keyword (go-goto-function - C-c C-f f)
    • Jump to the function name (go-goto-function-name - C-c C-f n)
    • Jump to the return values (go-goto-return-values - C-c C-f r)
    • Jump to the method receiver, adding a pair of parentheses if no method receiver exists (go-goto-method-receiver - C-c C-f m).

    All of these functions accept a prefix argument (C-u), causing them to skip anonymous functions.

Installation

MELPA

The recommended way of installing go-mode is via ELPA, the Emacs package manager, and the MELPA Stable repository, which provides an up-to-date version of go-mode.

If you're not familiar with ELPA yet, consider reading this guide.

Manual

To install go-mode manually, check out the go-mode.el repository in a directory of your choice, add it to your load path and configure Emacs to automatically load it when opening a .go file:

(add-to-list 'load-path "/place/where/you/put/it/")
(autoload 'go-mode "go-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.go\\'" . go-mode))

Either evaluate the statements with C-x C-e, or restart Emacs.

Other extensions

There are several third party extensions that can enhance the Go experience in Emacs.

Gopls integration

Gopls is the official language server protocol (lsp) implementation provided by the Go team. It is intended to replace the existing third party tools for code formatting (gofmt), automatic imports (goimports), code navigation (godef/guru), type and function descriptions (godoc/godef), error checking, auto completion (gocode), variable and type renaming (rename), and more. Once gopls is stable the older tools will no longer be supported.

Gopls is a supported backend for lsp-mode. It will be used automatically by lsp-mode if gopls is found in your PATH. You can install gopls via: go install golang.org/x/tools/gopls@latest. To enable lsp-mode for go buffers:

(add-hook 'go-mode-hook 'lsp-deferred)

Syntax/error checking

There are two ways of using flymake with Go:

  1. goflymake, which internally uses go build to capture all errors that a regular compilation would also produce
  2. flymake-go for a more lightweight solution that only uses gofmt and as such is only able to catch syntax errors. Unlike goflymake, however, it does not require an additional executable.

Additionally, there is flycheck, a modern replacement for flymake, which comes with built-in support for Go. In addition to using go build or gofmt, it also has support for go vet, golint and errcheck.

Auto completion

For auto completion, take a look at gocode.

eldoc

https://github.com/syohex/emacs-go-eldoc provides eldoc functionality for go-mode.

Snippets

I maintain a set of YASnippet snippets for go-mode at https://github.com/dominikh/yasnippet-go

Integration with errcheck

https://github.com/dominikh/go-errcheck.el provides integration with errcheck.

Stability

go-mode.el has regular, tagged releases and is part of the MELPA Stable repository. These tagged releases are intended to provide a stable experience. APIs added in tagged releases will usually not be removed or changed in future releases.

Changes made on the master branch, which is tracked by the normal MELPA repository, however, are under active development. New APIs are experimental and may be changed or removed before the next release. Furthermore, there is a higher chance for bugs.

If you want a stable experience, use MELPA Stable. If you want cutting edge features, or "beta-test" future releases, use MELPA or the master branch.

go-mode.el's People

Contributors

adg avatar adonovan avatar aeronotix avatar buzztaiki avatar dominikh avatar imsodin avatar jmhodges avatar jvshahid avatar kostya-sh avatar miciah avatar muirdm avatar olivia5k avatar petergardfjall avatar phst avatar pierre-rouleau avatar psanford avatar ruediger avatar rui314 avatar sajmani avatar samwagg avatar sergeyklay avatar sfllaw avatar skangas avatar syohex avatar vchimishuk avatar wg avatar wilfred avatar xuchunyang avatar yasuyk avatar yuezhu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-mode.el's Issues

Split Window Remains After Error Buffer Killed

I'm new to emacs, so if this is standard emacs behavior, that's fine. If there's a conventional way to make it close the buffer, please let me know.

Steps to reproduce:

  1. open a go file in a single window buffer
  2. introduce a syntax error to the file
  3. M-x gofmt or C-x C-s with the the before-save-hook
  4. Error buffer shown
  5. fix formatting error and perform step 3 again.

Expected behavior: Error buffer killed and window split removed

Actual behavior: Error buffer killed and window split remains

incorrect indentation after multi-line function call

go-mode incorrectly indents the line following a multi-line function call (at least, in certain circumstances). Example code, as gofmt formats it:

func f() {
    g(someSillyLongExpression(param1, param2, param3),
        "boo")
    x := 42
}

Expected behaviour: put the cursor in "x := 42" and hit tab; tab should align 'x' with 'g', as shown.

Actual behaviour: it indents that line an extra level, like this:

func f() {
    g(someSillyLongExpression(param1, param2, param3),
        "boo")
        x := 42
}

incorrect indentation after raw string in parens

If you have a raw string that starts with a newline inside parentheses (eg. function argument), then go-mode incorrectly indents lines following it.

Example code:

package main

func x() {
    s := f(`
foo`)
    return s
}

Expected behaviour: put the cursor on "return s" and hit tab. Indentation should not change (or it should make it line up under "s" from 2 lines back).

Actual behaviour: the "return s" line is indented flush left.

In go-import-add, support grouped imports

A common pattern in Go is to group imports into multiple blocks, such as "local to project", "other remote imports" and "standard library".

When adding an import, it should be possible to find the best group with a basic longest common prefix search.

go-remove-unused-imports doesn't remove any imports

If I edit an existing Go file, and add package to the import list that isn't referenced anywhere, then invoke go-remove-unused-imports, no imports are removed, even though the compiling the file results in an unused import error.

Using the code with go-flymake, gocode, and auto-complete enabled. I haven't tried turning them off yet.

Not working properly with go-autocomplete.el

This go-mode.el is not working properly with go-autocomplete.el. I get a lot of buffers named "gocode" (created by go-autocomplete.el), and each time I kill one, it creates a new one. This does not happen in the other go-mode.

end-of-defun: infinite loop from comment at top of file

My source files all start with a comment, e.g.

// Copyright © 2012-2013, Greg Ward. All rights reserved.
// Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE.txt file.

package dag

func NewDAG() *DAG {
    return &DAG{
        nodes: make([]Node, 0),
        index: make(map[string]int),
    }
}

If point is in the comment at the top of file, hitting C-M-a (end-of-defun) appears to trigger an infinite loop: "top" shows emacs taking 100% CPU, and the mouse cursor switches to the "wait" icon.

After the comment, it's fine.

MELPA installation

I don't think the MELPA go-mode installation description is complete. Should I add something to my init files in addition to adding the repositories?

Ignore already imported packages for go-import-add

Is there a reason why it adds duplicates in the current implementation?

I want to use this for elisp snippet insertion code that adds (possibly) unused imports.

Sorry, but have not taken the time to study the current implementation yet.

comments can start inside strings

go-mode seems to think that the characters /* inside a string start a comment. Example code:

package main

func Test_FinderNode_Add_Expand(t *testing.T) {
    finder1 := NewFinderNode("**/*.c")
    finder2 := NewFinderNode("doc/*.txt")

    // sum = <**/*.c> + <doc/*.txt>
    expect := []string{"main.c", "src/foo.c", "doc/stuff.txt"}

    // sum = sum + <"*c*/?o?.h">
    finder3 := NewFinderNode("*c*/?o?.h")
}

Expected behaviour:

  • the comment lines are coloured red, but the code lines are not
  • the last line of the function ("finder3 := ...") indents as shown

Actual behaviour:

  • most of the function is coloured red, like comments
  • go-mode indents "finder3" too much

I'll attach a screenshot to demonstrate the incorrect syntax colouring.
spoof-comment

Byte-compile warnings in GNU Emacs 23.3.2

Byte-compiling in GNU Emacs 23.3.2, I get these warnings:

In go--backward-irrelevant:
go-mode.el:134:44:Warning: `previous-line' used from Lisp code
That command is designed for interactive use only

In go--common-prefix:
go-mode.el:530:27:Warning: `(common-prefix (s1 s2) (let ((diff-pos (mismatch
    s1 s2))) (if diff-pos (subseq s1 0 diff-pos) s1)))' is a malformed
    function

In go-import-add:
go-mode.el:554:35:Warning: `(quote fail)' is a malformed function
go-mode.el:554:35:Warning: `(quote block)' is a malformed function
go-mode.el:554:35:Warning: `(quote single)' is a malformed function
go-mode.el:554:35:Warning: `(quote none)' is a malformed function
go-mode.el:572:64:Warning: `beginning-of-buffer' used from Lisp code
That command is designed for interactive use only

In go-remove-unused-imports:
go-mode.el:662:22:Warning: `goto-line' used from Lisp code
That command is designed for interactive use only

In end of data:
go-mode.el:670:1:Warning: the following functions are not known to be defined: diff-hunk-next,
    diff-apply-hunk, assert, flet, reduce, case

Fontify variable declarations

Variable names should be highlighted with font-lock-variable-name-face where the variable is declared. For example, u, v, x, y, and z should be highlighted in the following:

var x, y = 1, 2
x, y := 1, 2
for x, y := range aSlice {
func f(x, y int) (u, v bool)
func(x int, y char) (z bool)
func (x T) MyMethod(y int) (z int)

Highlighting variable declarations is performed in Emacs Lisp mode (for "defvar") and c-mode (for function parameters and variable declarations). I miss it in go-mode.

BTW, Thank you very much for the improved go-mode!

Incorrect fontification of function arguments

This is with the latest version of 27 Feb 2013

I have this line in a Go file:

func transform(srcpj, dstpj *Proj, x, y, z []float64) ([]float64, []float64, []float64, error) {

Of the four time this has float64, only the the first, third and fourth are fontified.

Support outline-minor-mode

Is it possible to add support for outline-minor-mode? outline style code folding makes it much easier to work with large source code files. This is esp. useful for go-lang as one can keep the whole package source in a single file which makes code searching and navigation much easier.

python.el https://github.com/fgallina/python.el works with outline-minor-mode for Python and can be used as a reference. It defines two regexps: outline-regexp and outline-heading-end-regexp, and one function outline-level.

Reference for outline minor mode can be found here:
http://emacswiki.org/emacs/OutlineMinorMode

autoload

Shouldn't there be an autoload comment?

;;;###autoload
(define-derived-mode go-mode fundamental-mode "Go"

Installation instructions

I know this is probably trivial for seasoned Emacs users, but not for newcomers. Would you please consider adding proper installation instructions in the README.

Thanks.

incorrect indentation inside function with multi-line args

When I write a function with a long argument list, I like to break the declaration across multiple lines. Example:

package longargs

func somewhatLongFunctionName(
    arg1 package1.RatherLongTypeName, arg2 package2.AnotherLongTypeName) {
    return
}

Expected behaviour: go-mode should indent "return" as shown; that's what gofmt does.

Actual behaviour: go-mode indents it like this:

func somewhatLongFunctionName(
    arg1 package1.RatherLongTypeName, arg2 package2.AnotherLongTypeName) {
        return
}

#s(hash-table tags eql) is not supported by emacs-22

The "#s(hash-table ...)" construct fails at the '#' in emacs-22.1.1, the stock /usr/bin/emacs on Macs. Apparently, #s is not supported there. My first attempt at a workaround using (make-hash-table :tags eql) failed.

Reproduce as follows:

/usr/bin/emacs -Q --batch --load $GOMODE -eval "(with-current-buffer (find-file \"indentation_tests/gh-10.go\")) (kill-emacs 0)" ; echo $?
Invalid read syntax: "#"
255

Remove quote characters from package name in go-add-import

When prompted for a package name in go-add-import, I sometimes forget and enter the package name with quotes. This results in a an import with two sets of quotes:

import (
    "math"
    "sync"
    "time"
    ""fmt""
)

It would be nice if go-add-import would remove matching quote characters from the package name before inserting the package into the import list.

gofmt breaks kill-ring

I have no idea why this is the case, but I've found that kill-line and kill-region work as expected when I first start emacs. After running gofmt in a buffer, however, text that is killed is no longer added to the kill-ring.

Emacs version: 24.3.1

{beginning,end}-of-defun skip methods

beginning-of-defun and end-of-defun skip over many methods. That is, they work just fine on plain old functions with no receiver. Consider the following skeletal source file:

type DAG struct {
}

func NewDAG() *DAG {
}

func (self *DAG) Nodes() []Node {
}

func (self *DAG) copy() *DAG {
}

func (self *DAG) verify() {
}

func (self *DAG) MakeNodeSet(names ...string) *NodeSet {
}

func (self *DAG) AddManyParents(targets, sources []Node) {
}

type DFSVisitor func(node Node) error

func (self *DAG) DFS(start *NodeSet, visit DFSVisitor) error {
    var descend func(id int) error
    descend = func(id int) error {
        return nil
    }
}

type CycleError struct {
}

func (self CycleError) Error() string {
}

func (self *DAG) MarkSources() {
}

func (self *DAG) Lookup(name string) Node {
}

func (self *DAG) AddNode(node Node) Node {
}

func (self *DAG) addNode(node Node) (int, Node) {
}

func (self *DAG) HasParents(node Node) bool {
}

func (self *DAG) ParentNodes(node Node) []Node {
}

func (self *DAG) AddParent(child Node, parent Node) {
}

func (self *DAG) length() int {
}

func (self *NodeSet) String() string {
}

func (self *NodeSet) Length() int {
}

type TestDAG struct {
}

func NewTestDAG() *TestDAG {
}

func (self *TestDAG) Add(name string, parent ...string) {
}

func (self *TestDAG) Finish() *DAG {
}

Expected behaviour:

  • end-of-defun should always go to the next blank line after the "}" that closes a "func ... {"
  • beginning-of-defun should always go to the previous "func ... {" line

Actual behaviour:

  • starting from top of file, end-of-defun goes to the end of NewDAG(), then end of NewTestDAG(), skipping all the methods of *DAG and *NodeSet in between
  • starting from EOF, beginning-of-defun goes to NewTestDAG(), then NewDAG(), skipping all the methods in between

gofmt bug

first, It give empty brackets like

{
var a
}

a error message: expected declaration, found '{'

second, when I use redis like this(https://github.com/gosexy/redis):

var client *redis.Client
client = redis.New()

It give a error message too: expected declaration, found 'IDENT' client

the two useage is allowed in golang, but go-mode's gofmt think it's a error.
it refuse to format my code and I cannt use align in go-mode (because #29) too.

Can I set goftm to format the code first, then shows the error?
So I can skip the errors and got my code tidy.


must put : client = redis.New() to a func

use `go doc` to replace `godoc` ?

I found I can't find godoc command on my Ubuntu 14.14. only support command go doc.
Is the command godoc comes from package golang-godoc? (I can't find this package too).

can this be added to marmalade?

There's a version of go-mode on marmalade... I guess it's out of date?

An Emacs user building their own Emacs will rely on marmalade or melpa more than pulling files from the go lang distribution.

Could this be uploaded to http://marmalade-repo.org when you release?

go-mode.el indentation of struct initializers

This issue is transferred from the Go issue tracker issue number 8523.

I have downloaded from this github repository and replaced "go-mode.el" with the newest version at the time of this bug report. The bug is still present. The following is the text of the above bug report:

I am using the "go-mode.el"

/usr/local/go/misc/emacs/go-mode.el

which came with go 1.3:

$ go version
go version go1.3 freebsd/386

The following example illustrates the problem:

package main

func hugamuga(w http.ResponseWriter, r * http.Request) {
    h := &cgi.Handler{
    Path: path,
    }
}

Pressing "tab" on the line containing "Path:" or "indent-region" does not alter the indentation. However, gofmt goemacsbug.go produces this:

package main

func hugamuga(w http.ResponseWriter, r *http.Request) {
    h := &cgi.Handler{
        Path: path,
    }
}

I think it's a bug in go-mode.el.

The above program was edited from a longer example to illustrate the problem.

Magic comma moves cursor around unpredictably

go-mode has a magic comma that occasionally drives me insane by moving the cursor around at random. Here's a tiny example:

package magiccomma

/*
extern void CallMyFunction(void* pfoo);
*/
import "C"

To reproduce:

  1. put cursor right after "pfoo" in the C declaration (I'm about to add a second param)
  2. hit comma (",")

Expected behaviour: inserts a comma

Actual behaviour: inserts a command and moves to the beginning of the line

I've seen this behaviour in pure Go code; no need for CGo and comments. It's particularly obnoxious here, because go-mode should not try to format anything inside comments.

go-mode does not correctly highlight Go types

Currently, Go types such as int32, float64 etc. are not recognized as part of Go's syntax:

package main

import "fmt"

func main() {
var testvar int32
}

In the above piece of code, 'int32' is not highlighted, even trough it is a valid Go type.
gomode

Go vet error

After updating my Emacs packages I am now getting this error when I try to edit .go files:

Checker go-vet returned non-zero exit code 1, but no errors from output: panic: import failed: can't find import: fmt

goroutine 16 [running]:
runtime.panic(0x1fccc0, 0x208468a50)
/Users/lmauldin/Downloads/go/src/pkg/runtime/panic.c:279 +0xf5
main.importType(0x2a8720, 0x3, 0x2b3250, 0x8, 0x0, 0x0)
/Users/lmauldin/dev/goexternal/src/code.google.com/p/go.tools/cmd/vet/types.go:33 +0x11b
main.init()
/Users/lmauldin/dev/goexternal/src/code.google.com/p/go.tools/cmd/vet/types.go:23 +0x1c26

goroutine 17 [runnable]:
runtime.MHeap_Scavenger()
/Users/lmauldin/Downloads/go/src/pkg/runtime/mheap.c:507
runtime.goexit()
/Users/lmauldin/Downloads/go/src/pkg/runtime/proc.c:1445

goroutine 18 [runnable]:
bgsweep()
/Users/lmauldin/Downloads/go/src/pkg/runtime/mgc0.c:1976
runtime.goexit()
/Users/lmauldin/Downloads/go/src/pkg/runtime/proc.c:1445

goroutine 19 [runnable]:
runfinq()
/Users/lmauldin/Downloads/go/src/pkg/runtime/mgc0.c:2606
runtime.goexit()
/Users/lmauldin/Downloads/go/src/pkg/runtime/proc.c:1445

Checker definition probably flawed.

incorrect indentation after simple raw string

A simple raw string on its own seems to confuse indentation in following lines. Example code:

package main

func x() {
    s := `foo`
    return s
}

Expected behaviour: tab on the "return s" line should align "return" with "s" above.

Actual behaviour: it inserts an extra tab, so the code looks like

func x() {
    s := `foo`
        return s
}

go-import-add often fails after hitting max-lisp-eval-depth

The default max-lisp-eval-depth is 600 on my version of Emacs (24.3.50.1) The code for getting the list of package name completions can easily exceed that. Even after setting the value to 6000, I still saw failures after several calls to to go-import-add.

A short-term work-around would be to set the max-lisp-eval-depth in your code by doing something like:

(set (make-local-variable 'max-lisp-eval-depth) (max max-lisp-eval-depth 6000))

In the long-term, you probably want to convert the function to be iterative.

You may want to consider not building the package list on every call to go-import-add. It's probably not necessary. Instead build it on the first call and cache the value. Provide a function to refresh the package name cache, if needed.

Allow gofmt to respect indent-tabs-mode.

gofmt will not respect indent-tabs-mode (since the go standard is for tabs so it assumes this to be the case). It would be better to allow the user to decide based on their individual indent-tabs-mode setting what gofmt should do.

Since indent-tabs-mode is set in a hook in go-mode the user will need to explicitly set this in a hook so it cannot have unintended consequences.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.