{"id":13564210,"url":"https://github.com/mvdan/gofumpt","last_synced_at":"2025-05-13T16:06:25.372Z","repository":{"id":37406278,"uuid":"178628673","full_name":"mvdan/gofumpt","owner":"mvdan","description":"A stricter gofmt","archived":false,"fork":false,"pushed_at":"2025-04-21T18:43:47.000Z","size":616,"stargazers_count":3541,"open_issues_count":29,"forks_count":114,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-23T20:56:03.165Z","etag":null,"topics":["format","go","gofmt","goimports","idiomatic","style"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/mvdan.cc/gofumpt","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mvdan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"mvdan"}},"created_at":"2019-03-31T01:17:51.000Z","updated_at":"2025-04-23T19:49:35.000Z","dependencies_parsed_at":"2023-09-26T02:37:43.645Z","dependency_job_id":"ca565faa-1e44-47dd-b05c-ee648789a26f","html_url":"https://github.com/mvdan/gofumpt","commit_stats":{"total_commits":256,"total_committers":38,"mean_commits":"6.7368421052631575","dds":0.21484375,"last_synced_commit":"ea3d4139c13ad425d654add975cf34b657ed9469"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvdan%2Fgofumpt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvdan%2Fgofumpt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvdan%2Fgofumpt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvdan%2Fgofumpt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mvdan","download_url":"https://codeload.github.com/mvdan/gofumpt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250514767,"owners_count":21443208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["format","go","gofmt","goimports","idiomatic","style"],"created_at":"2024-08-01T13:01:28.038Z","updated_at":"2025-04-23T20:56:14.719Z","avatar_url":"https://github.com/mvdan.png","language":"Go","funding_links":["https://github.com/sponsors/mvdan"],"categories":["Go","开源类库","Open source library","Code formatters","Linters","Programming Languages","[](https://github.com/golang/go/wiki/CodeTools#code-formatting)Code Formatting","Repositories"],"sub_categories":["代码分析","Code Analysis","Code Formatting","[](https://github.com/golang/go/wiki/CodeTools#tools)Tools"],"readme":"# gofumpt\n\n[![Go Reference](https://pkg.go.dev/badge/mvdan.cc/gofumpt/format.svg)](https://pkg.go.dev/mvdan.cc/gofumpt/format)\n\n\tgo install mvdan.cc/gofumpt@latest\n\nEnforce a stricter format than `gofmt`, while being backwards compatible.\nThat is, `gofumpt` is happy with a subset of the formats that `gofmt` is happy with.\n\nThe tool is a fork of `gofmt` as of Go 1.24.0, and requires Go 1.23 or later.\nIt can be used as a drop-in replacement to format your Go code,\nand running `gofmt` after `gofumpt` should produce no changes.\nFor example:\n\n\tgofumpt -l -w .\n\nSome of the Go source files in this repository belong to the Go project.\nThe project includes copies of `go/printer` and `go/doc/comment` as of Go 1.24.0\nto ensure consistent formatting independent of what Go version is being used.\nThe [added formatting rules](#Added-rules) are implemented in the `format` package.\n\n`vendor` and `testdata` directories are skipped unless given as explicit arguments.\nSimilarly, the added rules do not apply to generated Go files unless they are\ngiven as explicit arguments.\n\nFinally, note that the `-r` rewrite flag is removed in favor of `gofmt -r`,\nand the `-s` flag is hidden as it is always enabled.\n\n### Added rules\n\n**No empty lines following an assignment operator**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nfunc foo() {\n    foo :=\n        \"bar\"\n}\n```\n\n```go\nfunc foo() {\n\tfoo := \"bar\"\n}\n```\n\n\u003c/details\u003e\n\n**No empty lines around function bodies**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nfunc foo() {\n\n\tprintln(\"bar\")\n\n}\n```\n\n```go\nfunc foo() {\n\tprintln(\"bar\")\n}\n```\n\n\u003c/details\u003e\n\n**Functions should separate `) {` where the indentation helps readability**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nfunc foo(s string,\n\ti int) {\n\tprintln(\"bar\")\n}\n\n// With an empty line it's slightly better, but still not great.\nfunc bar(s string,\n\ti int) {\n\n\tprintln(\"bar\")\n}\n```\n\n```go\nfunc foo(s string,\n\ti int,\n) {\n\tprintln(\"bar\")\n}\n\n// With an empty line it's slightly better, but still not great.\nfunc bar(s string,\n\ti int,\n) {\n\tprintln(\"bar\")\n}\n```\n\n\u003c/details\u003e\n\n**No empty lines around a lone statement (or comment) in a block**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nif err != nil {\n\n\treturn err\n}\n```\n\n```go\nif err != nil {\n\treturn err\n}\n```\n\n\u003c/details\u003e\n\n**No empty lines before a simple error check**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nfoo, err := processFoo()\n\nif err != nil {\n\treturn err\n}\n```\n\n```go\nfoo, err := processFoo()\nif err != nil {\n\treturn err\n}\n```\n\n\u003c/details\u003e\n\n**Composite literals should use newlines consistently**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\n// A newline before or after an element requires newlines for the opening and\n// closing braces.\nvar ints = []int{1, 2,\n\t3, 4}\n\n// A newline between consecutive elements requires a newline between all\n// elements.\nvar matrix = [][]int{\n\t{1},\n\t{2}, {\n\t\t3,\n\t},\n}\n```\n\n```go\nvar ints = []int{\n\t1, 2,\n\t3, 4,\n}\n\nvar matrix = [][]int{\n\t{1},\n\t{2},\n\t{\n\t\t3,\n\t},\n}\n```\n\n\u003c/details\u003e\n\n**Empty field lists should use a single line**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nvar V interface {\n} = 3\n\ntype T struct {\n}\n\nfunc F(\n)\n```\n\n```go\nvar V interface{} = 3\n\ntype T struct{}\n\nfunc F()\n```\n\n\u003c/details\u003e\n\n**`std` imports must be in a separate group at the top**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nimport (\n\t\"foo.com/bar\"\n\n\t\"io\"\n\n\t\"io/ioutil\"\n)\n```\n\n```go\nimport (\n\t\"io\"\n\t\"io/ioutil\"\n\n\t\"foo.com/bar\"\n)\n```\n\n\u003c/details\u003e\n\n**Short case clauses should take a single line**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nswitch c {\ncase 'a', 'b',\n\t'c', 'd':\n}\n```\n\n```go\nswitch c {\ncase 'a', 'b', 'c', 'd':\n}\n```\n\n\u003c/details\u003e\n\n**Multiline top-level declarations must be separated by empty lines**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nfunc foo() {\n\tprintln(\"multiline foo\")\n}\nfunc bar() {\n\tprintln(\"multiline bar\")\n}\n```\n\n```go\nfunc foo() {\n\tprintln(\"multiline foo\")\n}\n\nfunc bar() {\n\tprintln(\"multiline bar\")\n}\n```\n\n\u003c/details\u003e\n\n**Single var declarations should not be grouped with parentheses**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nvar (\n\tfoo = \"bar\"\n)\n```\n\n```go\nvar foo = \"bar\"\n```\n\n\u003c/details\u003e\n\n**Contiguous top-level declarations should be grouped together**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nvar nicer = \"x\"\nvar with = \"y\"\nvar alignment = \"z\"\n```\n\n```go\nvar (\n\tnicer     = \"x\"\n\twith      = \"y\"\n\talignment = \"z\"\n)\n```\n\n\u003c/details\u003e\n\n**Simple var-declaration statements should use short assignments**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nvar s = \"somestring\"\n```\n\n```go\ns := \"somestring\"\n```\n\n\u003c/details\u003e\n\n**The `-s` code simplification flag is enabled by default**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nvar _ = [][]int{[]int{1}}\n```\n\n```go\nvar _ = [][]int{{1}}\n```\n\n\u003c/details\u003e\n\n**Octal integer literals should use the `0o` prefix on modules using Go 1.13 and later**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nconst perm = 0755\n```\n\n```go\nconst perm = 0o755\n```\n\n\u003c/details\u003e\n\n**Comments which aren't Go directives should start with a whitespace**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\n//go:noinline\n\n//Foo is awesome.\nfunc Foo() {}\n```\n\n```go\n//go:noinline\n\n// Foo is awesome.\nfunc Foo() {}\n```\n\n\u003c/details\u003e\n\n**Composite literals should not have leading or trailing empty lines**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nvar _ = []string{\n\n\t\"foo\",\n\n}\n\nvar _ = map[string]string{\n\n\t\"foo\": \"bar\",\n\n}\n```\n\n```go\nvar _ = []string{\n\t\"foo\",\n}\n\nvar _ = map[string]string{\n\t\"foo\": \"bar\",\n}\n```\n\n\u003c/details\u003e\n\n**Field lists should not have leading or trailing empty lines**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\ntype Person interface {\n\n\tName() string\n\n\tAge() int\n\n}\n\ntype ZeroFields struct {\n\n\t// No fields are needed here.\n\n}\n```\n\n```go\ntype Person interface {\n\tName() string\n\n\tAge() int\n}\n\ntype ZeroFields struct {\n\t// No fields are needed here.\n}\n```\n\n\u003c/details\u003e\n\n**Avoid naked returns for the sake of clarity**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nfunc Foo() (err error) {\n\treturn\n}\n```\n\n```go\nfunc Foo() (err error) {\n\treturn err\n}\n```\n\n\u003c/details\u003e\n\n### Extra rules behind `-extra`\n\n**Adjacent parameters with the same type should be grouped together**\n\n\u003cdetails\u003e\u003csummary\u003e\u003ci\u003eExample\u003c/i\u003e\u003c/summary\u003e\n\n```go\nfunc Foo(bar string, baz string) {}\n```\n\n```go\nfunc Foo(bar, baz string) {}\n```\n\n\u003c/details\u003e\n\n### Installation\n\n`gofumpt` is a replacement for `gofmt`, so you can simply `go install` it as\ndescribed at the top of this README and use it.\n\nWhen using an IDE or editor with Go integration based on `gopls`,\nit's best to configure the editor to use the `gofumpt` support built into `gopls`.\n\nThe instructions below show how to set up `gofumpt` for some of the\nmajor editors out there.\n\n#### Visual Studio Code\n\nEnable the language server following [the official docs](https://github.com/golang/vscode-go#readme),\nand then enable gopls's `gofumpt` option. Note that VS Code will complain about\nthe `gopls` settings, but they will still work.\n\n```json\n\"go.useLanguageServer\": true,\n\"gopls\": {\n\t\"formatting.gofumpt\": true,\n},\n```\n\n#### GoLand\n\nGoLand doesn't use `gopls` so it should be configured to use `gofumpt` directly.\nOnce `gofumpt` is installed, follow the steps below:\n\n- Open **Settings** (File \u003e Settings)\n- Open the **Tools** section\n- Find the *File Watchers* sub-section\n- Click on the `+` on the right side to add a new file watcher\n- Choose *Custom Template*\n\nWhen a window asks for settings, you can enter the following:\n\n* File Types: Select all .go files\n* Scope: Project Files\n* Program: Select your `gofumpt` executable\n* Arguments: `-w $FilePath$`\n* Output path to refresh: `$FilePath$`\n* Working directory: `$ProjectFileDir$`\n* Environment variables: `GOROOT=$GOROOT$;GOPATH=$GOPATH$;PATH=$GoBinDirs$`\n\nTo avoid unnecessary runs, you should disable all checkboxes in the *Advanced* section.\n\n#### Vim\n\nThe configuration depends on the plugin you are using: [vim-go](https://github.com/fatih/vim-go)\nor [govim](https://github.com/govim/govim).\n\n##### vim-go\n\nTo configure `gopls` to use `gofumpt`:\n\n```vim\nlet g:go_fmt_command=\"gopls\"\nlet g:go_gopls_gofumpt=1\n```\n\n##### govim\n\nTo configure `gopls` to use `gofumpt`:\n\n```vim\ncall govim#config#Set(\"Gofumpt\", 1)\n```\n\n#### Neovim\n\nWhen using [`lspconfig`](https://github.com/neovim/nvim-lspconfig), pass the `gofumpt` setting to `gopls`:\n\n```lua\nrequire('lspconfig').gopls.setup({\n    settings = {\n        gopls = {\n            gofumpt = true\n        }\n    }\n})\n```\n\n#### Emacs\n\nFor [lsp-mode](https://emacs-lsp.github.io/lsp-mode/) users on version 8.0.0 or higher:\n\n```elisp\n(setq lsp-go-use-gofumpt t)\n```\n\nFor users of `lsp-mode` before `8.0.0`:\n\n```elisp\n(lsp-register-custom-settings\n '((\"gopls.gofumpt\" t)))\n```\n\nFor [eglot](https://github.com/joaotavora/eglot) users:\n\n```elisp\n(setq-default eglot-workspace-configuration\n '((:gopls . ((gofumpt . t)))))\n```\n\n#### Helix\n\nWhen using the `gopls` language server, modify the Go settings in `~/.config/helix/languages.toml`:\n\n```toml\n[language-server.gopls.config]\n\"formatting.gofumpt\" = true\n```\n\n#### Sublime Text\n\nWith ST4, install the Sublime Text LSP extension according to [the documentation](https://github.com/sublimelsp/LSP),\nand enable `gopls`'s `gofumpt` option in the LSP package settings,\nincluding setting `lsp_format_on_save` to `true`.\n\n```json\n\"lsp_format_on_save\": true,\n\"clients\":\n{\n\t\"gopls\":\n\t{\n\t\t\"enabled\": true,\n\t\t\"initializationOptions\": {\n\t\t\t\"gofumpt\": true,\n\t\t}\n\t}\n}\n```\n\n### Roadmap\n\nThis tool is a place to experiment. In the long term, the features that work\nwell might be proposed for `gofmt` itself.\n\nThe tool is also compatible with `gofmt` and is aimed to be stable, so you can\nrely on it for your code as long as you pin a version of it.\n\n### Frequently Asked Questions\n\n\u003e Why attempt to replace `gofmt` instead of building on top of it?\n\nOur design is to build on top of `gofmt`, and we'll never add rules which\ndisagree with its formatting. So we extend `gofmt` rather than compete with it.\n\nThe tool is a modified copy of `gofmt`, for the purpose of allowing its use as a\ndrop-in replacement in editors and scripts.\n\n\u003e Why are my module imports being grouped with standard library imports?\n\nAny import paths that don't start with a domain name like `foo.com` are\neffectively [reserved by the Go toolchain](https://github.com/golang/go/issues/32819).\nThird party modules should either start with a domain name,\neven a local one like `foo.local`, or use [a reserved path prefix](https://github.com/golang/go/issues/37641).\n\nFor backwards compatibility with modules set up before these rules were clear,\n`gofumpt` will treat any import path sharing a prefix with the current module\npath as third party. For example, if the current module is `mycorp/mod1`, then\nall import paths in `mycorp/...` will be considered third party.\n\n\u003e How can I use `gofumpt` if I already use `goimports` to replace `gofmt`?\n\nMost editors have replaced the `goimports` program with the same functionality\nprovided by a language server like `gopls`. This mechanism is significantly\nfaster and more powerful, since the language server has more information that is\nkept up to date, necessary to add missing imports.\n\nAs such, the general recommendation is to let your editor fix your imports -\neither via `gopls`, such as VSCode or vim-go, or via their own custom\nimplementation, such as GoLand. Then follow the install instructions above to\nenable the use of `gofumpt` instead of `gofmt`.\n\nIf you want to avoid integrating with `gopls`, and are OK with the overhead of\ncalling `goimports` from scratch on each save, you should be able to call both\ntools; for example, `goimports file.go \u0026\u0026 gofumpt file.go`.\n\n### Contributing\n\nIssues and pull requests are welcome! Please open an issue to discuss a feature\nbefore sending a pull request.\n\nWe also use the `#gofumpt` channel over at the\n[Gophers Slack](https://invite.slack.golangbridge.org/) to chat.\n\nWhen reporting a formatting bug, insert a `//gofumpt:diagnose` comment.\nThe comment will be rewritten to include useful debugging information.\nFor instance:\n\n```\n$ cat f.go\npackage p\n\n//gofumpt:diagnose\n$ gofumpt f.go\npackage p\n\n//gofumpt:diagnose v0.1.1-0.20211103104632-bdfa3b02e50a -lang=go1.16\n```\n\n### License\n\nNote that much of the code is copied from Go's `gofmt` command. You can tell\nwhich files originate from the Go repository from their copyright headers. Their\nlicense file is `LICENSE.google`.\n\n`gofumpt`'s original source files are also under the 3-clause BSD license, with\nthe separate file `LICENSE`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmvdan%2Fgofumpt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmvdan%2Fgofumpt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmvdan%2Fgofumpt/lists"}