commit a4fa31150f186611ad083c3387e3cb2c5d25f991 (HEAD, refs/remotes/origin/master) Author: Tino Calancha Date: Fri Aug 19 17:04:42 2016 +0900 Add tests for Bug#24264 * test/lisp/emacs-lisp/cl-seq-tests.el (cl-seq-test-bug24264): Add test for Bug#24264. (cl-seq-fill-test, cl-seq-replace-test) (cl-seq-remove-test ,cl-seq-delete-test) (cl-seq-remove-duplicates-test, cl-seq-substitute-test) (cl-seq-nsubstitute-test, cl-seq-position-test) (cl-seq-count-test, cl-seq-mismatch-test) (cl-seq-search-test, cl-seq-test-bug24264): Add tests for all functions in the file; test all keywords. diff --git a/test/lisp/emacs-lisp/cl-seq-tests.el b/test/lisp/emacs-lisp/cl-seq-tests.el index d2eb412..cc393f4 100644 --- a/test/lisp/emacs-lisp/cl-seq-tests.el +++ b/test/lisp/emacs-lisp/cl-seq-tests.el @@ -27,6 +27,7 @@ (require 'cl-seq) (ert-deftest cl-union-test-00 () + "Test for http://debbugs.gnu.org/22729 ." (let ((str1 "foo") (str2 (make-string 3 ?o))) ;; Emacs may make two string literals eql when reading. @@ -38,5 +39,270 @@ (should (equal (cl-union (list str1) (list str2) :test 'eql) (list str1 str2))))) +(defvar cl-seq--test-list nil + "List used on `cl-seq' tests with side effects.") +(defvar cl-seq--test-list2 nil + "List used on `cl-seq' tests with side effects.") + +(defmacro cl-seq--with-side-effects (list list2 &rest body) + "Run a test with side effects on lists; after the test restore the lists. +LIST is the value of `cl-seq--test-list' before the test. +LIST2, if non-nil, is the value of `cl-seq--test-list2' before the test. +Body are forms defining the test." + (declare (indent 2) (debug t)) + (let ((orig (make-symbol "orig")) + (orig2 (make-symbol "orig2"))) + `(let ((,orig (copy-sequence ,list)) + (,orig2 (copy-sequence ,list2))) + (unwind-protect (progn ,@body) + (setq cl-seq--test-list ,orig) + (when ,list2 + (setq cl-seq--test-list2 ,orig2)))))) + +;; keywords supported: :start :end +(ert-deftest cl-seq-fill-test () + (let* ((cl-seq--test-list '(1 2 3 4 5 2 6)) + (orig (copy-sequence cl-seq--test-list)) + (tests '((should (equal '(b b b b b b b) (cl-fill _list 'b))) + (should (equal '(1 2 3 4 b b b) (cl-fill _list 'b :start 4))) + (should (equal '(b b b b 5 2 6) (cl-fill _list 'b :end 4))) + (should (equal '(1 2 b b 5 2 6) (cl-fill _list 'b :start 2 :end 4))) + (should (equal orig (cl-fill _list 'b :end 0)))))) + (dolist (test tests) + (let ((_list cl-seq--test-list)) + (cl-seq--with-side-effects orig nil + test))))) + +;; keywords supported: :start1 :end1 :start2 :end2 +(ert-deftest cl-seq-replace-test () + (let* ((cl-seq--test-list '(1 2 3 4 5 2 6)) + (cl-seq--test-list2 (make-list 6 'a)) + (orig (copy-sequence cl-seq--test-list)) + (orig2 (copy-sequence cl-seq--test-list2)) + (tests '((should (equal '(a a a a a a 6) (cl-replace _list _list2))) + (should (equal '(a a a a a a 6) (cl-replace _list _list2 :start1 0))) + (should (equal '(a a a a a a 6) (cl-replace _list _list2 :start2 0))) + (should (equal orig (cl-replace _list _list2 :start1 (length _list)))) + (should (equal orig (cl-replace _list _list2 :start2 (length _list2)))) + (should (equal orig (cl-replace _list _list2 :end1 0))) + (should (equal orig (cl-replace _list _list2 :end2 0))) + (should (equal '(1 2 3 4 a a a) (cl-replace _list _list2 :start1 4))) + (should (equal '(a a a a 5 2 6) (cl-replace _list _list2 :end1 4))) + (should (equal '(a a 3 4 5 2 6) (cl-replace _list _list2 :start2 4))) + (should (equal '(a a a a 5 2 6) (cl-replace _list _list2 :end2 4))) + (should (equal '(1 2 a a 5 2 6) (cl-replace _list _list2 :start1 2 :end1 4))) + (should (equal '(a a 3 4 5 2 6) (cl-replace _list _list2 :start2 2 :end2 4)))))) + (dolist (test tests) + (let ((_list cl-seq--test-list) + (_list2 cl-seq--test-list2)) + (cl-seq--with-side-effects orig orig2 + test))))) + +;; keywords supported: :test :test-not :key :count :start :end :from-end +(ert-deftest cl-seq-remove-test () + (let ((list '(1 2 3 4 5 2 6))) + (should (equal list (cl-remove 'foo list))) + (should (equal '(1 3 4 5 6) (cl-remove 2 list))) + (should (equal '(1 3 4 5 6) (cl-remove 2 list + :key #'identity + :test (lambda (a b) (eql a b))))) + (should (equal '(1 2 3 4 2) (cl-remove 4 list :test (lambda (a b) (> b a))))) + (should (equal '(5 6) (cl-remove 4 list :test-not (lambda (a b) (> b a))))) + (should (equal '(1 3 5) (cl-remove 'foo list :if #'cl-evenp))) + (should (equal '(2 4 2 6) (cl-remove 'foo list :if-not #'cl-evenp))) + (should (equal '(1 2 3 4 5) (cl-remove 'foo list :if #'cl-evenp :start 4))) + (should (equal '(1 2 3 4 5 6) (cl-remove 2 list :start 5 :end 6))) + (should (equal '(1 3 4 5 2 6) (cl-remove 2 list :count 1))) + (should (equal '(1 3 4 5 2 6) (cl-remove 2 list :from-end nil :count 1))) + (should (equal '(1 2 3 4 5 6) (cl-remove 2 list :from-end t :count 1))))) + +;; keywords supported: :test :test-not :key :count :start :end :from-end +(ert-deftest cl-seq-delete-test () + (let* ((cl-seq--test-list '(1 2 3 4 5 2 6)) + (orig (copy-sequence cl-seq--test-list)) + (tests '((should (equal orig (cl-delete 'foo _list))) + (should (equal '(1 3 4 5 6) (cl-delete 2 _list))) + (should (equal '(1 3 4 5 6) (cl-delete 2 _list + :key #'identity + :test (lambda (a b) (eql a b))))) + (should (equal '(1 2 3 4 2) (cl-delete 4 _list :test (lambda (a b) (> b a))))) + (should (equal '(5 6) (cl-delete 4 _list :test-not (lambda (a b) (> b a))))) + (should (equal '(1 3 5) (cl-delete 'foo _list :if #'cl-evenp))) + (should (equal '(2 4 2 6) (cl-delete 'foo _list :if-not #'cl-evenp))) + (should (equal '(1 2 3 4 5) (cl-delete 'foo _list :if #'cl-evenp :start 4))) + (should (equal '(1 2 3 4 5 6) (cl-delete 2 _list :start 5 :end 6))) + (should (equal '(1 3 4 5 2 6) (cl-delete 2 _list :count 1))) + (should (equal '(1 3 4 5 2 6) (cl-delete 2 _list :from-end nil :count 1))) + (should (equal '(1 2 3 4 5 6) (cl-delete 2 _list :from-end t :count 1)))))) + (dolist (test tests) + (let ((_list cl-seq--test-list)) + (cl-seq--with-side-effects orig nil + test))))) + +;; keywords supported: :test :test-not :key :start :end :from-end +(ert-deftest cl-seq-remove-duplicates-test () + (let ((list '(1 2 3 4 5 2 6))) + (should (equal '(1 3 4 5 2 6) (cl-remove-duplicates list))) + (should (equal '(1 2 3 4 5 6) (cl-remove-duplicates list :from-end t))) + (should (equal list (cl-remove-duplicates list :start 2))) + (should (equal list (cl-remove-duplicates list :start 2 :from-end t))) + (should (equal list (cl-remove-duplicates list :end 4))) + (should (equal '(6) (cl-remove-duplicates list :test (lambda (a b) (< a b))))) + (should (equal '(1 2 6) (cl-remove-duplicates list :test (lambda (a b) (>= a b))))) + (should (equal (cl-remove-duplicates list :test (lambda (a b) (>= a b))) + (cl-remove-duplicates list :test-not (lambda (a b) (< a b))))) + (should (equal (cl-remove-duplicates list) + (cl-remove-duplicates list :key #'number-to-string :test #'string=))) + (should (equal list + (cl-remove-duplicates list :key #'number-to-string :test #'eq))))) + +;; keywords supported: :test :test-not :key :count :start :end :from-end +(ert-deftest cl-seq-substitute-test () + (let ((list '(1 2 3 4 5 2 6))) + (should (equal '(1 b 3 4 5 b 6) (cl-substitute 'b 2 list))) + (should (equal list (cl-substitute 'b 2 list :start (length list)))) + (should (equal list (cl-substitute 'b 2 list :end 0))) + (should (equal '(1 2 3 4 5 b 6) (cl-substitute 'b 2 list :start 2))) + (should (equal '(1 b 3 4 5 2 6) (cl-substitute 'b 2 list :end 2))) + (should (equal list (cl-substitute 'b 2 list :start 2 :end 4))) + (should (equal '(1 b 3 4 5 2 6) (cl-substitute 'b 2 list :count 1))) + (should (equal '(1 2 3 4 5 b 6) (cl-substitute 'b 2 list :count 1 :from-end t))) + (should (equal list (cl-substitute 'b 2 list :count -1))) + (should (equal '(1 b 3 4 5 b 6) (cl-substitute 'b "2" list :key #'number-to-string + :test #'string=))) + (should (equal (cl-substitute 'b 2 list) + (cl-substitute 'b 2 list :test #'eq))) + (should (equal '(1 2 b b b 2 b) (cl-substitute 'b 2 list :test (lambda (a b) (< a b))))) + (should (equal '(b b 3 4 5 b 6) (cl-substitute 'b 2 list :test (lambda (a b) (>= a b))))) + (should (equal list (cl-substitute 'b 99 list :test (lambda (a b) (< a b))))) + (should (equal (cl-substitute 'b 2 list :test (lambda (a b) (>= a b))) + (cl-substitute 'b 2 list :test-not (lambda (a b) (< a b))))) + (should (equal '(1 2 b b b 2 b) (cl-substitute 'b nil list :if (lambda (x) (> (cl-position x list) 1))))) + (should (equal '(1 b b b b b b) (cl-substitute 'b nil list :if (lambda (x) (> (cl-position x list :from-end t) 1))))) + + (should (equal '(b b 3 4 5 b 6) (cl-substitute 'b nil list + :if-not (lambda (x) (> (cl-position x list) 1))))) + (should (equal '(b 2 3 4 5 2 6) (cl-substitute 'b nil list + :if-not (lambda (x) (> (cl-position x list :from-end t) 1))))))) + + +;; keywords supported: :test :test-not :key :count :start :end :from-end +(ert-deftest cl-seq-nsubstitute-test () + (let ((cl-seq--test-list '(1 2 3 4 5 2 6)) + (orig (copy-sequence cl-seq--test-list)) + (tests '((should (equal '(1 b 3 4 5 b 6) (cl-nsubstitute 'b 2 _list))) + (should (equal _list (cl-substitute 'b 2 _list :start (length _list)))) + (should (equal _list (cl-substitute 'b 2 _list :end 0))) + (should (equal '(1 2 3 4 5 b 6) (cl-substitute 'b 2 _list :start 2))) + (should (equal '(1 b 3 4 5 2 6) (cl-substitute 'b 2 _list :end 2))) + (should (equal _list (cl-substitute 'b 2 _list :start 2 :end 4))) + (should (equal '(1 b 3 4 5 2 6) (cl-nsubstitute 'b 2 _list :count 1))) + (should (equal '(1 2 3 4 5 b 6) (cl-nsubstitute 'b 2 _list :count 1 :from-end t))) + (should (equal _list (cl-nsubstitute 'b 2 _list :count -1))) + (should (equal '(1 b 3 4 5 b 6) (cl-nsubstitute 'b "2" _list :key #'number-to-string + :test #'string=))) + (should (equal (cl-nsubstitute 'b 2 _list) + (cl-nsubstitute 'b 2 _list :test #'eq))) + (should (equal '(1 2 b b b 2 b) (cl-nsubstitute 'b 2 _list :test (lambda (a b) (< a b))))) + (should (equal '(b b 3 4 5 b 6) (cl-nsubstitute 'b 2 _list :test (lambda (a b) (>= a b))))) + (should (equal _list (cl-nsubstitute 'b 99 _list :test (lambda (a b) (< a b))))) + (should (equal (cl-nsubstitute 'b 2 _list :test (lambda (a b) (>= a b))) + (cl-nsubstitute 'b 2 _list :test-not (lambda (a b) (< a b))))) + (should (equal '(1 2 b b b 2 b) + (cl-nsubstitute 'b nil _list :if (lambda (x) (> (cl-position x _list) 1))))) + (should (equal '(1 b b b b b b) + (cl-nsubstitute 'b nil _list :if (lambda (x) (> (cl-position x _list :from-end t) 1))))) + (should (equal '(b b 3 4 5 b 6) + (cl-nsubstitute 'b nil _list + :if-not (lambda (x) (> (cl-position x _list) 1))))) + (should (equal '(b 2 3 4 5 2 6) + (cl-nsubstitute 'b nil _list + :if-not (lambda (x) (> (cl-position x _list :from-end t) 1)))))))) + (dolist (test tests) + (let ((_list cl-seq--test-list)) + (cl-seq--with-side-effects orig nil + test))))) + +;; keywords supported: :test :test-not :key :start :end :from-end +(ert-deftest cl-seq-position-test () + (let ((list '(1 2 3 4 5 2 6))) + (should-not (cl-position 'foo list)) + (should (= 1 (cl-position 2 list))) + (should (= 5 (cl-position 2 list :start 5 :end 6))) + (should (= 1 (cl-position 2 list :from-end nil))) + (should (= 5 (cl-position 2 list :from-end t))) + (should (cl-position 2 list :key #'identity + :test (lambda (a b) (eql a b)))) + (should (= 1 (cl-position "2" list :key #'number-to-string :test #'string=))) + (should (= 5 (cl-position "2" list :key #'number-to-string :test #'string= :from-end t))) + (should-not (cl-position "2" list :key #'number-to-string)) + (should (cl-position 5 list :key (lambda (x) (1+ (* 1.0 x x))) :test #'=)) + (should-not (cl-position 5 list :key (lambda (x) (1+ (* 1.0 x x))))) + (should (= 1 (cl-position 5 list :key (lambda (x) (1+ (* x x)))))) + (should (= 5 (cl-position 5 list :key (lambda (x) (1+ (* x x))) :from-end t))))) + +;; keywords supported: :test :test-not :key :start :end +(ert-deftest cl-seq-count-test () + (let ((list '(1 2 3 4 5 2 6))) + (should (= 2 (cl-count 2 list))) + (should (= 1 (cl-count 2 list :start 2))) + (should (= 1 (cl-count 2 list :end 4))) + (should (= 0 (cl-count -5 list))) + (should (= 0 (cl-count 2 list :start 2 :end 4))) + (should (= 4 (cl-count 'foo list :key (lambda (x) (and (cl-evenp x) 'foo))))) + (should (= 4 (cl-count 'foo list :test (lambda (a b) (cl-evenp b))))) + (should (equal (cl-count 'foo list :test (lambda (a b) (cl-oddp b))) + (cl-count 'foo list :test-not (lambda (a b) (cl-evenp b))))))) + +;; keywords supported: :test :test-not :key :start1 :end1 :start2 :end2 :from-end +(ert-deftest cl-seq-mismatch-test () + (let ((list '(1 2 3 4 5 2 6)) + (list2 '(1 999 2 3 4 5 2 6))) + (should-not (cl-mismatch list list)) + (should-not (cl-mismatch list (remove 999 list2))) + (should (= 0 (cl-mismatch list list :key #'number-to-string))) + (should-not (cl-mismatch list list :key #'number-to-string :test #'string=)) + (should (= 1 (cl-mismatch list list2))) + (should (= 0 (cl-mismatch list list2 :from-end t))) + (should (= 3 (cl-mismatch '(1 2 3) list))) + (should-not (cl-mismatch list list2 :end1 1 :end2 1)) + (should-not (cl-mismatch list list2 :start1 1 :start2 2)) + (should (= 1 (cl-mismatch list list2 :start1 1 :end1 2 :start2 4 :end2 4))) + (should (= -1 (cl-mismatch list list2 :key #'number-to-string + :test (lambda (a b) + (and (stringp a) (stringp b))) :from-end t))) + (should (= 7 (cl-mismatch list list2 :key #'number-to-string + :test (lambda (a b) + (and (stringp a) (stringp b)))))))) + +;; keywords supported: :test :test-not :key :start1 :end1 :start2 :end2 :from-end +(ert-deftest cl-seq-search-test () + (let ((list '(1 2 3 4 5 2 6)) + (list2 '(1 999 2 3 4 5 2 6))) + (should-not (cl-search list list2)) + (should (= 2 (cl-search list list2 :start1 1 :start2 2))) + (should (= 4 (cl-search list list2 :start1 3))) + (should (= 6 (cl-search list list2 :start1 5))) + (should (= 0 (cl-search list list2 :end1 1))) + (should (= 0 (cl-search nil list2))) + (should (= 2 (cl-search list list2 :start1 1 :end1 2 :end2 3))) + (should (= 0 (cl-search list list2 :test (lambda (a b) (and (numberp a) (numberp b)))))) + (should (= 0 (cl-search list list2 :key (lambda (x) (and (numberp x) 'foo)) + :test (lambda (a b) (and (eq a 'foo) (eq b 'foo)))))) + (should (= 1 (cl-search (nthcdr 2 list) (nthcdr 2 list2)))) + (should (= 3 (cl-search (nthcdr 2 list) list2))))) + +(ert-deftest cl-seq-test-bug24264 () + "Test for http://debbugs.gnu.org/24264 ." + :expected-result :failed + (let ((list (append (make-list 8000005 1) '(8))) + (list2 (make-list 8000005 2))) + (should (cl-position 8 list)) + (should-not (equal '(8) (last (cl-remove 8 list)))) + (should (equal '(2 8) (last (cl-substitute 2 1 list) 2))) + (should (equal '(2 8) (last (cl-replace list list2) 2))) + (should (equal '(1 1) (last (cl-fill list 1) 2))))) + + (provide 'cl-seq-tests) ;;; cl-seq-tests.el ends here commit 8fcf3df9395a3b1196fd5c95aeebba9e75f69247 Author: Johan Bockgård Date: Thu Aug 18 21:25:11 2016 +0200 Fix bug in --eval reply message from server * lisp/server.el (server-reply-print): Fix check for truncated quote sequence at end of message. Problem reported in: http://lists.gnu.org/archive/html/emacs-devel/2016-08/msg00101.html diff --git a/lisp/server.el b/lisp/server.el index e4cf431..5300984 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -784,7 +784,7 @@ This handles splitting the command if it would be bigger than ;; We have to split the string (setq part (substring qtext 0 (- server-msg-size (length prefix) 1))) ;; Don't split in the middle of a quote sequence - (if (string-match "\\(^\\|[^&]\\)\\(&&\\)+$" part) + (if (string-match "\\(^\\|[^&]\\)&\\(&&\\)*$" part) ;; There is an uneven number of & at the end (setq part (substring part 0 -1))) (setq qtext (substring qtext (length part))) commit b305fab44c10488e601096d506a30259961e8d7f Author: Eli Zaretskii Date: Thu Aug 18 18:06:33 2016 +0300 Add tests for 'substitute-command-keys' * test/src/doc-tests.el (doc-test-substitute-command-keys): New tests. diff --git a/test/src/doc-tests.el b/test/src/doc-tests.el new file mode 100644 index 0000000..be49054 --- /dev/null +++ b/test/src/doc-tests.el @@ -0,0 +1,92 @@ +;;; doc-tests.el --- Tests for doc.c + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Eli Zaretskii + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Code: + +(require 'ert) + +(ert-deftest doc-test-substitute-command-keys () + ;; Bindings. + (should (string= (substitute-command-keys "foo \\[goto-char]") "foo M-g c")) + ;; Cannot use string= here, as that compares unibyte and multibyte + ;; strings not equal. + (should (compare-strings + (substitute-command-keys "\200 \\[goto-char]") nil nil + "\200 M-g c" nil nil)) + ;; Literals. + (should (string= (substitute-command-keys "foo \\=\\[goto-char]") + "foo \\[goto-char]")) + (should (string= (substitute-command-keys "foo \\=\\=") + "foo \\=")) + ;; Keymaps. + (should (string= (substitute-command-keys + "\\{minibuffer-local-must-match-map}") + "\ +key binding +--- ------- + +C-g abort-recursive-edit +TAB minibuffer-complete +C-j minibuffer-complete-and-exit +RET minibuffer-complete-and-exit +ESC Prefix Command +SPC minibuffer-complete-word +? minibuffer-completion-help + file-cache-minibuffer-complete + previous-history-element + next-history-element + next-line-or-history-element + next-history-element + switch-to-completions + previous-line-or-history-element + +M-v switch-to-completions + +M-n next-history-element +M-p previous-history-element +M-r previous-matching-history-element +M-s next-matching-history-element + +")) + (should (string= + (substitute-command-keys + "\\\\[abort-recursive-edit]") + "C-g")) + ;; Allow any style of quotes, since the terminal might not support + ;; UTF-8. + (should (string-match + "\nUses keymap [`‘']foobar-map['’], which is not currently defined.\n" + (substitute-command-keys "\\{foobar-map}"))) + ;; Quotes. + (should (let ((text-quoting-style 'grave)) + (string= (substitute-command-keys "quotes `like this'") + "quotes `like this'"))) + (should (let ((text-quoting-style 'grave)) + (string= (substitute-command-keys "quotes ‘like this’") + "quotes ‘like this’"))) + (should (let ((text-quoting-style 'straight)) + (string= (substitute-command-keys "quotes `like this'") + "quotes 'like this'"))) + ;; Bugs. + (should (string= (substitute-command-keys "\\[foobar") "\\[foobar")) + (should (string= (substitute-command-keys "\\=") "\\=")) + ) + +(provide 'doc-tests) +;;; doc-tests.el ends here commit 45522a1ed316ea639bee563e7ad91060b921dbfa Author: Oleh Krehel Date: Thu Aug 18 16:05:29 2016 +0200 lisp/textmodes/table.el (table-generate-source): Fix completing-read call Doesn't make sense to pass '(("html") ("latex") ("cals")) to `completing-read'. diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 3502adf..8330e17 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -2968,8 +2968,7 @@ CALS (DocBook DTD): (default (car table-source-language-history)) (language (downcase (completing-read (format "Language (default %s): " default) - (mapcar (lambda (s) (list (symbol-name s))) - table-source-languages) + table-source-languages nil t nil 'table-source-language-history default)))) (list (intern language) commit 4db19cdaf63289d413e5554253aa7eae931a5d4a Author: Oleh Krehel Date: Thu Jul 14 11:40:53 2016 +0200 lisp/dired-aux.el (dired-compress-file-suffixes): Add entry for tgz The previous behavior resulted in a "tgz" -> "tar" -> "tgz" loop, without any files being extracted. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index ff1f14d..4bdded3 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -942,8 +942,8 @@ command with a prefix argument (the value does not matter)." ;; Solaris10 version of tar. Solaris10 becomes obsolete in 2021. ;; Same thing on AIX 7.1. ("\\.tar\\.gz\\'" "" "gzip -dc %i | tar -xv") + ("\\.tgz\\'" "" "gzip -dc %i | tar -xv") ("\\.gz\\'" "" "gunzip") - ("\\.tgz\\'" ".tar" "gunzip") ("\\.Z\\'" "" "uncompress") ;; For .z, try gunzip. It might be an old gzip file, ;; or it might be from compact? pack? (which?) but gunzip handles both.