dired で tar.gz 圧縮をする その4
完成版と書いちゃったけど, まだまだ更新できる限りつづきます.
plus さんからメールをもらいました.
1つの関数で4つの状態を扱えるようになっています.
(defun dired-do-tar-create (output-filename arg) "マークしたファイルを tar + gzip(or bzip2) でまとめて圧縮する. M-x dired-do-tar-create : tar + gzip C-u M-x dired-do-tar-create : tar + gzip(ファイル追加あり) - M-x dired-do-tar-create : tar + bzip2 - C-u M-x dired-do-tar-create : tar + bzip2(ファイル追加あり)" (interactive "FOUTPUT FILENAME: \nP") (let ((opt (if (>= (prefix-numeric-value arg) 0) '("\\.t\\(ar\\.\\)?gz$" ".tar.gz" "z") '("\\.t\\(ar\\.bz2\\|bz\\)$" ".tar.bz2" "j")))) (or (when (string= "" (file-name-nondirectory output-filename)) ;; 出力ファイル名が入力されていなかったらエラーとする. (message "ERROR: Output filename is empty.")) (when (file-exists-p (setq output-filename (concat output-filename (unless (string-match (car opt) output-filename) (nth 1 opt))))) ;; 出力ファイル名と同じ名前のファイルが, 既にあった場合, 上書きするか問い合わせる. (not (y-or-n-p (concat "file " output-filename " exists. overwrite the file ?")))) ;; 実際に圧縮をする. (let (add-file) (when (and current-prefix-arg (listp current-prefix-arg)) (while (y-or-n-p "ADD FILE?") (add-to-list 'add-file (file-relative-name (read-file-name "" nil nil t))))) (dired-do-shell-command (format "tar cv%sf %s *" (nth 2 opt) output-filename) nil (append (dired-get-marked-files t) add-file))))))
21行目のこの処理が強引かもとのことで,
公開は任せるとのことでしたが, 公開してしまいました.
(when (and current-prefix-arg (listp current-prefix-arg))
確かにこういう, マイナスの前置引数でも分岐をする場合, どういう風にやるのが上手いのでしょうね?
ついでに, この関数を受けて, 私も改造してみました.
はっきり言って微妙です.
(defun dired-do-compression-file-create (output-filename arg &optional regex-ext-cmd-list) "マークしたファイルを tar + gzip(or bzip2) でまとめて圧縮する. M-x dired-do-tar-create : tar + gzip C-u M-x dired-do-tar-create : tar + gzip(ファイル追加あり)" (interactive "FOUTPUT FILENAME: \nP") (let ((opt (if regex-ext-cmd-list regex-ext-cmd-list '("\\.t\\(ar\\.\\)?gz$" ".tar.gz" "tar cvzf")))) (or (when (string= "" (file-name-nondirectory output-filename)) ;; 出力ファイル名が入力されていなかったらエラーとする. (message "ERROR: Output filename is empty.")) (when (file-exists-p (setq output-filename (concat output-filename (unless (string-match (car opt) output-filename) (nth 1 opt))))) ;; 出力ファイル名と同じ名前のファイルが, 既にあった場合, 上書きするか問い合わせる. (not (y-or-n-p (concat "file " output-filename " exists. overwrite the file ?")))) ;; 実際に圧縮をする. (let (add-file) (when arg (while (y-or-n-p "ADD FILE?") (add-to-list 'add-file (file-relative-name (read-file-name "" nil nil t))))) (dired-do-shell-command (format "%s %s *" (nth 2 opt) output-filename) nil (append (dired-get-marked-files t) add-file)))))) (define-key dired-mode-map "\C-cz" (lambda (output-filename arg) (interactive "FOUTPUT FILENAME: \nP") (dired-do-compression-file-create output-filename arg '("\\.zip$" ".zip" "zip -r")))) (define-key dired-mode-map "\C-cj" (lambda (output-filename arg) (interactive "FOUTPUT FILENAME: \nP") (dired-do-compression-file-create output-filename arg '("\\.t\\(ar\\.bz2\\|bz\\)$" ".tar.bz2" "tar cjvf"))))
この関数では, &optional 引数と lambda を使うことにより, 他の圧縮形式も使えるようにしています.
ただ, 1つの関数で4つの状態を表すことはできなくなっています. 今まで通り2つです.
それに lambda 以下が長すぎるし, 任意の圧縮方式を M-x とやって呼出せるわけでもないですからねえ.