用于包含多行函数签名的Vim文件夹

Vim foldexpr for including multiline function signatures

本文关键字:Vim 文件夹 包含多 函数 用于      更新时间:2023-10-16

我想折叠源代码,以便在函数折叠中包含跨越多行的函数签名。例如,在c++中,我想要

void ClassName::FunctionName(LongType1 LongArgument1,
                             LongType2 LongArgument2,
                             LongType3 LongArgument3) {
  ...
}

折叠成

+-- 5 lines: void ClassName::FunctionName [...]

而不是

void ClassName::FunctionName(LongType1 LongArgument1,
                             LongType2 LongArgument2,
+-- 3 lines: LongType3 LongArgument3) [...]

,其中+表示闭合褶皱。

我能想到的唯一解决方案是为foldexpr使用一个函数,该函数有效地遍历周围的行,寻找{}

有更干净的方法吗?

我的VimFold4C插件将显示更接近你正在寻找的东西(3年前…)

+void ClassName::FunctionName(LongType1 LongArgument1, LongType2 LongArgument2, LongType3 LongArgument3) ----------

foldtext目前还不完美,但将来可能会在这个主题上得到改进。无论如何,这次您将只得到一行。

有两个问题。第二个问题可能是FoldText,你在这里是正确的。添加代码来解析文本和右括号的后续行是最好的方法。如果你担心这会拖慢进度,那就别担心。我有一个折叠文本函数,我做的远远不止这些,它不会对事物产生明显的影响。(折叠文本函数可能不像你想象的那样经常被调用;它只对可见行进行维护。)

编辑:折叠文本部分甚至比这更容易。如果您将光标放置在签名的第一个大括号处,执行normal! va{y将把签名的大括号部分放入@"。然后得到前括号部分,并将join(split((@","n"))附加到它。

另一个问题,主要问题,是折叠规则。即使对于多行签名,您似乎也希望函数折叠位于函数签名的第一行。您可以尝试使用folexpression方法来接近您想要的结果。如果每个函数(且仅函数)在最左列以'void'开头,则此文件夹将工作:

set foldexpr=getline(v:lnum+1)=~'^void'?'<0':'1'

由于这是不现实的,你可以定义一些模式来匹配你想要的所有可折叠行,也就是说,函数定义的第一行以及你想要的任何其他折叠块:

function! VimFoldLevel(line)
    "check if this is the last line in a fold block
    if getline(a:line + 1) =~ '[pattern that matches first fold lines]'
        return '<0'
    else
        return '1'
    endif
endfunction

然后确保将foldexpr设置为等于foldlevel函数c: set foldexpr=VimFoldLevel(v:lnum)

并将您的折叠方法设置为expr: set foldmethod=expr

可能还有其他方法,但这是我想到的一个…如果c++中有一些常用的折叠方法(例如,语法),并且有不同级别的折叠,您可能想要修改它。我给出的例子只提供了一级折叠,功能完全折叠或完全展开。