按正则表达式搜索模式折叠


13

我得到了一个纯文本文件,其中用空格分隔值的列。像这样:

AU 3030 .... ... ....  
AU 3031 .... ... ....  
AU 3032 .... ... .... 
AU 3033 .... ... .... 
IT 48100 ... .. .....
IT 40100 ... .. .....
IT 48123 ... .. .....
UK 3333 ... ... ..... 
UK 4444 ... ... .....
UK 5555 ... ... .....

我还得到了此正则表达式,它将匹配第一列中具有相同值的任何相邻行(假设文件在第一列中排序),除了最后一行:

/^\(\([A-Z0-9]\+\)\s\+.*\n\)\(\2\)\@=

(或使其不那么“毛茸茸”):

/^\v([A-Z0-9]+)\s+.*\n(\1)@=

是否可以将线折叠到不匹配的线上?结果如下:

+-- 4 lines AU ....
+-- 3 lines IT ....
+-- 3 lines UK ....

Answers:


14

执行set foldmethod=expr并使用'foldexpr'来设置将定义折叠起点的vim脚本表达式。

set foldmethod=expr
set foldexpr=get(split(getline(v:lnum-1)),0,'')!=get(split(getline(v:lnum)),0,'')?'>1':'='

这看起来比实际要复杂,因为我们不能轻易使用中的空格:set,而要使用空格和一个换行符或2,它看起来像:

get(split(getline(v:lnum - 1)), 0, '') != get(split(getline(v:lnum)), 0, '')
    \ ? '>1'
    \ : '='

总览

基本上,这会将每行的第一个单词与前一行进行比较。如果单词不同,则该行是折线的开始>1。否则,它会保持相同的折叠水平=

荣耀细节

  • set foldmethod=expr 告诉Vim使用vim脚本表达式来确定折叠
  • 'foldexpr' 选项保存vim脚本表达式
  • 使用三元数评估条件,该三元数将>1在何时开始折叠以及=何时继续折叠级别时返回
  • v:lnum'foldexpr'正在运行以更新折叠的当前行
  • 通过获取当前行(v:lnum)和上一行(v:lnum - 1)的内容getline()
  • 通过将每一行分割成单词 split()
  • 使用get()获得的新鲜拆分单词的第一个指数
  • ''如果为空行,请使用默认值。例如get(words, 0, '')
  • 在三进制的条件部分中比较当前行的第一个单词与上一行的第一个单词

注意:此方法对于非常大的文档可能会有一些性能问题

有关更多帮助,请参见:

:h 'foldmethod'
:h 'foldexpr'
:h getline(
:h v:lnum
:h split(
:h get(
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.