xref: /vim-8.2.3635/runtime/plugin/gzip.vim (revision 071d4279)
1" Vim plugin for editing compressed files.
2" Maintainer: Bram Moolenaar <[email protected]>
3" Last Change: 2004 Jan 12
4
5" Exit quickly when:
6" - this plugin was already loaded
7" - when 'compatible' is set
8" - some autocommands are already taking care of compressed files
9if exists("loaded_gzip") || &cp || exists("#BufReadPre#*.gz")
10  finish
11endif
12let loaded_gzip = 1
13
14augroup gzip
15  " Remove all gzip autocommands
16  au!
17
18  " Enable editing of gzipped files
19  " set binary mode before reading the file
20  " use "gzip -d", gunzip isn't always available
21  autocmd BufReadPre,FileReadPre	*.gz,*.bz2,*.Z setlocal bin
22  autocmd BufReadPost,FileReadPost	*.gz  call s:read("gzip -dn")
23  autocmd BufReadPost,FileReadPost	*.bz2 call s:read("bzip2 -d")
24  autocmd BufReadPost,FileReadPost	*.Z   call s:read("uncompress")
25  autocmd BufWritePost,FileWritePost	*.gz  call s:write("gzip")
26  autocmd BufWritePost,FileWritePost	*.bz2 call s:write("bzip2")
27  autocmd BufWritePost,FileWritePost	*.Z   call s:write("compress -f")
28  autocmd FileAppendPre			*.gz  call s:appre("gzip -dn")
29  autocmd FileAppendPre			*.bz2 call s:appre("bzip2 -d")
30  autocmd FileAppendPre			*.Z   call s:appre("uncompress")
31  autocmd FileAppendPost		*.gz  call s:write("gzip")
32  autocmd FileAppendPost		*.bz2 call s:write("bzip2")
33  autocmd FileAppendPost		*.Z   call s:write("compress -f")
34augroup END
35
36" Function to check that executing "cmd [-f]" works.
37" The result is cached in s:have_"cmd" for speed.
38fun s:check(cmd)
39  let name = substitute(a:cmd, '\(\S*\).*', '\1', '')
40  if !exists("s:have_" . name)
41    let e = executable(name)
42    if e < 0
43      let r = system(name . " --version")
44      let e = (r !~ "not found" && r != "")
45    endif
46    exe "let s:have_" . name . "=" . e
47  endif
48  exe "return s:have_" . name
49endfun
50
51" After reading compressed file: Uncompress text in buffer with "cmd"
52fun s:read(cmd)
53  " don't do anything if the cmd is not supported
54  if !s:check(a:cmd)
55    return
56  endif
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  " when filtering the whole buffer, it will become empty
67  let empty = line("'[") == 1 && line("']") == line("$")
68  let tmp = tempname()
69  let tmpe = tmp . "." . expand("<afile>:e")
70  " write the just read lines to a temp file "'[,']w tmp.gz"
71  execute "silent '[,']w " . tmpe
72  " uncompress the temp file: call system("gzip -dn tmp.gz")
73  call system(a:cmd . " " . tmpe)
74  " delete the compressed lines; remember the line number
75  let l = line("'[") - 1
76  if exists(":lockmarks")
77    lockmarks '[,']d _
78  else
79    '[,']d _
80  endif
81  " read in the uncompressed lines "'[-1r tmp"
82  setlocal nobin
83  if exists(":lockmarks")
84    execute "silent lockmarks " . l . "r " . tmp
85  else
86    execute "silent " . l . "r " . tmp
87  endif
88
89  " if buffer became empty, delete trailing blank line
90  if empty
91    silent $delete _
92    1
93  endif
94  " delete the temp file and the used buffers
95  call delete(tmp)
96  silent! exe "bwipe " . tmp
97  silent! exe "bwipe " . tmpe
98  let &pm = pm_save
99  let &cpo = cpo_save
100  let &l:ma = ma_save
101  " When uncompressed the whole buffer, do autocommands
102  if empty
103    if &verbose >= 8
104      execute "doau BufReadPost " . expand("%:r")
105    else
106      execute "silent! doau BufReadPost " . expand("%:r")
107    endif
108  endif
109endfun
110
111" After writing compressed file: Compress written file with "cmd"
112fun s:write(cmd)
113  " don't do anything if the cmd is not supported
114  if s:check(a:cmd)
115    " Rename the file before compressing it.
116    let nm = expand("<afile>")
117    let nmt = s:tempname(nm)
118    if rename(nm, nmt) == 0
119      call system(a:cmd . " " . nmt)
120      call rename(nmt . "." . expand("<afile>:e"), nm)
121    endif
122  endif
123endfun
124
125" Before appending to compressed file: Uncompress file with "cmd"
126fun s:appre(cmd)
127  " don't do anything if the cmd is not supported
128  if s:check(a:cmd)
129    " Rename to a weird name to avoid the risk of overwriting another file
130    let nm = expand("<afile>")
131    let nmt = expand("<afile>:p:h") . "/X~=@l9q5"
132    let nmte = nmt . "." . expand("<afile>:e")
133    if rename(nm, nmte) == 0
134      if &patchmode != "" && getfsize(nm . &patchmode) == -1
135	" Create patchmode file by creating the decompressed file new
136	call system(a:cmd . " -c " . nmte . " > " . nmt)
137	call rename(nmte, nm . &patchmode)
138      else
139	call system(a:cmd . " " . nmte)
140      endif
141      call rename(nmt, nm)
142    endif
143  endif
144endfun
145
146" find a file name for the file to be compressed.  Use "name" without an
147" extension if possible.  Otherwise use a weird name to avoid overwriting an
148" existing file.
149fun s:tempname(name)
150  let fn = fnamemodify(a:name, ":r")
151  if !filereadable(fn) && !isdirectory(fn)
152    return fn
153  endif
154  return fnamemodify(a:name, ":p:h") . "/X~=@l9q5"
155endfun
156
157" vim: set sw=2 :
158