EditorConfig 生成器

.editorconfig

勾选你仓库里用到的技术栈。每勾选一项,就会多出一个区块,写入该技术栈需要的规则。

下一步

放在仓库根目录的 .editorconfig,会告诉每一款现代 IDE 这个项目该怎样格式化文件,把制表符与空格之争逐个文件地定下来。真正麻烦的不是全局区块,而是各语言各自的区块:YAML 根本不允许用制表符缩进,make 不接受以空格开头的命令行,用 CRLF 保存的 Shell 脚本压根跑不起来。勾选你仓库里用到的语言,这个生成器就会写出每种语言需要的区块,并在旁边注明它为什么在那里。

如何生成一份 .editorconfig

  1. 1

    勾选仓库里用到的语言

    JavaScript、JSON、HTML 和 CSS、YAML、Python、PHP、Go、Rust、Ruby、Java、Markdown、Makefile、Shell 脚本以及 Windows 批处理文件。每勾选一项,就会多出一个区块。

  2. 2

    设定所有文件都会继承的规则

    缩进样式与宽度、换行符、字符集、末尾换行符、行尾空格,还有行长上限。它们都写在顶部的 `[*]` 区块里,下面的每个区块只覆盖各自语言确实需要改的那几项。

  3. 3

    看清每个区块存在的理由

    文件旁边的表格会逐条说明生成器写下的每个区块,方便你在提交前删掉团队不想要的那些。

  4. 4

    复制到仓库根目录

    把它存成 `.editorconfig`,和 `.gitignore` 放在一起。你下次打开文件时编辑器就会读到它,不需要构建步骤,也不用配置插件。

.editorconfig 有什么用

项目根目录下名为 .editorconfig 的文件用来声明格式约定。支持 EditorConfig 的编辑器(所有主流 IDE 和大多数现代文本编辑器)会在打开文件时套用这些规则。查找过程从正在编辑的那个文件出发,沿目录树逐级向上,遇到第一个写着 root = true 的文件就停下。

输出示例

用默认设置(空格、缩进宽度 4、LF、utf-8),加上已经替你勾好的两个区块,生成器输出:

root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 120

[*.{md,markdown}]
trim_trailing_whitespace = false

[{Makefile,makefile,GNUmakefile,*.mk}]
indent_style = tab

再勾上 Python、Go 或 YAML,对应的区块就会出现在下面,并且已经带好了该技术栈的格式化工具所强制的约定。

主要指令

指令 可用取值 说明
root true 在项目根目录设为 true,查找到此为止
charset latin1、utf-8、utf-8-bom、utf-16be、utf-16le 一般都用 utf-8。规范不建议使用字节顺序标记(BOM);而 utf-16 那两个取值会作用于每一个文件,大多数构建工具都读不了
end_of_line lf、crlf、cr 跨平台协作用 lf;只有纯 Windows 的仓库才用 crlf
indent_style space、tab
indent_size 整数,或 tab 配合 indent_style = tab 时它并不会被忽略:tab_width 会回退到它,于是由它决定制表符显示多宽
tab_width 整数 很少需要,因为它默认取 indent_size 的值
insert_final_newline true、false 让文件符合 POSIX 习惯,也让 diff 更清爽
trim_trailing_whitespace true、false 对 Markdown 要关掉,那里行尾空格表示换行
max_line_length 正整数,或 unset 不在核心规范里,它属于属性 wiki。若不想设上限,就别写这一行,而不是写 0

三条会让构建失败的规则,它们不只是风格偏好

.editorconfig 里的大多数条目只是偏好。下面这三条不是,它们正是值得为每种语言单独写一个区块的理由:

  • YAML 禁止用制表符缩进。 这是解析错误,不是 lint 警告。如果你的项目用制表符缩进,同时又有 GitHub Actions 工作流、Docker Compose 文件或 Kubernetes 清单,那么 YAML 区块就必须把空格强制改回来。
  • make 要求每条规则的命令行以真正的制表符开头。 用空格会得到 missing separator. Stop.,构建就此中止。这也是 [{Makefile,makefile,GNUmakefile,*.mk}] 列出好几种写法的原因:EditorConfig 匹配文件名时区分大小写,而仓库里 Makefile 和 makefile 两种写法都有人用。
  • 用 CRLF 保存的 Shell 脚本根本不会运行。 内核会把回车符当成解释器路径的一部分,然后报出类似 /bin/bash^M: bad interpreter: No such file or directory 的错误。Windows 批处理文件则有个反过来的毛病:cmd.exe 是按字节偏移量去找 goto 和 call :label 的,所以只用 LF 保存的 .bat 可能跳到错误的行,或者中途停下却连个报错都没有。

这三条里有两条,全局区块非但修不好,反而正是祸根,所以这个生成器会专门盯着它们。如果你选了制表符却没有勾上 YAML 区块,或者选了 CRLF 却没有勾上 Shell 区块,那么它写出的文件哪怕一次都没提到那些文件,照样会把它们弄坏。生成器会在输出上方直接讲明白,而不是等你从一次失败的流水线构建里才发现。utf-16 那两个字符集也一样:它们会作用于项目里的每一个文件,而 make、Shell 解释器和 Python 都读不了这样保存的源码。

生成器会写入的各语言约定

语言或文件 区块 设置了什么,以及为什么
JavaScript、TypeScript *.{js,jsx,mjs,cjs,ts,tsx} 2 个空格,Prettier 的默认值
JSON *.{json,jsonc} 2 个空格,npm 写 package.json 时用的宽度
HTML、CSS、模板 *.{html,htm,css,scss,sass,less,vue,svelte} 2 个空格,而且缩进式的 Sass 语法必须靠空格缩进才能解析
YAML *.{yml,yaml} 2 个空格;即便项目其余部分用制表符,这里也是空格
Python *.{py,pyi} 4 个空格,PEP 8 与 Black
PHP *.php 4 个空格,PSR-12。WordPress 用制表符,Drupal 用 2 个
Go {*.go,go.mod} 制表符,因为 gofmt 就是用制表符缩进
Rust *.rs 4 个空格,rustfmt 的默认值
Ruby {*.rb,*.rake,Gemfile,Rakefile} 2 个空格,RuboCop 的默认值
Java *.java 4 个空格,Oracle 的规范。Google 的 Java 风格用 2 个
Markdown *.{md,markdown} 保留行尾空格,Markdown 就是靠它来换行的
Makefile {Makefile,makefile,GNUmakefile,*.mk} 制表符,这是 make 的硬性要求
Shell 脚本 *.{sh,bash,zsh} LF,不管项目其余部分怎么设
Windows 批处理 *.{bat,cmd} CRLF,因为 cmd.exe 是按字节偏移量找标签的

请留意这张表里没有的东西:行长。PEP 8 说 79,Black 说 88,PSR-12 给的是不强制的 120,rustfmt 则是 100。把其中任何一个写进语言区块,都会悄悄盖掉你为整个项目选定的上限,所以生成器只把 max_line_length 留在 [*] 区块里,而把这些数字放在这里,由你自己决定要不要采用。

你的编辑器支持它吗?

原生支持的有:VS Code、JetBrains 的 IntelliJ 系列、Visual Studio、Sublime Text、Xcode 和 Notepad++。Vim、Emacs、Neovim 以及另外一些编辑器需要装一个小插件。这个文件就是普通的 INI 格式,代码检查工具和格式化工具同样读得懂,Prettier 和一些语言服务器正是这样跟它保持一致的。

常见问题

放在项目根目录,开头写上 root = true。你还可以在子目录里再放几个 .editorconfig 来覆盖特定路径;查找会从正在编辑的那个文件沿目录树向上进行,遇到第一个 root = true 就停下。

把这个字段填成 0,生成器就不会把 max_line_length 写进文件。这个属性有文档记载的取值是正整数,外加规范通用的 unset,后者的用途是取消从上层文件继承来的值。而这里是最顶层的文件,没有什么可取消,少写这一行表达的是同一个意思。不该写的是 max_line_length = 0,本工具过去就是这么干的:规范要求插件忽略自己不支持的取值,所以 0 并不代表上限为零,它只是一行悄无声息、什么也不做的配置。

不会。EditorConfig 管的是各种编辑器里的空白字符和换行符,包括那些你不用、同事却在用的编辑器。Prettier 和各语言的代码检查工具负责更深一层的风格规则,比如引号、分号和尾随逗号。两者相辅相成,而且 Prettier 也会读你的 .editorconfig 来确定这些基础项。

因为 YAML 根本不允许用制表符缩进。用制表符缩进的工作流文件或 compose 文件,还没等哪个工具读到就已经解析失败了。生成器会在其他地方保留你的制表符,只覆盖 YAML 区块,并且这么做时会在文件上方明确提示你。

如果仓库里的 Windows 工具确实需要,就设 end_of_line = crlf。通常更好的做法是这里用 lf,再配一个写有 * text=auto 的 .gitattributes,这样 git 会在提交时统一换行符,而检出时各操作系统仍能拿到合适的形式。

你的选择用来生成文件,并会通过页面链接在各步骤之间传递,方便你分享或收藏某一套配置。页面生成之后,我们的服务器不会保存任何内容。

相关工具

此工具还提供其他语言版本