Comment échapper une chaîne entière dans une commande:?

13

Voyons voir. J'ai un gvimfonctionnement et je veux ouvrir un fichier, en respectant le autocmds ( ce qui exclut--remote-tab ).

Maintenant, je sais que je peux faire (en gros, avec quelques ajustements):

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

qui fonctionne. Mais si un fichier contient des espaces ou des caractères étranges, je dois faire ce qui suit:

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

(le double \\est parce que l'un d'eux est mangé par la coquille; cela équivaut à taper manuellement

`:tabe my\ file` 

dans vimet cela fonctionne). Maintenant, je peux trouver un moyen de créer cette chaîne dans le shell ou autre chose, mais j'espérais pouvoir "citer globalement" la chaîne dans la commande ": tabe", comme

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

ou

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

--- cela équivaut à écrire directement dans la ligne de commande vim :tabe "my file"; il semble que cela ne fonctionne pas. Je peux explicitement citer tout l'espace dans la chaîne avec le shell, en faisant quelque chose comme

# <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>"

mais cela ne fonctionne que pour les espaces et non pour les autres caractères spéciaux comme les tabulations et "(ni les sauts de ligne, mais si vous avez des retours à la ligne dans vos noms de fichiers, vous le méritez!).

La question :

Indépendamment du shell particulier, avec lequel je traiterai après :-), y a-t-il un moyen, en tapant directement dans la tabe:ligne vim , de citer globalement un nom de fichier sans aller citer les caractères "étranges" un par un?

Rmano
la source
1
Semble fortement dépendant de la coquille. gvim --remote-send ':tabe foo\ bar.txt<CR>'travaillé pour moi sur bash et zsh. Et les citations semblent également avoir leur importance. Si j'utilise en "interne, cela n'a pas fonctionné, mais 'a:gvim --remote-send ":tabe 'foo bar.txt'<CR>"
muru le
Hmmm ... gvim --remote-send ":tabe 'f s.txt'<CR>"n'a pas fonctionné pour moi, ni écrire :tabe 'f s.txt'en vim, j'ai compris E77: Too many files names.
Rmano
1
Ce ne serait pas gvim --servername $desktop --remote-send "<ESC>:tabe ${file// /\\ }<CR>"plus simple?
muru
1
La shellescapefonction serait-elle utile?
EvergreenTree
1
Gardez à l'esprit que :edit(et ses variantes) n'acceptent pas un nom de fichier cité. Tous les caractères spéciaux doivent être échappés individuellement. Donc, ça :edit "foo bar.txt"ne marchera pas; vous avez besoin :edit foo\ bar.txt. Cela dit, quelque chose comme ça :execute 'tabedit' escape('$file', ' ')pourrait être sur la bonne voie.
tommcdo

Réponses:

2

Pour des informations générales, et grâce à tous les commentaires, voici le script que j'utilise pour avoir un script "ouvrir dans un onglet sur le gvim sur ce bureau":

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

Ce que j'ai réussi à envoyer à Vim, c'est: '<C-\\><C-N>:1wincmd<C-q>x20w<CR>' Où l'espace est défini comme x20, ce qui signifie insérer un hex de 20 $.

Matija
la source