xref: /vim-8.2.3635/runtime/autoload/gzip.vim (revision 5c5b0941)
187e25fdfSBram Moolenaar" Vim autoload file for editing compressed files.
287e25fdfSBram Moolenaar" Maintainer: Bram Moolenaar <[email protected]>
3*5c5b0941SBram Moolenaar" Last Change: 2006 Oct 09
487e25fdfSBram Moolenaar
587e25fdfSBram Moolenaar" These functions are used by the gzip plugin.
687e25fdfSBram Moolenaar
787e25fdfSBram Moolenaar" Function to check that executing "cmd [-f]" works.
887e25fdfSBram Moolenaar" The result is cached in s:have_"cmd" for speed.
987e25fdfSBram Moolenaarfun s:check(cmd)
1087e25fdfSBram Moolenaar  let name = substitute(a:cmd, '\(\S*\).*', '\1', '')
1187e25fdfSBram Moolenaar  if !exists("s:have_" . name)
1287e25fdfSBram Moolenaar    let e = executable(name)
1387e25fdfSBram Moolenaar    if e < 0
1487e25fdfSBram Moolenaar      let r = system(name . " --version")
1587e25fdfSBram Moolenaar      let e = (r !~ "not found" && r != "")
1687e25fdfSBram Moolenaar    endif
1787e25fdfSBram Moolenaar    exe "let s:have_" . name . "=" . e
1887e25fdfSBram Moolenaar  endif
1987e25fdfSBram Moolenaar  exe "return s:have_" . name
2087e25fdfSBram Moolenaarendfun
2187e25fdfSBram Moolenaar
2287e25fdfSBram Moolenaar" Set b:gzip_comp_arg to the gzip argument to be used for compression, based on
2387e25fdfSBram Moolenaar" the flags in the compressed file.
2487e25fdfSBram Moolenaar" The only compression methods that can be detected are max speed (-1) and max
2587e25fdfSBram Moolenaar" compression (-9).
2687e25fdfSBram Moolenaarfun s:set_compression(line)
2787e25fdfSBram Moolenaar  " get the Compression Method
2887e25fdfSBram Moolenaar  let l:cm = char2nr(a:line[2])
2987e25fdfSBram Moolenaar  " if it's 8 (DEFLATE), we can check for the compression level
3087e25fdfSBram Moolenaar  if l:cm == 8
3187e25fdfSBram Moolenaar    " get the eXtra FLags
3287e25fdfSBram Moolenaar    let l:xfl = char2nr(a:line[8])
3387e25fdfSBram Moolenaar    " max compression
3487e25fdfSBram Moolenaar    if l:xfl == 2
3587e25fdfSBram Moolenaar      let b:gzip_comp_arg = "-9"
3687e25fdfSBram Moolenaar    " min compression
3787e25fdfSBram Moolenaar    elseif l:xfl == 4
3887e25fdfSBram Moolenaar      let b:gzip_comp_arg = "-1"
3987e25fdfSBram Moolenaar    endif
4087e25fdfSBram Moolenaar  endif
4187e25fdfSBram Moolenaarendfun
4287e25fdfSBram Moolenaar
4387e25fdfSBram Moolenaar
4487e25fdfSBram Moolenaar" After reading compressed file: Uncompress text in buffer with "cmd"
4587e25fdfSBram Moolenaarfun gzip#read(cmd)
4687e25fdfSBram Moolenaar  " don't do anything if the cmd is not supported
4787e25fdfSBram Moolenaar  if !s:check(a:cmd)
4887e25fdfSBram Moolenaar    return
4987e25fdfSBram Moolenaar  endif
5087e25fdfSBram Moolenaar
5187e25fdfSBram Moolenaar  " for gzip check current compression level and set b:gzip_comp_arg.
5287e25fdfSBram Moolenaar  silent! unlet b:gzip_comp_arg
5387e25fdfSBram Moolenaar  if a:cmd[0] == 'g'
5487e25fdfSBram Moolenaar    call s:set_compression(getline(1))
5587e25fdfSBram Moolenaar  endif
5687e25fdfSBram Moolenaar
5787e25fdfSBram Moolenaar  " make 'patchmode' empty, we don't want a copy of the written file
5887e25fdfSBram Moolenaar  let pm_save = &pm
5987e25fdfSBram Moolenaar  set pm=
6087e25fdfSBram Moolenaar  " remove 'a' and 'A' from 'cpo' to avoid the alternate file changes
6187e25fdfSBram Moolenaar  let cpo_save = &cpo
6287e25fdfSBram Moolenaar  set cpo-=a cpo-=A
6387e25fdfSBram Moolenaar  " set 'modifiable'
6487e25fdfSBram Moolenaar  let ma_save = &ma
6587e25fdfSBram Moolenaar  setlocal ma
6687e25fdfSBram Moolenaar  " when filtering the whole buffer, it will become empty
6787e25fdfSBram Moolenaar  let empty = line("'[") == 1 && line("']") == line("$")
6887e25fdfSBram Moolenaar  let tmp = tempname()
6987e25fdfSBram Moolenaar  let tmpe = tmp . "." . expand("<afile>:e")
7087e25fdfSBram Moolenaar  " write the just read lines to a temp file "'[,']w tmp.gz"
7160a495f0SBram Moolenaar  execute "silent '[,']w " . escape(tmpe, ' ')
7287e25fdfSBram Moolenaar  " uncompress the temp file: call system("gzip -dn tmp.gz")
7360a495f0SBram Moolenaar  call system(a:cmd . " " . s:escape(tmpe))
7487e25fdfSBram Moolenaar  if !filereadable(tmp)
7587e25fdfSBram Moolenaar    " uncompress didn't work!  Keep the compressed file then.
7687e25fdfSBram Moolenaar    echoerr "Error: Could not read uncompressed file"
7787e25fdfSBram Moolenaar    return
7887e25fdfSBram Moolenaar  endif
7987e25fdfSBram Moolenaar  " delete the compressed lines; remember the line number
8087e25fdfSBram Moolenaar  let l = line("'[") - 1
8187e25fdfSBram Moolenaar  if exists(":lockmarks")
8287e25fdfSBram Moolenaar    lockmarks '[,']d _
8387e25fdfSBram Moolenaar  else
8487e25fdfSBram Moolenaar    '[,']d _
8587e25fdfSBram Moolenaar  endif
8687e25fdfSBram Moolenaar  " read in the uncompressed lines "'[-1r tmp"
87910f66f9SBram Moolenaar  " Use ++edit if the buffer was empty, keep the 'ff' and 'fenc' options.
8887e25fdfSBram Moolenaar  setlocal nobin
8987e25fdfSBram Moolenaar  if exists(":lockmarks")
90910f66f9SBram Moolenaar    if empty
91910f66f9SBram Moolenaar      execute "silent lockmarks " . l . "r ++edit " . tmp
92910f66f9SBram Moolenaar    else
9387e25fdfSBram Moolenaar      execute "silent lockmarks " . l . "r " . tmp
94910f66f9SBram Moolenaar    endif
9587e25fdfSBram Moolenaar  else
9687e25fdfSBram Moolenaar    execute "silent " . l . "r " . tmp
9787e25fdfSBram Moolenaar  endif
9887e25fdfSBram Moolenaar
9987e25fdfSBram Moolenaar  " if buffer became empty, delete trailing blank line
10087e25fdfSBram Moolenaar  if empty
10187e25fdfSBram Moolenaar    silent $delete _
10287e25fdfSBram Moolenaar    1
10387e25fdfSBram Moolenaar  endif
10487e25fdfSBram Moolenaar  " delete the temp file and the used buffers
10587e25fdfSBram Moolenaar  call delete(tmp)
10687e25fdfSBram Moolenaar  silent! exe "bwipe " . tmp
10787e25fdfSBram Moolenaar  silent! exe "bwipe " . tmpe
10887e25fdfSBram Moolenaar  let &pm = pm_save
10987e25fdfSBram Moolenaar  let &cpo = cpo_save
11087e25fdfSBram Moolenaar  let &l:ma = ma_save
11187e25fdfSBram Moolenaar  " When uncompressed the whole buffer, do autocommands
11287e25fdfSBram Moolenaar  if empty
11387e25fdfSBram Moolenaar    if &verbose >= 8
11487e25fdfSBram Moolenaar      execute "doau BufReadPost " . expand("%:r")
11587e25fdfSBram Moolenaar    else
11687e25fdfSBram Moolenaar      execute "silent! doau BufReadPost " . expand("%:r")
11787e25fdfSBram Moolenaar    endif
11887e25fdfSBram Moolenaar  endif
11987e25fdfSBram Moolenaarendfun
12087e25fdfSBram Moolenaar
12187e25fdfSBram Moolenaar" After writing compressed file: Compress written file with "cmd"
12287e25fdfSBram Moolenaarfun gzip#write(cmd)
12387e25fdfSBram Moolenaar  " don't do anything if the cmd is not supported
12487e25fdfSBram Moolenaar  if s:check(a:cmd)
12587e25fdfSBram Moolenaar    " Rename the file before compressing it.
12687e25fdfSBram Moolenaar    let nm = resolve(expand("<afile>"))
12787e25fdfSBram Moolenaar    let nmt = s:tempname(nm)
12887e25fdfSBram Moolenaar    if rename(nm, nmt) == 0
12987e25fdfSBram Moolenaar      if exists("b:gzip_comp_arg")
13060a495f0SBram Moolenaar	call system(a:cmd . " " . b:gzip_comp_arg . " " . s:escape(nmt))
13187e25fdfSBram Moolenaar      else
13260a495f0SBram Moolenaar	call system(a:cmd . " " . s:escape(nmt))
13387e25fdfSBram Moolenaar      endif
13487e25fdfSBram Moolenaar      call rename(nmt . "." . expand("<afile>:e"), nm)
13587e25fdfSBram Moolenaar    endif
13687e25fdfSBram Moolenaar  endif
13787e25fdfSBram Moolenaarendfun
13887e25fdfSBram Moolenaar
13987e25fdfSBram Moolenaar" Before appending to compressed file: Uncompress file with "cmd"
14087e25fdfSBram Moolenaarfun gzip#appre(cmd)
14187e25fdfSBram Moolenaar  " don't do anything if the cmd is not supported
14287e25fdfSBram Moolenaar  if s:check(a:cmd)
14387e25fdfSBram Moolenaar    let nm = expand("<afile>")
14487e25fdfSBram Moolenaar
14587e25fdfSBram Moolenaar    " for gzip check current compression level and set b:gzip_comp_arg.
14687e25fdfSBram Moolenaar    silent! unlet b:gzip_comp_arg
14787e25fdfSBram Moolenaar    if a:cmd[0] == 'g'
14887e25fdfSBram Moolenaar      call s:set_compression(readfile(nm, "b", 1)[0])
14987e25fdfSBram Moolenaar    endif
15087e25fdfSBram Moolenaar
15187e25fdfSBram Moolenaar    " Rename to a weird name to avoid the risk of overwriting another file
15287e25fdfSBram Moolenaar    let nmt = expand("<afile>:p:h") . "/X~=@l9q5"
15387e25fdfSBram Moolenaar    let nmte = nmt . "." . expand("<afile>:e")
15487e25fdfSBram Moolenaar    if rename(nm, nmte) == 0
15587e25fdfSBram Moolenaar      if &patchmode != "" && getfsize(nm . &patchmode) == -1
15687e25fdfSBram Moolenaar	" Create patchmode file by creating the decompressed file new
15760a495f0SBram Moolenaar	call system(a:cmd . " -c " . s:escape(nmte) . " > " . s:escape(nmt))
15887e25fdfSBram Moolenaar	call rename(nmte, nm . &patchmode)
15987e25fdfSBram Moolenaar      else
16060a495f0SBram Moolenaar	call system(a:cmd . " " . s:escape(nmte))
16187e25fdfSBram Moolenaar      endif
16287e25fdfSBram Moolenaar      call rename(nmt, nm)
16387e25fdfSBram Moolenaar    endif
16487e25fdfSBram Moolenaar  endif
16587e25fdfSBram Moolenaarendfun
16687e25fdfSBram Moolenaar
16787e25fdfSBram Moolenaar" find a file name for the file to be compressed.  Use "name" without an
16887e25fdfSBram Moolenaar" extension if possible.  Otherwise use a weird name to avoid overwriting an
16987e25fdfSBram Moolenaar" existing file.
17087e25fdfSBram Moolenaarfun s:tempname(name)
17187e25fdfSBram Moolenaar  let fn = fnamemodify(a:name, ":r")
17287e25fdfSBram Moolenaar  if !filereadable(fn) && !isdirectory(fn)
17387e25fdfSBram Moolenaar    return fn
17487e25fdfSBram Moolenaar  endif
17587e25fdfSBram Moolenaar  return fnamemodify(a:name, ":p:h") . "/X~=@l9q5"
17687e25fdfSBram Moolenaarendfun
17787e25fdfSBram Moolenaar
17860a495f0SBram Moolenaarfun s:escape(name)
17960a495f0SBram Moolenaar  " shellescape() was added by patch 7.0.111
180*5c5b0941SBram Moolenaar  if exists("*shellescape")
18160a495f0SBram Moolenaar    return shellescape(a:name)
18260a495f0SBram Moolenaar  endif
18360a495f0SBram Moolenaar  return "'" . a:name . "'"
18460a495f0SBram Moolenaarendfun
18560a495f0SBram Moolenaar
18687e25fdfSBram Moolenaar" vim: set sw=2 :
187