VIM 排序
当Ex命令与
:global
一起组合使用时,也可以为[cmd]
单独指定范围。Vim允许以:g/{pattern}
为参考点,动态地设定范围。接下来,看看如何利用这一点,将CSS文件中每一条规则的所有属性均按照字母顺序排列。
用以下 CSS 文件作为演示。
global/unsorted.css
Line 1 html {
- margin: 0;
- padding: 0;
- border: 0;
5 font-size: 100%;
- font: inherit;
- vertical-align: baseline;
- }
- body {
10 line-height: 1.5;
- color: black;
- background: white;
- }
假设想把每一组规则内的属性都按照字母顺序排序。借助Vim的内置命令 :sort
(参见:h :sort
![]),就可以实现这一功能。
0.1 对单条规则的属性进行排序
先用 :sort
命令在该文件的子集上练练手(参见表15-1)。
首先,使用文本对象 vi{
,可以轻易地选中一段由 {} 所围的文本块。然后,运行 :'<,'>sort
,便可以将这些文本行按照字母顺序重新排列了。如果每次仅对一条规则进行排序,此法完全可以胜任,但假设我们遇到的是一个包含数百条规则的样式表呢?如果能把这一过程自动化岂不更好么?
表15-1 对文件的子集进行排序
按键操作 | 缓冲区内容 |
---|---|
html { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } | |
vi{ | html { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } |
:'<,'>sort | html { border: 0; font-size: 100%; font: inherit; margin: 0; padding: 0; vertical-align: baseline; } |
0.2 对所有规则的属性进行排序
其实,可以用一条 :global
命令对文件中所有规则的属性进行排序。假设在本例的样式表中运行以下命令。
➾ :g/{/ .+1,/}/-1 sort
最终会得到以下结果。
html {
border: 0;
font-size: 100%;
font: inherit;
margin: 0;
padding: 0;
vertical-align: baseline;
}
body {
background: white;
color: black;
line-height: 1.5;
}
这条排序命令会在每条规则的{} 块内执行。尽管本例中的样式表仅仅包含十几行文本,但对于内容更多的CSS文件,此法也同样适用。
这条命令很复杂,但掌握其机理后,将会由衷地赞叹 :global
命令的强大。:global
命令的标准格式如下。
:g/{pattern}/[cmd]
请牢记,Ex命令通常都会接受“范围”作为其参数(正如技巧28讨论的那样)。对于:global
命令内部的 [cmd]
,该规则依然有效。因此,可以将命令的模板扩展成以下形式。
:g/{pattern}/[range][cmd]
实际上,可以用 :g/{pattern}
匹配作为参考点,动态设置 [cmd]
的 [range]
。. 符号通常表示光标所在行,但在 :global
命令的上下文中,它则表示 {pattern}
的匹配行。
可以把原有的命令拆分成两条单独的Ex命令进行讲解,先分析命令的后半部分。以下是一条有效的Ex命令。
➾ :.+1,/}/-1 sort
如果去掉范围中的偏移,该范围可简化为 .,/}/
,其含义是“从当前行开始,一直到匹配模式 /}/ 的那一行为止”。偏移值 +1 与 —1 仅仅用于缩小操作范围,让我们把目光集中在 {} 之间的内容上面。对于排序前的原始CSS文件,如果把光标置于第1行或第9行,以上这条Ex命令将会对相应 {} 之内的规则按照字母顺序重新排序。
也就是说,只需将光标置于每个{} 块的起始位置,再运行 :.,/}/ sort
命令,即可将其中的规则按照字母顺序重新排序了。明白了么?现在,试着用 :global
命令中的 {pattern}
执行一次查找。
➾ /{/
以上命令会将光标置于某个 {} 块的起始位置,即我们的目标所在。现在,再重新将 :global
与 Ex命令 [cmd]
组合在一起。
➾ :g/{/ .+1,/}/—1 sort
其中,模式 { 会匹配每个 {} 块的起始行。而对于每个匹配行,:sort
会在匹配行到 {} 块的结尾这个[range]
范围内执行。最终,每一条规则的CSS属性都会按照字母顺序排列整齐。