runtime(zip): refactor save and restore of options

Problem:  zip plugin has no way to set/restore option values
Solution: Add the SetSaneOpts() and RestoreOpts() functions,
          so options that cause issues are set to sane values
          and restored back to their initial values later on.
          (this affects the 'shellslash' option on windows, which also
          changes how the shellescape() function works)

Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/autoload/zip.vim b/runtime/autoload/zip.vim
index cf70135..7e833fe 100644
--- a/runtime/autoload/zip.vim
+++ b/runtime/autoload/zip.vim
@@ -83,14 +83,13 @@
    return
   endif
 
-  let repkeep= &report
-  set report=10
+  let dict = s:SetSaneOpts()
 
   " sanity checks
   if !executable(g:zip_unzipcmd)
    redraw!
    echohl Error | echomsg "***error*** (zip#Browse) unzip not available on your system"
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
   if !filereadable(a:zipfile)
@@ -99,7 +98,7 @@
     redraw!
     echohl Error | echomsg "***error*** (zip#Browse) File not readable<".a:zipfile.">" | echohl None
    endif
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
   if &ma != 1
@@ -136,6 +135,7 @@
    exe "keepj r ".fnameescape(a:zipfile)
    let &ei= eikeep
    keepj 1d
+   call s:RestoreOpts(dict)
    return
   endif
 
@@ -147,28 +147,28 @@
    noremap <silent> <buffer>	<leftmouse>	<leftmouse>:call <SID>ZipBrowseSelect()<cr>
   endif
 
-  let &report= repkeep
+  call s:RestoreOpts(dict)
 endfun
 
 " ---------------------------------------------------------------------
 " ZipBrowseSelect: {{{2
 fun! s:ZipBrowseSelect()
-  let repkeep= &report
-  set report=10
+  let dict = s:SetSaneOpts()
   let fname= getline(".")
   if !exists("b:zipfile")
+   call s:RestoreOpts(dict)
    return
   endif
 
   " sanity check
   if fname =~ '^"'
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
   if fname =~ '/$'
    redraw!
    echohl Error | echomsg "***error*** (zip#Browse) Please specify a file, not a directory" | echohl None
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
 
@@ -184,14 +184,13 @@
   exe "noswapfile e ".fnameescape("zipfile://".zipfile.'::'.fname)
   filetype detect
 
-  let &report= repkeep
+  call s:RestoreOpts(dict)
 endfun
 
 " ---------------------------------------------------------------------
 " zip#Read: {{{2
 fun! zip#Read(fname,mode)
-  let repkeep= &report
-  set report=10
+  let dict = s:SetSaneOpts()
 
   if has("unix")
    let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
@@ -205,7 +204,7 @@
   if !executable(substitute(g:zip_unzipcmd,'\s\+.*$','',''))
    redraw!
    echohl Error | echomsg "***error*** (zip#Read) sorry, your system doesn't appear to have the ".g:zip_unzipcmd." program" | echohl None
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
 
@@ -225,26 +224,25 @@
   " cleanup
   set nomod
 
-  let &report= repkeep
+  call s:RestoreOpts(dict)
 endfun
 
 " ---------------------------------------------------------------------
 " zip#Write: {{{2
 fun! zip#Write(fname)
-  let repkeep= &report
-  set report=10
+  let dict = s:SetSaneOpts()
 
   " sanity checks
   if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
    redraw!
    echohl Error | echomsg "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program" | echohl None
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
   if !exists("*mkdir")
    redraw!
    echohl Error | echomsg "***error*** (zip#Write) sorry, mkdir() doesn't work on your system" | echohl None
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
 
@@ -257,7 +255,7 @@
 
   " attempt to change to the indicated directory
   if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
 
@@ -323,26 +321,25 @@
   call delete(tmpdir, "rf")
   setlocal nomod
 
-  let &report= repkeep
+  call s:RestoreOpts(dict)
 endfun
 
 " ---------------------------------------------------------------------
 " zip#Extract: extract a file from a zip archive {{{2
 fun! zip#Extract()
 
-  let repkeep= &report
-  set report=10
+  let dict = s:SetSaneOpts()
   let fname= getline(".")
 
   " sanity check
   if fname =~ '^"'
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
   if fname =~ '/$'
    redraw!
    echohl Error | echomsg "***error*** (zip#Extract) Please specify a file, not a directory" | echohl None
-   let &report= repkeep
+   call s:RestoreOpts(dict)
    return
   endif
 
@@ -357,7 +354,7 @@
   endif
 
   " restore option
-  let &report= repkeep
+  call s:RestoreOpts(dict)
 
 endfun
 
@@ -373,15 +370,11 @@
   else
    let qnameq= g:zip_shq.escape(a:fname,g:zip_shq).g:zip_shq
   endif
-  if exists("+shellslash") && &shellslash && &shell =~ "cmd.exe"
-   " renormalize directory separator on Windows
-   let qnameq=substitute(qnameq, '/', '\\', 'g')
-  endif
   return qnameq
 endfun
 
 " ---------------------------------------------------------------------
-" ChgDir: {{{2
+" s:ChgDir: {{{2
 fun! s:ChgDir(newdir,errlvl,errmsg)
   try
    exe "cd ".fnameescape(a:newdir)
@@ -400,6 +393,27 @@
   return 0
 endfun
 
+" ---------------------------------------------------------------------
+" s:SetSaneOpts: {{{2
+fun! s:SetSaneOpts()
+  let dict = {}
+  let dict.report = &report
+  let dict.shellslash = &shellslash
+
+  let &report = 10
+  let &shellslash = 0
+
+  return dict
+endfun
+
+" ---------------------------------------------------------------------
+" s:RestoreOpts: {{{2
+fun! s:RestoreOpts(dict)
+  for [key, val] in items(a:dict)
+    exe $"let &{key} = {val}"
+  endfor
+endfun
+
 " ------------------------------------------------------------------------
 " Modelines And Restoration: {{{1
 let &cpo= s:keepcpo