summaryrefslogtreecommitdiff
path: root/runtime/plugin/gzip.vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/plugin/gzip.vim')
-rw-r--r--runtime/plugin/gzip.vim157
1 files changed, 157 insertions, 0 deletions
diff --git a/runtime/plugin/gzip.vim b/runtime/plugin/gzip.vim
new file mode 100644
index 000000000..39b0cbc36
--- /dev/null
+++ b/runtime/plugin/gzip.vim
@@ -0,0 +1,157 @@
+" Vim plugin for editing compressed files.
+" Maintainer: Bram Moolenaar <Bram@vim.org>
+" Last Change: 2004 Jan 12
+
+" Exit quickly when:
+" - this plugin was already loaded
+" - when 'compatible' is set
+" - some autocommands are already taking care of compressed files
+if exists("loaded_gzip") || &cp || exists("#BufReadPre#*.gz")
+ finish
+endif
+let loaded_gzip = 1
+
+augroup gzip
+ " Remove all gzip autocommands
+ au!
+
+ " Enable editing of gzipped files
+ " set binary mode before reading the file
+ " use "gzip -d", gunzip isn't always available
+ autocmd BufReadPre,FileReadPre *.gz,*.bz2,*.Z setlocal bin
+ autocmd BufReadPost,FileReadPost *.gz call s:read("gzip -dn")
+ autocmd BufReadPost,FileReadPost *.bz2 call s:read("bzip2 -d")
+ autocmd BufReadPost,FileReadPost *.Z call s:read("uncompress")
+ autocmd BufWritePost,FileWritePost *.gz call s:write("gzip")
+ autocmd BufWritePost,FileWritePost *.bz2 call s:write("bzip2")
+ autocmd BufWritePost,FileWritePost *.Z call s:write("compress -f")
+ autocmd FileAppendPre *.gz call s:appre("gzip -dn")
+ autocmd FileAppendPre *.bz2 call s:appre("bzip2 -d")
+ autocmd FileAppendPre *.Z call s:appre("uncompress")
+ autocmd FileAppendPost *.gz call s:write("gzip")
+ autocmd FileAppendPost *.bz2 call s:write("bzip2")
+ autocmd FileAppendPost *.Z call s:write("compress -f")
+augroup END
+
+" 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
+
+" After reading compressed file: Uncompress text in buffer with "cmd"
+fun s:read(cmd)
+ " don't do anything if the cmd is not supported
+ if !s:check(a:cmd)
+ return
+ 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
+ " 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 " . tmpe
+ " uncompress the temp file: call system("gzip -dn tmp.gz")
+ call system(a:cmd . " " . tmpe)
+ " 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"
+ setlocal nobin
+ if exists(":lockmarks")
+ execute "silent lockmarks " . l . "r " . tmp
+ 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
+ let &pm = pm_save
+ let &cpo = cpo_save
+ let &l:ma = ma_save
+ " When uncompressed the whole buffer, do autocommands
+ if empty
+ if &verbose >= 8
+ execute "doau BufReadPost " . expand("%:r")
+ else
+ execute "silent! doau BufReadPost " . expand("%:r")
+ endif
+ endif
+endfun
+
+" After writing compressed file: Compress written file with "cmd"
+fun s: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 = expand("<afile>")
+ let nmt = s:tempname(nm)
+ if rename(nm, nmt) == 0
+ call system(a:cmd . " " . nmt)
+ call rename(nmt . "." . expand("<afile>:e"), nm)
+ endif
+ endif
+endfun
+
+" Before appending to compressed file: Uncompress file with "cmd"
+fun s:appre(cmd)
+ " don't do anything if the cmd is not supported
+ if s:check(a:cmd)
+ " Rename to a weird name to avoid the risk of overwriting another file
+ let nm = expand("<afile>")
+ 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 " . nmte . " > " . nmt)
+ call rename(nmte, nm . &patchmode)
+ else
+ call system(a:cmd . " " . nmte)
+ 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
+
+" vim: set sw=2 :