Mercurial > hg > xemacs-beta
view lisp/efs/dired-cmpr.el @ 149:538048ae2ab8 r20-3b1
Import from CVS: tag r20-3b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:36:16 +0200 |
parents | 9f59509498e1 |
children |
line wrap: on
line source
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; File: dired-cmpr.el ;; Dired Version: #Revision: 7.9 $ ;; RCS: ;; Description: Commands for compressing marked files. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Requirements and provisions (provide 'dired-cmpr) (require 'dired) ;;; Entry points. (defun dired-do-compress (&optional arg files) "Compress or uncompress marked (or next ARG) files. With a zero prefix, prompts for a new value of `dired-compression-method'." (interactive (let ((arg (prefix-numeric-value current-prefix-arg)) files) (if (zerop arg) (let ((new (completing-read (format "Set compression method (currently %s): " dired-compression-method) (mapcar (function (lambda (x) (cons (symbol-name (car x)) nil))) dired-compression-method-alist) nil t))) (or (string-equal new "") (setq dired-compression-method (intern new)))) (setq files (dired-get-marked-files nil current-prefix-arg)) (or (memq 'compress dired-no-confirm) (let* ((dir (dired-current-directory)) (rfiles (mapcar (function (lambda (fn) (dired-make-relative fn dir t))) files)) (prompt "") (comp 0) (uncomp nil) (total (length files)) elt) (mapcar (function (lambda (fn) (if (listp (setq elt (dired-make-compressed-filename fn))) (let* ((method (car (nth 3 elt))) (count (assoc method uncomp))) (if count (setcdr count (1+ (cdr count))) (setq uncomp (cons (cons method 1) uncomp)))) (setq comp (1+ comp))))) files) (if (/= comp 0) (setq prompt (format "%s %d" (car (nth 2 (assq dired-compression-method dired-compression-method-alist))) comp))) (if uncomp (let ((case-fold-search t) method) (or (string-equal prompt "") (setq prompt (concat prompt "; "))) (setq uncomp (sort (mapcar (function (lambda (elt) (setq method (car elt)) (if (string-equal method "gzip") (setq method "gunzip") (or (string-match "^un" method) (setq method (concat "un" method)))) (setcar elt method) elt)) uncomp) (function (lambda (x y) (string< (car x) (car y)))))) (setq prompt (concat prompt (mapconcat (function (lambda (elt) (format "%s %d" (car elt) (cdr elt)))) uncomp ", "))))) (cond ((= (length rfiles) 1) (setq prompt (format "%s %s? " ;; Don't need the number 1 (substring prompt 0 -2) (car rfiles)))) ((or (> (length uncomp) 1) (and (/= 0 comp) uncomp)) (setq prompt (format "%s? Total: %d file%s " prompt total (dired-plural-s total)))) ((setq prompt (format "%s file%s? " prompt (dired-plural-s total))))) (or (dired-mark-pop-up nil 'compress rfiles 'y-or-n-p prompt) (setq arg 0))))) (list arg files))) (if (not (zerop arg)) (dired-create-files 'dired-compress-file "Compress or Uncompress" files (function (lambda (fn) (let ((cfn (dired-make-compressed-filename fn))) (if (stringp cfn) cfn (substring fn 0 (- (length (nth 1 cfn)))))))) dired-keep-marker-compress nil t))) (defun dired-compress-subdir-files (&optional uncompress) "Compress all uncompressed files in the current subdirectory. With a prefix argument uncompresses all compressed files." (interactive "P") (let ((dir (dired-current-directory)) files methods uncomp elt) (save-excursion (save-restriction (narrow-to-region (dired-subdir-min) (dired-subdir-max)) (dired-map-dired-file-lines (function (lambda (f) (if uncompress (and (listp (setq uncomp (dired-make-compressed-filename f))) (let ((program (car (nth 3 uncomp)))) (setq files (cons f files)) (if (setq elt (assoc program methods)) (setcdr elt (1+ (cdr elt))) (setq methods (cons (cons program 1) methods))))) (and (stringp (dired-make-compressed-filename f)) (setq files (cons f files))))))))) (if files (let ((total (length files)) (rfiles (mapcar (function (lambda (fn) (dired-make-relative fn dir t))) files)) prompt) (if uncompress (progn (setq prompt (mapconcat (function (lambda (x) (format "%s %d" (if (string-equal (car x) "gzip") "gunzip" (if (string-match "^un" (car x)) (car x) (concat "un" (car x)))) (cdr x)))) methods ", ")) (cond ((= total 1) (setq prompt (concat (substring prompt 0 -1) (car rfiles) "? "))) ((= (length methods) 1) (setq prompt (format "%s file%s? " prompt (dired-plural-s total)))) (t (setq prompt (format "%s? Total: %d file%s " prompt total (dired-plural-s total)))))) (setq prompt (if (= total 1) (format "%s %s? " dired-compression-method (car rfiles)) (format "%s %d file%s? " dired-compression-method total (dired-plural-s total))))) (if (dired-mark-pop-up nil 'compress rfiles 'y-or-n-p prompt) (dired-create-files 'dired-compress-file "Compress or Uncompress" files (function (lambda (fn) (let ((cfn (dired-make-compressed-filename fn))) (if (stringp cfn) cfn (substring fn 0 (- (length (nth 1 cfn)))))))) dired-keep-marker-compress nil t))) (message "No files need %scompressing in %s." (if uncompress "un" "") (dired-abbreviate-file-name dir))))) (defun dired-compress-file (file ok-flag) ;; Compress or uncompress FILE. ;; If ok-flag is non-nil, it is OK to overwrite an existing ;; file. How well this actually works may depend on the compression ;; program. ;; Return the name of the compressed or uncompressed file. (let ((handler (find-file-name-handler file 'dired-compress-file))) (if handler (funcall handler 'dired-compress-file file ok-flag) (let ((compressed-fn (dired-make-compressed-filename file)) (err-buff (get-buffer-create " *dired-check-process output*"))) (save-excursion (set-buffer err-buff) (erase-buffer) (cond ((file-symlink-p file) (signal 'file-error (list "Error compressing file" file "a symbolic link"))) ((listp compressed-fn) (message "Uncompressing %s..." file) (let* ((data (nth 3 compressed-fn)) (ret (apply 'call-process (car data) file t nil (append (cdr data) (and ok-flag (list (nth 4 compressed-fn))) (list file))))) (if (or (and (integerp ret) (/= ret 0)) (not (bobp))) (signal 'file-error (nconc (list "Error uncompressing file" file) (and (not (bobp)) (list (progn (goto-char (point-min)) (buffer-substring (point) (progn (end-of-line) (point)))))))))) (message "Uncompressing %s...done" file) (dired-remove-file file) (let ((to (substring file 0 (- (length (nth 1 compressed-fn)))))) ;; rename any buffers (and (get-file-buffer file) (save-excursion (set-buffer (get-file-buffer file)) (let ((modflag (buffer-modified-p))) ;; kills write-file-hooks (set-visited-file-name to) (set-buffer-modified-p modflag)))) to)) ((stringp compressed-fn) (message "Compressing %s..." file) (let* ((data (assq dired-compression-method dired-compression-method-alist)) (compr-args (nth 2 data)) (ret (apply 'call-process (car compr-args) file t nil (append (cdr compr-args) (and ok-flag (list (nth 4 data))) (list file))))) (if (or (and (integerp ret) (/= ret 0)) (not (bobp))) (signal 'file-error (nconc (list "Error compressing file" file) (and (not (bobp)) (list (progn (goto-char (point-min)) (buffer-substring (point) (progn (end-of-line) (point)))))))))) (message "Compressing %s...done" file) (dired-remove-file file) ;; rename any buffers (and (get-file-buffer file) (save-excursion (set-buffer (get-file-buffer file)) (let ((modflag (buffer-modified-p))) ;; kills write-file-hooks (set-visited-file-name compressed-fn) (set-buffer-modified-p modflag)))) compressed-fn) (t (error "Strange error in dired-compress-file.")))))))) (defun dired-make-compressed-filename (name &optional method) ;; If NAME is in the syntax of a compressed file (according to ;; dired-compression-method-alist), return the data (a list) from this ;; alist on how to uncompress it. Otherwise, return a string, the ;; compressed form of this file name. This is computed using the optional ;; argument METHOD (a symbol). If METHOD is nil, the ambient value of ;; dired-compression-method is used. (let ((handler (find-file-name-handler name 'dired-make-compressed-filename))) (if handler (funcall handler 'dired-make-compressed-filename name method) (let ((alist dired-compression-method-alist) (len (length name)) ext ext-len result) (while alist (if (and (> len (setq ext-len (length (setq ext (nth 1 (car alist)))))) (string-equal ext (substring name (- ext-len)))) (setq result (car alist) alist nil) (setq alist (cdr alist)))) (or result (concat name (nth 1 (or (assq (or method dired-compression-method) dired-compression-method-alist) (error "Unknown compression method: %s" (or method dired-compression-method)))))) )))) ;;; end of dired-cmpr.el