I'm looking for a means to extract individual and marked files from archives (e.g., *.zip; *.gz, etc.) to the hard-drive (without opening them in a buffer) using archive-mode. A suggested modification of that major-mode (that would permit this new feature) will be greatly appreciated.


1 Answer 1


Here's a sketch of an implementation.

Archive mode stores maps from archive types to commands used to extract data in variables archive-TYPE-extract; we can find the right variable using (archive-name "extract").

All commands are tailored for extracting to standard out; luckily we can still use them if we redirect stdout to a file of our choice.

(defun archive-extract-to-file (archive-name item-name command dir)
  "Extract ITEM-NAME from ARCHIVE-NAME using COMMAND. Save to
      ;; remove the leading / from the file name to force
      ;; expand-file-name to interpret its path as relative to dir
      (let* ((file-name (if (string-match "\\`/" item-name)
                            (substring item-name 1)
             (output-file (expand-file-name file-name dir))
             (output-dir (file-name-directory output-file)))
        ;; create the output directory (and its parents) if it does
        ;; not exist yet
        (unless (file-directory-p output-dir)
          (make-directory output-dir t))
        ;; execute COMMAND, redirecting output to output-file
        (apply #'call-process
               (car command)            ;program
               nil                      ;infile
               `(:file ,output-file)    ;destination
               nil                      ;display
               (append (cdr command) (list archive-name item-name))))
    ;; FIXME: add unwind forms

I modified archive-extract-by-file to get this.

(defun archive-extract-marked-to-file (output-dir)
  "Extract marked archive items to OUTPUT-DIR."
  (interactive "sOutput directory: ")
  (let ((command (symbol-value (archive-name "extract")))
        (archive (buffer-file-name))
        (items (archive-get-marked ?* t))) ; get marked items; t means
                                           ; get item under point if
                                           ; nothing is marked
     (lambda (item)
       (archive-extract-to-file archive
                                (aref item 0) ; get the name from the descriptor
                                command output-dir))

Here I use mapc to loop over all marked files and extract them.

Now we just need to add a key binding:

(require 'arc-mode)
(define-key archive-mode-map "F" #'archive-extract-marked-to-file)

I tested this on a dummy .zip file containing a subdirectory, but your mileage may vary.

Note that archive-mode supports Arc, Lzh, Zip, Zoo, Rar, and 7z. It does not support .tgz, .tbz, .tar.gz and friends, which are opened using tar-mode and uncompress.el.

  • @lawlist: Please see the updated answer; now it should be able to extract files contained in subdirectories. Note that it re-creates the directory structure: foo/bar.txt in an archive gets extracted to output-dir/foo/bar.txt, not to output-dir/bar.txt. The latter is possible, of course, but would require some more code. Commented Nov 25, 2014 at 8:10
  • That's really nice. Once you feel confident with it, would you consider adding it to archive-mode itself?
    – Malabarba
    Commented Nov 25, 2014 at 10:17
  • @Malabarba: Yes, I would. I'm waiting for a reply from [email protected] (I got this e-mail from Lars Ingebrigtsen) right now; in the meantime I'll clean this up and put it on GitHub. Commented Nov 25, 2014 at 18:53
  • This new feature is awesome! Thank you so very much -- greatly appreciated! This would indeed be a wonderful addition to archive-mode. As you noted, the ability to target a specific output directory without necessarily re-creating the zip-archive directory structure (in the output directory) would be handy. As is, it is certainly worthy of a checkmark+ for the correct answer :)
    – lawlist
    Commented Nov 25, 2014 at 18:57
  • Thanks a lot for this code! One thing though: it'd be better to (interactive "G...") this way it will suggest the current directory, plus it'll autocomplete and interact with Ido mode etc.
    – wvxvw
    Commented Mar 10, 2015 at 12:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.