Da ajuda :help backtick-expansion
:
On Unix and a few other systems you can also use backticks for the file name
argument, for example:
:next `find . -name ver\\*.c -print`
:view `ls -t *.patch \| head -n1`
The backslashes before the star are required to prevent the shell from
expanding "ver*.c" prior to execution of the find program. The backslash
before the shell pipe symbol "|" prevents Vim from parsing it as command
termination.
Se eu digitar o comando retirado da ajuda, recebo um erro:
:next `find . -name ver\\*.c -print
E79: Cannot expand wildcards
Por que o exemplo da ajuda usa duas barras invertidas em vez de uma e por que não funciona?
O seguinte trabalho:
Se eu remover uma das duas barras invertidas que protegem a estrela de ser expandida pelo shell antes do
find
programa::next `find . -name ver\*.c -print`
Se eu remover as duas barras invertidas e colocar aspas simples em torno do padrão
ver*.c
::next `find . -name 'ver*.c' -print`
Até esse ponto, a regra parece ser:
se o seu comando shell contiver uma estrela e você não quiser que o shell o expanda antes do comando, coloque uma barra invertida na frente ou aspas simples ao redor do padrão .
Mas a ajuda dá outro exemplo:
:view `ls -t *.patch \| head -n1`
Este comando funciona sem nenhuma modificação, sem necessidade de aspas simples, sem necessidade de barra invertida.
Suponho que o motivo pelo qual ele funcione é porque o ls
comando (ao contrário do -name
argumento do find
comando) aceita vários argumentos de arquivo e não vê nenhum problema com o shell em expansão *.patch
.
Agora, digamos que eu quero olhar para todos os arquivos com a extensão .conf
dentro da /etc
pasta e envia a saída de find
para grep
de obter apenas os jogos contêm a cadeia input
.
No shell, em qualquer diretório de trabalho, digitei:
find /etc -name '*.conf' | grep input
E funcionaria.
No vim, digitarei o mesmo comando colocando barras em volta dele e uma barra invertida na frente do símbolo de pipe para impedir que o vim interprete-o como uma finalização de comando:
:next `find /etc -name '*.conf' \| grep input`
E isso funciona.
Agora, se eu digitar o mesmo comando sem o pipe e o grep input
, recebo um erro:
:next `find /etc -name '*.conf'`
E79: Cannot expand wildcards
Por que existe um erro neste caso, mesmo que eu tenha protegido a estrela com aspas simples?
E por que há um erro agora, mas não antes com o pipe e o grep input
?
Para tentar entender, criei um comando mais simples:
find . -name '*.conf'
Ele procura todos os arquivos com a extensão .conf
no diretório de trabalho. O comando funciona no shell.
Para testá-lo no vim, digitei: :next `find . -name '*.conf'`
E funciona. Nesse caso, o ponto representa meu diretório de trabalho atual, conforme exibido pelo comando Ex, :pwd
que é o meu diretório pessoal /home/username
desde que iniciei a sessão do vim.
Por que funciona quando solicito pesquisar no diretório de trabalho atual, enquanto não funciona quando solicito pesquisar em uma pasta arbitrária como /etc
?
Agora, se eu mudar meu diretório de trabalho de /home/username
para para /etc
com o comando vim Ex :cd /etc
e tentar novamente o mesmo comando de antes, novamente ocorrerá um erro:
:next `find . -name '*.conf'`
E79: Cannot expand wildcards
Por que o mesmo comando funciona quando estou na minha pasta pessoal, mas não quando estou /etc
?
Tenho certeza de que há alguma lógica, mas não consigo encontrar uma.
Qual é a sintaxe geral e correta para preencher o arglist com um comando de shell arbitrário (contendo uma estrela, um pipe, pesquisando em qualquer diretório de qualquer diretório ativo)?
Estou usando a versão 7.4.942 do vim e o zsh é meu shell padrão. Testei esses comandos com um mínimo de inicializações ( vim -u NORC -N
) do bash e do zsh.
Preciso configurar o vim para chamar bash e não zsh?
fonte
vim $(find . -name ver*.c)
vim $(find . -name ver\*.c -print)
,vim $(ls -t *.patch | head -n1)
,vim $(find /etc -name '*.conf' | grep input)
,vim $(find /etc -name '*.conf')
,vim $(find . -name '*.conf')
--remote
, consulte: vi.stackexchange.com/a/5618/4939 ), mas estou curioso para saber como faça isso diretamente da sessão atual. Se não for possível, tudo bem, mas depois de ler a ajuda, parece que isso pode ser feito. Se for, eu gostaria de entender por que o vim reage de maneira tão diferente a comandos semelhantes.find /etc -name '*.conf'
não funcionar, acho que alguns nomes engraçados saem desse comando e, esse pode ser o motivo pelo qual ele funcionou quando transmitidogrep
.Respostas:
Ainda não sei como usar o backtick-expansion para preencher o arglist com um comando shell arbitrário, no entanto, encontrei uma solução alternativa.
De
:help `=
:Então, em vez de expandir diretamente um comando shell como este:
Podemos enviar o comando shell para a função Vim
systemlist()
e usar o registrador de expressão=
para expandir a expressão resultante assim:Para salvar algumas teclas, defini o seguinte comando Ex no meu vimrc (
:PA
para Populate Arglist):E testou-o com vários comandos do shell:
Até agora, ele funciona como o esperado e o comando pode ser digitado como seria no shell (não é necessário escapar do cano, por exemplo).
Parece mais consistente e confiável do que a expansão direta do backtick.
fonte