Why does “locate filename | xargs vim” cause strange terminal behaviour?

梦想与她 提交于 2019-11-27 15:28:01
sehe

Vim expects to be connected to a real terminal and sends codes appropriate to that.

Reset the terminal with

reset

The easiest workaround:

locate 50local.policy | xargs gvim

Rationale gui vim doesn't require a terminal

Otherwise:

vim $(locate 50local.policy)

Rationale vim is started directly connected to the terminal (instead of as a child process under xargs which in turn runs in a subshell with stdin/stdout connected to pipes instead of a terminal). It is like saying

vim /usr/some/dir/50local.policy /usr/local/some/dir/50local.policy

Alternatively

You can dodge the issue by not starting vim with the arguments, but adding the arguments from vim! Vim is in fact a lot better at running shells than shells are at running vim.

Whilst in vim:

:args `locate 50local.policy`
:rewind

This sets the argument list to the files returned from the shell command between the ticks; :rewind then goes to the first file from that list. If you were editing multiple matches, try this:

:w|next

This sequence of commands (separated by |) writes the current buffer to file, then goes to the next file in the args list.

mkomitee

An other alternative is to execute xargs with the -o option. From the man page:

-o      Reopen stdin as /dev/tty in the child process before executing
        the command.  This is useful if you want xargs to run an interac-
        tive application.

Note, -o is a BSD extension to xargs.

A more portable means to achieve the same effect is:

xargs sh -c 'vim "$@" < /dev/tty' vim
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!