emacs的editorconfig使用

Last Updated:

2022-08-12

先限定住范围(能editorconfig的定义)为缩进和对齐

目前就是,本人使用的emacs时候,有些项目有.editorconfg的配置信息,但是我的emacs依然使用的规则和.editorconfig不一致。最直观的就是缩进上的问题。

editorconfig的一些概念

官网

一个样例配置文件长相

# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8

# 4 space indentation
[*.py]
indent_style = space
indent_size = 4

# Tab indentation (no size specified)
[Makefile]
indent_style = tab

# Indentation override for all JS under lib directory
[lib/**.js]
indent_style = space
indent_size = 2

# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2

当打开一个文件后,editorconfig如何发挥效果

When opening a file, EditorConfig plugins look for a file named .editorconfig in the directory of the opened file and in every parent directory. A search for .editorconfig files will stop if the root filepath is reached or an EditorConfig file with root=true is found.

意思就是,当打开一个文件的时候,editorconfig会先在同级目录下寻找.editorconfig这个配置文件,并且,循着上级目录一直重复寻找,直到找到一个含有root=true.editorconfig文件或者根目录为止。

EditorConfig files are read top to bottom and the most recent rules found take precedence. Properties from matching EditorConfig sections are applied in the order they were read, so properties in closer files take precedence.

所以,某一属性(譬如tab-width),以最近的配置文件(aka, .editorconfig)中配置到优先;(同一配置文件中),以最近一条配置规则优先(文件从上往下读取)

windows系统的特殊化(即,在windows下如何创建一个.editorconfig文件)

For Windows Users: To create an .editorconfig file within Windows Explorer, you need to create a file named .editorconfig. (note the trailing dot), which Windows Explorer will automatically rename to .editorconfig for you.

意思就是,windows下,你要想创建一个.editorconfig文件,你需要把文件名命名成.editorconfig.(注意结尾处的点)

样例文件中的[*.js]这些叫做规则名(section name),是遵循globs语法规则

规则名大小写敏感 语法就是globs

具体规则表如下(tbc:需要翻译成中文):

* Matches any string of characters, except path separators (/) ** Matches any string of characters ? Matches any single character [name] Matches any single character in name [!name] Matches any single character not in name {s1,s2,s3} Matches any of the strings given (separated by commas) (Available since EditorConfig Core 0.11.0) {num1..num2} Matches any integer numbers between num1 and num2, where num1 and num2 can be either positive or negative

* 匹配除了路径分隔符 (/)之外的任意长度的字符串 ** 匹配任意长度的字符串 ? 匹配任意单个字符(没有试验过一个中文字符算不算这里的单个字符) [name] 匹配在 _name_中任意一个单个字符 [!name] 匹配不在 _name_中的任意一个单个字符 {s1,s2,s3} 匹配大括号({})里头的任意一串字符串(以逗号分割) (Available since EditorConfig Core 0.11.0) {num1..num2} 匹配在 num1 and _num2_这两个数字之间的整数。_num1_和_num2_可以使正整数,也可以是负整数

editorconfig里头的属性(property)取值列表

emacs要想使用editorconfig,需要的插件

插件地址

emacs里头的概念

先emacs配置规则

(editorconfig-mode 1)

emacs里头的概念

文档

键盘输入一个tab键,emacs下写入tab键还是不能写入tab键(在js-mode下,tab键被转换写入空格键)的关键

是由emacs的indent-tabs-mode变量控制,该变量默认是t 如果该变量为nil,那么在emacs中,当用户通过键盘按下tab键后,是不会写入一个tab到文件中的。

在js-mode中,由于我配置了js-indent-level,从而emacs会把tab键转换成js-indent-level指定的n个空格数

tab-width

指定了tab键,显示成n个空格键;从文件源码角度,底层依然是一个tab键(而不是n个空格)

我之前使用emacs的缩进和.editorconfig不一致的原因

我之前的emacs相关配置配置信息是(至少js代码下的配置)(starter-kit-misc.org)

(add-hook 'js-mode-hook (lambda () (setq indent-tabs-mode nil) (setq tab-width 4) (setq js-indent-level tab-width)))

所以在js-mode下,我的editorconfig里头的配置被上面的配置给强行覆盖了

上面的js-mode下的配置。

具体我的emacs配置

    (add-hook 'vue-mode-hook (lambda () (message "MMMMMMMMMMM vue-mode-hook,defined from starter-kit-misc.org") (setq js-indent-level tab-width) (message "MMMMMMMMMMM vue-mode-hook,current tab-width %s" tab-width) (message "MMMMMMMMMMM vue-mode-hook,current js-indent-level %s" js-indent-level)))
    (add-hook 'js-mode-hook (lambda () (message "MMMMMMMMMMM js-mode-hook,defined from starter-kit-misc.org") (setq js-indent-level tab-width) (message "MMMMMMMMMMM js-mode-hook,current tab-width %s" tab-width)))

在启动过程中,会发现,vue-mode-hook被触发了两次(不知道是不是editorconfig的mode影响的)。之后,再出发一次js-mode-hook

*Message*Buffer的输出是:

MMMMMMMMMMM vue-mode-hook,defined from starter-kit-misc.org MMMMMMMMMMM vue-mode-hook,current tab-width 2 MMMMMMMMMMM vue-mode-hook,current js-indent-level 2 MMMMMMMMMMM vue-mode-hook,defined from starter-kit-misc.org MMMMMMMMMMM vue-mode-hook,current tab-width 8 MMMMMMMMMMM vue-mode-hook,current js-indent-level 8 MMMMMMMMMMM js-mode-hook,defined from starter-kit-misc.org MMMMMMMMMMM js-mode-hook,current tab-width 8

发现,第一次触发的vue-mode-hook是正确的。之后开始不对了(tab-width变量,全局默认是8)。从而导致后面的hook都不正确了。(editorconfig里头设置的是2)

猜测 上述是先触发vue-mode-hook,然后再editorconfig的minor-mode开始运作(由于配置文件里头indent_style=space),从而这个minor-mode将tab-width又设回了默认的8,然后vue-mode-hook又被触发一次(不知道为何触发),此时tab-width已经是8了,之后的js-mood-hook也乱套了。

最后没办法,只好把js-indent-level写死成2(即,不再依赖于tab-width了)

    (add-hook 'js-mode-hook (lambda () (message "MMMMMMMMMMM js-mode-hook,defined from starter-kit-misc.org") (setq js-indent-level 2) ))