(defvar uncompress-program-alist '(("\\.Z$" "gunzip" ".Z")
("\\.gz$" "gunzip" ".gz")
("\\.bz2$" "bunzip2" ".bz2"))
"List of programs to use to uncompress files matching specific regexps.
This alist maps from a regexp matching a compressed file to a program
to decompress it, and to a string to append to filenames when a file
is not found to determine whether a compressed version of that type
exists instead.")
(defun uncompress-backup-file (uncompress-program)
(and buffer-file-name make-backup-files (not buffer-backed-up)
(not (file-exists-p buffer-file-name))
(call-process uncompress-program nil nil nil buffer-file-name))
nil)
(mapc (function (lambda (fileprog)
(or (assoc (car fileprog) auto-mode-alist)
(setq auto-mode-alist
(cons `(,(car fileprog) . uncompress-while-visiting)
auto-mode-alist))))) uncompress-program-alist)
(defun uncompress-while-visiting ()
"Temporary \"major mode\" used for .Z, .gz, and .bz2 files, to uncompress them.
It then selects a major mode from the uncompressed file name and contents."
(lexical-let ((uncompress-program)) (mapc (function (lambda (fileprog)
(if (and (not (null buffer-file-name))
(string-match (car fileprog) buffer-file-name))
(progn (set-visited-file-name (substring buffer-file-name 0
(match-beginning 0)))
(setq uncompress-program (car (cdr fileprog)))))))
uncompress-program-alist)
(message "Uncompressing...")
(let ((buffer-read-only nil))
(shell-command-on-region (point-min) (point-max) uncompress-program t))
(message "Uncompressing...done")
(set-buffer-modified-p nil)
(make-local-hook 'write-file-hooks)
(add-hook 'write-file-hooks
(function (lambda ()
(uncompress-backup-file uncompress-program))) nil t))
(normal-mode))
(or (memq 'find-compressed-version find-file-not-found-hooks)
(setq find-file-not-found-hooks
(cons 'find-compressed-version find-file-not-found-hooks)))
(defun find-compressed-version ()
"Hook to read and uncompress the compressed version of a file."
(let (found-p)
(mapc (function (lambda (fileprog)
(let (name)
(if (file-exists-p (setq name (concat buffer-file-name
(car (cdr (cdr fileprog))))))
(progn (setq buffer-file-name name
found-p t))))))
uncompress-program-alist)
(if found-p
(progn
(insert-file-contents buffer-file-name t)
(goto-char (point-min))
(setq error nil)
t))))
(provide 'uncompress)