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

Cla*_*ley 6 lisp vim common-lisp

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

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

例如,这里是vim格式'何时(标准lisp构造)和'awhen(通常使用的'当时的aaphoric版本;不是lisp标准的一部分)

(when 'this
  (process 'this))

(awhen 'this
       (process it))
Run Code Online (Sandbox Code Playgroud)

我想像''那样'自动格式化'.我有什么想法可以做到这一点?

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

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

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

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

我发现这适用于特定类型的语言扩展.通常使用&body关键字定义为宏.这似乎在大多数时候"做正确的事",但我使用的宏仍然没有正确自动格式化.虽然我会说这更像是宏写法(非标准语言扩展)的问题,而不是其他任何问题.

所以,对于大多数情况,这个解决方案对我来说效果很好,而且我不需要编码(和维护)任何东西.好东西!

gil*_*gan 5

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

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

  • 如果连接到 swank 服务器并且 awhen 在当前 REPL 中定义,Slimv 也会正确缩进 awhen。缩进基于从 swank 服务器获取的运行时信息,就像 Emacs 中的 Slime 一样。 (2认同)

Kaz*_*Kaz 5

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

Vim 的 Lisp 缩进与其他语言不同;它有一个特殊的“Lisp 模式”。该模式的开启方式为

:set lisp
Run Code Online (Sandbox Code Playgroud)

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

Vim 的 Lisp 模式有一个简单的机制来识别需要运算符样式缩进的形式:即,有一个名为 的参数,lispwords它保存以逗号分隔的标识符列表。

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

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

(symbol-macrolet ((foo bar))
                 you get indented out to here!)
Run Code Online (Sandbox Code Playgroud)

尽管事实是这样的,但这symbol-macrolet是被认可和着色的。为什么?这是因为它symbol-macrolet没有出现在相当少的lispwords列表中,而它确实出现在lisp.vim语法突出显示定义文件中。

结果是您可以组合一些脚本来扫描.lisp文件目录中的宏并生成set lispwords=...放置到目录中的命令.vimrc

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

这是一个实施疏忽:该lispwords选项没有本地价值;你不能用setlocal lispwords ...它来给它一个特定于缓冲区的值。换句话说,看起来(至少在我在 Ubuntu 下使用的 Vim 7.3 中)你不能打开两个或多个缓冲区来保存具有不同缩进标识符的不同 Lisp 方言。默认内容lispwords包含少量 LispScheme 符号,试图成为一种“一刀切”的解决方案。