home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / gnu / emacs / help / 4014 < prev    next >
Encoding:
Text File  |  1992-09-08  |  8.5 KB  |  202 lines

  1. Newsgroups: gnu.emacs.help
  2. Path: sparky!uunet!decwrl!access.usask.ca!ccu.umanitoba.ca!ccu!buhr
  3. From: buhr@umanitoba.ca (Kevin Andrew Buhr)
  4. Subject: autoZ.el -- auto (un)compress [was: Creating a *.Z file from scratch]
  5. In-Reply-To: ralph@laas.fr's message of 2 Sep 92 18:01:22 GMT
  6. Message-ID: <BUHR.92Sep5170009@ccu.umanitoba.ca>
  7. Followup-To: gnu.emacs.help
  8. Sender: news@ccu.umanitoba.ca
  9. Nntp-Posting-Host: ccu.umanitoba.ca
  10. Organization: University of Manitoba, Canada
  11. References: <RALPH.92Sep2200122@orion.laas.fr>
  12. Date: Sat, 5 Sep 1992 23:00:09 GMT
  13. Lines: 187
  14.  
  15. In <RALPH.92Sep2200122@orion.laas.fr>, ralph@laas.fr writes:
  16.  
  17.    Under GNUS or VM, or even elsewhere, crypt.el works *very* nicely when
  18.    you save to compressed files, uncompressing the data in the buffer and
  19.    then recompressing before writing the data out!
  20.  
  21. I was interested in a general purpose compressor/decompressor, too.  I
  22. looked at "ange-crypt.el" and "zcat.el" and couldn't get them to work
  23. exactly the way I liked, either.
  24.  
  25. I tried writing my own which recognized the two-byte magic cookie at
  26. the file's beginning as an indication it was compressed and then
  27. stored this fact in a buffer-local variable.  Unfortunately, many
  28. modes cleared local variables, messing up the saving of these files.
  29.  
  30. In the end, I settled on using a regular expression to recognize file
  31. *names* that indicated a file was compressed.  With the default
  32. variable values, the code will treat files ending in ".Z" as
  33. compressed.  When loaded, they will be uncompressed if the magic
  34. cookie is found at file start, and, when saved, they will be
  35. recompressed if the absence of the cookie indicates they haven't
  36. already been compressed.  This scheme has the disadvantage that *all*
  37. files whose names end in ".Z" will be compressed when saved, whether
  38. they were originally compressed or not.
  39.  
  40. I've tested this using compressed Rmail files and compressed GNUS
  41. ".newsrc" files.  The only problem I have encountered is this:
  42. attempts to append articles to the end of compressed Rmail files on
  43. disk will fail; the uncompressed message will be tacked onto the end
  44. of the compressed file.  Just don't try using compressed Rmail files
  45. to automatically store author copies or save outgoing mail: if you
  46. forget to load the appropriate Rmail buffer before a message is
  47. automatically saved, you'll trash the file.  To save a message to a
  48. compressed Rmail file, run Rmail on the buffer first.  Then, use a
  49. function that saves the article or message to the end of the *buffer*
  50. rather than the file.  Better yet, uncompress the disk file first,
  51. save your articles, and then recompress it.
  52.  
  53. I have also tested the code using "ange-ftp.el" to a limited extent.
  54. Loading compressed files works fine, though I haven't tried saving
  55. them.
  56.  
  57. Inserting compressed files in an existing buffer does not work in the
  58. current version, either.  You have to load the compressed file into
  59. another buffer and then "insert-buffer" it.
  60.  
  61. This is alpha code, provided as-is, with no guarantees or warranties
  62. of any kind including fitness for a particular purpose.  Please do not
  63. redistribute it in modified form.  I will be releasing a cleaner
  64. version in the near future.  That version will be governed by GNU's
  65. copyleft and will be redistributable subject to the terms of that
  66. document.
  67.  
  68. Kevin Buhr <buhr@ccu.UManitoba.CA>
  69.  
  70. ;;; autoZ.el
  71. ;;;
  72. ;;; Copyright (c) 1992 by Kevin Buhr
  73. ;;;
  74. ;;; This program code is provided as-is, with no guarantees or
  75. ;;; warranties of any kind including, but not limited to, fitness for
  76. ;;; any particular purpose.  The author is not responsible for the
  77. ;;; loss of data or other damages caused by the use of this software.
  78. ;;; USE IT AT YOUR OWN RISK.
  79. ;;; 
  80. ;;; This code incorporates modified GNU emacs lisp code, which is
  81. ;;; distributed under the GNU Copyleft document.  The distribution of
  82. ;;; this software may therefore be subject to additional limitations
  83. ;;; or considerations outlined in that document.  You are advised to
  84. ;;; consult that document before redistributing this program.
  85. ;;;
  86. ;;; -----
  87. ;;;
  88. ;;; "autoZ.el" provides automatic decompression and compression of
  89. ;;; data files from within GNU emacs.  To use it, optionally byte
  90. ;;; compile it, and load it in your initialization file.
  91. ;;;
  92. ;;; If you find any bugs in this code or come up with a good patch to
  93. ;;; increase its usefulness, please e-mail the author at the following
  94. ;;; address:
  95. ;;;
  96. ;;;        Kevin Buhr <buhr@ccu.UManitoba.CA>
  97.  
  98. ;; Define variables
  99. (defvar autoZ-magic-cookie "\037\235"
  100.     "*A regular expression to match the beginning of a buffer and identify
  101. its contents as compressed.  See also autoZ-compressed-filename-regexp.")
  102.  
  103. (defvar autoZ-compressed-filename-regexp ".\\.Z$"
  104.   "*A regular expression that matches the filenames of compressed
  105. files.  If a file has a name that is matched by this expression, autoZ
  106. considers it a compressed file.  It will be uncompressed when read, if
  107. necessary, and compressed when written, if necessary.
  108.  
  109. The \"if necessary\" qualification depends on the value of
  110. autoZ-magic-cookie.")
  111.  
  112.  
  113. ;; Function to uncompress the buffer if necessary
  114. (defun autoZ-uncompress-buffer-if-necessary ()
  115.   "Uncompresses the current buffer if the autoZ-magic-cookie is 
  116. found at the start and the filename is matched by
  117. autoZ-compressed-filename-regexp."
  118.   (if (and (string-match autoZ-compressed-filename-regexp (buffer-file-name))
  119.        (save-excursion
  120.          (goto-char (point-min))
  121.          (looking-at autoZ-magic-cookie)))
  122.       (progn (message "Auto-uncompressing buffer...")
  123.          (let ((ro buffer-read-only) (bufmod (buffer-modified-p)))
  124.            (if ro (toggle-read-only))
  125.            (call-process-region (point-min) (point-max) "zcat" t t nil)
  126.            (if ro (toggle-read-only))
  127.            (set-buffer-modified-p bufmod))
  128.          (message "Auto-uncompressing buffer... done"))))
  129.  
  130. ;; Function to recompress buffer if necessary
  131. (defun autoZ-compress-buffer-if-necessary ()
  132.   "Recompress and save the current buffer if the filename matches
  133. autoZ-compressed-filename-regexp and the absence of the
  134. autoZ-magic-cookie at the beginning of the buffer indicates it has not
  135. already been compressed."
  136.   (save-excursion
  137.     (if (and (string-match autoZ-compressed-filename-regexp (buffer-file-name))
  138.          (progn (goto-char (point-min))
  139.             (not (looking-at autoZ-magic-cookie))))
  140.     ;; so, remember uncompressed version and then compress and save it
  141.     (let ((ro buffer-read-only) (saved-point-max (point-max)))
  142.       (message "Auto-compressing buffer...")
  143.       (if ro (toggle-read-only))
  144.       (goto-char saved-point-max)
  145.       (call-process-region 
  146.        (point-min) saved-point-max "compress" nil t nil "-c")
  147.       (message "Auto-compressing buffer... done")
  148.       ;; following code stolen from basic-save-file defun
  149.       (if file-precious-flag
  150.           ;; If file is precious, rename it away before
  151.           ;; overwriting it.
  152.           (let ((rename t) nodelete
  153.             (file (concat buffer-file-name "#")))
  154.         (condition-case ()
  155.             (progn (rename-file buffer-file-name file t)
  156.                (setq setmodes (file-modes file)))
  157.           (file-error (setq rename nil nodelete t)))
  158.         (unwind-protect
  159.             (progn (clear-visited-file-modtime)
  160.                (write-region saved-point-max (point-max)
  161.                      buffer-file-name nil t)
  162.                (setq rename nil))
  163.           ;; If rename is still t, writing failed.
  164.           ;; So rename the old file back to original name,
  165.           (if rename
  166.               (progn
  167.             (rename-file file buffer-file-name t)
  168.             (clear-visited-file-modtime))
  169.             ;; Otherwise we don't need the original file,
  170.             ;; so flush it.  Unless we already lost it.
  171.             (or nodelete
  172.             (condition-case ()
  173.                 (delete-file file)
  174.               (error nil))))))
  175.         ;; If file not writable, see if we can make it writable
  176.         ;; temporarily while we write it.
  177.         ;; But no need to do so if we have just backed it up
  178.         ;; (setmodes is set) because that says we're superseding.
  179.         (cond ((and tempsetmodes (not setmodes))
  180.            ;; Change the mode back, after writing.
  181.            (setq setmodes (file-modes buffer-file-name))
  182.            (set-file-modes buffer-file-name 511)))
  183.         (write-region saved-point-max (point-max) 
  184.               buffer-file-name nil t))
  185.       (delete-region saved-point-max (point-max))
  186.       (set-buffer-modified-p nil)
  187.       (setq buffer-read-only ro)
  188.       t)
  189.       ;; otherwise, we didn't save anything
  190.       nil)))
  191.  
  192. ;; Add functions to appropriate hooks
  193. (or (memq 'autoZ-uncompress-buffer-if-necessary find-file-hooks)
  194.     (setq find-file-hooks
  195.       (append find-file-hooks
  196.           (list 'autoZ-uncompress-buffer-if-necessary))))
  197.  
  198. (or (memq 'autoZ-compress-buffer-if-necessary write-file-hooks)
  199.     (setq write-file-hooks
  200.       (append write-file-hooks
  201.           (list 'autoZ-compress-buffer-if-necessary))))
  202.