* bug#19274: tar-mode.el: allow for adding new archive members @ 2014-12-04 21:17 Ivan Shmakov 2014-12-05 2:10 ` Stefan Monnier 0 siblings, 1 reply; 17+ messages in thread From: Ivan Shmakov @ 2014-12-04 21:17 UTC (permalink / raw) To: 19274 [-- Attachment #1: Type: text/plain, Size: 442 bytes --] Package: emacs Severity: wishlist Please consider the patch MIMEd. * tar-mode.el: Allow for adding new archive members. (tar--pad-to, tar--put-at, tar-header-serialize): New functions. (tar-current-position): Split from tar-current-descriptor. (tar-current-descriptor): Use it. (tar-new-entry): New command. (tar-mode-map): Bind it. -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Type: text/diff, Size: 4769 bytes --] --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el @@ -369,6 +369,58 @@ string) (tar-parse-octal-integer string)) +(defun tar--pad-to (pos) + (make-string (+ pos (- (point)) (point-min)) 0)) + +(defun tar--put-at (pos val) + (when val + (insert (tar--pad-to pos) val))) + +(defun tar-header-serialize (header &optional update-checksum) + (with-temp-buffer + (set-buffer-multibyte nil) + (let ((encoded-name + (encode-coding-string (tar-header-name header) + tar-file-name-coding-system))) + (unless (< (length encoded-name) 99) + ;; FIXME: implement it + (error "Long file name support is not implemented")) + (insert encoded-name)) + (insert (tar--pad-to tar-mode-offset) + (format "%6o\0 " (logand #o777777 (tar-header-mode header))) + (format "%6o\0 " (logand #o777777 (tar-header-uid header))) + (format "%6o\0 " (logand #o777777 (tar-header-gid header)))) + (insert (tar--pad-to tar-size-offset) + (format "%11o " (tar-header-size header))) + (insert (tar--pad-to tar-time-offset) + (tar-octal-time (tar-header-date header)) + " ") + ;; omit tar-header-checksum (tar-chk-offset) for now + (tar--put-at tar-linkp-offset (tar-header-link-type header)) + (tar--put-at tar-link-offset (tar-header-link-name header)) + (when (tar-header-magic header) + (tar--put-at tar-magic-offset (tar-header-magic header)) + (tar--put-at tar-uname-offset (tar-header-uname header)) + (tar--put-at tar-gname-offset (tar-header-gname header)) + (let ((dmaj (tar-header-dmaj header)) + (dmin (tar-header-dmin header))) + (tar--put-at tar-dmaj-offset + (and dmaj (format "%7o\0" (logand #o7777777 dmaj)))) + (tar--put-at tar-dmin-offset + (and dmin (format "%7o\0" (logand #o7777777 dmin)))))) + (tar--put-at 512 "") + (let ((ck (tar-header-block-checksum (buffer-string)))) + (goto-char (+ (point-min) tar-chk-offset)) + (delete-char 8) + (insert (format "%6o\0 " ck)) + (when update-checksum + (setf (tar-header-checksum header) ck)) + (tar-header-block-check-checksum (buffer-string) + (tar-header-checksum header) + (tar-header-name header))) + ;; . + (buffer-string))) + (defun tar-header-block-checksum (string) "Compute and return a tar-acceptable checksum for this block." @@ -547,6 +599,7 @@ defvar tar-mode-map (define-key map "p" 'tar-previous-line) (define-key map "\^P" 'tar-previous-line) (define-key map [up] 'tar-previous-line) + (define-key map "I" 'tar-new-entry) (define-key map "R" 'tar-rename-entry) (define-key map "u" 'tar-unflag) (define-key map "v" 'tar-view) @@ -731,10 +784,14 @@ (interactive "p") (tar-next-line (- arg))) +(defun tar-current-position () + "Return the `tar-parse-info' index for the current line." + (count-lines (point-min) (line-beginning-position))) + (defun tar-current-descriptor (&optional noerror) "Return the tar-descriptor of the current line, or signals an error." ;; I wish lines had plists, like in ZMACS... - (or (nth (count-lines (point-min) (line-beginning-position)) + (or (nth (tar-current-position) tar-parse-info) (if noerror nil @@ -948,6 +1005,45 @@ (write-region start end to-file nil nil nil t))) (message "Copied tar entry %s to %s" name to-file))) +(defun tar-new-entry (filename &optional index) + "Insert a new empty regular file before point." + (interactive "*sNew file name: ") + (let* ((buffer (current-buffer)) + (index (or index (tar-current-position))) + (d-list (and (not (zerop index)) + (nthcdr (+ -1 index) tar-parse-info))) + (pos (if d-list + (tar-header-data-end (car d-list)) + (point-min))) + (new-descriptor + (make-tar-header + nil + filename + #o644 0 0 0 + (current-time) + nil ; checksum + nil nil + nil nil nil nil nil))) + ;; update the data buffer; fill the missing descriptor fields + (with-current-buffer tar-data-buffer + (goto-char pos) + (insert (tar-header-serialize new-descriptor t)) + (setf (tar-header-data-start new-descriptor) + (copy-marker (point) nil))) + ;; update tar-parse-info + (if d-list + (setcdr d-list (cons new-descriptor (cdr d-list))) + (setq tar-parse-info (cons new-descriptor + tar-parse-info))) + ;; update the listing buffer + (save-excursion + (goto-char (point-min)) + (forward-line index) + (let ((inhibit-read-only t)) + (insert (tar-header-block-summarize new-descriptor) ?\n))) + ;; . + index)) + (defun tar-flag-deleted (p &optional unflag) "In Tar mode, mark this sub-file to be deleted from the tar file. With a prefix argument, mark that many files." ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-04 21:17 bug#19274: tar-mode.el: allow for adding new archive members Ivan Shmakov @ 2014-12-05 2:10 ` Stefan Monnier 2014-12-05 20:20 ` Ivan Shmakov 0 siblings, 1 reply; 17+ messages in thread From: Stefan Monnier @ 2014-12-05 2:10 UTC (permalink / raw) To: Ivan Shmakov; +Cc: 19274 > * tar-mode.el: Allow for adding new archive members. > (tar--pad-to, tar--put-at, tar-header-serialize): New functions. > (tar-current-position): Split from tar-current-descriptor. > (tar-current-descriptor): Use it. > (tar-new-entry): New command. > (tar-mode-map): Bind it. Thanks, looks good, please install (with appropriate etc/NEWS entry). See nitpicks below, Stefan > + ;; omit tar-header-checksum (tar-chk-offset) for now Please capitalize and punctuate your comments. ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-05 2:10 ` Stefan Monnier @ 2014-12-05 20:20 ` Ivan Shmakov 2014-12-06 5:09 ` Stefan Monnier 0 siblings, 1 reply; 17+ messages in thread From: Ivan Shmakov @ 2014-12-05 20:20 UTC (permalink / raw) To: 19274 >>>>> Stefan Monnier <monnier@iro.umontreal.ca> writes: […] >> + ;; omit tar-header-checksum (tar-chk-offset) for now > Please capitalize and punctuate your comments. Even the one-line ones? Given that I have some time to improve this patch, could someone please suggest a good place to add a menu entry for tar-new-entry in tar-mode-map? (I never use Emacs’ menus myself, so I’m rather clueless on this.) BTW, I wonder if it makes sense to split the make-tar-header form (with all the nil’s there) off tar-new-entry into a new (tar-new-regular-file-header filename &optional size time) function? I guess that’d ease the creation of Tar archives from Emacs Lisp code; (and I already imagine some uses to that.) I’ll also write a proper docstring for tar-header-serialize, so to make it clear this function is part of the module’s external interface. PS. you know you may be a mathematician if your sentences start with a lower-case letter and end with a semicolon; -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A. ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-05 20:20 ` Ivan Shmakov @ 2014-12-06 5:09 ` Stefan Monnier 2014-12-06 19:17 ` Ivan Shmakov 0 siblings, 1 reply; 17+ messages in thread From: Stefan Monnier @ 2014-12-06 5:09 UTC (permalink / raw) To: 19274 >>> + ;; omit tar-header-checksum (tar-chk-offset) for now >> Please capitalize and punctuate your comments. > Even the one-line ones? Yes, we do that for all comments, since this poor little sentence would feel disrespected otherwise. > BTW, I wonder if it makes sense to split the make-tar-header > form (with all the nil’s there) off tar-new-entry into a new > (tar-new-regular-file-header filename &optional size time) > function? I guess that’d ease the creation of Tar archives from > Emacs Lisp code; (and I already imagine some uses to that.) BTW, if you're interested in hacking on tar-mode, I keep dreaming of plugging it into file-name-handler-alist so you can just visit /foo/bar.tar.gz/somefile, use dired on it, ... Stefan ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 5:09 ` Stefan Monnier @ 2014-12-06 19:17 ` Ivan Shmakov 2014-12-06 19:33 ` Eli Zaretskii 2014-12-06 23:13 ` Stefan Monnier 0 siblings, 2 replies; 17+ messages in thread From: Ivan Shmakov @ 2014-12-06 19:17 UTC (permalink / raw) To: 19274 [-- Attachment #1: Type: text/plain, Size: 1552 bytes --] >>>>> Stefan Monnier <monnier@iro.umontreal.ca> writes: Please consider the revised patch MIMEd. * tar-mode.el: Allow for adding new archive members. (tar-new-regular-file-header, tar--pad-to, tar--put-at) (tar-header-serialize): New functions. (tar-current-position): Split from tar-current-descriptor. (tar-current-descriptor): Use it. (tar-new-entry): New command. (tar-mode-map): Bind it. […] >> BTW, I wonder if it makes sense to split the make-tar-header form >> (with all the nil’s there) off tar-new-entry into a new >> (tar-new-regular-file-header filename &optional size time) function? (Done.) >> I guess that’d ease the creation of Tar archives from Emacs Lisp >> code; (and I already imagine some uses to that.) > BTW, if you're interested in hacking on tar-mode, I keep dreaming of > plugging it into file-name-handler-alist so you can just visit > /foo/bar.tar.gz/somefile, use dired on it, ... I’m not all that familiar with file-name-handler-alist, but I guess I could check it out. (Although at this point I’m simply interested in creating Tar archives from the contents of Emacs buffers, – without having them saved into files, that is.) Curiously, what would be the sensible behavior for Emacs when the copy of the Tar archive kept in the *tar-data* buffer happens to differ to the on-disk state of the respective file? -- FSF associate member #7257 np. Вселенская большая любовь — Гражданская Оборона [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Type: text/diff, Size: 6431 bytes --] --- a/etc/NEWS 2014-11-27 11:36:08 +0000 +++ b/etc/NEWS 2014-12-06 19:03:35 +0000 @@ -340,6 +340,9 @@ `tildify-ignored-environments-alist' variables (as well as a few helper functions) obsolete. +** tar-mode: new `tar-new-entry' command, allowing for new members to +be added to the archive. + ** Obsolete packages --- --- a/lisp/tar-mode.el 2014-08-28 19:18:24 +0000 +++ b/lisp/tar-mode.el 2014-12-06 19:04:02 +0000 @@ -50,9 +50,6 @@ ;; ;; o chmod should understand "a+x,og-w". ;; -;; o It's not possible to add a NEW file to a tar archive; not that -;; important, but still... -;; ;; o The code is less efficient that it could be - in a lot of places, I ;; pull a 512-character string out of the buffer and parse it, when I could ;; be parsing it in place, not garbaging a string. Should redo that. @@ -369,6 +366,83 @@ write-date, checksum, link-type, and link-name." string) (tar-parse-octal-integer string)) +(defun tar-new-regular-file-header (filename &optional size time) + "Return a Tar header for a regular file. +The header will lack a proper checksum; use `tar-header-block-checksum' +to compute one, or request `tar-header-serialize' to do that. + +Other tar-mode facilities may also require the data-start header +field to be set to a valid value. + +If SIZE is not given or nil, it defaults to 0. +If TIME is not given or nil, assume now." + (make-tar-header + nil + filename + #o644 0 0 (or size 0) + (or time (current-time)) + nil ; checksum + nil nil + nil nil nil nil nil)) + +(defun tar--pad-to (pos) + (make-string (+ pos (- (point)) (point-min)) 0)) + +(defun tar--put-at (pos val) + (when val + (insert (tar--pad-to pos) val))) + +(defun tar-header-serialize (header &optional update-checksum) + "Return the serialization of a Tar HEADER as a string. +This function calls `tar-header-block-check-checksum' to ensure the +checksum is correct. + +When UPDATE-CHECKSUM is non-nil, update HEADER with the newly-computed +checksum before doing the check." + (with-temp-buffer + (set-buffer-multibyte nil) + (let ((encoded-name + (encode-coding-string (tar-header-name header) + tar-file-name-coding-system))) + (unless (< (length encoded-name) 99) + ;; FIXME: implement it + (error "Long file name support is not implemented")) + (insert encoded-name)) + (insert (tar--pad-to tar-mode-offset) + (format "%6o\0 " (logand #o777777 (tar-header-mode header))) + (format "%6o\0 " (logand #o777777 (tar-header-uid header))) + (format "%6o\0 " (logand #o777777 (tar-header-gid header)))) + (insert (tar--pad-to tar-size-offset) + (format "%11o " (tar-header-size header))) + (insert (tar--pad-to tar-time-offset) + (tar-octal-time (tar-header-date header)) + " ") + ;; omit tar-header-checksum (tar-chk-offset) for now + (tar--put-at tar-linkp-offset (tar-header-link-type header)) + (tar--put-at tar-link-offset (tar-header-link-name header)) + (when (tar-header-magic header) + (tar--put-at tar-magic-offset (tar-header-magic header)) + (tar--put-at tar-uname-offset (tar-header-uname header)) + (tar--put-at tar-gname-offset (tar-header-gname header)) + (let ((dmaj (tar-header-dmaj header)) + (dmin (tar-header-dmin header))) + (tar--put-at tar-dmaj-offset + (and dmaj (format "%7o\0" (logand #o7777777 dmaj)))) + (tar--put-at tar-dmin-offset + (and dmin (format "%7o\0" (logand #o7777777 dmin)))))) + (tar--put-at 512 "") + (let ((ck (tar-header-block-checksum (buffer-string)))) + (goto-char (+ (point-min) tar-chk-offset)) + (delete-char 8) + (insert (format "%6o\0 " ck)) + (when update-checksum + (setf (tar-header-checksum header) ck)) + (tar-header-block-check-checksum (buffer-string) + (tar-header-checksum header) + (tar-header-name header))) + ;; . + (buffer-string))) + (defun tar-header-block-checksum (string) "Compute and return a tar-acceptable checksum for this block." @@ -547,6 +621,7 @@ MODE should be an integer which is a file mode value." (define-key map "p" 'tar-previous-line) (define-key map "\^P" 'tar-previous-line) (define-key map [up] 'tar-previous-line) + (define-key map "I" 'tar-new-entry) (define-key map "R" 'tar-rename-entry) (define-key map "u" 'tar-unflag) (define-key map "v" 'tar-view) @@ -731,10 +806,14 @@ tar-file's buffer." (interactive "p") (tar-next-line (- arg))) +(defun tar-current-position () + "Return the `tar-parse-info' index for the current line." + (count-lines (point-min) (line-beginning-position))) + (defun tar-current-descriptor (&optional noerror) "Return the tar-descriptor of the current line, or signals an error." ;; I wish lines had plists, like in ZMACS... - (or (nth (count-lines (point-min) (line-beginning-position)) + (or (nth (tar-current-position) tar-parse-info) (if noerror nil @@ -948,6 +1027,37 @@ the current tar-entry." (write-region start end to-file nil nil nil t))) (message "Copied tar entry %s to %s" name to-file))) +(defun tar-new-entry (filename &optional index) + "Insert a new empty regular file before point." + (interactive "*sFile name: ") + (let* ((buffer (current-buffer)) + (index (or index (tar-current-position))) + (d-list (and (not (zerop index)) + (nthcdr (+ -1 index) tar-parse-info))) + (pos (if d-list + (tar-header-data-end (car d-list)) + (point-min))) + (new-descriptor + (tar-new-regular-file-header filename))) + ;; Update the data buffer; fill the missing descriptor fields. + (with-current-buffer tar-data-buffer + (goto-char pos) + (insert (tar-header-serialize new-descriptor t)) + (setf (tar-header-data-start new-descriptor) + (copy-marker (point) nil))) + ;; Update tar-parse-info. + (if d-list + (setcdr d-list (cons new-descriptor (cdr d-list))) + (setq tar-parse-info (cons new-descriptor tar-parse-info))) + ;; Update the listing buffer. + (save-excursion + (goto-char (point-min)) + (forward-line index) + (let ((inhibit-read-only t)) + (insert (tar-header-block-summarize new-descriptor) ?\n))) + ;; . + index)) + (defun tar-flag-deleted (p &optional unflag) "In Tar mode, mark this sub-file to be deleted from the tar file. With a prefix argument, mark that many files." ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 19:17 ` Ivan Shmakov @ 2014-12-06 19:33 ` Eli Zaretskii 2014-12-06 19:45 ` Ivan Shmakov 2014-12-06 23:13 ` Stefan Monnier 1 sibling, 1 reply; 17+ messages in thread From: Eli Zaretskii @ 2014-12-06 19:33 UTC (permalink / raw) To: Ivan Shmakov; +Cc: 19274 > From: Ivan Shmakov <ivan@siamics.net> > Date: Sat, 06 Dec 2014 19:17:16 +0000 > > --- a/etc/NEWS 2014-11-27 11:36:08 +0000 > +++ b/etc/NEWS 2014-12-06 19:03:35 +0000 > @@ -340,6 +340,9 @@ > `tildify-ignored-environments-alist' variables (as well as a few > helper functions) obsolete. > > +** tar-mode: new `tar-new-entry' command, allowing for new members to > +be added to the archive. How about adding the necessary bits to the Emacs manual? > +(defun tar-header-serialize (header &optional update-checksum) > + "Return the serialization of a Tar HEADER as a string. > +This function calls `tar-header-block-check-checksum' to ensure the > +checksum is correct. > + > +When UPDATE-CHECKSUM is non-nil, update HEADER with the newly-computed Not "when", "if". "When" has an implicit timing reference, which is not what you mean here. Thanks. ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 19:33 ` Eli Zaretskii @ 2014-12-06 19:45 ` Ivan Shmakov 2014-12-06 19:56 ` Eli Zaretskii 0 siblings, 1 reply; 17+ messages in thread From: Ivan Shmakov @ 2014-12-06 19:45 UTC (permalink / raw) To: 19274 >>>>> Eli Zaretskii <eliz@gnu.org> writes: >>>>> From: Ivan Shmakov Date: Sat, 06 Dec 2014 19:17:16 +0000 […] >> ** tar-mode: new `tar-new-entry' command, allowing for new members >> to be added to the archive. > How about adding the necessary bits to the Emacs manual? Sure; what’s the respective .texi file? (Somehow, I failed to find one.) […] >> When UPDATE-CHECKSUM is non-nil, update HEADER with the >> newly-computed > Not "when", "if". "When" has an implicit timing reference, which is > not what you mean here. ACK. -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 19:45 ` Ivan Shmakov @ 2014-12-06 19:56 ` Eli Zaretskii 2014-12-06 20:04 ` Ivan Shmakov 0 siblings, 1 reply; 17+ messages in thread From: Eli Zaretskii @ 2014-12-06 19:56 UTC (permalink / raw) To: Ivan Shmakov; +Cc: 19274 > From: Ivan Shmakov <ivan@siamics.net> > Date: Sat, 06 Dec 2014 19:45:26 +0000 > > >>>>> Eli Zaretskii <eliz@gnu.org> writes: > >>>>> From: Ivan Shmakov Date: Sat, 06 Dec 2014 19:17:16 +0000 > > […] > > >> ** tar-mode: new `tar-new-entry' command, allowing for new members > >> to be added to the archive. > > > How about adding the necessary bits to the Emacs manual? > > Sure; what’s the respective .texi file? (Somehow, I failed to > find one.) "fgrep tar-mode doc/emacs/*.texi blames misc.texi. Thanks. ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 19:56 ` Eli Zaretskii @ 2014-12-06 20:04 ` Ivan Shmakov 2014-12-06 20:15 ` Eli Zaretskii 0 siblings, 1 reply; 17+ messages in thread From: Ivan Shmakov @ 2014-12-06 20:04 UTC (permalink / raw) To: 19274 >>>>> Eli Zaretskii <eliz@gnu.org> writes: >>>>> From: Ivan Shmakov Date: Sat, 06 Dec 2014 19:45:26 +0000 >>>>> Eli Zaretskii <eliz@gnu.org> writes: […] >>> How about adding the necessary bits to the Emacs manual? >> Sure; what’s the respective .texi file? (Somehow, I failed to find >> one.) > "fgrep tar-mode doc/emacs/*.texi blames misc.texi. For me, it only finds ‘tar-mode’ in ‘wordstar-mode’: $ grep -F -- tar-mode doc/emacs/*.texi doc/emacs/ack.texi:@file{tar-mode.el}, which provides simple viewing and editing commands doc/emacs/misc.texi:@findex wordstar-mode doc/emacs/misc.texi:@kbd{M-x wordstar-mode} provides a major mode with WordStar-like $ (And the same for -r --include=\*.texi over doc/ as a whole.) -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 20:04 ` Ivan Shmakov @ 2014-12-06 20:15 ` Eli Zaretskii 2014-12-06 20:50 ` Ivan Shmakov 0 siblings, 1 reply; 17+ messages in thread From: Eli Zaretskii @ 2014-12-06 20:15 UTC (permalink / raw) To: Ivan Shmakov; +Cc: 19274 > From: Ivan Shmakov <ivan@siamics.net> > Date: Sat, 06 Dec 2014 20:04:46 +0000 > > >>>>> Eli Zaretskii <eliz@gnu.org> writes: > >>>>> From: Ivan Shmakov Date: Sat, 06 Dec 2014 19:45:26 +0000 > >>>>> Eli Zaretskii <eliz@gnu.org> writes: > > […] > > >>> How about adding the necessary bits to the Emacs manual? > > >> Sure; what’s the respective .texi file? (Somehow, I failed to find > >> one.) > > > "fgrep tar-mode doc/emacs/*.texi blames misc.texi. > > For me, it only finds ‘tar-mode’ in ‘wordstar-mode’: You are right, sorry. Try this instead: fgrep -w Tar doc/emacs/*.texi ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 20:15 ` Eli Zaretskii @ 2014-12-06 20:50 ` Ivan Shmakov 2014-12-07 16:20 ` Eli Zaretskii 0 siblings, 1 reply; 17+ messages in thread From: Ivan Shmakov @ 2014-12-06 20:50 UTC (permalink / raw) To: 19274 [-- Attachment #1: Type: text/plain, Size: 648 bytes --] >>>>> Eli Zaretskii <eliz@gnu.org> writes: >>>>> From: Ivan Shmakov Date: Sat, 06 Dec 2014 20:04:46 +0000 >>>>> Eli Zaretskii <eliz@gnu.org> writes: […] >>> "fgrep tar-mode doc/emacs/*.texi blames misc.texi. >> For me, it only finds ‘tar-mode’ in ‘wordstar-mode’: > You are right, sorry. Try this instead: > fgrep -w Tar doc/emacs/*.texi Now, it makes me wonder if there should be an @findex tar-mode along with the @cindices? (And @findex archive-mode, too.) Otherwise, does the patch MIMEd look sane? TIA. -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Type: text/diff, Size: 911 bytes --] --- a/doc/emacs/files.texi 2014-06-08 07:41:27 +0000 +++ b/doc/emacs/files.texi 2014-12-06 20:44:44 +0000 @@ -1689,6 +1689,14 @@ likewise. @kbd{v} extracts a file into a buffer in View mode another window, so you could edit the file and operate on the archive simultaneously. + The @kbd{I} key adds a new (regular) file to the archive. The file +is initially empty, but can readily be edited using the commands +above. The command inserts the new file on the line above the current +one, so that using it on the topmost line of the Tar buffer makes the +new file the first one in the archive, and using it on the last line +(the one after the line describing the last file) makes it the last +one. + @kbd{d} marks a file for deletion when you later use @kbd{x}, and @kbd{u} unmarks a file, as in Dired. @kbd{C} copies a file from the archive to disk and @kbd{R} renames a file within the archive. ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 20:50 ` Ivan Shmakov @ 2014-12-07 16:20 ` Eli Zaretskii 2014-12-07 17:47 ` Ivan Shmakov 0 siblings, 1 reply; 17+ messages in thread From: Eli Zaretskii @ 2014-12-07 16:20 UTC (permalink / raw) To: Ivan Shmakov; +Cc: 19274 > From: Ivan Shmakov <ivan@siamics.net> > Date: Sat, 06 Dec 2014 20:50:36 +0000 > > > fgrep -w Tar doc/emacs/*.texi > > Now, it makes me wonder if there should be an @findex tar-mode > along with the @cindices? (And @findex archive-mode, too.) What, just to help us search for it? These functions are never mentioned in that node. But I don't mind adding the index entries. (In general, the best way of doing this search is to take note of the node you are reading in Info, and then search for the corresponding @node line.) > Otherwise, does the patch MIMEd look sane? Yes, with one comment; see below. > + The @kbd{I} key adds a new (regular) file to the archive. The file > +is initially empty, but can readily be edited using the commands > +above. The command inserts the new file on the line above the current > +one, so that using it on the topmost line of the Tar buffer makes the > +new file the first one in the archive, and using it on the last line > +(the one after the line describing the last file) makes it the last > +one. Instead of the complicated description of "the last line, which is one line after the last file's line", I'd simply say "at the end of the buffer". This is simpler and much more clear, especially to non-native speakers who might have problems with long and complex sentences. Otherwise, it's fine. Thanks. (Don't forget to mark the NEWS entry with "+++" together with installing this change.) ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-07 16:20 ` Eli Zaretskii @ 2014-12-07 17:47 ` Ivan Shmakov 2014-12-07 17:58 ` Eli Zaretskii 0 siblings, 1 reply; 17+ messages in thread From: Ivan Shmakov @ 2014-12-07 17:47 UTC (permalink / raw) To: 19274 [-- Attachment #1: Type: text/plain, Size: 2284 bytes --] >>>>> Eli Zaretskii <eliz@gnu.org> writes: >>>>> From: Ivan Shmakov Date: Sat, 06 Dec 2014 20:50:36 +0000 >>> fgrep -w Tar doc/emacs/*.texi >> Now, it makes me wonder if there should be an @findex tar-mode along >> with the @cindices? (And @findex archive-mode, too.) > What, just to help us search for it? These functions are never > mentioned in that node. > But I don't mind adding the index entries. I guess my idea of a better Emacs manual includes documenting all the command names alongside their respective default bindings. Looks like it warrants a separate bug report, though. > (In general, the best way of doing this search is to take note of the > node you are reading in Info, and then search for the corresponding > @node line.) In this particular case, I should have tried the command below. $ grep -irE --include=\*.texi -- '\<tar\>' doc/ […] >> The command inserts the new file on the line above the current one, >> so that using it on the topmost line of the Tar buffer makes the new >> file the first one in the archive, and using it on the last line >> (the one after the line describing the last file) makes it the last >> one. > Instead of the complicated description of "the last line, which is > one line after the last file's line", I'd simply say "at the end of > the buffer". This is simpler and much more clear, especially to > non-native speakers who might have problems with long and complex > sentences. Indeed, that’s much better. Does it make sense to also simplify the head of the sentence as follows? (I believe that “lines” are rather just an implementation detail here.) - The command inserts the new file on the line above the current one, + The command inserts the new file before the current one, > Otherwise, it's fine. Thanks. (Don't forget to mark the NEWS entry > with "+++" together with installing this change.) Meanwhile, I’ve also simplified tar-header-serialize a bit (at the cost of adding a couple of lines to tar--put-at) – and hopefully made it more readable at the same time. The (once again) revised patch is MIMEd. -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Type: text/diff, Size: 7081 bytes --] --- a/etc/NEWS 2014-11-27 11:36:08 +0000 +++ b/etc/NEWS 2014-12-07 17:31:11 +0000 @@ -340,6 +340,10 @@ `tildify-ignored-environments-alist' variables (as well as a few helper functions) obsolete. ++++ +** tar-mode: new `tar-new-entry' command, allowing for new members to +be added to the archive. + ** Obsolete packages --- --- a/doc/emacs/files.texi 2014-06-08 07:41:27 +0000 +++ b/doc/emacs/files.texi 2014-12-07 17:35:34 +0000 @@ -1689,6 +1689,13 @@ @node File Archives another window, so you could edit the file and operate on the archive simultaneously. + The @kbd{I} key adds a new (regular) file to the archive. The file +is initially empty, but can readily be edited using the commands +above. The command inserts the new file on the line above the current +one, so that using it on the topmost line of the Tar buffer makes the +new file the first one in the archive, and using it at the end of the +buffer makes it the last one. + @kbd{d} marks a file for deletion when you later use @kbd{x}, and @kbd{u} unmarks a file, as in Dired. @kbd{C} copies a file from the archive to disk and @kbd{R} renames a file within the archive. --- a/lisp/tar-mode.el 2014-08-28 19:18:24 +0000 +++ b/lisp/tar-mode.el 2014-12-07 17:44:40 +0000 @@ -50,9 +50,6 @@ ;; ;; o chmod should understand "a+x,og-w". ;; -;; o It's not possible to add a NEW file to a tar archive; not that -;; important, but still... -;; ;; o The code is less efficient that it could be - in a lot of places, I ;; pull a 512-character string out of the buffer and parse it, when I could ;; be parsing it in place, not garbaging a string. Should redo that. @@ -369,6 +366,80 @@ string) (tar-parse-octal-integer string)) +(defun tar-new-regular-file-header (filename &optional size time) + "Return a Tar header for a regular file. +The header will lack a proper checksum; use `tar-header-block-checksum' +to compute one, or request `tar-header-serialize' to do that. + +Other tar-mode facilities may also require the data-start header +field to be set to a valid value. + +If SIZE is not given or nil, it defaults to 0. +If TIME is not given or nil, assume now." + (make-tar-header + nil + filename + #o644 0 0 (or size 0) + (or time (current-time)) + nil ; checksum + nil nil + nil nil nil nil nil)) + +(defun tar--pad-to (pos) + (make-string (+ pos (- (point)) (point-min)) 0)) + +(defun tar--put-at (pos val &optional fmt mask) + (when val + (insert (tar--pad-to pos) + (if fmt + (format fmt (if mask (logand mask val) val)) + val)))) + +(defun tar-header-serialize (header &optional update-checksum) + "Return the serialization of a Tar HEADER as a string. +This function calls `tar-header-block-check-checksum' to ensure the +checksum is correct. + +If UPDATE-CHECKSUM is non-nil, update HEADER with the newly-computed +checksum before doing the check." + (with-temp-buffer + (set-buffer-multibyte nil) + (let ((encoded-name + (encode-coding-string (tar-header-name header) + tar-file-name-coding-system))) + (unless (< (length encoded-name) 99) + ;; FIXME: Implement it. + (error "Long file name support is not implemented")) + (insert encoded-name)) + (tar--put-at tar-mode-offset (tar-header-mode header) "%6o\0 " #o777777) + (tar--put-at tar-uid-offset (tar-header-uid header) "%6o\0 " #o777777) + (tar--put-at tar-gid-offset (tar-header-gid header) "%6o\0 " #o777777) + (tar--put-at tar-size-offset (tar-header-size header) "%11o ") + (insert (tar--pad-to tar-time-offset) + (tar-octal-time (tar-header-date header)) + " ") + ;; Omit tar-header-checksum (tar-chk-offset) for now. + (tar--put-at tar-linkp-offset (tar-header-link-type header)) + (tar--put-at tar-link-offset (tar-header-link-name header)) + (when (tar-header-magic header) + (tar--put-at tar-magic-offset (tar-header-magic header)) + (tar--put-at tar-uname-offset (tar-header-uname header)) + (tar--put-at tar-gname-offset (tar-header-gname header)) + (tar--put-at tar-dmaj-offset (tar-header-dmaj header) "%7o\0" #o7777777) + (tar--put-at tar-dmin-offset (tar-header-dmin header) "%7o\0" #o7777777)) + (tar--put-at 512 "") + (let ((ck (tar-header-block-checksum (buffer-string)))) + (goto-char (+ (point-min) tar-chk-offset)) + (delete-char 8) + (insert (format "%6o\0 " ck)) + (when update-checksum + (setf (tar-header-checksum header) ck)) + (tar-header-block-check-checksum (buffer-string) + (tar-header-checksum header) + (tar-header-name header))) + ;; . + (buffer-string))) + (defun tar-header-block-checksum (string) "Compute and return a tar-acceptable checksum for this block." @@ -547,6 +618,7 @@ defvar tar-mode-map (define-key map "p" 'tar-previous-line) (define-key map "\^P" 'tar-previous-line) (define-key map [up] 'tar-previous-line) + (define-key map "I" 'tar-new-entry) (define-key map "R" 'tar-rename-entry) (define-key map "u" 'tar-unflag) (define-key map "v" 'tar-view) @@ -731,10 +803,14 @@ (interactive "p") (tar-next-line (- arg))) +(defun tar-current-position () + "Return the `tar-parse-info' index for the current line." + (count-lines (point-min) (line-beginning-position))) + (defun tar-current-descriptor (&optional noerror) "Return the tar-descriptor of the current line, or signals an error." ;; I wish lines had plists, like in ZMACS... - (or (nth (count-lines (point-min) (line-beginning-position)) + (or (nth (tar-current-position) tar-parse-info) (if noerror nil @@ -948,6 +1024,37 @@ (write-region start end to-file nil nil nil t))) (message "Copied tar entry %s to %s" name to-file))) +(defun tar-new-entry (filename &optional index) + "Insert a new empty regular file before point." + (interactive "*sFile name: ") + (let* ((buffer (current-buffer)) + (index (or index (tar-current-position))) + (d-list (and (not (zerop index)) + (nthcdr (+ -1 index) tar-parse-info))) + (pos (if d-list + (tar-header-data-end (car d-list)) + (point-min))) + (new-descriptor + (tar-new-regular-file-header filename))) + ;; Update the data buffer; fill the missing descriptor fields. + (with-current-buffer tar-data-buffer + (goto-char pos) + (insert (tar-header-serialize new-descriptor t)) + (setf (tar-header-data-start new-descriptor) + (copy-marker (point) nil))) + ;; Update tar-parse-info. + (if d-list + (setcdr d-list (cons new-descriptor (cdr d-list))) + (setq tar-parse-info (cons new-descriptor tar-parse-info))) + ;; Update the listing buffer. + (save-excursion + (goto-char (point-min)) + (forward-line index) + (let ((inhibit-read-only t)) + (insert (tar-header-block-summarize new-descriptor) ?\n))) + ;; . + index)) + (defun tar-flag-deleted (p &optional unflag) "In Tar mode, mark this sub-file to be deleted from the tar file. With a prefix argument, mark that many files." ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-07 17:47 ` Ivan Shmakov @ 2014-12-07 17:58 ` Eli Zaretskii 2014-12-07 18:07 ` Ivan Shmakov 0 siblings, 1 reply; 17+ messages in thread From: Eli Zaretskii @ 2014-12-07 17:58 UTC (permalink / raw) To: Ivan Shmakov; +Cc: 19274 > From: Ivan Shmakov <ivan@siamics.net> > Date: Sun, 07 Dec 2014 17:47:30 +0000 > > > (In general, the best way of doing this search is to take note of the > > node you are reading in Info, and then search for the corresponding > > @node line.) > > In this particular case, I should have tried the command below. > > $ grep -irE --include=\*.texi -- '\<tar\>' doc/ What I meant is this: fgrep "@node File Archives" doc/emacs/*.texi > > Instead of the complicated description of "the last line, which is > > one line after the last file's line", I'd simply say "at the end of > > the buffer". This is simpler and much more clear, especially to > > non-native speakers who might have problems with long and complex > > sentences. > > Indeed, that’s much better. Does it make sense to also simplify > the head of the sentence as follows? (I believe that “lines” > are rather just an implementation detail here.) > > - The command inserts the new file on the line above the current one, > + The command inserts the new file before the current one, Yes, that's better. Thanks. ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-07 17:58 ` Eli Zaretskii @ 2014-12-07 18:07 ` Ivan Shmakov 2015-01-27 22:04 ` Ivan Shmakov 0 siblings, 1 reply; 17+ messages in thread From: Ivan Shmakov @ 2014-12-07 18:07 UTC (permalink / raw) To: 19274 [-- Attachment #1: Type: text/plain, Size: 741 bytes --] >>>>> Eli Zaretskii <eliz@gnu.org> writes: >>>>> From: Ivan Shmakov Date: Sun, 07 Dec 2014 17:47:30 +0000 […] >> Does it make sense to also simplify the head of the sentence as >> follows? (I believe that “lines” are rather just an implementation >> detail here.) >> - The command inserts the new file on the line above the current >> one, >> + The command inserts the new file before the current one, > Yes, that's better. The revised patch for doc/emacs/files.texi is MIMEd. (The rest remains the same [1].) [1] news:871tobl5cd.fsf@violet.siamics.net http://permalink.gmane.org/gmane.emacs.bugs/96948 -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Type: text/diff, Size: 815 bytes --] --- a/doc/emacs/files.texi 2014-06-08 07:41:27 +0000 +++ b/doc/emacs/files.texi 2014-12-07 18:05:31 +0000 @@ -1689,6 +1689,13 @@ @node File Archives another window, so you could edit the file and operate on the archive simultaneously. + The @kbd{I} key adds a new (regular) file to the archive. The file +is initially empty, but can readily be edited using the commands +above. The command inserts the new file before the current one, so +that using it on the topmost line of the Tar buffer makes the new file +the first one in the archive, and using it at the end of the buffer +makes it the last one. + @kbd{d} marks a file for deletion when you later use @kbd{x}, and @kbd{u} unmarks a file, as in Dired. @kbd{C} copies a file from the archive to disk and @kbd{R} renames a file within the archive. ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-07 18:07 ` Ivan Shmakov @ 2015-01-27 22:04 ` Ivan Shmakov 0 siblings, 0 replies; 17+ messages in thread From: Ivan Shmakov @ 2015-01-27 22:04 UTC (permalink / raw) To: 19274-done [-- Attachment #1: Type: text/plain, Size: 386 bytes --] Version: 25.1 >>>>> Ivan Shmakov <ivan@siamics.net> writes: […] > The revised patch for doc/emacs/files.texi is MIMEd. (The rest > remains the same [1].) > [1] news:871tobl5cd.fsf@violet.siamics.net > http://permalink.gmane.org/gmane.emacs.bugs/96948 Pushed; closing. -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A [-- Attachment #2: Type: text/plain, Size: 586 bytes --] commit a56eab8259568ea1389e972623e46359e73c0233 Allow for adding new members to Tar archives. * lisp/tar-mode.el: Allow for adding new archive members. (tar-new-regular-file-header, tar--pad-to, tar--put-at) (tar-header-serialize): New functions. (tar-current-position): Split from tar-current-descriptor. (tar-current-descriptor): Use it. (tar-new-entry): New command. (tar-mode-map): Bind it. * doc/emacs/files.texi (File Archives): Document "I" for tar-new-entry. * etc/NEWS: Mention the new tar-new-entry command. Fixes: debbugs:19274 ^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#19274: tar-mode.el: allow for adding new archive members 2014-12-06 19:17 ` Ivan Shmakov 2014-12-06 19:33 ` Eli Zaretskii @ 2014-12-06 23:13 ` Stefan Monnier 1 sibling, 0 replies; 17+ messages in thread From: Stefan Monnier @ 2014-12-06 23:13 UTC (permalink / raw) To: 19274 > Please consider the revised patch MIMEd. Looks good, thanks, Stefan ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2015-01-27 22:04 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-12-04 21:17 bug#19274: tar-mode.el: allow for adding new archive members Ivan Shmakov 2014-12-05 2:10 ` Stefan Monnier 2014-12-05 20:20 ` Ivan Shmakov 2014-12-06 5:09 ` Stefan Monnier 2014-12-06 19:17 ` Ivan Shmakov 2014-12-06 19:33 ` Eli Zaretskii 2014-12-06 19:45 ` Ivan Shmakov 2014-12-06 19:56 ` Eli Zaretskii 2014-12-06 20:04 ` Ivan Shmakov 2014-12-06 20:15 ` Eli Zaretskii 2014-12-06 20:50 ` Ivan Shmakov 2014-12-07 16:20 ` Eli Zaretskii 2014-12-07 17:47 ` Ivan Shmakov 2014-12-07 17:58 ` Eli Zaretskii 2014-12-07 18:07 ` Ivan Shmakov 2015-01-27 22:04 ` Ivan Shmakov 2014-12-06 23:13 ` Stefan Monnier
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).