Dired 7.9 bug: Broken dired-unmark-all-files

Ben North (north@robots.ox.ac.uk)
Mon, 15 Mar 1999 17:46:06 GMT


When attempting to remove just a particular mark, rather than
them all, it Doesn't Work.  Looking at the code, I think there's 
a problem as I've commented with `; *** FIXME? ***':

---- 8< ----

(defun dired-unmark-all-files (flag &optional arg)
  "Remove a specific mark or any mark from every file.
With prefix arg, query for each marked file.
Type \\[help-command] at that time for help.
With a zero prefix, only counts the number of marks."
  (interactive
   (let* ((cursor-in-echo-area t)
	  executing-kbd-macro) ; for XEmacs
     (list (and (not (eq current-prefix-arg 0))
		(progn (message "Remove marks (RET means all): ") (read-char)))
	   current-prefix-arg)))
  (save-excursion
    (let* ((help-form "\
Type SPC or `y' to unflag one file, DEL or `n' to skip to next,
`!' to unflag all remaining files with no more questions.")
	   (allp (memq flag '(?\n ?\r)))
	   (count-p (eq arg 0))
	   (count (if (or allp count-p)
		      (mapcar
		       (function
			(lambda (elt)
			(cons elt 0)))
		       (nreverse (dired-mark-list)))
		    0))
	   (msg "")
	   (no-query (or (not arg) count-p))
	   buffer-read-only case-fold-search query)
      (goto-char (point-min))
      (if (or allp count-p)
	  (while (re-search-forward dired-re-mark nil t)
	    (if (or no-query
		    (dired-query 'query "Unmark file `%s'? "
				 (dired-get-filename t)))
		(let ((ent (assq (preceding-char) count)))
		  (if ent (setcdr ent (1+ (cdr ent))))
		  (or count-p (dired-substitute-marker
			       (- (point) 1) (preceding-char) ?\ ))))
	    (forward-line 1))
	(while (search-forward (format "\n%c" flag) nil t)
	  (if (or no-query
		  (dired-query 'query "Unmark file `%s'? "
			       (dired-get-filename t)))
	      (progn

              ; *** FIXME? ***
              ;
              ; Original code:
              ;
	      ; (dired-substitute-marker (match-beginning 0) flag ?\ )
              ;
              ; Suggested new code:
              ;
		(dired-substitute-marker (1+ (match-beginning 0)) flag ?\ )
              ;
              ; *** end FIXME? ***

		(setq count (1+ count))))))
      (if (or allp count-p)
	  (mapcar
	   (function
	    (lambda (elt)
	      (or (zerop (cdr elt))
		  (setq msg (format "%s%s%d %c%s"
				    msg
				    (if (zerop (length msg))
					" "
				      ", ")
				    (cdr elt)
				    (car elt)
				    (if (= 1 (cdr elt)) "" "'s"))))))
	   count)
	(or (zerop count)
	    (setq msg (format " %d %c%s"
			      count flag (if (= 1 count) "" "'s")))))
      (if (zerop (length msg))
	  (setq msg " none")
	(or count-p (dired-update-mode-line-modified t)))
      (message "%s:%s" (if count-p "Number of marks" "Marks removed") msg))))

---- 8< ----

(That's from a slightly older version of the dired code, but
I've checked the code in the most recent version of xemacs and
the important bits are the same.)  Without the `(1+ ...)', the
dired-substitute-marker call attempts the substitution on the
newline character at (match-beginning 0) of the match of "\n%c",
instead of the "%c" part.  This is all `as far as I have been
able to work out', but hope it helps anyway.

Yours,

Ben North.



Emacs  : XEmacs 20.3 "Vatican City" [Lucid] (mips-sgi-irix5.3) of Wed Nov 26 1997 on gigondas
Package: Dired

current state:
==============
(setq
 dired-version "7.9"
 dired-backup-if-overwrite nil
 dired-chown-program "/etc/chown"
 dired-cleanup-alist '(("tex" ".toc" ".log" ".aux" ".dvi")
                       ("latex" ".toc" ".log" ".aux" ".idx" ".lof" ".lot"
                        ".glo" ".dvi")
                       ("bibtex" ".blg" ".bbl")
                       ("texinfo" ".cp" ".cps" ".fn" ".fns" ".ky" ".kys" ".pg"
                        ".pgs" ".tp" ".tps" ".vr" ".vrs")
                       ("patch" ".rej" ".orig") ("backups" "~")
                       ("completion-ignored-extensions" ".o" ".elc" "~" ".bin"
                        ".lbin" ".fasl" ".dvi" ".toc" ".log" ".aux" ".a" ".ln"
                        ".lof" ".blg" ".bbl" ".glo" ".idx" ".lot" ".fmt"
                        ".diff" ".oi")
                       )
 dired-compression-method 'compress
 dired-compression-method-alist '((gzip ".gz" ("gzip") ("gzip" "-d") "-f")
                                  (compress ".Z" ("compress" "-f")
                                   ("compress" "-d") "-f")
                                  (pack ".z" ("pack" "-f") ("unpack"))
                                  (compact ".C" ("compact") ("uncompact")))
 dired-copy-preserve-time nil
 dired-dwim-target nil
 dired-failed-marker-shell ?\!
 dired-filename-re-ext "\\..+\\'"
 dired-find-subdir nil
 dired-gnutar-program nil
 dired-keep-marker-compress t
 dired-keep-marker-copy ?C
 dired-keep-marker-hardlink ?H
 dired-keep-marker-kill ?K
 dired-keep-marker-rename t
 dired-keep-marker-symlink ?S
 dired-keep-marker-uucode ?U
 dired-kept-versions 2
 dired-listing-switches "-al"
 dired-local-variables-file ".dired"
 dired-ls-F-marks-symlinks nil
 dired-ls-program "ls"
 dired-mail-reader 'vm
 dired-mode-line-modified "-%s%s%s-"
 dired-no-confirm nil
 dired-omit-extensions '(".oi" ".diff" ".fmt" ".ln" ".a" ".fasl" ".lbin"
                         ".bin" ".elc" ".o" "~" ".orig" ".rej" ".vrs" ".vr"
                         ".tps" ".tp" ".pgs" ".pg" ".kys" ".ky" ".fns" ".fn"
                         ".cps" ".cp" ".bbl" ".blg" ".glo" ".lot" ".lof"
                         ".idx" ".dvi" ".aux" ".log" ".toc")
 dired-omit-files nil
 dired-omit-regexps '("\\`#" "\\`\\.")
 dired-refresh-automatically t
 dired-show-ls-switches nil
 dired-trivial-filenames "\\`\\.\\.?\\'\\|\\`#"
 dired-unshar-program nil
 dired-use-file-transformers t
 dired-verify-modtimes t
 reporter-version "3.2"
 )