Vim:如何在花括号之间递归运行“:sort”?

3
我是一名网站开发人员,经常需要编写 CSS 样式表:
我总是按字母顺序排列样式,例如下面这样:
.sorted_product_mens_color_list li, .sorted_product_womens_color_list li {
    margin: 0 5px 0 5px;
    padding: 5px;
    border: 2px solid black;
}

变成:

.sorted_product_mens_color_list li, .sorted_product_womens_color_list li {
    border: 2px solid black;
    margin: 0 5px 0 5px;
    padding: 5px;
}

然而,这种做法很繁琐,我希望能够通过编写一个在VIM中自动执行此操作的脚本来实现自动化。

我应该如何做到:1)在所有花括号内的文件中循环运行:sort命令或2)在目录中的所有CSS文件上运行:sort命令?(选择其一即可)

2个回答

9

@Edmund的请求,我会添加一个答案来进一步解释:g/{/+,/}/-sort:g命令的语法是

:{range}g/pattern/{ex command(s)}

初始考虑范围为空,缺省搜索整个文件。模式为{,用于搜索左花括号。
:g/{/{ex command(s)}

该命令是余数。在这种情况下,该ex命令为+,/}/-sort。它由一个可选范围(“+,/}/-”)和一个要在该范围上执行的命令(sort)组成。该范围从当前行开始(通过“:g”命令找到),向前一行(+,与+1同义,因为默认值为1)。然后,“,”将范围的起始位置与结束位置分隔开。为了找到范围的第二行,我们向前搜索下一个闭合大括号(“/}/”),然后向后一行(“-”,再次等同于“-1”)。现在,我们已经将范围定义为“从我们找到的开放大括号之后的行开始,到关闭大括号之前的行”,我们在该范围上执行sort ex命令。

8

如果只有一个文件,您可以执行以下操作:

:g/{/normal! f{viB:sort^M

这段代码的作用:

  • :g/{/ :对于每一行包含{的文本进行操作
  • normal! :进入普通模式(!可以跳过命令映射)
  • f{:查找第一个(在css中不应该会有问题)出现的{
  • viB:在大括号之间进入可视模式
  • :sort:对所选内容进行排序
  • ^M:按下回车键(这是单个字符,使用<C-v><CR>输入)

如果要处理多个文件,您可以执行以下操作:

# From you shell
# In zsh you would use 'vim **/*.css' to open all the css files in nested directories
# Not sure about your shell
$> vim *.css     # open css files in the current directory

" In vim
:argdo g/{/normal! f{viB:sort^M:update^M
:update:write相同,不同的是如果缓冲区未被修改,它将不会触发写操作。

1
哇,我可以问一下你是怎么学会关于VIM的这些东西的吗?我每天都在使用它,但我不知道你刚才写的任何内容。 - bigpotato
1
@edmund: 我不是自己想出 :g/{/normal 这个“技巧”的,是同事向我展示了如何使用它来合并大括号之间的所有行。除此之外,在这个问题之前,我不知道 normal! 中的 !(遇到了 :normal 的问题,查找了帮助文档,认为加上感叹号会更好)。对于 f{viB,我认为它是基础操作(当然取决于你使用 vim 的时间长短)。至于 ^M,我...不太清楚。关于资源方面,我没有什么,除了 :help(但您需要知道要查找什么...)。也许可以尝试 Vim Reddit? - Marth
@Edmund:还忘了提到这个问题,它有一些非常好的答案,帮助我在刚开始使用Vim时理解了许多概念。 - Marth
3
为此,我更倾向于全程使用 ex 命令::g/{/+,/}/-sort,这对我来说似乎更简单。查找包含 "{" 的行,在下一行("+")开始一个范围,在下一个 "}" 之前的上一行("-"),将它们排序。 - Gumnos
@Gumnos:哇,是的,这样好多了。我从来没有想过在传递给:g命令中使用范围,这真的很棒。而且用你的方法,你可以摆脱那些丑陋的^M,只需使用sort | update即可。感谢您的提示! - Marth
@Gumnos,也许您可以回答这个问题并进一步解释一下? - bigpotato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接