¿Cómo escapar de una cadena completa en un comando?

13

Veamos. Tengo una gvimejecución y quiero abrir un archivo, respetando el autocmds ( que descarta--remote-tab ).

Ahora sé que puedo hacer (básicamente, con algunos ajustes):

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

que funciona Pero si un archivo tiene espacios o caracteres extraños, tengo que hacer lo siguiente:

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

(el doble \\se debe a que uno de ellos es comido por el caparazón; esto es equivalente a escribir manualmente

`:tabe my\ file` 

en vimy funciona). Ahora, puedo encontrar una manera de crear esa cadena en el shell o lo que sea, pero esperaba poder "citar globalmente" la cadena en el comando ": tabe", como

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

o

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

--- esto es equivalente a escribir directamente en la línea de comando vim :tabe "my file"; Parece que no está funcionando. Puedo citar explícitamente todo el espacio en la cadena con el shell, haciendo 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>"

pero funciona solo para espacios y no para otros caracteres especiales como pestañas y "(ni líneas nuevas, pero si tiene líneas nuevas en los nombres de sus archivos, ¡se lo merece!).

La pregunta :

Independientemente del shell en particular, con el que trataré después :-), ¿hay alguna forma de escribir directamente en la tabe:línea vim para citar globalmente un nombre de archivo sin citar los caracteres "extraños" uno por uno?

Rmano
fuente
1
Parece altamente dependiente de la concha. gvim --remote-send ':tabe foo\ bar.txt<CR>'trabajó para mí en bash y zsh. Y las citas también parecen importar. Si lo uso "internamente, no funcionó, pero 'funcionó:gvim --remote-send ":tabe 'foo bar.txt'<CR>"
muru
Hmmm ... gvim --remote-send ":tabe 'f s.txt'<CR>"no funcionó para mí, ni escribir :tabe 'f s.txt'en vim, lo conseguí E77: Too many files names.
Rmano
1
¿No gvim --servername $desktop --remote-send "<ESC>:tabe ${file// /\\ }<CR>"sería más simple?
muru
1
¿ shellescapeSería útil la función?
EvergreenTree
1
Tenga en cuenta que :edit(y sus variantes) no acepta un nombre de archivo citado. Todos los caracteres especiales deben escaparse individualmente. Entonces, :edit "foo bar.txt"no funcionará; lo que necesita :edit foo\ bar.txt. Dicho esto, algo así :execute 'tabedit' escape('$file', ' ')podría estar en el camino correcto.
tommcdo

Respuestas:

2

Para información general, y gracias a todos los comentarios, este es el script que uso para tener un script "abrir en una pestaña en el gvim en este escritorio":

#!/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
fuente
0

Lo que he logrado enviar a Vim es: '<C-\\><C-N>:1wincmd<C-q>x20w<CR>' donde el espacio se define como x20, lo que significa insertar hexadecimal $ 20.

Matija
fuente