+;;;###autoload
+(defun dired-at-point (&optional filename)
+ "Start Dired, defaulting to file at point. See `ffap'."
+ (interactive)
+ (if (and (interactive-p)
+ (if dired-at-point-require-prefix
+ (not current-prefix-arg)
+ current-prefix-arg))
+ (let (current-prefix-arg) ; already interpreted
+ (call-interactively ffap-directory-finder))
+ (or filename (setq filename (dired-at-point-prompter)))
+ (cond
+ ((ffap-url-p filename)
+ (funcall ffap-url-fetcher filename))
+ ((and ffap-dired-wildcards
+ (string-match ffap-dired-wildcards filename))
+ (funcall ffap-directory-finder filename))
+ ((file-exists-p filename)
+ (if (file-directory-p filename)
+ (funcall ffap-directory-finder
+ (expand-file-name filename))
+ (funcall ffap-directory-finder
+ (concat (expand-file-name filename) "*"))))
+ ((and (file-writable-p
+ (or (file-name-directory (directory-file-name filename))
+ filename))
+ (y-or-n-p "Directory does not exist, create it? "))
+ (make-directory filename)
+ (funcall ffap-directory-finder filename))
+ ((error "No such file or directory `%s'" filename)))))
+
+(defun dired-at-point-prompter (&optional guess)
+ ;; Does guess and prompt step for find-file-at-point.
+ ;; Extra complication for the temporary highlighting.
+ (unwind-protect
+ (ffap-read-file-or-url
+ (if ffap-url-regexp "Dired file or URL: " "Dired file: ")
+ (prog1
+ (setq guess (or guess
+ (let ((guess (ffap-guesser)))
+ (if (or (not guess)
+ (ffap-url-p guess)
+ (ffap-file-remote-p guess))
+ guess
+ (setq guess (abbreviate-file-name
+ (expand-file-name guess)))
+ (cond
+ ;; Interpret local directory as a directory.
+ ((file-directory-p guess)
+ (file-name-as-directory guess))
+ ;; Get directory component from local files.
+ ((file-regular-p guess)
+ (file-name-directory guess))
+ (guess))))
+ ))
+ (and guess (ffap-highlight))))
+ (ffap-highlight t)))
+\f
+;;; ffap-dired-other-*, ffap-list-directory commands:
+
+(defun ffap-dired-other-window ()
+ "Like `dired-at-point', but put buffer in another window.
+Only intended for interactive use."
+ (interactive)
+ (let (value)
+ (switch-to-buffer-other-window
+ (save-window-excursion
+ (setq value (call-interactively 'dired-at-point))
+ (current-buffer)))
+ value))
+
+(defun ffap-dired-other-frame ()
+ "Like `dired-at-point', but put buffer in another frame.
+Only intended for interactive use."
+ (interactive)
+ ;; Extra code works around dedicated windows (noted by JENS, 7/96):
+ (let* ((win (selected-window))
+ (wdp (window-dedicated-p win))
+ value)
+ (unwind-protect
+ (progn
+ (set-window-dedicated-p win nil)
+ (switch-to-buffer-other-frame
+ (save-window-excursion
+ (setq value (call-interactively 'dired-at-point))
+ (current-buffer))))
+ (set-window-dedicated-p win wdp))
+ value))
+
+(defun ffap-list-directory ()
+ "Like `dired-at-point' and `list-directory'.
+Only intended for interactive use."
+ (interactive)
+ (let ((ffap-directory-finder 'list-directory))
+ (call-interactively 'dired-at-point)))
+
+\f
+;;; Offer default global bindings (`ffap-bindings'):
+
+(defvar ffap-bindings
+ '(
+ (global-set-key [S-mouse-3] 'ffap-at-mouse)
+ (global-set-key [C-S-mouse-3] 'ffap-menu)
+
+ (global-set-key "\C-x\C-f" 'find-file-at-point)
+ (global-set-key "\C-x\C-r" 'ffap-read-only)
+ (global-set-key "\C-x\C-v" 'ffap-alternate-file)
+
+ (global-set-key "\C-x4f" 'ffap-other-window)
+ (global-set-key "\C-x5f" 'ffap-other-frame)
+ (global-set-key "\C-x4r" 'ffap-read-only-other-window)
+ (global-set-key "\C-x5r" 'ffap-read-only-other-frame)
+
+ (global-set-key "\C-xd" 'dired-at-point)
+ (global-set-key "\C-x4d" 'ffap-dired-other-window)
+ (global-set-key "\C-x5d" 'ffap-dired-other-frame)
+ (global-set-key "\C-x\C-d" 'ffap-list-directory)
+
+ (add-hook 'gnus-summary-mode-hook 'ffap-gnus-hook)
+ (add-hook 'gnus-article-mode-hook 'ffap-gnus-hook)
+ (add-hook 'vm-mode-hook 'ffap-ro-mode-hook)
+ (add-hook 'rmail-mode-hook 'ffap-ro-mode-hook)
+ ;; (setq dired-x-hands-off-my-keys t) ; the default
+ )
+ "List of binding forms evaluated by function `ffap-bindings'.
+A reasonable ffap installation needs just this one line:
+ (ffap-bindings)
+Of course if you do not like these bindings, just roll your own!")
+
+;;;###autoload
+(defun ffap-bindings nil
+ "Evaluate the forms in variable `ffap-bindings'."
+ (interactive)
+ (eval (cons 'progn ffap-bindings)))
+
+\f