Linter checks formatting of paired brackets (inspired by this article).
According to the original notation, "a bracket should either start/end a line or be paired on the same line".
With modification for multiline items, the following cases are allowed:
- Both brackets and all items are in one line.
fmt.Printf("%s, %s!", "Hello", "world")
- Left (opening) bracket is the last character on a line and right (closing) bracket starts a new line.
fmt.Printf( // comments and whitespaces are ignored "%s, %s!", "Hello", "world", )
- If the last item is multiline, it can start on the same line with the left bracket.
In this case, the right bracket should be on the same line where the last item ends.http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ... })
x.go:1:16: left parenthesis should either be the last character on a line or be on the same line with the last argument
⬇
http.HandleFunc("/",
func(w http.ResponseWriter, r *http.Request) {
...
},
)
x.go:4:1: right parenthesis should be on the previous line
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
...
},
)
⬆
x.go:5:3: right parenthesis should be on the next line
http.HandleFunc(
"/",
func(w http.ResponseWriter, r *http.Request) {
...
})
⬆
Function/method call
Bad | Good |
---|---|
fmt.Printf("%s, %s!",
"Hello", "world") fmt.Printf("%s, %s!",
"Hello", "world",
) fmt.Printf(
"%s, %s!",
"Hello", "world") fmt.Printf("%s %s", "Last", `item
is multiline`,
) |
fmt.Printf("%s, %s!", "Hello", "world") fmt.Printf(
"%s, %s!", "Hello", "world",
) fmt.Printf(
"%s, %s!",
"Hello", "world",
) fmt.Printf("%s %s", "Last", `item
is multiline`) |
Composite literal
Bad | Good |
---|---|
foo := []int{1,
2, 3} foo := []int{1,
2, 3,
} foo := []int{
1,
2,
3} foo := []string{"Last", "item", `is
multiline`,
} |
bar := []int{1, 2, 3} bar := []int{
1,
2,
3,
} bar := []int{
1, 2, 3,
} bar := []string{"Last", "item", `is
multiline`} |
Function parameters
Bad | Good |
---|---|
func Foo(a int,
b string, c bool) {
...
} func Foo(a int,
b string, c bool,
) {
...
} func Foo(
a int,
b string,
c bool) {
...
} func Foo(a int, b string,
) {
...
} func Foo(a int, b struct {
X int
Y string
},
) {
...
} |
func Bar(a int, b string) {
...
} func Bar(
a int,
b string,
c bool,
) {
...
} func Bar(
a int, b string, c bool,
) {
...
} func Bar(a int, b struct {
X int
Y string
}) {
...
} |
Function type parameters (generics)
Bad | Good |
---|---|
func Foo[T int,
V string]() {
...
} func Foo[T int,
V string,
]() {
...
} func Foo[
T int,
V string]() {
...
} func Foo[T int, V string,
]() {
...
} func Foo[T int, V interface {
int | string
},
]() {
...
} |
func Bar[T int, V string]() {
...
} func Bar[
T int,
V string,
]() {
...
} func Bar[
T int, V string,
]() {
...
} func Bar[T int, V interface {
int | string
}]() {
...
} |
Function returns (output parameters)
Bad | Good |
---|---|
func Foo() (int,
error) {
...
} func Foo() (int,
error,
) {
...
} func Foo() (
int,
error) {
...
} func Foo() (int, error,
) {
...
} func Foo() (int, interface {
Error()
},
) {
...
} |
func Bar() (int, error) {
...
} func Bar() (
int,
error,
) {
...
} func Bar() (
int, error,
) {
...
} func Bar() (int, interface {
Error()
}) {
...
} |
gofmt
fixes many cases, which pairedbrackets
complains about. But not all of them. All examples above formatted correctly according to gofmt
.
gofumpt
is just a slightly better than gofmt
. It fixes some composite literal examples above. But not all of them, and it doesn't fix other examples.
You can use golangci-lint.
Unfortunately, v1 was rejected to be a built-in linter (hopefully v2 will be accepted).
You can configure pairedbrackets
as a plugin.
Prebuilt binaries doesn't support plugins (see discussion), so you have to build golangci-lint:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go install github.com/maratori/pairedbrackets@latest
pairedbrackets -build-golangci-lint-plugin
pairedbrackets.so
will be created in current working directory. You can change the output path with flag -plugin-output
(see other flags in help as well).
pairedbrackets
is disabled by default.
To enable it, add the following to your .golangci.yml
:
linters-settings:
custom:
pairedbrackets:
path: /path/to/plugin/pairedbrackets.so
description: The linter checks formatting of paired brackets
original-url: github.com/maratori/pairedbrackets
linters:
enable:
pairedbrackets
golangci-lint run
go install github.com/maratori/pairedbrackets@latest
pairedbrackets ./...