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 withroot=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)取值列表
indent_style
: set to tab or space to use hard tabs or soft tabs respectively.indent_size
: a whole number defining the number of columns used for each indentation level and the width of soft tabs (when supported). When set to tab, the value oftab_width
(if specified) will be used.tab_width
: a whole number defining the number of columns used to represent a tab character. This defaults to the value ofindent_size
and doesn't usually need to be specified.end_of_line
: set to lf, cr, or crlf to control how line breaks are represented.charset
: set to latin1, utf-8, utf-8-bom, utf-16be or utf-16le to control the character set.trim_trailing_whitespace
: set to true to remove any whitespace characters preceding newline characters and false to ensure it doesn't.insert_final_newline
: set to true to ensure file ends with a newline when saving and false to ensure it doesn't.root
: special property that should be specified at the top of the file outside of any sections. Set to true to stop.editorconfig
files search on current file.
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下的配置。
(setq indent-tabs-mode nil)
会使得我在js编写的时候,不允许我输入tab键(从而我格式化js文件的时候,缩进的时候,是无法输入tab的,会自动插入空格)(setq tab-width 4)
会使我的emacs,将tab的长度,显示成4个空格(底层依然是一个tab,因为有可能我打开的js文件是他人写的,他人有输入tab)(setq js-indent-level tab-width)
会使我输入tab键的时候,emacs自动转换成4(因为tab-width被我设置成4)个空格,并插入到文件中
具体我的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) ))