vim过滤器和stdout/stderr

ahe*_*ahe 9 vim

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

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

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

Cur*_*son 5

:!{cmd}执行{cmd}shell和设置v:shell_error.

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

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

nmap <leader>filter :%!/path/to/filter<CR>:call UndoIfShellError()<CR>
Run Code Online (Sandbox Code Playgroud)


ZyX*_*ZyX 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)
Run Code Online (Sandbox Code Playgroud)

  • 我只知道另一种方法:使用`system()`,将stderr重定向到临时文件(或`/dev/null`),将stdout保存到某个变量并使用`v:shell_error`来确定命令在覆盖之前是否失败缓冲。请注意,“:!”过滤器取代了“!” 与前一个命令和“%”与当前文件名,而“system()”则不然。 (2认同)