stsewd / fzf-checkout.vim

Manage branches and tags with fzf
MIT License
207 stars 18 forks source link

General Backslash problems (and Windows explicit) #61

Open Grueslayer opened 3 years ago

Grueslayer commented 3 years ago

Hi there,

thanx for this plugin.

You are using substitute for the replacement of the placeholder, e..g.

 let l:Execute_command = l:actions[l:action]['execute']
  if type(l:Execute_command) == v:t_string
    let l:Execute_command = substitute(l:Execute_command, '{git}', g:fzf_checkout_git_bin, 'g')
    let l:Execute_command = substitute(l:Execute_command, '{cwd}', fzf_checkout#get_cwd(), 'g')
    let l:Execute_command = substitute(l:Execute_command, '{branch}', l:branch, 'g')
    let l:Execute_command = substitute(l:Execute_command, '{tag}', l:branch, 'g')
    let l:Execute_command = substitute(l:Execute_command, '{input}', l:input, 'g')
    execute l:Execute_command
  elseif type(l:Execute_command) == v:t_func
    call l:Execute_command(g:fzf_checkout_git_bin, l:branch, l:input)
  endif            

Lets assume you are on a Linux machine in a directory

/some/where/dir with 'quote

then fnameescape will:

        When the 'shell' contains powershell (MS-Windows) or pwsh
        (MS-Windows, Linux, and MacOS) then it will enclose {string}
        in single quotes and will double up all internal single
        quotes.
        On MS-Windows, when 'shellslash' is not set, it will enclose
        {string} in double quotes and double all double quotes within
        {string}.
        Otherwise it will enclose {string} in single quotes and
        replace all "'" with "'\''".      

so you'll get

'/some/where/dir with '\''quote' 

from your fzf_checkout#get_cwd() and its but as replacement part in substitute() but in this part the backslash has a special meaning (e.g. for matches). Here you need to double all \ at least.

This is more brutal on Windows because the path mostly consists of c:\some\where, which is also fixed the same way.

It need to be done for all the vales replaced by substitute if they are plain text.

Now we've a second problem on windows, if shellslash is not set (mostly it isnt) and we are not on powershell/pwsh (mostly we aren't) the doublequotes create wrong VIML code:

if you use

!git -C {cwd} checkout {branch}

everything is fine, it becomes

!git -C "c:\some\where" ...

but if you use it as part of a string (like the default):

echo system("git -C {cwd} checkout {branch}")

everything is fine, it becomes

system("git -C "c:\some\where" checkout .... ")

The enclosing doublequotes kill the starting string for system.

Also using doubles quotes in system("") means you'll need to double the backslashes once more (also on linux).

A solution for this part maybe a copy for the placeholder for

Just an idea.

stsewd commented 3 years ago

Thanks for reporting this, I don't use windows, but I'll see if I can implement some of your suggestions.