| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  | " Vim autoload file for editing compressed files. | 
					
						
							|  |  |  | " Maintainer: Bram Moolenaar <Bram@vim.org> | 
					
						
							| 
									
										
										
										
											2008-07-13 17:41:49 +00:00
										 |  |  | " Last Change: 2008 Jul 04 | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | " 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_" . name | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " 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 | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " 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 | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |   " Reset 'foldenable', otherwise line numbers get adjusted. | 
					
						
							|  |  |  |   if has("folding") | 
					
						
							|  |  |  |     let fen_save = &fen | 
					
						
							|  |  |  |     setlocal nofen | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |   " when filtering the whole buffer, it will become empty | 
					
						
							|  |  |  |   let empty = line("'[") == 1 && line("']") == line("$") | 
					
						
							|  |  |  |   let tmp = tempname() | 
					
						
							|  |  |  |   let tmpe = tmp . "." . expand("<afile>:e") | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  |   if exists('*fnameescape') | 
					
						
							|  |  |  |     let tmp_esc = fnameescape(tmp) | 
					
						
							|  |  |  |     let tmpe_esc = fnameescape(tmpe) | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     let tmp_esc = escape(tmp, ' ') | 
					
						
							|  |  |  |     let tmpe_esc = escape(tmpe, ' ') | 
					
						
							|  |  |  |   endif | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |   " write the just read lines to a temp file "'[,']w tmp.gz" | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  |   execute "silent '[,']w " . tmpe_esc | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |   " uncompress the temp file: call system("gzip -dn tmp.gz") | 
					
						
							| 
									
										
										
										
											2006-10-03 12:44:42 +00:00
										 |  |  |   call system(a:cmd . " " . s:escape(tmpe)) | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |   if !filereadable(tmp) | 
					
						
							|  |  |  |     " uncompress didn't work!  Keep the compressed file then. | 
					
						
							|  |  |  |     echoerr "Error: Could not read uncompressed file" | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |     let ok = 0 | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |     let ok = 1 | 
					
						
							|  |  |  |     " delete the compressed lines; remember the line number | 
					
						
							|  |  |  |     let l = line("'[") - 1 | 
					
						
							|  |  |  |     if exists(":lockmarks") | 
					
						
							|  |  |  |       lockmarks '[,']d _ | 
					
						
							| 
									
										
										
										
											2006-04-05 20:41:53 +00:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |       '[,']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 | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  | 	execute "silent lockmarks " . l . "r ++edit " . tmp_esc | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  | 	execute "silent lockmarks " . l . "r " . tmp_esc | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |       endif | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  |       execute "silent " . l . "r " . tmp_esc | 
					
						
							| 
									
										
										
										
											2006-04-05 20:41:53 +00:00
										 |  |  |     endif | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |     " 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) | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  |     silent! exe "bwipe " . tmp_esc | 
					
						
							|  |  |  |     silent! exe "bwipe " . tmpe_esc | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |   endif | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   " Restore saved option values. | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |   let &pm = pm_save | 
					
						
							|  |  |  |   let &cpo = cpo_save | 
					
						
							|  |  |  |   let &l:ma = ma_save | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |   if has("folding") | 
					
						
							|  |  |  |     let &l:fen = fen_save | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |   " When uncompressed the whole buffer, do autocommands | 
					
						
							| 
									
										
										
										
											2007-05-10 16:56:30 +00:00
										 |  |  |   if ok && empty | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  |     if exists('*fnameescape') | 
					
						
							|  |  |  |       let fname = fnameescape(expand("%:r")) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<") | 
					
						
							|  |  |  |     endif | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |     if &verbose >= 8 | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  |       execute "doau BufReadPost " . fname | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2008-05-29 20:41:57 +00:00
										 |  |  |       execute "silent! doau BufReadPost " . fname | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |     endif | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " 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") | 
					
						
							| 
									
										
										
										
											2008-07-13 17:41:49 +00:00
										 |  |  | 	call system(a:cmd . " " . b:gzip_comp_arg . " -- " . s:escape(nmt)) | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2008-07-13 17:41:49 +00:00
										 |  |  | 	call system(a:cmd . " -- " . s:escape(nmt)) | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |       endif | 
					
						
							|  |  |  |       call rename(nmt . "." . expand("<afile>:e"), nm) | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " 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 | 
					
						
							| 
									
										
										
										
											2008-07-13 17:41:49 +00:00
										 |  |  | 	call system(a:cmd . " -c -- " . s:escape(nmte) . " > " . s:escape(nmt)) | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  | 	call rename(nmte, nm . &patchmode) | 
					
						
							|  |  |  |       else | 
					
						
							| 
									
										
										
										
											2008-07-13 17:41:49 +00:00
										 |  |  | 	call system(a:cmd . " -- " . s:escape(nmte)) | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  |       endif | 
					
						
							|  |  |  |       call rename(nmt, nm) | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-03 12:44:42 +00:00
										 |  |  | fun s:escape(name) | 
					
						
							|  |  |  |   " shellescape() was added by patch 7.0.111 | 
					
						
							| 
									
										
										
										
											2007-05-06 12:07:59 +00:00
										 |  |  |   if exists("*shellescape") | 
					
						
							| 
									
										
										
										
											2006-10-03 12:44:42 +00:00
										 |  |  |     return shellescape(a:name) | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  |   return "'" . a:name . "'" | 
					
						
							|  |  |  | endfun | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-27 21:13:01 +00:00
										 |  |  | " vim: set sw=2 : |