我在写作时使用Pandoc,并在html代码中粘贴更复杂的表格。这可能会使文件看起来不整洁,我想使用Vim的foldexpr使用正则表达式折叠这些表元素。这个正则表达式:
<table\b[^>]*>(?:(?=([^<]+))\1|<(?!table\b[^>]*>))*?</table>
用于突出Sublime Text和BBEdit中的表格代码,但我似乎无法让它在Vim中工作(非常多我的选择编辑器)。
看着“Vim Scripting the Hardway”,我希望写一个这样的简单函数:
setlocal foldmethod = expr setlocal foldexpr = GetTableFold(v:lnum)
function! GetTableFold(lnum)
if getline(a:lnum) =~? '\v<table\b[^>]*>(?:(?=([^<]+))\1|<(?!table\b[^>]*>))*? </table>
return '-1'
endif
return '0'
endfunction
为了隐藏我的文件中的表格元素,但它不起作用。当我尝试在Vim中进行简单搜索正则表达式时,我也得到一个“E64:?无所事事”错误。
非常欢迎任何想法!
答案 0 :(得分:3)
你在做这件事的方式上遇到了一些问题。首先,你的正则表达式存在语法问题(Ingo指出)。另外,我认为你不太明白vim如何计算折叠水平。 Vim为文件中的每一行调用一次“GetTableFold”函数。然后返回该特定行的折叠级别。因为您没有除行号以外的上下文,所以您不能将该行与跨越多行的正则表达式匹配。相反,您必须手动计算您的线是否落在此范围内。
我有一段时间没有写过任何vimscript,所以这可能有点儿麻烦,但似乎在我试过的几个简单案例中起作用。至少它应该为你提供一个从哪里开始的基础。
function GetTableFold(lnum)
let n = a:lnum
while n > 0
let currline = getline(n)
let prevline = getline(n-1)
if currline =~ '\v\<table\>|\<\/table\>'
return '1'
elseif currline =~ '\v^\s*$'
" special case for blank lines
return '-1'
elseif prevline =~ '\v\<\/table\>'
" special case for the line after </table>
return '0'
endif
let n -= 1
endwhile
return '0'
endfunction
set foldmethod=expr
set foldexpr=GetTableFold(v:lnum)
这会产生一些讨厌的(合理的?)假设,例如你永远不会在同一行上有<table>
和</table>
。鉴于您只在Pandoc文件中放置复杂表的用例,我认为这是一个安全的假设。它不能很好地处理表中的表。如果你需要,你必须稍微调整一下。