[comp.emacs] dired-mode-hook exists - here is the way to setq it

dmb@morgoth.UUCP (David M. Brown) (08/18/87)

Dave Jones wanted to know how to rebind keys in the dired-mode.  The
problem was that dired is autoloaded, so dired-mode-map is nil when
the .emacs file is eval'ed.

John Robinson told him to use dired-mode-hook, but misinformed him
that the hook does not exist, and therefore he had to redefine
dired-mode to call dired-mode-hook.

Dired-mode-hook exists.  It's right there in dired.el.  Also, I think
Dave needed to know how to setq a hook.  I have the following in my
.emacs because I often get dired-mode and buffer-menu-mode bindings
confused:

(setq dired-mode-hook
      (function
       (lambda nil
	 (define-key dired-mode-map "1" 'dired-find-file))))
(define-key Buffer-menu-mode-map "f" 'Buffer-menu-1-window)

Dave:  If you copy this style it will work.  Just don't ask me why, okay?


David Brown
{harvard | ll-xn | mirror}!adelie!morgoth!dmb
GZA, 320 Needham St., Newton Upper Falls, MA  02164
(617) 969-0050

 WE CHALLENGE our traditions
      BECAUSE we believe
        TRUTH without questioning
     IS FALSE

tom@uw-warp.UUCP (F. Thomas May) (08/23/87)

In article <431@morgoth.UUCP> dmb@morgoth.UUCP (David M. Brown) writes:

>   (setq dired-mode-hook
>	 (function
>	  (lambda nil
>	    (define-key dired-mode-map "1" 'dired-find-file))))
>
>   Dave:  If you copy this style it will work.  Just don't ask me why, okay?

Things get more complicated when using multiple hooks as supported by
run-hooks.  To make things a bit simpler, I wrote a function which
allows a new hook function to be added to a hook variable.  Here it is:

(defun add-hook (hook-var hook-fun)
  "Two arguments, HOOK-VAR and HOOK-FUN.  Adds HOOK-FUN to the list
of hooks in HOOK-VAR if it is not already present.  add-hook is very tolerant;
HOOK-VAR need not be previously defined, its value doesn't have to be a list,
lamda expressions are cool, etc."
  (or (boundp hook-var)
      (set hook-var nil))
  (let ((hook-var-val (symbol-value hook-var)))
    (or (listp hook-var-val)
	(setq hook-var-val (cons hook-var-val nil)))
    (if (eq (car hook-var-val) 'lambda)
	(setq hook-var-val (cons hook-var-val nil)))
    (or (spud-member hook-fun hook-var-val)
	(set hook-var (nreverse (cons hook-fun (reverse hook-var-val)))))))

;; non-recursive definition of member (used by add-hook)

(defun spud-member (elt list)
  "Returns non-nil if ELT is an element of LIST.  Comparison done with EQUAL.
The value is actually the tail of LIST whose car is ELT."
  (while (and list
	      (not (equal elt (car list))))
    (setq list (cdr list)))
  list)


Using add-hook, the original example becomes

   (add-hook 'dired-mode-hook
	 (function
	  (lambda nil
	    (define-key dired-mode-map "1" 'dired-find-file))))

which is nearly identical to the original.  The benefit comes when a
second hook is added to dired-mode-hook:

   (add-hook 'dired-mode-hook 'some-cool-function)

Now both the lambda thing and some-cool-function will be invoked, in
that order, when dired is used.  add-hook even diagnoses the case in
which setq was used previously to set a hook and fixes things up for
the multiple hook case.  It also won't add the same hook more than
once.
-- 
Tom May
uw-nsr!uw-warp!tom@beaver.cs.washington.edu
uw-beaver!uw-nsr!uw-warp!tom