X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/057f6dd3a417adf5a4bcc70420ef1c4a1e51f289..d3a36099e79e56cc513904728f28cfda2fe474a8:/lisp/tar-mode.el diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index 4d05746a34..ba4ded36a8 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el @@ -161,14 +161,19 @@ This information is useful, but it takes screen space away from file names." (defun tar-data-swapped-p () "Return non-nil if the tar-data is in `tar-data-buffer'." - ;; We need to be careful to keep track of which buffer holds the tar-data, - ;; since we swap them back and forth. Since the user may make the summary - ;; buffer unibyte, we can't rely on the multibyteness of the buffers. - ;; We could try and recognize the tar-format signature, but instead - ;; I decided to go for something simpler. - (and (buffer-live-p tar-data-buffer) - (> (buffer-size tar-data-buffer) (buffer-size)))) - + (buffer-live-p buffer-swapped-with)) + +(defun tar-swap-data () + "Swap buffer contents between current buffer and `tar-data-buffer'. +Preserve the modified states of the buffers and set `buffer-swapped-with'." + (let ((data-buffer-modified-p (buffer-modified-p tar-data-buffer)) + (current-buffer-modified-p (buffer-modified-p))) + (buffer-swap-text tar-data-buffer) + (setq buffer-swapped-with + (if buffer-swapped-with nil tar-data-buffer)) + (set-buffer-modified-p data-buffer-modified-p) + (with-current-buffer tar-data-buffer + (set-buffer-modified-p current-buffer-modified-p)))) ;;; down to business. @@ -207,7 +212,7 @@ This information is useful, but it takes screen space away from file names." "Round S up to the next multiple of 512." (ash (ash (+ s 511) -9) 9)) -(defun tar-header-block-tokenize (pos) +(defun tar-header-block-tokenize (pos coding) "Return a `tar-header' structure. This is a list of name, mode, uid, gid, size, write-date, checksum, link-type, and link-name." @@ -249,10 +254,9 @@ write-date, checksum, link-type, and link-name." "/" name))) (if default-enable-multibyte-characters (setq name - (decode-coding-string name tar-file-name-coding-system) + (decode-coding-string name coding) linkname - (decode-coding-string linkname - tar-file-name-coding-system))) + (decode-coding-string linkname coding))) (if (and (null link-p) (string-match "/\\'" name)) (setq link-p 5)) ; directory @@ -264,7 +268,7 @@ write-date, checksum, link-type, and link-name." ;; -1 so as to strip the terminating 0 byte. (name (buffer-substring pos (+ pos size -1))) (descriptor (tar-header-block-tokenize - (+ pos (tar-roundup-512 size))))) + (+ pos (tar-roundup-512 size)) coding))) (cond ((eq link-p (- ?L ?0)) ;GNUTYPE_LONGNAME. (setf (tar-header-name descriptor) name)) @@ -456,6 +460,7 @@ MODE should be an integer which is a file mode value." (let* ((modified (buffer-modified-p)) (result '()) (pos (point-min)) + (coding tar-file-name-coding-system) (progress-reporter (with-current-buffer tar-data-buffer (make-progress-reporter "Parsing tar file..." @@ -463,7 +468,7 @@ MODE should be an integer which is a file mode value." descriptor) (with-current-buffer tar-data-buffer (while (and (<= (+ pos 512) (point-max)) - (setq descriptor (tar-header-block-tokenize pos))) + (setq descriptor (tar-header-block-tokenize pos coding))) (let ((size (tar-header-size descriptor))) (if (< size 0) (error "%s has size %s - corrupted" @@ -578,7 +583,7 @@ MODE should be an integer which is a file mode value." (defun tar-change-major-mode-hook () ;; Bring the actual Tar data back into the main buffer. - (when (tar-data-swapped-p) (buffer-swap-text tar-data-buffer)) + (when (tar-data-swapped-p) (tar-swap-data)) ;; Throw away the summary. (when (buffer-live-p tar-data-buffer) (kill-buffer tar-data-buffer))) @@ -621,7 +626,6 @@ See also: variables `tar-update-datestamp' and `tar-anal-blocksize'. ;; buffer for the summary. (assert (not (tar-data-swapped-p))) (set (make-local-variable 'revert-buffer-function) 'tar-mode-revert) - (add-hook 'write-region-annotate-functions 'tar-write-region-annotate nil t) (add-hook 'kill-buffer-hook 'tar-mode-kill-buffer-hook nil t) (add-hook 'change-major-mode-hook 'tar-change-major-mode-hook nil t) ;; Tar data is made of bytes, not chars. @@ -630,7 +634,7 @@ See also: variables `tar-update-datestamp' and `tar-anal-blocksize'. (generate-new-buffer (format " *tar-data %s*" (file-name-nondirectory (or buffer-file-name (buffer-name)))))) - (buffer-swap-text tar-data-buffer) + (tar-swap-data) (tar-summarize-buffer) (tar-next-line 0)) @@ -666,16 +670,14 @@ appear on disk when you save the tar-file's buffer." (defun tar-mode-revert (&optional no-auto-save no-confirm) (unwind-protect (let ((revert-buffer-function nil)) - (if (tar-data-swapped-p) (buffer-swap-text tar-data-buffer)) + (if (tar-data-swapped-p) (tar-swap-data)) ;; FIXME: If we ask for confirmation, the user will be temporarily ;; looking at the raw data. (revert-buffer no-auto-save no-confirm 'preserve-modes) - ;; The new raw data may be smaller than the old summary, so let's - ;; make sure tar-data-swapped-p doesn't get confused. - (if (buffer-live-p tar-data-buffer) (kill-buffer tar-data-buffer)) ;; Recompute the summary. + (if (buffer-live-p tar-data-buffer) (kill-buffer tar-data-buffer)) (tar-mode)) - (unless (tar-data-swapped-p) (buffer-swap-text tar-data-buffer)))) + (unless (tar-data-swapped-p) (tar-swap-data)))) (defun tar-next-line (arg) @@ -1197,17 +1199,6 @@ Leaves the region wide." (delete-region goal-end (point-max)) (goto-char (point-max)) (insert (make-string (- goal-end (point-max)) ?\0)))))))) - - -;; Used in write-region-annotate-functions to write tar-files out correctly. -(defun tar-write-region-annotate (start end) - ;; When called from write-file (and auto-save), `start' is nil. - ;; When called from M-x write-region, we assume the user wants to save - ;; (part of) the summary, not the tar data. - (unless (or start (not (tar-data-swapped-p))) - (tar-clear-modification-flags) - (set-buffer tar-data-buffer) - nil)) (provide 'tar-mode)