fzf-checkout.vim
fzf-checkout.vim copied to clipboard
General Backslash problems (and Windows explicit)
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
- plain
- escaped double quotes
- escaped single quotes
Just an idea.
Thanks for reporting this, I don't use windows, but I'll see if I can implement some of your suggestions.