【问题标题】:LLVM-IR syntax folding for VimVim 的 LLVM-IR 语法折叠
【发布时间】:2014-01-08 04:15:41
【问题描述】:

我正在使用由clang -emit-llvm 生成的 LLVM-IR 代码,并且希望代码折叠正常工作。

到目前为止,我使用的是 foldmethod=exprfoldexpr=LLVMFold()。 我想使用来自 llvm 存储库的语法文件来使用基于语法的折叠(即foldmethod=syntax)。 Available here.

请注意,第一个正则表达式来自标签的语法文件。

function! LLVMFolds()
    let thisline = getline(v:lnum)
    if match(thisline, '^[-a-zA-Z$._][-a-zA-Z$._0-9]*:') >= 0
        return ">2"
    elseif match(thisline, '^\}$') >= 0
        return "<1"
    elseif match(thisline, '{$') >= 0
        return ">1"
    else
        return "="
    endif
endfunction

这会将右大括号吞噬到 2 级折叠中。

还尝试了foldmethod=indent,它没有足够折叠,foldmethod=markerfoldmark="{,}" 理想情况下,此示例不完整的 LLVM-IR 代码:

define i32 @main() nounwind {
entry:
  %retval = alloca i32, align 4

for.cond:                                         ; preds = %entry
  %4 = load i32* %i, align 4
  %cmp1 = icmp slt i32 %4, 10
  br i1 %cmp1, label %for.body, label %for.end
}

我希望折叠从define{} 以及每个标记的部分,即从entry: 到清晰的线。

【问题讨论】:

    标签: vim syntax folding llvm-ir


    【解决方案1】:

    我不这么认为

    :set foldmethod=syntax
    

    将帮助您处理链接中的语法文件,因为该文件没有定义任何 fold 参数。

    您的 LLVMFolds() 函数似乎几乎可以满足您的需求,但是(如果我理解正确的话)您不希望折叠包含 } 行。也许您想要的是使上一行结束折叠,如下所示:

    function! Foo(lnum)
        let thisline = getline(v:lnum)
        let nextline = getline(v:lnum + 1)
        if match(thisline, '^[-a-zA-Z$._][-a-zA-Z$._0-9]*:') >= 0
            return ">2"
        elseif match(nextline, '^\}$') >= 0
            return "<1"
        elseif match(thisline, '{$') >= 0
            return ">1"
        else
            return "="
        endif
    endfunction
    

    如果{} 之间没有行,这可能会也可能不会做你想做的事。出于测试目的,请尝试

    :set fdm=expr foldexpr=LLVMFolds() fdc=5
    

    参考资料:

    :help fold-syntax
    :help :syn-fold
    :help fold-expr
    

    【讨论】:

    • “RTFM”真的有必要吗?
    • 不,但我想将三个:help 行与前面的:set 行分开,我想不出更好的办法。
    • 诸如“手册:”、“文档:”或“您可以通过阅读帮助页面了解更多信息”这样简单的东西就可以了。我知道“RTFM”在某些圈子中很常见,有些人不会被它冒犯,但很多人会。
    • nextline 是我所需要的。要遵循的解决方案。我是新手,需要等待 8 小时。
    • @jerry,我被告知 RTFM 代表“阅读精美手册”,所以我没想到它会打扰任何人。我会改变它。起初,我以为你只是在抱怨它是多余的。
    【解决方案2】:

    我已经用过这个功能了

    function! LLVMFolds()
        let thisline = getline(v:lnum)
        let nextline = getline(v:lnum + 1)
        " match start of global var block
        if match(thisline, '^@') == 0 && foldlevel(v:lnum - 1) <= 0
            return ">1"
        " match start of global struct block
        elseif match(thisline, '^%') == 0 && foldlevel(v:lnum - 1) <= 0
            return ">1"
        " matches lables
        elseif match(thisline, '^[-a-zA-Z$._][-a-zA-Z$._0-9]*:') >= 0
            return ">2"
        " keep closing brace outside  l2 fold
        elseif match(nextline, '^\}$') >= 0
            return "<2"
        " keep closing brace in l1 fold
        elseif match(thisline, '^\}$') >= 0
            return "<1"
        " open new l1 fold for open brace
        elseif match(thisline, '{$') >= 0
            return ">1"
        " for the next line being empty, close the fold for the var and struct blocks
        elseif match(nextline, '^$') >= 0
            if match(thisline, '^@') == 0 && foldlevel(v:lnum - 1) == 1
                return "<1"
            elseif match(thisline, '^%') >= 0 && foldlevel(v:lnum - 1) == 1
                return "<1"
            else
                return "="
            endif
        else
            return "="
        endif
    endfunction
    

    从第 2 级折叠中排除右大括号,并折叠全局结构和变量的初始列表。

    【讨论】:

    • 我的GitHub上提供了语法高亮和ftdetect
    猜你喜欢
    • 2011-04-23
    • 2010-10-22
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多