go-lang-plugin-org / go-lang-idea-plugin

Google Go language IDE built using the IntelliJ Platform
https://plugins.jetbrains.com/plugin/5047
Other
4.56k stars 571 forks source link

Arrange imports while auto-importing and formatting #1989

Open jerome-laforge opened 8 years ago

jerome-laforge commented 8 years ago

Hello all, First of all, thx for this awesome plugin. I configure the plugin filewatcher to goimported on each save my go giles. Is it possible to add the possibility to add new import at the beginning of the import block instead of at its end. Because that's cause some trouble with goimports that sort the import block.

I try to describle the pb with this example:

initial:

import (
    "fmt"
    "sync"
)

if add github.com/inconshreveable/log15 via auto import of the idea plugin, I have this :

import (
    "fmt"
    "sync"
    "github.com/inconshreveable/log15"
)

When I save (filewatcher executes goimport on it), I have this:

import (
    "fmt"
    "sync"

    "github.com/inconshreveable/log15"
)

If I add another package from stdlib (for example strconv) with auto import (as it appends the new import at the end of the block), I have this:

import (
    "fmt"
    "sync"

    "github.com/inconshreveable/log15"
    "strconv"
)

If I save it (and goimported), I have this:

import (
    "fmt"
    "sync"

    "strconv"

    "github.com/inconshreveable/log15"
)

So if autoimport add the new package à the beginning the import block like this

import (
    "strconv"
    "fmt"
    "sync"

    "github.com/inconshreveable/log15"
)

When I save/goimport the file, I have expected result like this:

import (
    "fmt"
    "strconv"
    "sync"

    "github.com/inconshreveable/log15"
)

Regard Jérôme

dlsniper commented 8 years ago

Hi Jerome,

Thank you for the detailed issue.

However, there are a couple problems with the fundamental issue itself.

First, the plugin respects what gofmt does not what goimports does. This might change in the future as goimports basically fragmented the ecosystem with this choice. I've asked @bradfitz about this and there doesn't seem to be any way to improve either gofmt nor change the default behavior of goimports to match gofmt.

The second problems is that goimports groups the imports by its own logic but there are people out there that do the following:

import (
    "std/lib/pkg"

    "appengine/pkg"

    "github.com/myOrg/myPkg"

    "github.com/otherOrgs/manyPkg"
)

or this:

import (
    "std/lib/pkg"

    "appengine/pkg"

    "github.com/otherOrgs/manyPkg"

    "github.com/myOrg/myPkg"
)

or this:

import (
    "std/lib/pkg"

    "appengine/pkg"

    "github.com/myOrg/myPkg"
    "github.com/otherOrgs/manyPkg"
)

or even group packages in other formats. Go documentation / guidelines don't state that the imports must be organized in a certain way and this is left to the user to choose, thus the choices people make :)

Maybe, as a possible solution, what the plugin could do is to group the imports according to "std/lib" "non-std/lib/" rule if the import statement contains an empty line and try to append the import to the similar package path if the path is already present (in which case this could be a valid option).

@zolotov do you think it would make sense to have a project setting to define how the imports are formatted based on user preference from either gofmt (default / now) or goimports rules? I'm asking not because of this particular setup @jerome-laforge has, with filewatcher + goimports, but because I've seen projects where the imports should be organized by the goimports rules and this would cause diffs in the commits if used otherwise.

mdwhatcott commented 8 years ago

I like the idea of separating "std/lib" packages from "non-std/lib" packages. This is how most code I've seen is formatted.

dlsniper commented 8 years ago

@mdwhatcott yup, I think that's the idea behind goimports. But goimports is not the default formating tool for Go (unfortunately), gofmt is.

I've did a very tiny survey and I've found these:

The first 5 most starred repositories in Go on Github are like this:

From the first 10, there's 1 using custom stuff, 9 using goimports.

mdwhatcott commented 8 years ago

Yeah, once you've used goimports, you probably won't go back to plain old gofmt :)

mdwhatcott commented 8 years ago

Why not allow the user to choose which style they prefer (gofmt or goimports)?

I suppose I could just stop caring about the order that the plugin inserts the import statements.. :(

vially commented 8 years ago

Any update on this?