diff options
| author | Richard M. Stallman | 1998-04-05 19:10:02 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1998-04-05 19:10:02 +0000 |
| commit | 400a1b1f841ff44e197d530f9871cfa5843c428e (patch) | |
| tree | 242ba609c5818a4268ac3db4c8615c2e4c3ab561 | |
| parent | 421f0bfe8e2a798dc6605a439f9a1f268ef15f8d (diff) | |
| download | emacs-400a1b1f841ff44e197d530f9871cfa5843c428e.tar.gz emacs-400a1b1f841ff44e197d530f9871cfa5843c428e.zip | |
(help-highlight-face): Use underline.
(help-mode-maybe): Ensure read-only.
(help-xref-button): Obey help-highlight-p.
(help-follow): Remove check for args being a list.
(help-mode): Doc fix.
(help-highlight-p): Put in help group.
(help-make-xrefs): Insert button label in scope of
inhibit-read-only binding.
(help-mode-map, help-make-xrefs): Define TAB, RET correctly.
Make hyperlinks for cross-reference info intuited from *Help* buffer.
(help-font-lock-keywords): Removed.
(help-mode-map): Define keys for navigating hyperlinks.
(help-xref-stack, help-xref-stack-item): New permanent-local variables.
(help-mode): Set font-lock-defaults to nil.
(help-mode-maybe): Invoke help-make-xrefs in Help mode.
(help-setup-xref): New function.
(describe-key, describe-mode, describe-function,
describe-variable): Call it.
(view-lossage, describe-bindings): Nullify help-xref-stack,
help-xref-stack-item.
(help-highlight-p): New option.
(help-highlight-face): New variable.
(help-back-label, help-xref-symbol-regexp, help-xref-info-regexp):
New variables.
(help-setup-xref, help-make-xrefs, help-xref-button,
help-xref-interned, help-xref-mode, help-follow-mouse,
help-xref-go-back, help-go-back, help-follow, help-next-ref): New functions.
| -rw-r--r-- | lisp/help.el | 332 |
1 files changed, 309 insertions, 23 deletions
diff --git a/lisp/help.el b/lisp/help.el index b16adbdd8e2..bef91749235 100644 --- a/lisp/help.el +++ b/lisp/help.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; help.el --- help commands for Emacs | 1 | ;;; help.el --- help commands for Emacs |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1985, 1986, 1993, 1994, 1998 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Maintainer: FSF | 5 | ;; Maintainer: FSF |
| 6 | ;; Keywords: help, internal | 6 | ;; Keywords: help, internal |
| @@ -91,27 +91,47 @@ | |||
| 91 | 91 | ||
| 92 | (define-key help-map "q" 'help-quit) | 92 | (define-key help-map "q" 'help-quit) |
| 93 | 93 | ||
| 94 | (defvar help-font-lock-keywords | 94 | (define-key help-mode-map [mouse-2] 'help-follow-mouse) |
| 95 | (eval-when-compile | 95 | (define-key help-mode-map "\C-c\C-b" 'help-go-back) |
| 96 | (let ((name-char "[-+a-zA-Z0-9_*]") (sym-char "[-+a-zA-Z0-9_:*]")) | 96 | (define-key help-mode-map "\C-c\C-c" 'help-follow) |
| 97 | (list | 97 | (define-key help-mode-map "\t" 'help-next-ref) |
| 98 | ;; | 98 | (define-key help-mode-map [backtab] 'help-previous-ref) |
| 99 | ;; The symbol itself. | 99 | ;; Documentation only, since we use minor-mode-overriding-map-alist. |
| 100 | (list (concat "\\`\\(" name-char "+\\)\\(\\(:\\)\\|\\('\\)\\)") | 100 | (define-key help-mode-map "\r" 'help-follow) |
| 101 | '(1 (if (match-beginning 3) | 101 | |
| 102 | font-lock-function-name-face | 102 | ;; Font-locking is incompatible with the new xref stuff. |
| 103 | font-lock-variable-name-face))) | 103 | ;(defvar help-font-lock-keywords |
| 104 | ;; | 104 | ; (eval-when-compile |
| 105 | ;; Words inside `' which tend to be symbol names. | 105 | ; (let ((name-char "[-+a-zA-Z0-9_*]") (sym-char "[-+a-zA-Z0-9_:*]")) |
| 106 | (list (concat "`\\(" sym-char sym-char "+\\)'") | 106 | ; (list |
| 107 | 1 'font-lock-constant-face t) | 107 | ; ;; |
| 108 | ;; | 108 | ; ;; The symbol itself. |
| 109 | ;; CLisp `:' keywords as builtins. | 109 | ; (list (concat "\\`\\(" name-char "+\\)\\(\\(:\\)\\|\\('\\)\\)") |
| 110 | (list (concat "\\<:" sym-char "+\\>") 0 'font-lock-builtin-face t)))) | 110 | ; '(1 (if (match-beginning 3) |
| 111 | "Default expressions to highlight in Help mode.") | 111 | ; font-lock-function-name-face |
| 112 | ; font-lock-variable-name-face))) | ||
| 113 | ; ;; | ||
| 114 | ; ;; Words inside `' which tend to be symbol names. | ||
| 115 | ; (list (concat "`\\(" sym-char sym-char "+\\)'") | ||
| 116 | ; 1 'font-lock-constant-face t) | ||
| 117 | ; ;; | ||
| 118 | ; ;; CLisp `:' keywords as references. | ||
| 119 | ; (list (concat "\\<:" sym-char "+\\>") 0 'font-lock-builtin-face t)))) | ||
| 120 | ; "Default expressions to highlight in Help mode.") | ||
| 121 | |||
| 122 | (defvar help-xref-stack nil | ||
| 123 | "A stack of ways by which to return to help buffers after following xrefs. | ||
| 124 | Used by `help-follow' and `help-xref-go-back'.") | ||
| 125 | (put 'help-xref-stack 'permanent-local t) | ||
| 126 | |||
| 127 | (defvar help-xref-stack-item nil | ||
| 128 | "An item for `help-follow' in this buffer to push onto `help-xref-stack'.") | ||
| 129 | (put 'help-xref-stack-item 'permanent-local t) | ||
| 130 | |||
| 131 | (setq-default help-xref-stack nil help-xref-stack-item nil) | ||
| 112 | 132 | ||
| 113 | (defun help-mode () | 133 | (defun help-mode () |
| 114 | "Major mode for viewing help text. | 134 | "Major mode for viewing help text and navigating references in it. |
| 115 | Entry to this mode runs the normal hook `help-mode-hook'. | 135 | Entry to this mode runs the normal hook `help-mode-hook'. |
| 116 | Commands: | 136 | Commands: |
| 117 | \\{help-mode-map}" | 137 | \\{help-mode-map}" |
| @@ -121,15 +141,22 @@ Commands: | |||
| 121 | (setq mode-name "Help") | 141 | (setq mode-name "Help") |
| 122 | (setq major-mode 'help-mode) | 142 | (setq major-mode 'help-mode) |
| 123 | (make-local-variable 'font-lock-defaults) | 143 | (make-local-variable 'font-lock-defaults) |
| 124 | (setq font-lock-defaults '(help-font-lock-keywords)) | 144 | (setq font-lock-defaults nil) ; font-lock would defeat xref |
| 125 | (view-mode) | 145 | (view-mode) |
| 126 | (make-local-variable 'view-no-disable-on-exit) | 146 | (make-local-variable 'view-no-disable-on-exit) |
| 127 | (setq view-no-disable-on-exit t) | 147 | (setq view-no-disable-on-exit t) |
| 148 | ;; `help-make-xrefs' would be run here if not invoked from | ||
| 149 | ;; `help-mode-maybe'. | ||
| 128 | (run-hooks 'help-mode-hook)) | 150 | (run-hooks 'help-mode-hook)) |
| 129 | 151 | ||
| 130 | (defun help-mode-maybe () | 152 | (defun help-mode-maybe () |
| 131 | (if (eq major-mode 'fundamental-mode) | 153 | (if (eq major-mode 'fundamental-mode) |
| 132 | (help-mode)) | 154 | (help-mode)) |
| 155 | (when (eq major-mode 'help-mode) | ||
| 156 | ;; View mode's read-only status of existing *Help* buffer is lost | ||
| 157 | ;; by with-output-to-temp-buffer. | ||
| 158 | (toggle-read-only 1) | ||
| 159 | (help-make-xrefs (current-buffer))) | ||
| 133 | (setq view-return-to-alist | 160 | (setq view-return-to-alist |
| 134 | (list (cons (selected-window) help-return-method)))) | 161 | (list (cons (selected-window) help-return-method)))) |
| 135 | 162 | ||
| @@ -320,7 +347,8 @@ If FUNCTION is nil, applies `message' to it, thus printing it." | |||
| 320 | (let ((doc (documentation defn))) | 347 | (let ((doc (documentation defn))) |
| 321 | (if doc | 348 | (if doc |
| 322 | (progn (terpri) | 349 | (progn (terpri) |
| 323 | (princ doc)) | 350 | (princ doc) |
| 351 | (help-setup-xref (cons #'describe-key key) (interactive-p))) | ||
| 324 | (princ "not documented"))) | 352 | (princ "not documented"))) |
| 325 | (print-help-return-message))))))) | 353 | (print-help-return-message))))))) |
| 326 | 354 | ||
| @@ -364,6 +392,7 @@ followed by the major mode, which is described on the last page.\n\f\n")) | |||
| 364 | (princ mode-name) | 392 | (princ mode-name) |
| 365 | (princ " mode:\n") | 393 | (princ " mode:\n") |
| 366 | (princ (documentation major-mode)) | 394 | (princ (documentation major-mode)) |
| 395 | (help-setup-xref (cons #'help-xref-mode (current-buffer)) (interactive-p)) | ||
| 367 | (print-help-return-message))) | 396 | (print-help-return-message))) |
| 368 | 397 | ||
| 369 | ;; So keyboard macro definitions are documented correctly | 398 | ;; So keyboard macro definitions are documented correctly |
| @@ -448,6 +477,8 @@ With numeric argument display information on correspondingly older changes." | |||
| 448 | (while (progn (move-to-column 50) (not (eobp))) | 477 | (while (progn (move-to-column 50) (not (eobp))) |
| 449 | (search-forward " " nil t) | 478 | (search-forward " " nil t) |
| 450 | (insert "\n"))) | 479 | (insert "\n"))) |
| 480 | (setq help-xref-stack nil | ||
| 481 | help-xref-stack-item nil) | ||
| 451 | (print-help-return-message))) | 482 | (print-help-return-message))) |
| 452 | 483 | ||
| 453 | (defalias 'help 'help-for-help) | 484 | (defalias 'help 'help-for-help) |
| @@ -616,7 +647,8 @@ C-w Display information on absence of warranty for GNU Emacs." | |||
| 616 | (let ((doc (documentation function))) | 647 | (let ((doc (documentation function))) |
| 617 | (if doc | 648 | (if doc |
| 618 | (progn (terpri) | 649 | (progn (terpri) |
| 619 | (princ doc)) | 650 | (princ doc) |
| 651 | (help-setup-xref (cons #'describe-function function) (interactive-p))) | ||
| 620 | (princ "not documented")))) | 652 | (princ "not documented")))) |
| 621 | (print-help-return-message) | 653 | (print-help-return-message) |
| 622 | (save-excursion | 654 | (save-excursion |
| @@ -696,6 +728,7 @@ Returns the documentation as a string, also." | |||
| 696 | (terpri) | 728 | (terpri) |
| 697 | (let ((doc (documentation-property variable 'variable-documentation))) | 729 | (let ((doc (documentation-property variable 'variable-documentation))) |
| 698 | (princ (or doc "not documented as a variable."))) | 730 | (princ (or doc "not documented as a variable."))) |
| 731 | (help-setup-xref (cons #'describe-variable variable) (interactive-p)) | ||
| 699 | (print-help-return-message) | 732 | (print-help-return-message) |
| 700 | (save-excursion | 733 | (save-excursion |
| 701 | (set-buffer standard-output) | 734 | (set-buffer standard-output) |
| @@ -710,6 +743,8 @@ We put that list in a buffer, and display the buffer. | |||
| 710 | The optional argument PREFIX, if non-nil, should be a key sequence; | 743 | The optional argument PREFIX, if non-nil, should be a key sequence; |
| 711 | then we display only bindings that start with that prefix." | 744 | then we display only bindings that start with that prefix." |
| 712 | (interactive "P") | 745 | (interactive "P") |
| 746 | (setq help-xref-stack nil | ||
| 747 | help-xref-stack-item nil) | ||
| 713 | (describe-bindings-internal nil prefix)) | 748 | (describe-bindings-internal nil prefix)) |
| 714 | 749 | ||
| 715 | (defun where-is (definition &optional insert) | 750 | (defun where-is (definition &optional insert) |
| @@ -788,4 +823,255 @@ is used instead of `load-path'." | |||
| 788 | (message "No library %s in search path" library))) | 823 | (message "No library %s in search path" library))) |
| 789 | result)) | 824 | result)) |
| 790 | 825 | ||
| 826 | |||
| 827 | ;;; Grokking cross-reference information in doc strings and | ||
| 828 | ;;; hyperlinking it. | ||
| 829 | |||
| 830 | ;; This may have some scope for extension and the same or something | ||
| 831 | ;; similar should be done for widget doc strings, which currently use | ||
| 832 | ;; another mechanism. | ||
| 833 | |||
| 834 | (defcustom help-highlight-p t | ||
| 835 | "*If non-nil, `help-make-xrefs' highlight cross-references. | ||
| 836 | Under a window system it highlights them with face defined by | ||
| 837 | `help-highlight-face'. On a character terminal highlighted | ||
| 838 | references look like cross-references in info mode." | ||
| 839 | :group 'help | ||
| 840 | :version "20.3" | ||
| 841 | :type 'boolean) | ||
| 842 | |||
| 843 | (defcustom help-highlight-face 'underline | ||
| 844 | "Face used by `help-make-xrefs' to highlight cross-references. | ||
| 845 | Must be previously-defined." | ||
| 846 | :group 'help | ||
| 847 | :version "20.3" | ||
| 848 | :type 'symbol) | ||
| 849 | |||
| 850 | (defvar help-back-label "[back]" | ||
| 851 | "Label to use by `help-make-xrefs' for the go-back reference.") | ||
| 852 | |||
| 853 | (defvar help-xref-symbol-regexp | ||
| 854 | (concat "\\(\\<\\(\\(variable\\|option\\)\\|" | ||
| 855 | "\\(function\\|command\\)\\|" | ||
| 856 | "\\(symbol\\)\\)\\s-+\\)?" | ||
| 857 | ;; Note starting with word-syntax character: | ||
| 858 | "`\\(\\sw\\(\\sw\\|\\s_\\)+\\)'") | ||
| 859 | "Regexp matching doc string references to symbols. | ||
| 860 | |||
| 861 | The words preceding the quoted symbol can be used in doc strings to | ||
| 862 | distinguish references to variables, functions and symbols.") | ||
| 863 | |||
| 864 | (defvar help-xref-info-regexp | ||
| 865 | "\\<info\\s-+node\\s-`\\([^']+\\)'" | ||
| 866 | "Regexp matching doc string references to an Info node.") | ||
| 867 | |||
| 868 | (defun help-setup-xref (item interactive-p) | ||
| 869 | "Invoked from commands using the \"*Help*\" buffer to install some xref info. | ||
| 870 | |||
| 871 | ITEM is a (function . args) pair appropriate for recreating the help | ||
| 872 | buffer after following a reference. INTERACTIVE-P is non-nil if the | ||
| 873 | calling command was invoked interactively. In this case the stack of | ||
| 874 | items for help buffer \"back\" buttons is cleared." | ||
| 875 | (if interactive-p | ||
| 876 | (setq help-xref-stack nil)) | ||
| 877 | (setq help-xref-stack-item item)) | ||
| 878 | |||
| 879 | (defun help-make-xrefs (&optional buffer) | ||
| 880 | "Parse and hyperlink documentation cross-references in the given BUFFER. | ||
| 881 | |||
| 882 | Find cross-reference information in a buffer and, if | ||
| 883 | `help-highlight-p' is non-nil, highlight it with face defined by | ||
| 884 | `help-highlight-face'; activate such cross references for selection | ||
| 885 | with `help-follow'. Cross-references have the canonical form `...' | ||
| 886 | and the type of reference may be disambiguated by the preceding | ||
| 887 | word(s) used in `help-xref-symbol-regexp'. | ||
| 888 | |||
| 889 | A special reference `back' is made to return back through a stack of | ||
| 890 | help buffers. Variable `help-back-label' specifies the text for | ||
| 891 | that." | ||
| 892 | (interactive "b") | ||
| 893 | (save-excursion | ||
| 894 | (set-buffer (or buffer (current-buffer))) | ||
| 895 | (goto-char (point-min)) | ||
| 896 | ;; Skip the header-type info, though it might be useful to parse | ||
| 897 | ;; it at some stage (e.g. "function in `library'"). | ||
| 898 | (forward-paragraph) | ||
| 899 | (let ((old-modified (buffer-modified-p))) | ||
| 900 | (let ((stab (syntax-table)) | ||
| 901 | (case-fold-search t) | ||
| 902 | (inhibit-read-only t)) | ||
| 903 | (set-syntax-table emacs-lisp-mode-syntax-table) | ||
| 904 | ;; The following should probably be abstracted out. | ||
| 905 | (unwind-protect | ||
| 906 | (progn | ||
| 907 | ;; Quoted symbols | ||
| 908 | (save-excursion | ||
| 909 | (while (re-search-forward help-xref-symbol-regexp nil t) | ||
| 910 | (let* ((data (match-string 6)) | ||
| 911 | (sym (intern-soft data))) | ||
| 912 | (if sym | ||
| 913 | (cond | ||
| 914 | ((match-string 3) ; `variable' &c | ||
| 915 | (and (boundp sym) ; `variable' doesn't ensure | ||
| 916 | ; it's actually bound | ||
| 917 | (help-xref-button 6 #'describe-variable sym))) | ||
| 918 | ((match-string 4) ; `function' &c | ||
| 919 | (and (fboundp sym) ; similarly | ||
| 920 | (help-xref-button 6 #'describe-function sym))) | ||
| 921 | ((match-string 5)) ; nothing for symbol | ||
| 922 | ((and (boundp sym) (fboundp sym)) | ||
| 923 | ;; We can't intuit whether to use the | ||
| 924 | ;; variable or function doc -- supply both. | ||
| 925 | (help-xref-button 6 #'help-xref-interned sym)) | ||
| 926 | ((boundp sym) | ||
| 927 | (help-xref-button 6 #'describe-variable sym)) | ||
| 928 | ((fboundp sym) | ||
| 929 | (help-xref-button 6 #'describe-function sym))))))) | ||
| 930 | ;; Info references | ||
| 931 | (save-excursion | ||
| 932 | (while (re-search-forward help-xref-info-regexp nil t) | ||
| 933 | (help-xref-button 1 #'Info-goto-node (list (match-data 1))))) | ||
| 934 | ;; An obvious case of a key substitution: | ||
| 935 | (save-excursion | ||
| 936 | (while (re-search-forward | ||
| 937 | "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)+\\)" nil t) | ||
| 938 | (let ((sym (intern-soft (match-string 1)))) | ||
| 939 | (if (fboundp sym) | ||
| 940 | (help-xref-button 1 #'describe-function sym)))))) | ||
| 941 | (set-syntax-table stab)) | ||
| 942 | ;; Make a back-reference in this buffer if appropriate. | ||
| 943 | (when help-xref-stack | ||
| 944 | (goto-char (point-max)) | ||
| 945 | (save-excursion | ||
| 946 | (insert "\n\n" help-back-label)) | ||
| 947 | ;; Just to provide the match data: | ||
| 948 | (looking-at (concat "\n\n\\(" (regexp-quote help-back-label) "\\)")) | ||
| 949 | (help-xref-button 1 #'help-xref-go-back nil))) | ||
| 950 | ;; View mode steals RET from us. | ||
| 951 | (set (make-local-variable 'minor-mode-overriding-map-alist) | ||
| 952 | (list (cons 'view-mode | ||
| 953 | (let ((map (make-sparse-keymap))) | ||
| 954 | (define-key map "\r" 'help-follow) | ||
| 955 | map)))) | ||
| 956 | (set-buffer-modified-p old-modified)))) | ||
| 957 | |||
| 958 | (defun help-xref-button (match-number function data) | ||
| 959 | "Make a hyperlink for cross-reference text previously matched. | ||
| 960 | |||
| 961 | MATCH-NUMBER is the subexpression of interest in the last matched | ||
| 962 | regexp. FUNCTION is a function to invoke when the button is | ||
| 963 | activated, applied to DATA. DATA may be a single value or a list. | ||
| 964 | See `help-make-xrefs'." | ||
| 965 | (put-text-property (match-beginning match-number) | ||
| 966 | (match-end match-number) | ||
| 967 | 'mouse-face 'highlight) | ||
| 968 | (if help-highlight-p | ||
| 969 | (put-text-property (match-beginning match-number) | ||
| 970 | (match-end match-number) | ||
| 971 | 'face help-highlight-face)) | ||
| 972 | (put-text-property (match-beginning match-number) | ||
| 973 | (match-end match-number) | ||
| 974 | 'help-xref (cons function | ||
| 975 | (if (listp data) | ||
| 976 | data | ||
| 977 | (list data))))) | ||
| 978 | |||
| 979 | |||
| 980 | ;; Additional functions for (re-)creating types of help buffers. | ||
| 981 | (defun help-xref-interned (symbol) | ||
| 982 | "Follow a hyperlink which appeared to be an arbitrary interned SYMBOL. | ||
| 983 | |||
| 984 | Both variable and function documentation are extracted into a single | ||
| 985 | help buffer." | ||
| 986 | (let ((fdoc (describe-function symbol))) | ||
| 987 | (describe-variable symbol) | ||
| 988 | ;; We now have a help buffer on the variable. Insert the function | ||
| 989 | ;; text after it. | ||
| 990 | (goto-char (point-max)) | ||
| 991 | (insert "\n\n" fdoc)) | ||
| 992 | (goto-char (point-min)) | ||
| 993 | (help-setup-xref (cons #'help-xref-interned symbol) nil)) | ||
| 994 | |||
| 995 | (defun help-xref-mode (buffer) | ||
| 996 | "Do a `describe-mode' for the specified BUFFER." | ||
| 997 | (save-excursion | ||
| 998 | (set-buffer buffer) | ||
| 999 | (describe-mode))) | ||
| 1000 | |||
| 1001 | ;;; Navigation/hyperlinking with xrefs | ||
| 1002 | |||
| 1003 | (defun help-follow-mouse (click) | ||
| 1004 | "Follow the cross-reference that you click on." | ||
| 1005 | (interactive "e") | ||
| 1006 | (save-excursion | ||
| 1007 | (let* ((start (event-start click)) | ||
| 1008 | (window (car start)) | ||
| 1009 | (pos (car (cdr start)))) | ||
| 1010 | (set-buffer (window-buffer window)) | ||
| 1011 | (help-follow pos)))) | ||
| 1012 | |||
| 1013 | (defun help-xref-go-back () | ||
| 1014 | "Go back to the previous help buffer using info on `help-xref-stack'." | ||
| 1015 | (interactive) | ||
| 1016 | (when help-xref-stack | ||
| 1017 | (setq help-xref-stack (cdr help-xref-stack)) ; due to help-follow | ||
| 1018 | (let* ((item (car help-xref-stack)) | ||
| 1019 | (method (car item)) | ||
| 1020 | (args (cdr item))) | ||
| 1021 | (setq help-xref-stack (cdr help-xref-stack)) | ||
| 1022 | (if (listp args) | ||
| 1023 | (apply method args) | ||
| 1024 | (funcall method args))))) | ||
| 1025 | |||
| 1026 | (defun help-go-back () | ||
| 1027 | (interactive) | ||
| 1028 | (help-follow (1- (point-max)))) | ||
| 1029 | |||
| 1030 | (defun help-follow (&optional pos) | ||
| 1031 | "Follow cross-reference at POS, defaulting to point. | ||
| 1032 | |||
| 1033 | For the cross-reference format, see `help-make-xrefs'." | ||
| 1034 | (interactive "d") | ||
| 1035 | (let* ((help-data (get-text-property pos 'help-xref)) | ||
| 1036 | (method (car help-data)) | ||
| 1037 | (args (cdr help-data))) | ||
| 1038 | (setq help-xref-stack (cons help-xref-stack-item help-xref-stack)) | ||
| 1039 | (setq help-xref-stack-item nil) | ||
| 1040 | (when help-data | ||
| 1041 | ;; There is a reference at point. Follow it. | ||
| 1042 | (apply method args)))) | ||
| 1043 | |||
| 1044 | ;; For tabbing through buffer. | ||
| 1045 | (defun help-next-ref () | ||
| 1046 | "Find the next help cross-reference in the buffer." | ||
| 1047 | (interactive) | ||
| 1048 | (let (pos) | ||
| 1049 | (while (not pos) | ||
| 1050 | (if (get-text-property (point) 'help-xref) ; move off reference | ||
| 1051 | (or (goto-char (next-single-property-change (point) 'help-xref)) | ||
| 1052 | (point))) | ||
| 1053 | (cond ((setq pos (next-single-property-change (point) 'help-xref)) | ||
| 1054 | (if pos (goto-char pos))) | ||
| 1055 | ((bobp) | ||
| 1056 | (message "No cross references in the buffer.") | ||
| 1057 | (setq pos t)) | ||
| 1058 | (t ; be circular | ||
| 1059 | (goto-char (point-min))))))) | ||
| 1060 | |||
| 1061 | (defun help-previous-ref () | ||
| 1062 | "Find the previous help cross-reference in the buffer." | ||
| 1063 | (interactive) | ||
| 1064 | (let (pos) | ||
| 1065 | (while (not pos) | ||
| 1066 | (if (get-text-property (point) 'help-xref) ; move off reference | ||
| 1067 | (goto-char (or (previous-single-property-change (point) 'help-xref) | ||
| 1068 | (point)))) | ||
| 1069 | (cond ((setq pos (previous-single-property-change (point) 'help-xref)) | ||
| 1070 | (if pos (goto-char pos))) | ||
| 1071 | ((bobp) | ||
| 1072 | (message "No cross references in the buffer.") | ||
| 1073 | (setq pos t)) | ||
| 1074 | (t ; be circular | ||
| 1075 | (goto-char (point-max))))))) | ||
| 1076 | |||
| 791 | ;;; help.el ends here | 1077 | ;;; help.el ends here |