14

Let's see. I have a gvim running and I want open a file, respecting the autocmds (which rules out --remote-tab).

Now I know I can do (basically, with some tweak):

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

which works. But if a file has spaces or strange chars in it, I have to do the following:

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

(the double \\ is because one of them is eaten by the shell; this is equivalent to manually type

`:tabe my\ file` 

in vim and it works). Now, I can find a way to create that string in the shell or whatever, but I hoped I could "globally quote" the string in the ":tabe" command, like

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

or

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

--- this is equivalent to writing directly in the vim command line :tabe "my file"; it seems it is not working. I can explicitly quote all space in the string with the shell, doing something like

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

but it works just for spaces and not other special chars like tabs and " (nor newlines, but if you have newlines in your file names you deserve it!).

The question:

Independently on the particular shell, with which I will deal after :-), is there a way when directly typing in the vim tabe: line to globally quote a filename without going to quote the "strange" chars one by one?

Rmano
  • 758
  • 5
  • 18
  • 1
    Seems highly shell dependent. gvim --remote-send ':tabe foo\ bar.txt<CR>' worked for me on bash and zsh. And the quotes seem to matter too. If I use " internally, it didn't work, but ' did: gvim --remote-send ":tabe 'foo bar.txt'<CR>" – muru Feb 21 '15 at 11:12
  • Hmmm... gvim --remote-send ":tabe 'f s.txt'<CR>" didn't work for me, nor writing :tabe 'f s.txt' in vim, I got E77: Too many files names. – Rmano Feb 21 '15 at 12:00
  • I jumped the gun a bit. For me, a tab opens alright, but the filename is 'foo bar.txt', with the quotes. But a single backslash still works, as does foo="f\ s.txt" gvim --remote-send ":tabe $foo<CR>". – muru Feb 21 '15 at 12:07
  • @muru yep I have fileq="$(echo "$file" | awk '{gsub(/ /,"\\\ ")}1')" and gvim --servername $desktop --remote-send "<ESC>:tabe $fileq <CR><CR>" which works, but just for spaces... – Rmano Feb 21 '15 at 12:20
  • 1
    Wouldn't gvim --servername $desktop --remote-send "<ESC>:tabe ${file// /\\ }<CR>" be simpler? – muru Feb 21 '15 at 12:25
  • @muru probably yes. Although working just for spaces again... – Rmano Feb 21 '15 at 12:27
  • I have one twisted idea: Keep a fixed file open in GVim, write your filename to that file, have Vim autoreload its contents and open any new lines in new tabs. – muru Feb 21 '15 at 13:00
  • Have you tried replacing spaces with <Space>? Since <Esc> and <Cr> is captured by Vim and interpreted correctly maybe <Space> would too – Sukima Feb 21 '15 at 13:27
  • @Sukima -- the problem is that I would like a way to quote the whole string without having to substitute anything. The solution for spaces works, but it's not generic (what about ", or other special chars?) – Rmano Feb 21 '15 at 13:34
  • 1
    Would the shellescape function be helpful? – EvergreenTree Feb 21 '15 at 19:13
  • 1
    Keep in mind that :edit (and its variants) doesn't accept a quoted filename. All special characters need to be individually escaped. So, :edit "foo bar.txt" won't work; you need :edit foo\ bar.txt. That said, something like :execute 'tabedit' escape('$file', ' ') might be on the right track. – tommcdo Feb 22 '15 at 03:13

2 Answers2

2

For general info, and thanks to all the comments, this is the script I use to have an "open in a tab on the gvim on this desktop" script:

#!/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
  • 758
  • 5
  • 18
0

What i've managed to send to Vim is: '<C-\\><C-N>:1wincmd<C-q>x20w<CR>' Where space is defined as x20 which means insert hex$20.

Matija
  • 1