在Common Lisp中为vim自定义自动格式化/自动缩进的最佳方法

时间:2011-12-15 01:08:45

标签: lisp common-lisp vim

我想知道在vim for Common Lisp中自定义自动格式化/自动缩进的最佳方法。

自动格式化(我通常通过在每行的命令模式下键入' ==')对vim中的基本lisp语言非常有效(例如,defmacro,defun,lambda,if, with-output-to-string),但是在定义新语言结构的任何时候(例如,使用宏),我发现新构造的格式通常不是我喜欢的格式。

例如,这里是vim如何格式化(标准lisp构造)和&#39; awhen(常用的照应版本&#39;何时;不是lisp标准的一部分)< / p>

(when 'this
  (process 'this))

(awhen 'this
       (process it))

我希望自动格式化,比如“。我有什么想法可以做到这一点吗?

编辑:感谢Gilligan和Tamas提出的Slimv建议。作为测试,我下载了MacVim(将需要这个与终端vim一起使用,但这是一个不同的问题)和slimv,将精简版下载到〜/ .vim,启动MacVim,并加载.lisp文件。

然后我启动了lisp服务器(通过带有MacVim的GUI完成),它加载了我的默认lisp可执行文件和核心文件。

并且*因为我的核心文件已经加载了我经常使用的语言扩展名(awhen是其中之一),所以开箱即用的格式正确。

我真的很喜欢这个解决方案。而不是[1]必须学习如何告诉vim正确缩进特定函数,[2]为我定义的每个语言扩展编写明确执行此操作的代码,并且[3]每次添加新代码时都会更新代码语言结构。相反,我利用slimv为我做格式化。苗条可以学习&#39;新的语言扩展,只要这些宏已经加载到服务器会话正在使用的lisp核心中。非常光滑!

我发现这适用于特定类型的语言扩展。通常使用&amp; body关键字定义为宏。这似乎做了正确的事情&#39;大部分时间,但我使用的宏仍然没有正确自动格式化。虽然我说这更像是宏写法(非标准语言扩展)的问题,而不是其他任何问题。

因此,对于大多数情况,这个解决方案对我来说效果很好,而且我没有必要编码(和维护)任何东西。好东西!

3 个答案:

答案 0 :(得分:5)

这可能不是您问题的直接答案,但我强烈建议您安装 slimv插件:http://www.vim.org/scripts/script.php?script_id=2531

它是一个很棒的插件,它将SLIME功能集成到vim中,除了许多其他功能之外,它还带有改进的clisp和clojure缩进功能。它不会以你想要的方式缩进。

答案 1 :(得分:3)

对于那些正在寻找这个主题并且不想运行Slimv的人,因为他们没有使用Common Lisp或其他原因,所以这是独家新闻。

Vim的Lisp缩进与其他语言不同;它有一个特殊的&#34; Lisp模式&#34;。

打开此模式
:set lisp

自动为.lisp个文件完成。 Lisp模式不是Vim的发明;经典的Vi实现使用:set lisp启用了Lisp模式。 (不幸的是,POSIX没有描述它。)

Vim的Lisp模式有一个简单的机制来识别需要操作符样式缩进的表单:即,有一个名为lispwords的参数,它包含逗号分隔的标识符列表。

您可以向自己证明这是使用的标识符列表,即使您正在编辑具有语法突出显示功能的Common Lisp .lisp文件时也是如此。只需执行:set listwords[TAB]并修改列表即可从中删除内容,例如defun。然后尝试重新加入defun:您现在将看到函数式缩进而不是运算符样式。

对Common Lisp的语法突出显示支持与Lisp模式的lispwords参数分开;它有自己的标识符列表。例如,在Vim 7.3中输入:

(symbol-macrolet ((foo bar))
                 you get indented out to here!)

尽管symbol-macrolet被识别并着色,但这仍然存在。为什么?这是因为symbol-macrolet没有出现在相当稀疏的lispwords列表中,而 出现在lisp.vim语法高亮定义文件中。

结果是,您可以将一些脚本扫描在一起,该脚本扫描您的.lisp文件目录中的宏,并生成set lispwords=...命令,该命令放在目录.vimrc中。

或者,如果您正在使用自定义Lisp方言,则可以在加载时使其Vim语法突出显示文件自定义lispwords

这是一个实施疏忽:lispwords选项没有本地值;您无法使用setlocal lispwords ...为其指定缓冲区特定值。换句话说,似乎(至少在Vim 7.3中我在Ubuntu下使用)你不能打开两个或多个缓冲区,持有不同的Lisp方言和不同的缩进标识符。 lispwords的默认内容包含一小部分Lisp Scheme符​​号,试图成为一种&#34;一种尺寸几乎适合所有&#34;溶液

答案 2 :(得分:1)

如果你的文件类型是'lisp',那么我认为你需要在'/ vim7x / indent'目录的'lisp.vim'文件中为你的特殊情况添加缩进规则。您可以在:h indent-expr:h indentexpr的帮助中找到更多信息。

有人可能能够更好地告诉你,但我相信默认的lisp.vim缩进文件基本上什么都不做,因为内置函数lispindent()用于获取缩进值。你会想:

(1)set函数用于将缩进值(即indentexpr)提取到您自己的indent / lisp.vim文件中的函数,例如GetLispIndent()。
(2)在你的GetLispIndent()函数中,你将使用lispindent()来获取除特殊情况之外的所有行的缩进值。查看其他语言的缩进文件并阅读文档以了解indentexpr的工作原理,例如java.vim。