9

我使用 vim 并希望它可以防止我保存具有解析错误的 php 文件。如果我想使用例如“php -l <​​file>”来实现这一点,.vimrc 中的 autocmd 会是什么样子?

我知道我可以通过类似的方式连接到 BufWritePre

autocmd FileType php autocmd BufWritePre * !php -l %

但如果 php 命令失败,我希望它中止“写入”。

4

2 回答 2

5

你可以在钩子中抛出一个未捕获的异常,它会中止写:

function s:RunPHP()
    execute '!php -l' shellescape(@%, 1)
    if v:shell_error | throw 'PHP failed' | endif
endfunction

function s:DefineBWPphpevent()
    augroup Run_php
        autocmd! BufWritePre <buffer> :call s:RunPHP()
    augroup END
endfunction

augroup Run_php
    autocmd!
    autocmd FileType  *  :autocmd! Run_php BufWritePre <buffer>
    autocmd FileType php :call s:DefineBWPphpevent()
augroup END

另请注意

  1. shellescape:你不应该使用:!shell_command %这里 vim 没有正确转义,如果文件名包含特殊符号,如空格、引号、美元、换行符,你会遇到麻烦...
  2. <buffer>代替*第二种模式。您的原始命令没有为 php 文件定义自动命令,而是为所有文件类型定义自动命令(如果文件类型之一是 php)。
  3. autocmd 分组和 banged :autocmd!s:它们防止重复自动命令。

顺便说一句,你想通过在旧版本的文件上运行 php 来实现什么(它是 BufWrite Pre事件,所以它发生在文件写入之前)?也许您应该将运行 php 的代码替换为:w !php -l:w !php -l -或者甚至:w !php -l /dev/stdin取决于 php 接受的内容(我的系统上没有它,也不想拥有)。

于 2011-05-20T15:54:36.503 回答
2

但如果 php 命令失败,我希望它中止“写入”。

据我所知,这对于 VIM 是不可能的。文档也没有说明这种能力,所以我很确定如果没有 hack 就无法做到。问题是你想要完成什么?我有一个脚本,可以确保在我提交版本控制之前在 PHP 中没有解析错误,而不是在我保存文件时。那是一个简单的预提交钩子,也许那会起作用?

如果您真的对在保存文件之前进行 linting 感兴趣,您可以将 "ZZ" 和 ":w" 重写为您自己编写的命令,从而对文件进行 lint(如果是 PHP 文件)和保存在没有错误。我不确定您是否可以重新映射:w,但它可能会导致比它解决的问题更多的问题。

也许一个更简单的解决方案是在您自己选择的按键上创建一个命令(例如 F5),并让它做您想做的事情?

于 2011-05-19T09:14:02.690 回答