*** old/dired.el	Sun Jul 15 15:42:33 2007
--- new/dired.el	Sun Jul 15 21:19:44 2007
***************
*** 1042,1047 ****
--- 1042,1048 ----
      (goto-char (point-min))
      (setq mark-alist;; only after dired-remember-hidden since this unhides:
  	  (dired-remember-marks (point-min) (point-max)))
+     (dired-details-delete-overlays) ;;ditch the entire overlay cache
      ;; treat top level dir extra (it may contain wildcards)
      (dired-uncache
       (if (consp dired-directory) (car dired-directory) dired-directory))
***************
*** 1242,1247 ****
--- 1243,1251 ----
      (define-key map "\C-n" 'dired-next-line)
      (define-key map "\C-p" 'dired-previous-line)
      (define-key map [down] 'dired-next-line)
+     (define-key map "(" 'dired-details-hide)
+     (define-key map ")" 'dired-details-show)
+     (define-key map ";" 'dired-details-toggle)
      (define-key map [up] 'dired-previous-line)
      ;; hiding
      (define-key map "$" 'dired-hide-subdir)
***************
*** 3334,3339 ****
--- 3338,3508 ----
  	     '(dired-mode . dired-restore-desktop-buffer))
  
  
+ ;;; optionally hide file details and link targets
+ 
+ (defgroup dired-details nil
+   "Settings for to hide file details and symbolic link targets."
+   :group 'dired
+   :prefix "dired-details-")
+ 
+ (defcustom dired-details-hidden-string "[...]"
+   "*This string will be shown in place of file details and symbolic links."
+   :group 'dired-details
+   :type 'string)
+ 
+ (defcustom dired-details-hide-link-targets t
+   "*Hide symbolic link target paths."
+   :group 'dired-details
+   :type 'boolean)
+ 
+ (defcustom dired-details-initially-hide nil
+   "*Hide dired details on entry to dired buffers."
+   :group 'dired-details
+   :type 'boolean)
+ 
+ (defvar dired-details-internal-overlay-cache nil)
+ (make-variable-buffer-local 'dired-details-internal-overlay-cache)
+ 
+ (defvar dired-details-state nil
+   "Three possible values: nil (has not been set), 'hidden (details are
+ hidden), 'shown (details are visible).")
+ (make-variable-buffer-local 'dired-details-state)
+ 
+ (defun dired-details-activate()
+   "Set up dired-details in the current dired buffer. Called by
+ dired-after-readin-hook on initial display and when a dired
+ buffer is modified. If the state of detail display has been set
+ in this buffer then use that state, otherwise use the value of
+ `dired-details-initially-hide'."
+   (if (eq 'hidden dired-details-state)
+       (dired-details-hide)
+       (when dired-details-initially-hide
+         (dired-details-hide))))
+ (add-hook 'dired-after-readin-hook 'dired-details-activate)
+ 
+ (defun dired-details-delete-overlays()
+   (dolist (dir-and-overlays dired-details-internal-overlay-cache)
+     (dolist (overlay (cdr dir-and-overlays))
+       (delete-overlay overlay)))
+   (setq dired-details-internal-overlay-cache nil))
+ 
+ (defun dired-details-toggle (&optional arg default-too)
+   "Toggle visibility of dired details.
+ With positive prefix argument ARG hide the details, with negative
+ show them."
+   (interactive "P")
+   (let ((hide (if (null arg)
+                   (not (eq 'hidden dired-details-state))
+                 (> (prefix-numeric-value arg) 0))))
+     (if default-too
+         (setq dired-details-initially-hide hide))
+     (if hide (dired-details-hide)
+       (dired-details-show))))
+ 
+ (defun dired-details-hide()
+   "Make an invisible, evaporable overlay for each visible file
+ details in this dired buffer. This is called from
+ dired-after-readin-hook in different contexts: (1) narrowed to a
+ single file (after copy, move, symlink etc.)  (2) narrowed to a
+ single subdir (e.g. after dired-insert-subdir) (3) with multiple
+ visible subdirs and not narrowed (e.g. after dired-revert)"
+   (interactive)
+   (unless (memq major-mode '(dired-mode vc-dired-mode))
+     (error "dired-details-hide can only be called in dired mode"))
+ 
+   (save-excursion
+     (goto-char (point-min))
+     (if (not (looking-at dired-subdir-regexp))
+         ;;a single file or files -- just make an overlay for each
+         (let* ((parent (dired-current-directory))
+                (cached-parent-overlays
+                 (assoc parent dired-details-internal-overlay-cache)))
+           (unless cached-parent-overlays
+             (error "dired-details overlays not found for directory %s" parent))
+           (dired-goto-next-file)
+           (while (< (point) (point-max))
+             (dired-details-make-current-line-overlay cached-parent-overlays)
+             (dired-next-line 1)))
+ 
+         ;;hide each visible subdirectory (either of cases (2) or (3)
+         ;;mentioned above)
+         (dolist (dir-and-pos dired-subdir-alist)
+           (let* ((dir (car dir-and-pos))
+                  (pos (cdr dir-and-pos))
+                  (cached-overlays
+                   (assoc dir dired-details-internal-overlay-cache)))
+             ;;skip this directory if it's outside of a narrowed region
+             (when (and (>= pos (point-min)) (<= pos (point-max)))
+               (if cached-overlays
+                   (dired-details-frob-overlays t) ;;reuse existing
+                   (let ((cache (list dir)) ;;make new overlays
+                         (subdir-start (let ((rest pos))
+                                         ;;xemacs compat: in xemacs, this is a list
+                                         (if (atom rest) rest (car rest))))
+                         (subdir-end (1- (dired-get-subdir-max dir-and-pos))))
+                     (goto-char subdir-start)
+                     (dired-goto-next-file)
+                     (while (< (point) subdir-end)
+                       ;;nb: uses setcdr to update cache
+                       (dired-details-make-current-line-overlay cache)
+                       (dired-next-line 1))
+                     (setq dired-details-internal-overlay-cache
+                           (cons cache dired-details-internal-overlay-cache)))))))
+         (setq dired-details-state 'hidden))))
+     
+ (defun dired-details-show()
+   "Show whatever details a call to `dired-details-hide' may have
+ hidden in this buffer."
+   (interactive)
+   (dired-details-frob-overlays nil)
+   (setq dired-details-state 'shown))
+ 
+ (defun dired-details-make-current-line-overlay (cache)
+   (let ((detail-overlay ;hide the flags, size, owner, date, etc.
+          (make-overlay
+           (+ 2 (progn (beginning-of-line) (point)))
+           (progn (dired-move-to-filename)(point))))
+          
+         (ln-target ;hide the destination of a symbolic when
+          (when dired-details-hide-link-targets
+            (if (progn (beginning-of-line)
+                       (search-forward-regexp
+                        "-> \\(.*\\)"
+                        (save-excursion (end-of-line)(point)) t))
+                (make-overlay (match-beginning 1) (match-end 1))))))
+ 
+     ;;delete the overlay when the dired line goes away
+     (overlay-put detail-overlay 'evaporate t)
+     (dired-details-hide-overlay detail-overlay)
+ 
+     (when ln-target
+       (overlay-put ln-target 'evaporate t)
+       (dired-details-hide-overlay ln-target))
+ 
+     (setcdr cache (append (if ln-target
+                               (list ln-target detail-overlay)
+                             (list detail-overlay))
+                           (cdr cache)))
+     detail-overlay))
+ 
+ (defun dired-details-hide-overlay (o)
+   (overlay-put o 'invisible t)
+   (overlay-put o 'before-string dired-details-hidden-string))
+ 
+ (defun dired-details-show-overlay (o)
+   (overlay-put o 'invisible nil)
+   (overlay-put o 'before-string ""))
+ 
+ (defun dired-details-frob-overlays (hide)
+   (when dired-details-internal-overlay-cache
+     (let ((frobber (if hide 'dired-details-hide-overlay
+                             'dired-details-show-overlay)))
+       (dolist (dir-and-overlays dired-details-internal-overlay-cache)
+         (dolist (overlay (cdr dir-and-overlays))
+           (funcall frobber overlay))))))
+   
+ 
+ 
  (if (eq system-type 'vax-vms)
      (load "dired-vms"))
  
