Mercurial > emacs
annotate lisp/docref.el @ 25709:ba4e2a641663
(SXHASH_COMBINE): Add missing parentheses.
(Fchar_table_range, Fset_char_table_default, mapcar1,
Fyes_or_no_p, sweep_weak_hash_tables): Remove unused variable(s).
| author | Gerd Moellmann <gerd@gnu.org> |
|---|---|
| date | Tue, 14 Sep 1999 13:09:25 +0000 |
| parents | ac1673121774 |
| children |
| rev | line source |
|---|---|
| 13337 | 1 ;;; docref.el --- Simple cross references for Elisp documentation strings |
| 14169 | 2 |
| 11270 | 3 ;; Copyright (C) 1994 Free Software Foundation, Inc. |
| 4 | |
| 5 ;; Author: Vadim Geshel <vadik@unas.cs.kiev.ua> | |
| 6 ;; Created: 12 Jul 1994 | |
| 7 ;; Keywords: docs, help, lisp | |
| 8 ;; original name was cross-ref.el. | |
| 9 | |
| 10 ;; This file is part of GNU Emacs. | |
| 11 | |
| 12 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
| 13 ;; it under the terms of the GNU General Public License as published by | |
| 14 ;; the Free Software Foundation; either version 2, or (at your option) | |
| 15 ;; any later version. | |
| 16 | |
| 17 ;; GNU Emacs is distributed in the hope that it will be useful, | |
| 18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 20 ;; GNU General Public License for more details. | |
| 21 | |
| 22 ;; You should have received a copy of the GNU General Public License | |
| 14169 | 23 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
| 24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
| 25 ;; Boston, MA 02111-1307, USA. | |
| 11270 | 26 |
| 27 ;;; Commentary: | |
| 14169 | 28 |
| 11270 | 29 ;; This package allows you to use a simple form of cross references in |
| 30 ;; your Emacs Lisp documentation strings. Cross-references look like | |
| 31 ;; \\(type@[label@]data), where type defines a method for retrieving | |
| 13976 | 32 ;; reference information, data is used by a method routine as an argument, |
| 11270 | 33 ;; and label "represents" the reference in text. If label is absent, data |
| 34 ;; is used instead. | |
| 35 ;; | |
| 36 ;; Special reference labeled `back', when present, can be used to return | |
| 37 ;; to the previous contents of help buffer. | |
| 38 ;; | |
| 39 ;; Cross-referencing currently is intended for use in doc strings only | |
| 40 ;; and works only in temporary buffers (created by `with-output-to-temp-buffer'). | |
| 41 ;; List of temp buffers in which cross-referencing is to be active is specified | |
| 42 ;; by variable DOCREF-BUFFERS-LIST, which contains only "*Help*" by default. | |
| 43 ;; | |
| 44 ;; Documentation strings for this package's functions and variables can serve | |
| 45 ;; as examples of usage. | |
| 46 ;; | |
| 47 ;;; Customization: | |
| 48 ;; | |
| 49 ;; See source. The main customization variable is `docref-methods-alist'. | |
| 50 ;; It consists of (type . function) pairs, where type is a string which | |
| 51 ;; corresponds to type in cross-references and function is called with | |
| 52 ;; one argument - reference `data' - when a reference is activated. | |
| 53 ;; | |
| 54 ;;; Installation: | |
| 55 ;; | |
| 56 ;; Place this file somewhere in your load-path, byte-compiled it, and add | |
| 57 ;; (require 'cross-ref) | |
| 58 ;; to your .emacs. | |
| 59 | |
| 60 ;;; Code: | |
| 61 | |
| 62 ;; User customizable variables | |
| 21088 | 63 (defgroup docref nil |
| 64 "Simple cross references for Elisp documentation strings." | |
| 65 :prefix "docref-" | |
| 66 :group 'help | |
| 67 :group 'lisp | |
| 68 :group 'docs) | |
| 11270 | 69 |
| 21088 | 70 (defcustom docref-highlight-p t |
| 11270 | 71 "*If non-nil, \\(f@docref-subst) highlights cross-references. |
| 72 Under window system it highlights them with face defined by | |
| 73 \\(v@docref-highlight-face), on character terminal highlighted references | |
| 21088 | 74 look like cross-references in info mode." |
| 75 :type 'boolean | |
| 76 :group 'docref) | |
| 11270 | 77 |
| 21088 | 78 (defcustom docref-highlight-face 'highlight |
| 79 "*Face used to highlight cross-references (used by \\(f@docref-subst))" | |
| 80 :type 'face | |
| 81 :group 'docref) | |
| 11270 | 82 |
| 21088 | 83 (defcustom docref-methods-alist |
| 11270 | 84 '(("f" . docref-describe-function) ; reference to a function documentation |
| 85 ("v" . docref-describe-variable) ; reference to a variable documentation | |
| 86 ("F" . docref-read-file) ; reference to a file contents | |
| 87 ("s" . docref-use-string) ; reference to a string | |
| 88 ("V" . docref-use-variable-value) ; reference to variable value | |
| 89 ("0" . beep)) ; just highlighted text | |
| 90 "Alist which maps cross-reference ``types'' to retrieval functions. | |
| 91 | |
| 92 The car of each element is a string that serves as `type' in cross-references. | |
| 93 \(See \\(f@docref-subst)). The cdr is a function of one argument, | |
| 21088 | 94 to be called to find this reference." |
| 95 :type '(repeat (cons string function)) | |
| 96 :group 'docref) | |
| 11270 | 97 |
| 21088 | 98 (defcustom docref-back-label "\nback" |
| 99 "Label to use by \\(f@docref-subst) for the go-back reference." | |
| 100 :type 'string | |
| 101 :group 'docref) | |
| 11270 | 102 |
| 103 (defvar docref-back-reference nil | |
| 104 "If non-nil, this is a go-back reference to add to the current buffer. | |
| 105 The value specifies how to go back. It should be suitable for use | |
| 106 as the second argument to \\(f@docref-insert-label). | |
| 107 \\(f@docref-subst) uses this to set up the go-back reference.") | |
|
11271
15c71d840a81
(docref-last-active-buffer): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
11270
diff
changeset
|
108 |
|
15c71d840a81
(docref-last-active-buffer): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
11270
diff
changeset
|
109 (defvar docref-last-active-buffer) |
| 11270 | 110 |
| 111 ;;;###autoload | |
| 112 (defun docref-setup () | |
| 113 "Process docref cross-references in the current buffer. | |
| 114 See also \\(f@docref-subst)." | |
| 115 (interactive) | |
| 116 (docref-subst (current-buffer)) | |
| 117 (docref-mode)) | |
| 118 | |
| 119 (defvar docref-mode-map nil) | |
| 120 (or docref-mode-map | |
| 121 (let ((map (make-sparse-keymap))) | |
| 122 (define-key map [mouse-2] 'docref-follow-mouse) | |
| 123 (define-key map "\C-c\C-b" 'docref-go-back) | |
| 124 (define-key map "\C-c\C-c" 'docref-follow) | |
| 125 (setq docref-mode-map map))) | |
| 126 | |
| 127 (defun docref-mode () | |
| 128 "Major mode for help buffers that contain cross references. | |
| 129 To follow a reference, move to it and type \\[docref-follow], or use | |
| 130 \\[docref-follow-mouse]. The command \\[docref-go-back] can used to go | |
| 131 back to where you came from." | |
| 132 (interactive) | |
| 133 (kill-all-local-variables) | |
| 134 (setq major-mode 'docref-mode) | |
| 135 (setq mode-name "Docref") | |
| 136 (use-local-map docref-mode-map) | |
| 137 (run-hooks 'docref-mode)) | |
| 138 | |
| 139 (defun docref-subst (buf) | |
| 140 "Parse documentation cross-references in buffer BUF. | |
| 141 | |
| 142 Find cross-reference information in a buffer and | |
| 143 highlight them with face defined by \\(v@docref-highlight-face). | |
| 144 | |
| 145 Cross-reference has the following format: \\ (TYPE[@LABEL]@DATA), where | |
| 13976 | 146 TYPE defines method used to retrieve xref data (like reading from file or |
| 11270 | 147 calling \\(f@describe-function)), DATA is an argument to this method |
| 148 \(like file name or function name), and LABEL is displayed in text using | |
| 149 \\(v@docref-highlight-face). | |
| 150 | |
| 151 The special reference `back' can be used to return back. | |
| 152 The variable \\(v@docref-back-label) specifies the label to use for that. | |
| 153 | |
| 154 See \\(v@docref-methods-alist) for currently defined methods." | |
| 155 (interactive "b") | |
| 156 (save-excursion | |
| 157 (set-buffer buf) | |
| 158 (goto-char (point-min)) | |
| 159 ;; The docref-seen property indicates that we have processed this | |
| 160 ;; buffer's contents already, so don't do it again. | |
| 161 (if (not (get-text-property (point-min) 'docref-seen)) | |
| 162 (let ((old-modified (buffer-modified-p))) | |
| 163 (while (re-search-forward "[\\](\\([^\)\@]+\\)\\(@[^\)\@]+\\)?@\\([^\)]*\\))" | |
| 164 nil t) | |
| 165 (let* ((start (match-beginning 0)) | |
| 166 (type (buffer-substring (match-beginning 1) (match-end 1))) | |
| 167 (data (buffer-substring (match-beginning 3) (match-end 3))) | |
| 168 (label | |
| 169 (if (match-beginning 2) | |
| 170 (buffer-substring (+ (match-beginning 2) 1) (match-end 2)) | |
| 171 data))) | |
| 172 (replace-match "" t) | |
| 173 (docref-insert-label label (cons type data)))) | |
| 174 | |
| 175 ;; Make a back-reference in this buffer, if desired. | |
| 176 ;; (This is true if called from docref-follow.) | |
| 177 (if docref-back-reference | |
| 178 (progn | |
| 179 (goto-char (point-max)) | |
| 180 (put-text-property (point-min) (1+ (point-min)) | |
| 181 'docref-back-position (point)) | |
| 182 (docref-insert-label docref-back-label docref-back-reference))) | |
| 183 (put-text-property (point-min) (1+ (point-min)) 'docref-seen t) | |
| 184 (set-buffer-modified-p old-modified))))) | |
| 185 | |
| 186 (defun docref-insert-label (string ref) | |
| 187 (let ((label (concat string)) | |
| 188 (pos (point))) | |
| 189 ;; decorate the label | |
| 190 (let ((leading-space-end (save-match-data | |
| 191 (if (string-match "^\\([ \t\n]+\\)" label) | |
| 192 (match-end 1) | |
| 193 0))) | |
| 194 (trailing-space-start (save-match-data | |
| 195 (if (string-match "\\([ \t\n]+\\)$" label) | |
| 196 (match-beginning 1) | |
| 197 (length label))))) | |
| 198 (if docref-highlight-p | |
| 199 (if (not window-system) | |
| 200 (setq label | |
| 201 (concat (substring label 0 leading-space-end) | |
| 202 "(*note " | |
| 203 (substring label leading-space-end trailing-space-start) | |
| 204 ")" | |
| 205 (substring label trailing-space-start))) | |
| 206 ;; window-system | |
| 207 (put-text-property leading-space-end | |
| 208 trailing-space-start | |
| 209 'face docref-highlight-face label))) | |
| 210 (put-text-property 0 (length label) 'docref ref label) | |
| 211 (insert label)))) | |
| 212 | |
| 213 (defun docref-follow-mouse (click) | |
| 214 "Follow the cross-reference that you click on." | |
| 215 (interactive "e") | |
| 216 (save-excursion | |
| 217 (let* ((start (event-start click)) | |
| 218 (window (car start)) | |
| 219 (pos (car (cdr start))) | |
| 220 (docref-last-active-buffer (current-buffer))) | |
| 221 (set-buffer (window-buffer window)) | |
| 222 (docref-follow pos)))) | |
| 223 | |
| 224 (defun docref-go-back () | |
| 225 "Go back to the previous contents of help buffer." | |
| 226 (interactive) | |
| 227 (let ((pos (get-text-property (point-min) 'docref-back-position))) | |
| 228 (if pos | |
| 229 (docref-follow pos) | |
| 230 (error "No go-back reference")))) | |
| 231 | |
| 232 (defun docref-follow (&optional pos) | |
| 233 "Follow cross-reference at point. | |
| 234 For the cross-reference format, see \\(f@docref-subst). | |
| 235 The special reference named `back' can be used to return back" | |
| 236 (interactive) | |
| 237 (or pos (setq pos (point))) | |
| 238 (let ((docref-data (get-text-property pos 'docref))) | |
| 239 (if docref-data | |
| 240 ;; There is a reference at point. Follow it. | |
| 241 (let* ((type (car docref-data)) | |
| 242 (name (cdr docref-data)) | |
| 243 (method (assoc type docref-methods-alist)) | |
| 244 (cur-contents (buffer-string)) | |
| 245 (opoint (point)) | |
| 246 (docref-back-reference (cons "s" cur-contents)) | |
| 247 success) | |
| 248 (if (null method) | |
| 249 (error "Unknown cross-reference type: %s" type)) | |
| 250 (unwind-protect | |
| 251 (save-excursion | |
| 252 (funcall (cdr method) name) | |
| 253 (setq success t)) | |
| 254 (or success | |
| 255 (progn | |
| 256 ;; (cdr method) got an error. | |
| 257 ;; Put back the text that we had. | |
| 258 (erase-buffer) | |
| 259 (insert cur-contents) | |
| 260 (goto-char opoint))) | |
| 261 (set-buffer-modified-p nil)))))) | |
| 262 | |
| 263 ;; Builtin methods for accessing a reference. | |
| 264 | |
| 265 (defun docref-describe-function (data) | |
| 266 (save-excursion | |
| 267 (if (boundp 'docref-last-active-buffer) | |
| 268 (set-buffer docref-last-active-buffer)) | |
| 269 (describe-function (intern data)))) | |
| 270 | |
| 271 (defun docref-describe-variable (data) | |
| 272 (save-excursion | |
| 273 (if (boundp 'docref-last-active-buffer) | |
| 274 (set-buffer docref-last-active-buffer)) | |
| 275 (describe-variable (intern data)))) | |
| 276 | |
| 277 (defun docref-read-file (data) | |
| 278 (with-output-to-temp-buffer (buffer-name) | |
| 279 (erase-buffer) | |
| 280 (insert-file-contents (expand-file-name data)))) | |
| 281 | |
| 282 (defun docref-use-string (data) | |
| 283 (with-output-to-temp-buffer (buffer-name) | |
| 284 (erase-buffer) | |
| 285 (insert data))) | |
| 286 | |
| 287 (defun docref-use-variable-value (data) | |
| 288 (let ((sym (intern data))) | |
| 289 (with-output-to-temp-buffer (buffer-name) | |
| 290 (erase-buffer) | |
| 291 (princ (symbol-value sym))))) | |
| 292 | |
| 293 (provide 'docref) | |
| 294 | |
| 295 ;;; docref.el ends here | |
| 296 |
