Vimscript 缩进和调试 ftplugin 脚本

Vimscript indent and debugging ftplugin scripts

我正在尝试使用 ftplugin 脚本为 .tex 文件手动定义缩进级别。

~/.vim/ftplugin/tex/indent.vim:

      1 setlocal indentexpr=TeXIndent(v:lnum)
      2
      3 function! TeXIndent(lnum)
      4     if a:lnum == 0
      5         return 0
      6     endif
      7
      8     let prev = getline(a:lnum - 1)
      9     let line = getline(a:lnum)
     10
     11     " sections have hardcoded indentation; environments are always subordinate to sections
     12     if prev =~ '^\s*\section'
     13         return 1
     14     elseif prev =~ '^\s*\subsection'
     15         return 2
     16     elseif prev =~ '^\s*\subsubsection'
     17         return 3
     18     elseif prev =~ '^\s*\paragraph'
     19         return 4
     20     " environment indentation
     21     elseif prev =~ '\begin'
     22         return indent(a:lnum - 1) + 1 " increase indentation by 1 if previous line has \begin
     23     elseif line =~ '\end'
     24         return indent(a:lnum - 1) - 1 " decrease indentation by 1 if line has \end
     25     else
     26         return indent(a:lnum - 1) " use previous indentation
     27     endif
     28 endfunction

当我键入 \section 时,我希望按 enter 将光标移动到下一行的缩进级别 1(其他条件相同,在 TeXIndent 中指定) ), 而事实并非如此。使用更简单的函数进行测试,每次 returns 2 也没有这种行为,所以我怀疑我的方法有缺陷。我如何实现预期的行为?

一般情况下,ftplugin脚本如何调试?

调试 ftplugin 时所有常用方法都可用。

  • :debug exe "normal keysequence"可用于调试映射
  • :debug Command可用于调试命令、函数(使用:debug call:debug echo)...
  • :verbose 可用于了解实际定义的内容以及定义的位置——请参阅 vi.SE 上的专用 Q/A:https://vi.stackexchange.com/q/7722/626
  • 也可以使用日志——参见 my framework
  • 我们甚至可以添加一些断言以在编程错误时快速失败——请参阅我的 other framework(来自相同的库插件)

现在您的问题不在于 ftplugins,而在于缩进表达式。如果我没记错的话,它面临着与折叠表达式相同的问题:indenting/folding 函数由 Vim 每行自动调用一次。消息将被静音,:debug 的内部使用将以噩梦告终。

我们能做什么:

  • log 到一个文件,或者其他地方像 qf window

  • 不要将函数绑定到 v:lnum 以便能够独立调用该函数。太完美了,你已经做到了。我们可以使用

    测试所有调用的响应
      :echo map(range(1, line('$')), 'the_expr_function(v:val)')
    
  • 玩气球(需要gvim而不是vim)

  • 玩符号

您会在我维护的 folding plugin 中找到这些方法。

(另见 vi.SE 上的 Q/A:https://vi.stackexchange.com/a/19916/626

PS:缩进插件应该进入{rtp}/indent/,而不是{rtp}/ftplugin/,我们通常分析最后一个非空行。你应该在 $VIMRUNTIME/indent 中找到示例,我有几个 Johannes Zellner 大约在 2002 年编写的 TeX 缩进插件。