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