Vim 编辑器自定义语法折叠规则遇到问题,如何设置 'if endif' 折叠?

新手上路,请多包涵

求助:vim 自定义语法折叠
vim的折叠方式有好几种,但想自己写个语法折叠。

看帮助文档里面,只有简单的介绍一个例子:
"fold" 参数使得本项目的折叠级别加 1。示例: >
:syn region myFold start="{" end="}" transparent fold
:syn sync fromstart
:set foldmethod=syntax
这使得每个 {} 块形成一个折叠。
然而,将{}替换成其他的,例如 if endif ,均不成功,只有花括号才成功。
请教一下有哪位知道要怎么设置?例如设置成 "if" "endif" 之类的

阅读 1.7k
avatarAI BotBETA

在 Vim 中设置基于 ifendif 的语法折叠,你需要使用 Vim 的语法高亮(syntax highlighting)和折叠(folding)功能。由于 Vim 的语法文件(通常是 .vim 文件)定义了如何高亮和折叠代码,你需要编写或修改一个语法文件来识别 ifendif 之间的区域作为折叠区域。

以下是一个简化的步骤和示例,说明如何为 Vim 创建一个基本的语法折叠规则,用于识别 ifendif 的代码块:

  1. 创建或修改语法文件
    首先,你需要一个语法文件(.vim 文件),这个文件定义了如何识别你的代码结构。假设你的文件名为 mylang.vim,并放在 Vim 的 syntax 文件夹中(或者在你的 ~/.vim/syntax 文件夹中,如果你使用的是个人 Vim 配置)。
  2. 定义折叠区域
    在语法文件中,你可以使用 syn region 命令来定义一个区域,这个区域从 if 开始到 endif 结束。但是,由于 Vim 的语法引擎不直接支持跨行匹配(如从 ifendif),你需要使用其他技巧,如匹配 if 并使用 syn sync 来尝试同步到 endif,但这通常不直接支持。

    一个更实用的方法是使用 Vim 的 foldmethod=markerfoldmethod=expr,但如果你坚持使用 foldmethod=syntax,你可能需要定义多个区域或使用正则表达式来近似匹配。

    然而,这里有一个简化的示例,它使用 foldmethod=expr 来实现基于 if/endif 的折叠,因为 foldmethod=syntax 直接处理可能较为复杂:

    " 在你的 vimrc 或类似的配置文件中设置
    autocmd FileType mylang setlocal foldmethod=expr foldexpr=GetMyLangFold(v:lnum)
    
    " 定义一个 Vim 函数来返回折叠级别
    function! GetMyLangFold(lnum)
      let line = getline(a:lnum)
      if line =~? '^if\s'
        return '>1'
      elseif line =~? '^endif\s'
        return '<1'
      else
        return '='
      endif
    endfunction

注意:上面的示例使用了 Vim 脚本(VimL)来定义一个函数 GetMyLangFold,该函数根据行内容返回折叠级别。这要求你设置 foldmethod=expr 并指定 foldexpr 为这个函数。

  1. 应用语法文件
    确保 Vim 能够找到并加载你的语法文件。你可以通过在你的 .vimrc 文件中添加 autocmd 来自动为特定文件类型设置语法和折叠方法。

请注意,上述示例使用了 foldmethod=expr 而不是 foldmethod=syntax,因为 foldmethod=syntax 通常需要语法文件内部定义折叠区域,这在使用 if/endif 时较为复杂。使用 foldmethod=expr 提供了更大的灵活性,但可能需要更多的 Vim 脚本知识。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏