200 lines · 5.6 KB · Text
RawDownload
" Vim autoload file for editing compressed files." Maintainer: Bram Moolenaar <Bram@vim.org>" Last Change: 2007 May 10 " These functions are used by the gzip plugin. " Function to check that executing "cmd [-f]" works." The result is cached in s:have_"cmd" for speed.fun s:check(cmd)  let name = substitute(a:cmd, '\(\S*\).*', '\1', '')  if !exists("s:have_" . name)    let e = executable(name)    if e < 0      let r = system(name . " --version")      let e = (r !~ "not found" && r != "")    endif    exe "let s:have_" . name . "=" . e  endif  exe "return s:have_" . nameendfun " Set b:gzip_comp_arg to the gzip argument to be used for compression, based on" the flags in the compressed file." The only compression methods that can be detected are max speed (-1) and max" compression (-9).fun s:set_compression(line)  " get the Compression Method  let l:cm = char2nr(a:line[2])  " if it's 8 (DEFLATE), we can check for the compression level  if l:cm == 8    " get the eXtra FLags    let l:xfl = char2nr(a:line[8])    " max compression    if l:xfl == 2      let b:gzip_comp_arg = "-9"    " min compression    elseif l:xfl == 4      let b:gzip_comp_arg = "-1"    endif  endifendfun  " After reading compressed file: Uncompress text in buffer with "cmd"fun gzip#read(cmd)  " don't do anything if the cmd is not supported  if !s:check(a:cmd)    return  endif   " for gzip check current compression level and set b:gzip_comp_arg.  silent! unlet b:gzip_comp_arg  if a:cmd[0] == 'g'    call s:set_compression(getline(1))  endif   " make 'patchmode' empty, we don't want a copy of the written file  let pm_save = &pm  set pm=  " remove 'a' and 'A' from 'cpo' to avoid the alternate file changes  let cpo_save = &cpo  set cpo-=a cpo-=A  " set 'modifiable'  let ma_save = &ma  setlocal ma  " Reset 'foldenable', otherwise line numbers get adjusted.  if has("folding")    let fen_save = &fen    setlocal nofen  endif   " when filtering the whole buffer, it will become empty  let empty = line("'[") == 1 && line("']") == line("$")  let tmp = tempname()  let tmpe = tmp . "." . expand("<afile>:e")  " write the just read lines to a temp file "'[,']w tmp.gz"  execute "silent '[,']w " . escape(tmpe, ' ')  " uncompress the temp file: call system("gzip -dn tmp.gz")  call system(a:cmd . " " . s:escape(tmpe))  if !filereadable(tmp)    " uncompress didn't work!  Keep the compressed file then.    echoerr "Error: Could not read uncompressed file"    let ok = 0  else    let ok = 1    " delete the compressed lines; remember the line number    let l = line("'[") - 1    if exists(":lockmarks")      lockmarks '[,']d _    else      '[,']d _    endif    " read in the uncompressed lines "'[-1r tmp"    " Use ++edit if the buffer was empty, keep the 'ff' and 'fenc' options.    setlocal nobin    if exists(":lockmarks")      if empty	execute "silent lockmarks " . l . "r ++edit " . tmp      else	execute "silent lockmarks " . l . "r " . tmp      endif    else      execute "silent " . l . "r " . tmp    endif     " if buffer became empty, delete trailing blank line    if empty      silent $delete _      1    endif    " delete the temp file and the used buffers    call delete(tmp)    silent! exe "bwipe " . tmp    silent! exe "bwipe " . tmpe  endif   " Restore saved option values.  let &pm = pm_save  let &cpo = cpo_save  let &l:ma = ma_save  if has("folding")    let &l:fen = fen_save  endif   " When uncompressed the whole buffer, do autocommands  if ok && empty    if &verbose >= 8      execute "doau BufReadPost " . expand("%:r")    else      execute "silent! doau BufReadPost " . expand("%:r")    endif  endifendfun " After writing compressed file: Compress written file with "cmd"fun gzip#write(cmd)  " don't do anything if the cmd is not supported  if s:check(a:cmd)    " Rename the file before compressing it.    let nm = resolve(expand("<afile>"))    let nmt = s:tempname(nm)    if rename(nm, nmt) == 0      if exists("b:gzip_comp_arg")	call system(a:cmd . " " . b:gzip_comp_arg . " " . s:escape(nmt))      else	call system(a:cmd . " " . s:escape(nmt))      endif      call rename(nmt . "." . expand("<afile>:e"), nm)    endif  endifendfun " Before appending to compressed file: Uncompress file with "cmd"fun gzip#appre(cmd)  " don't do anything if the cmd is not supported  if s:check(a:cmd)    let nm = expand("<afile>")     " for gzip check current compression level and set b:gzip_comp_arg.    silent! unlet b:gzip_comp_arg    if a:cmd[0] == 'g'      call s:set_compression(readfile(nm, "b", 1)[0])    endif     " Rename to a weird name to avoid the risk of overwriting another file    let nmt = expand("<afile>:p:h") . "/X~=@l9q5"    let nmte = nmt . "." . expand("<afile>:e")    if rename(nm, nmte) == 0      if &patchmode != "" && getfsize(nm . &patchmode) == -1	" Create patchmode file by creating the decompressed file new	call system(a:cmd . " -c " . s:escape(nmte) . " > " . s:escape(nmt))	call rename(nmte, nm . &patchmode)      else	call system(a:cmd . " " . s:escape(nmte))      endif      call rename(nmt, nm)    endif  endifendfun " find a file name for the file to be compressed.  Use "name" without an" extension if possible.  Otherwise use a weird name to avoid overwriting an" existing file.fun s:tempname(name)  let fn = fnamemodify(a:name, ":r")  if !filereadable(fn) && !isdirectory(fn)    return fn  endif  return fnamemodify(a:name, ":p:h") . "/X~=@l9q5"endfun fun s:escape(name)  " shellescape() was added by patch 7.0.111  if exists("*shellescape")    return shellescape(a:name)  endif  return "'" . a:name . "'"endfun " vim: set sw=2 :