Como escapar uma string inteira em um comando:?

13

Vamos ver. Eu tenho uma gvimcorrida e quero abrir um arquivo, respeitando os autocmd(o que exclui--remote-tab ).

Agora eu sei que posso fazer (basicamente, com alguns ajustes):

gvim --remote-send ":tabe my_file<CR>" 

que funciona Mas se um arquivo tiver espaços ou caracteres estranhos, eu tenho que fazer o seguinte:

gvim --remote-send ":tabe my\\ file<CR>"

(o dobro \\é porque um deles é comido pela casca; isso é equivalente ao tipo manualmente

`:tabe my\ file` 

no vime ele funciona). Agora, posso encontrar uma maneira de criar essa string no shell ou qualquer outra coisa, mas esperava poder "citar globalmente" a string no comando ": tabe", como

 gvim --remote-send ":tabe 'my file'<CR>"

ou

 gvim --remote-send ":tabe \"my file\"<CR>"

--- isso é equivalente a escrever diretamente na linha de comando do vim :tabe "my file"; parece que não está funcionando. Eu posso citar explicitamente todo o espaço na string com o shell, fazendo algo como

# <ESC> because the gvim instance can be in a mode different from normal
# the double CR: do not ask. 
# the argument MUST be a full path
file="$(readlink -f "$@")"
fileq="$(echo "$file" |  awk '{gsub(/ /,"\\\ ")}1')" # quote spaces FIXME add other chars
exec gvim 2>/dev/null --servername $desktop --remote-send "<ESC>:tabe $fileq <CR><CR>"

mas funciona apenas para espaços e não para outros caracteres especiais, como tabulações e "(nem novas linhas, mas se você tiver novas linhas nos nomes dos arquivos, você merece!).

A questão :

Independentemente do shell em particular, com o qual tratarei depois :-), existe uma maneira de digitar diretamente na tabe:linha vim para citar globalmente um nome de arquivo sem citar os caracteres "estranhos" um por um?

Rmano
fonte
1
Parece altamente dependente do shell. gvim --remote-send ':tabe foo\ bar.txt<CR>'trabalhou para mim no bash e zsh. E as citações parecem importar também. Se eu uso "internamente, não funcionou, mas 'funcionou:gvim --remote-send ":tabe 'foo bar.txt'<CR>"
muru 21/02
Hmmm ... gvim --remote-send ":tabe 'f s.txt'<CR>"não funcionou para mim, nem escrevi :tabe 'f s.txt'no vim, entendi E77: Too many files names.
Rmano 21/02
1
Não gvim --servername $desktop --remote-send "<ESC>:tabe ${file// /\\ }<CR>"seria mais simples?
muru
1
A shellescapefunção seria útil?
EvergreenTree
1
Lembre-se de que :edit(e suas variantes) não aceitam um nome de arquivo citado. Todos os caracteres especiais precisam ser escapados individualmente. Então, :edit "foo bar.txt"não vai funcionar; você precisa :edit foo\ bar.txt. Dito isto, algo como :execute 'tabedit' escape('$file', ' ')pode estar no caminho certo.
Tommcdo

Respostas:

2

Para informações gerais, e graças a todos os comentários, este é o script que eu uso para ter um script "aberto em uma guia no gvim nesta área de trabalho":

#!/bin/bash -x
#
# this is convoluted because it has to finish in an exec to keep the DM happy
# remember to set StartupNotify=false in the .desktop file
#
desktop=desktop_$(xprop -root -notype  _NET_CURRENT_DESKTOP | perl -pe 's/.*?= (\d+)/$1/')

if ! vim --serverlist | grep -iq $desktop; then #we need to start the server
    if [ $# != 0 ]; then 
        exec gvim 2>/dev/null --servername $desktop "$@"
    else
        exec gvim 2>/dev/null --servername $desktop  #no files 
    fi
fi
# the only case here is if we need to open a tab in an existing server
if [ $# != 0 ]; then  
        # Do not use --remote-tab, see http://vi.stackexchange.com/questions/2066/different-autocmd-behavior-when-using-remote-tab-silent
        # <ESC> because the gvim instance can be in a mode different from normal
        # the double CR: do not ask. 
        # the argument MUST be a full path
        file="$(readlink -f "$@")"
        #fileq="$(echo "$file" |  awk '{gsub(/ /,"\\\ ")}1')" # quote spaces FIXME add other chars
        fileq=${file// /\\ } # quote spaces FIXME add other chars
        exec gvim 2>/dev/null --servername $desktop --remote-send "<ESC>:tabe $fileq <CR><CR>"
fi
Rmano
fonte
0

O que eu consegui enviar para o Vim é: '<C-\\><C-N>:1wincmd<C-q>x20w<CR>' Onde o espaço é definido como x20, o que significa inserir hex $ 20.

Matija
fonte