0
0
mirror of https://github.com/vim/vim.git synced 2025-08-27 20:13:38 -04:00

runtime(zip): MS-Windows: handle files with spaces properly

This change does the following 3 things:

1) non need to quote the file to be extracted

The zipfile plugin used to quote and fnameescape() the path to the
file to be extracted. However testing with unzip showed, that while this
works on Linux on Windows you shall not escape the blanks in filenames.

As long as the pathname is properly quoted, this words on Linux and
Windows.

2) reset shellslash (MS-Windows only)

When shellslash is set, filenames to the zip archive will be forward
quoted. However since the filename is eventually handed over to the
unzip command, we need to make sure to use native paths so that the
command will understand what file to open. Therefore, if shellslash is
set (and the shell is cmd.exe), replace any forward slashes by the
expected backslashes

3) style:
Use tabs for the Header, remove a few comments in the s:Escape() and
zip#read() functions

fixes: #14998

Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Christian Brabandt 2024-06-15 14:49:24 +02:00
parent 6dd5840fdf
commit 1c67342912
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09

View File

@ -4,17 +4,18 @@
" Version: 33 " Version: 33
" Maintainer: This runtime file is looking for a new maintainer. " Maintainer: This runtime file is looking for a new maintainer.
" Former Maintainer: Charles E Campbell " Former Maintainer: Charles E Campbell
" Last Change:
" 2024 Jun 16 by Vim Project: handle whitespace on Windows properly (#14998)
" License: Vim License (see vim's :help license) " License: Vim License (see vim's :help license)
" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1 " Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
" Permission is hereby granted to use and distribute this code, " Permission is hereby granted to use and distribute this code,
" with or without modifications, provided that this copyright " with or without modifications, provided that this copyright
" notice is copied with it. Like anything else that's free, " notice is copied with it. Like anything else that's free,
" zip.vim and zipPlugin.vim are provided *as is* and comes with " zip.vim and zipPlugin.vim are provided *as is* and comes with
" no warranty of any kind, either expressed or implied. By using " no warranty of any kind, either expressed or implied. By using
" this plugin, you agree that in no event will the copyright " this plugin, you agree that in no event will the copyright
" holder be liable for any damages resulting from the use " holder be liable for any damages resulting from the use
" of this software. " of this software.
"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" Load Once: {{{1 " Load Once: {{{1
@ -214,7 +215,6 @@ endfun
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" zip#Read: {{{2 " zip#Read: {{{2
fun! zip#Read(fname,mode) fun! zip#Read(fname,mode)
" call Dfunc("zip#Read(fname<".a:fname.">,mode=".a:mode.")")
let repkeep= &report let repkeep= &report
set report=10 set report=10
@ -226,15 +226,12 @@ fun! zip#Read(fname,mode)
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','') let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
let fname = substitute(fname, '[', '[[]', 'g') let fname = substitute(fname, '[', '[[]', 'g')
endif endif
" call Decho("zipfile<".zipfile.">")
" call Decho("fname <".fname.">")
" sanity check " sanity check
if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','','')) if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','',''))
redraw! redraw!
echohl Error | echo "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None echohl Error | echo "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None
" call inputsave()|call input("Press <cr> to continue")|call inputrestore() " call inputsave()|call input("Press <cr> to continue")|call inputrestore()
let &report= repkeep let &report= repkeep
" call Dret("zip#Write")
return return
endif endif
@ -242,10 +239,8 @@ fun! zip#Read(fname,mode)
" exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1) " exe "keepj sil! r! ".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1)
" but allows zipfile://... entries in quickfix lists " but allows zipfile://... entries in quickfix lists
let temp = tempname() let temp = tempname()
" call Decho("using temp file<".temp.">")
let fn = expand('%:p') let fn = expand('%:p')
exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1).' > '.temp exe "sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fname,1).' > '.temp
" call Decho("exe sil! !".g:zip_unzipcmd." -p -- ".s:Escape(zipfile,1)." ".s:Escape(fnameescape(fname),1).' > '.temp)
sil exe 'keepalt file '.temp sil exe 'keepalt file '.temp
sil keepj e! sil keepj e!
sil exe 'keepalt file '.fnameescape(fn) sil exe 'keepalt file '.fnameescape(fn)
@ -254,11 +249,9 @@ fun! zip#Read(fname,mode)
filetype detect filetype detect
" cleanup " cleanup
" keepj 0d " used to be needed for the ...r! ... method
set nomod set nomod
let &report= repkeep let &report= repkeep
" call Dret("zip#Read")
endfun endfun
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
@ -314,6 +307,7 @@ fun! zip#Write(fname)
if has("unix") if has("unix")
let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','') let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','') let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
let fname = fnameescape(fname)
else else
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','') let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','') let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
@ -422,7 +416,6 @@ endfun
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" s:Escape: {{{2 " s:Escape: {{{2
fun! s:Escape(fname,isfilt) fun! s:Escape(fname,isfilt)
" call Dfunc("QuoteFileDir(fname<".a:fname."> isfilt=".a:isfilt.")")
if exists("*shellescape") if exists("*shellescape")
if a:isfilt if a:isfilt
let qnameq= shellescape(a:fname,1) let qnameq= shellescape(a:fname,1)
@ -432,7 +425,10 @@ fun! s:Escape(fname,isfilt)
else else
let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq
endif endif
" call Dret("QuoteFileDir <".qnameq.">") if exists("+shellslash") && &shellslash && &shell =~ "cmd.exe"
" renormalize directory separator on Windows
let qnameq=substitute(qnameq, '/', '\\', 'g')
endif
return qnameq return qnameq
endfun endfun