vim过滤器和stdout / stderr

时间:2010-04-04 19:59:40

标签: vim

当我使用:%!通过筛选器运行文件的内容,并且筛选器失败(它返回0以外的其他代码)并向stderr输出错误消息我将此文件替换为此错误消息。如果过滤器返回指示错误的状态代码和/或忽略过滤器程序写入stderr的输出,有没有办法告诉vim跳过过滤?

在某些情况下,您希望将文件替换为过滤器的输出,但通常这种行为是错误的。当然,我可以用一个按键撤消过滤,但这不是最佳的。

在编写自定义vim脚本进行过滤时,我也遇到了类似的问题。我有一个脚本,用system()调用过滤器程序,并用它的输出替换缓冲区中的文件,但似乎没有办法检测system()返回的行是否写入stdout或stderr 。有没有办法在vim脚本中区分它们?

5 个答案:

答案 0 :(得分:5)

:!{cmd}使用shell执行{cmd}并设置v:shell_error

如果您碰巧设置映射来调用过滤器,则可以执行以下操作:

function! UndoIfShellError()
    if v:shell_error
        undo
    endif
endfuntion

nmap <leader>filter :%!/path/to/filter<CR>:call UndoIfShellError()<CR>

答案 1 :(得分:3)

您可以使用Python来区分stdout和stderr:

python import vim, subprocess
python b=vim.current.buffer
python line=vim.current.range.start
python p=subprocess.Popen(["command", "argument", ...], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
python returncode=p.poll()
python if not returncode: b.append(("STDOUT:\n"+p.stdout.read()+"\nSTDERR:\n"+p.stderr.read()).split("\n"), line)

答案 2 :(得分:1)

另一种方法是运行filter命令,例如它修改磁盘上的文件。

例如,对于gofmt(www.golang.org),我有这些映射:

map <f9> :w<CR>:silent !gofmt -w=true %<CR>:e<CR>
imap <f9> <ESC>:w<CR>:silent !gofmt -w=true %<CR>:e<CR>

说明: :w - 保存文件 :沉默 - 避免在最后按Enter键 % - 将文件传递给gofmt -w = true - 告诉gofmt写回文件 :e - 告诉vim重新加载修改后的文件

答案 3 :(得分:1)

在Vim 7中添加了新的自动命令事件:ShellCmdPostShellFilterPost

augroup FILTER_ERROR
  au!
  autocmd ShellFilterPost * if v:shell_error | undo | endif
augroup END

答案 4 :(得分:0)

这就是我最终做的事情:

function MakeItAFunction(line1, line2, args)
  let l:results=system() " call filter via system or systemlist
  if v:shell_error
    "no changes were ever actually made!
    echom "Error with etc etc"
    echom results
  endif
  "process results if anything needed?

  " delete lines but don't put in register:
  execute a:line1.",".a:line2." normal \"_dd"
  call append(a:line1-1, l:result)  " add lines
  call cursor(a:line1, 1)  " back to starting place
  " echom any messages
endfunction
command -range <command keys> MakeItAFunction(<line1>,<line2>,<q-args>) 
"                                         or <f-args>, etc.

您可以在http://vim.wikia.com/wiki/Perl_compatible_regular_expressions

看到我的完整代码

它很复杂,但它有效,当它被使用时,它相当透明和优雅。希望以任何方式有所帮助!