;;; help-mode.el --- `help-mode' used by *Help* buffers
-;; Copyright (C) 1985-1986, 1993-1994, 1998-2011
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1993-1994, 1998-2013 Free Software
+;; Foundation, Inc.
;; Maintainer: FSF
;; Keywords: help, internal
;;; Code:
(require 'button)
-(require 'view)
(eval-when-compile (require 'easymenu))
(defvar help-mode-map
(let ((map (make-sparse-keymap)))
- (set-keymap-parent map button-buffer-map)
-
+ (set-keymap-parent map (make-composed-keymap button-buffer-map
+ special-mode-map))
(define-key map [mouse-2] 'help-follow-mouse)
(define-key map "\C-c\C-b" 'help-go-back)
(define-key map "\C-c\C-f" 'help-go-forward)
+ (define-key map [XF86Back] 'help-go-back)
+ (define-key map [XF86Forward] 'help-go-forward)
(define-key map "\C-c\C-c" 'help-follow-symbol)
- ;; Documentation only, since we use minor-mode-overriding-map-alist.
(define-key map "\r" 'help-follow)
map)
"Keymap for help mode.")
'help-function 'describe-character-set
'help-echo (purecopy "mouse-2, RET: describe this character set"))
-;; make some more ideosyncratic button types
+;; Make some more idiosyncratic button types.
(define-button-type 'help-symbol
:supertype 'help-xref
(define-button-type 'help-info-variable
:supertype 'help-xref
;; the name of the variable is put before the argument to Info
- 'help-function (lambda (a v) (info v))
+ 'help-function (lambda (_a v) (info v))
'help-echo (purecopy "mouse-2, RET: read this Info node"))
(define-button-type 'help-info
:supertype 'help-xref
'help-function 'customize-create-theme
'help-echo (purecopy "mouse-2, RET: edit this theme file"))
+
+(define-button-type 'help-dir-local-var-def
+ :supertype 'help-xref
+ 'help-function (lambda (var &optional file)
+ ;; FIXME: this should go to the point where the
+ ;; local variable was defined.
+ (find-file file))
+ 'help-echo (purecopy "mouse-2, RET: open directory-local variables file"))
+
\f
+(defvar bookmark-make-record-function)
+
;;;###autoload
-(defun help-mode ()
+(define-derived-mode help-mode special-mode "Help"
"Major mode for viewing help text and navigating references in it.
Entry to this mode runs the normal hook `help-mode-hook'.
Commands:
\\{help-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (use-local-map help-mode-map)
- (setq mode-name "Help")
- (setq major-mode 'help-mode)
-
- (view-mode)
- (set (make-local-variable 'view-no-disable-on-exit) t)
- ;; With Emacs 22 `view-exit-action' could delete the selected window
- ;; disregarding whether the help buffer was shown in that window at
- ;; all. Since `view-exit-action' is called with the help buffer as
- ;; argument it seems more appropriate to have it work on the buffer
- ;; only and leave it to `view-mode-exit' to delete any associated
- ;; window(s).
- (setq view-exit-action
- (lambda (buffer)
- ;; Use `with-current-buffer' to make sure that `bury-buffer'
- ;; also removes BUFFER from the selected window.
- (with-current-buffer buffer
- (bury-buffer))))
-
(set (make-local-variable 'revert-buffer-function)
'help-mode-revert-buffer)
-
- (run-mode-hooks 'help-mode-hook))
+ (set (make-local-variable 'bookmark-make-record-function)
+ 'help-bookmark-make-record))
;;;###autoload
(defun help-mode-setup ()
;;;###autoload
(defun help-mode-finish ()
- (if (eq help-window t)
- ;; If `help-window' is t, `view-return-to-alist' is handled by
- ;; `with-help-window'. In this case set `help-window' to the
- ;; selected window since now is the only moment where we can
- ;; unambiguously identify it.
- (setq help-window (selected-window))
- (let ((entry (assq (selected-window) view-return-to-alist)))
- (if entry
- ;; When entering Help mode from the Help window,
- ;; such as by following a link, preserve the same
- ;; meaning for the q command.
- ;; (setcdr entry (cons (selected-window) help-return-method))
- nil
- (setq view-return-to-alist
- (cons (cons (selected-window) help-return-method)
- view-return-to-alist)))))
-
(when (eq major-mode 'help-mode)
- ;; View mode's read-only status of existing *Help* buffer is lost
- ;; by with-output-to-temp-buffer.
- (toggle-read-only 1)
-
+ (setq buffer-read-only t)
(save-excursion
(goto-char (point-min))
(let ((inhibit-read-only t))
- (when (re-search-forward "^This \\w+ is advised.$" nil t)
+ (when (re-search-forward "^This [^[:space:]]+ is advised.$" nil t)
(put-text-property (match-beginning 0)
(match-end 0)
'face 'font-lock-warning-face))))
(defun help-buffer ()
"Return the name of a buffer for inserting help.
If `help-xref-following' is non-nil, this is the name of the
-current buffer.
-Otherwise, it is *Help*; if no buffer with that name currently
-exists, it is created."
+current buffer. Signal an error if this buffer is not derived
+from `help-mode'.
+Otherwise, return \"*Help*\", creating a buffer with that name if
+it does not already exist."
(buffer-name ;for with-output-to-temp-buffer
- (if help-xref-following
- (current-buffer)
- (get-buffer-create "*Help*"))))
-
-(defvar help-xref-override-view-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map view-mode-map)
- (define-key map "\r" nil)
- map)
- "Replacement keymap for `view-mode' in help buffers.")
+ (if (not help-xref-following)
+ (get-buffer-create "*Help*")
+ (unless (derived-mode-p 'help-mode)
+ (error "Current buffer is not in Help mode"))
+ (current-buffer))))
;;;###autoload
(defun help-make-xrefs (&optional buffer)
(or
(documentation-property
sym 'variable-documentation)
- (condition-case nil
- (documentation-property
- (indirect-variable sym)
- 'variable-documentation)
- (cyclic-variable-indirection nil))))
+ (documentation-property
+ (indirect-variable sym)
+ 'variable-documentation)))
(help-xref-button 8 'help-variable sym))
((fboundp sym)
(help-xref-button 8 'help-function sym)))))))
(current-buffer)))
(when (or help-xref-stack help-xref-forward-stack)
(insert "\n")))
- ;; View mode steals RET from us.
- (set (make-local-variable 'minor-mode-overriding-map-alist)
- (list (cons 'view-mode help-xref-override-view-map)))
(set-buffer-modified-p old-modified)))))
;;;###autoload
(help-xref-go-forward (current-buffer))
(error "No next help buffer")))
-(defun help-do-xref (pos function args)
+(defun help-do-xref (_pos function args)
"Call the help cross-reference function FUNCTION with args ARGS.
Things are set up properly so that the resulting help-buffer has
a proper [back] button."
(fboundp sym) (facep sym))
(help-do-xref pos #'help-xref-interned (list sym)))))
-(defun help-mode-revert-buffer (ignore-auto noconfirm)
+(defun help-mode-revert-buffer (_ignore-auto noconfirm)
(when (or noconfirm (yes-or-no-p "Revert help buffer? "))
(let ((pos (point))
(item help-xref-stack-item)
(with-output-to-temp-buffer (help-buffer)
(insert string)))
+\f
+;; Bookmark support
+
+(declare-function bookmark-prop-get "bookmark" (bookmark prop))
+(declare-function bookmark-make-record-default "bookmark"
+ (&optional no-file no-context posn))
+
+(defun help-bookmark-make-record ()
+ "Create and return a help-mode bookmark record.
+Implements `bookmark-make-record-function' for help-mode buffers."
+ (unless (car help-xref-stack-item)
+ (error "Cannot create bookmark - help command not known"))
+ `(,@(bookmark-make-record-default 'NO-FILE 'NO-CONTEXT)
+ (help-fn . ,(car help-xref-stack-item))
+ (help-args . ,(cdr help-xref-stack-item))
+ (position . ,(point))
+ (handler . help-bookmark-jump)))
+
+;;;###autoload
+(defun help-bookmark-jump (bookmark)
+ "Jump to help-mode bookmark BOOKMARK.
+Handler function for record returned by `help-bookmark-make-record'.
+BOOKMARK is a bookmark name or a bookmark record."
+ (let ((help-fn (bookmark-prop-get bookmark 'help-fn))
+ (help-args (bookmark-prop-get bookmark 'help-args))
+ (position (bookmark-prop-get bookmark 'position)))
+ (apply help-fn help-args)
+ (pop-to-buffer "*Help*")
+ (goto-char position)))
+
+
(provide 'help-mode)
;;; help-mode.el ends here