home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / runtime / dos / autoload / gzip.vim < prev    next >
Encoding:
Text File  |  2010-08-15  |  6.2 KB  |  213 lines

  1. " Vim autoload file for editing compressed files.
  2. " Maintainer: Bram Moolenaar <Bram@vim.org>
  3. " Last Change: 2008 Jul 04
  4.  
  5. " These functions are used by the gzip plugin.
  6.  
  7. " Function to check that executing "cmd [-f]" works.
  8. " The result is cached in s:have_"cmd" for speed.
  9. fun s:check(cmd)
  10.   let name = substitute(a:cmd, '\(\S*\).*', '\1', '')
  11.   if !exists("s:have_" . name)
  12.     let e = executable(name)
  13.     if e < 0
  14.       let r = system(name . " --version")
  15.       let e = (r !~ "not found" && r != "")
  16.     endif
  17.     exe "let s:have_" . name . "=" . e
  18.   endif
  19.   exe "return s:have_" . name
  20. endfun
  21.  
  22. " Set b:gzip_comp_arg to the gzip argument to be used for compression, based on
  23. " the flags in the compressed file.
  24. " The only compression methods that can be detected are max speed (-1) and max
  25. " compression (-9).
  26. fun s:set_compression(line)
  27.   " get the Compression Method
  28.   let l:cm = char2nr(a:line[2])
  29.   " if it's 8 (DEFLATE), we can check for the compression level
  30.   if l:cm == 8
  31.     " get the eXtra FLags
  32.     let l:xfl = char2nr(a:line[8])
  33.     " max compression
  34.     if l:xfl == 2
  35.       let b:gzip_comp_arg = "-9"
  36.     " min compression
  37.     elseif l:xfl == 4
  38.       let b:gzip_comp_arg = "-1"
  39.     endif
  40.   endif
  41. endfun
  42.  
  43.  
  44. " After reading compressed file: Uncompress text in buffer with "cmd"
  45. fun gzip#read(cmd)
  46.   " don't do anything if the cmd is not supported
  47.   if !s:check(a:cmd)
  48.     return
  49.   endif
  50.  
  51.   " for gzip check current compression level and set b:gzip_comp_arg.
  52.   silent! unlet b:gzip_comp_arg
  53.   if a:cmd[0] == 'g'
  54.     call s:set_compression(getline(1))
  55.   endif
  56.  
  57.   " make 'patchmode' empty, we don't want a copy of the written file
  58.   let pm_save = &pm
  59.   set pm=
  60.   " remove 'a' and 'A' from 'cpo' to avoid the alternate file changes
  61.   let cpo_save = &cpo
  62.   set cpo-=a cpo-=A
  63.   " set 'modifiable'
  64.   let ma_save = &ma
  65.   setlocal ma
  66.   " Reset 'foldenable', otherwise line numbers get adjusted.
  67.   if has("folding")
  68.     let fen_save = &fen
  69.     setlocal nofen
  70.   endif
  71.  
  72.   " when filtering the whole buffer, it will become empty
  73.   let empty = line("'[") == 1 && line("']") == line("$")
  74.   let tmp = tempname()
  75.   let tmpe = tmp . "." . expand("<afile>:e")
  76.   if exists('*fnameescape')
  77.     let tmp_esc = fnameescape(tmp)
  78.     let tmpe_esc = fnameescape(tmpe)
  79.   else
  80.     let tmp_esc = escape(tmp, ' ')
  81.     let tmpe_esc = escape(tmpe, ' ')
  82.   endif
  83.   " write the just read lines to a temp file "'[,']w tmp.gz"
  84.   execute "silent '[,']w " . tmpe_esc
  85.   " uncompress the temp file: call system("gzip -dn tmp.gz")
  86.   call system(a:cmd . " " . s:escape(tmpe))
  87.   if !filereadable(tmp)
  88.     " uncompress didn't work!  Keep the compressed file then.
  89.     echoerr "Error: Could not read uncompressed file"
  90.     let ok = 0
  91.   else
  92.     let ok = 1
  93.     " delete the compressed lines; remember the line number
  94.     let l = line("'[") - 1
  95.     if exists(":lockmarks")
  96.       lockmarks '[,']d _
  97.     else
  98.       '[,']d _
  99.     endif
  100.     " read in the uncompressed lines "'[-1r tmp"
  101.     " Use ++edit if the buffer was empty, keep the 'ff' and 'fenc' options.
  102.     setlocal nobin
  103.     if exists(":lockmarks")
  104.       if empty
  105.     execute "silent lockmarks " . l . "r ++edit " . tmp_esc
  106.       else
  107.     execute "silent lockmarks " . l . "r " . tmp_esc
  108.       endif
  109.     else
  110.       execute "silent " . l . "r " . tmp_esc
  111.     endif
  112.  
  113.     " if buffer became empty, delete trailing blank line
  114.     if empty
  115.       silent $delete _
  116.       1
  117.     endif
  118.     " delete the temp file and the used buffers
  119.     call delete(tmp)
  120.     silent! exe "bwipe " . tmp_esc
  121.     silent! exe "bwipe " . tmpe_esc
  122.   endif
  123.  
  124.   " Restore saved option values.
  125.   let &pm = pm_save
  126.   let &cpo = cpo_save
  127.   let &l:ma = ma_save
  128.   if has("folding")
  129.     let &l:fen = fen_save
  130.   endif
  131.  
  132.   " When uncompressed the whole buffer, do autocommands
  133.   if ok && empty
  134.     if exists('*fnameescape')
  135.       let fname = fnameescape(expand("%:r"))
  136.     else
  137.       let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<")
  138.     endif
  139.     if &verbose >= 8
  140.       execute "doau BufReadPost " . fname
  141.     else
  142.       execute "silent! doau BufReadPost " . fname
  143.     endif
  144.   endif
  145. endfun
  146.  
  147. " After writing compressed file: Compress written file with "cmd"
  148. fun gzip#write(cmd)
  149.   " don't do anything if the cmd is not supported
  150.   if s:check(a:cmd)
  151.     " Rename the file before compressing it.
  152.     let nm = resolve(expand("<afile>"))
  153.     let nmt = s:tempname(nm)
  154.     if rename(nm, nmt) == 0
  155.       if exists("b:gzip_comp_arg")
  156.     call system(a:cmd . " " . b:gzip_comp_arg . " -- " . s:escape(nmt))
  157.       else
  158.     call system(a:cmd . " -- " . s:escape(nmt))
  159.       endif
  160.       call rename(nmt . "." . expand("<afile>:e"), nm)
  161.     endif
  162.   endif
  163. endfun
  164.  
  165. " Before appending to compressed file: Uncompress file with "cmd"
  166. fun gzip#appre(cmd)
  167.   " don't do anything if the cmd is not supported
  168.   if s:check(a:cmd)
  169.     let nm = expand("<afile>")
  170.  
  171.     " for gzip check current compression level and set b:gzip_comp_arg.
  172.     silent! unlet b:gzip_comp_arg
  173.     if a:cmd[0] == 'g'
  174.       call s:set_compression(readfile(nm, "b", 1)[0])
  175.     endif
  176.  
  177.     " Rename to a weird name to avoid the risk of overwriting another file
  178.     let nmt = expand("<afile>:p:h") . "/X~=@l9q5"
  179.     let nmte = nmt . "." . expand("<afile>:e")
  180.     if rename(nm, nmte) == 0
  181.       if &patchmode != "" && getfsize(nm . &patchmode) == -1
  182.     " Create patchmode file by creating the decompressed file new
  183.     call system(a:cmd . " -c -- " . s:escape(nmte) . " > " . s:escape(nmt))
  184.     call rename(nmte, nm . &patchmode)
  185.       else
  186.     call system(a:cmd . " -- " . s:escape(nmte))
  187.       endif
  188.       call rename(nmt, nm)
  189.     endif
  190.   endif
  191. endfun
  192.  
  193. " find a file name for the file to be compressed.  Use "name" without an
  194. " extension if possible.  Otherwise use a weird name to avoid overwriting an
  195. " existing file.
  196. fun s:tempname(name)
  197.   let fn = fnamemodify(a:name, ":r")
  198.   if !filereadable(fn) && !isdirectory(fn)
  199.     return fn
  200.   endif
  201.   return fnamemodify(a:name, ":p:h") . "/X~=@l9q5"
  202. endfun
  203.  
  204. fun s:escape(name)
  205.   " shellescape() was added by patch 7.0.111
  206.   if exists("*shellescape")
  207.     return shellescape(a:name)
  208.   endif
  209.   return "'" . a:name . "'"
  210. endfun
  211.  
  212. " vim: set sw=2 :
  213.