Zip files have a comment field for files and an archive comment, that you can set activating the --archive-comment option and display them with the zipnote command.

Is there any emacs package to edit them?


I do not have a direct answer to your question whether there is some emacs package out there for setting the archive content but I have a solution for your problem:

Getting and setting the archive comment is relatively simple since that comment is the last thing in the archive.

After installing the following code in your initialization files (e.g. ~/.emacs.d/init.el) you can display and change the archive comment of zip archives from within archive-mode.

Just open some zip-archive with emacs and type M-x archive-zip-comment RET. The current comment is shown in the minibuffer where you can edit its value and set it with RET.

Note, that you must save the zip file before the new comment takes effect on disk.

archive-zip-comment provides an input history. So, if you want to undo your changes you just go back in history ().

(defun archive-zip-assert (&optional fun)
  "Assert that current buffer is an archive of subtype 'zip.
The error message "
  (assert (eq archive-subtype 'zip) nil "Function %s only works for archives of subtype zip" (or fun this-command)))

(defun archive-zip-eocd ()
  "Move point to the beginning of the end record of the central directory (eocd)."
  (goto-char (buffer-size))
  (assert (search-backward "PK\005\006" nil t)
      nil  "End of central directory signature not found in zip archive"))

(defun archive-zip-comment-start ()
  "Goto start of archive comment."
  (forward-char 20);; offset comment length

(defun archive-zip-comment-length ()
  "Get length of zip archive comment.
Warn if the end of the comment does not match the file end.
Goto start of string."
  (let* ((comment-length (archive-l-e (point) 2))
     (comment-end (progn (forward-char 2) (+ (point) comment-length -1))))
    (if (> comment-end (buffer-size))
    (warn "Zip file %s ends prematurely." (buffer-file-name))
      (when (< comment-end (buffer-size))
    (warn "Extra butes at end of zip file %s." (buffer-file-name))))

(defun archive-zip-get-comment ()
  "Return zip archive comment of current zip archive buffer."
      (let* ((comment-length (archive-zip-comment-length)))
    (buffer-substring-no-properties (point) (+ (point) comment-length))))))

(defun archive-zip-set-comment (str)
  "Replace current zip archive comment with STR."
  (require 'bindat)
      (let* ((inhibit-read-only t)
         (spec '((length u16r) (data str (length))))
         (data (bindat-pack spec (list (cons 'length (length str))
                       (cons 'data str))))
         (old-length (archive-zip-comment-length)))
    (delete-region (- (point) 2) (min (1+ (buffer-size)) (+ (point) old-length)))
    (insert data)))))

(defvar-local archive-zip-comment-history '()
  "Input history for zip archive comments.")
(defvar archive-zip-global-comment-history nil
  "Global variable for `archive-zip-comment-history'.")

(defun archive-zip-comment (str)
  "Display zip editable archive comment in minibuffer."
  (interactive (let ((current-comment (archive-zip-get-comment)))
         (add-to-history 'archive-zip-comment-history current-comment)
         (setq archive-zip-global-comment-history archive-zip-comment-history)
         (list (read-string
            "Archive comment: "
            '(archive-zip-global-comment-history . 1)))))
  (archive-zip-set-comment str))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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