aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Engster2014-01-08 22:59:19 +0100
committerDavid Engster2014-01-08 22:59:19 +0100
commit0116ee837aed1f34fe406febc991db00c22ee073 (patch)
tree8505681f872a17621fa08be26be11553a276eb52
parent4b9e6087a01a5d92299ecfac806b5dc533e0529c (diff)
parent0f918d96d79265531f65fd37a81e73b240f8f3d5 (diff)
downloademacs-0116ee837aed1f34fe406febc991db00c22ee073.tar.gz
emacs-0116ee837aed1f34fe406febc991db00c22ee073.zip
Proper help support for EIEIO classes and methods.
-rw-r--r--lisp/ChangeLog30
-rw-r--r--lisp/emacs-lisp/eieio-opt.el553
-rw-r--r--lisp/emacs-lisp/eieio.el4
-rw-r--r--lisp/help-fns.el17
4 files changed, 268 insertions, 336 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 8d36ae9911f..b7b5c621e40 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,33 @@
12014-01-08 David Engster <deng@randomsample.de>
2
3 * help-fns.el (help-fns-describe-function-functions): New
4 variable to call functions for augmenting help buffers.
5 (describe-function-1): Remove explicit calls to
6 `help-fns--compiler-macro', `help-fns--parent-mode' and
7 `help-fns--obsolete'. Put them in above new variable instead, and
8 call them through `run-hook-with-args'.
9 * emacs-lisp/eieio-opt.el (eieio-help-class): Rename from
10 `eieio-describe-class'. Not meant for interactive use anymore,
11 but to augment existing help buffers. Remove optional second
12 argument. Create proper button for file location. Rewrite
13 function to use `insert' instead of `princ' and `prin1' where
14 possible.
15 (eieio-help-class-slots): Rename from `eieio-describe-class-slots'.
16 (eieio-method-def, eieio-class-def): Move further up.
17 (describe-method, describe-generic, eieio-describe-method): Remove
18 aliases.
19 (eieio-help-constructor, eieio-help-generic): Rename from
20 `eieio-describe-constructor' and `eieio-describe-generic', resp.
21 Rewrite to use `insert' in the current buffer and use proper help
22 buttons.
23 (eieio-help-find-method-definition)
24 (eieio-help-find-class-definition): Also accept symbols as
25 arguments.
26 (eieio-help-mode-augmentation-maybee): Remove.
27 (eieio-describe-class-sb): Use `describe-function'.
28 * emacs-lisp/eieio.el (help-fns-describe-function-functions): Add
29 `eieio-help-generic' and `eieio-help-constructor'.
30
12014-01-08 Paul Eggert <eggert@cs.ucla.edu> 312014-01-08 Paul Eggert <eggert@cs.ucla.edu>
2 32
3 Spelling fixes. 33 Spelling fixes.
diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el
index 647bbb344b1..9269c744b9f 100644
--- a/lisp/emacs-lisp/eieio-opt.el
+++ b/lisp/emacs-lisp/eieio-opt.el
@@ -74,108 +74,81 @@ Argument CH-PREFIX is another character prefix to display."
74 74
75;;; CLASS COMPLETION / DOCUMENTATION 75;;; CLASS COMPLETION / DOCUMENTATION
76 76
77;;;###autoload(defalias 'describe-class 'eieio-describe-class)
78
79;;;###autoload 77;;;###autoload
80(defun eieio-describe-class (class &optional headerfcn) 78(defun eieio-help-class (class)
81 "Describe a CLASS defined by a string or symbol. 79 "Print help description for CLASS.
82If CLASS is actually an object, then also display current values of that object. 80If CLASS is actually an object, then also display current values of that object."
83Optional HEADERFCN should be called to insert a few bits of info first." 81 ;; Header line
84 (interactive (list (eieio-read-class "Class: "))) 82 (prin1 class)
85 (with-output-to-temp-buffer (help-buffer) ;"*Help*" 83 (insert " is a"
86 (help-setup-xref (list #'eieio-describe-class class headerfcn) 84 (if (class-option class :abstract)
87 (called-interactively-p 'interactive)) 85 "n abstract"
88 86 "")
89 (when headerfcn (funcall headerfcn)) 87 " class")
90 (prin1 class) 88 (let ((location (get class 'class-location)))
91 (princ " is a") 89 (when location
92 (if (class-option class :abstract) 90 (insert " in `")
93 (princ "n abstract")) 91 (help-insert-xref-button
94 (princ " class") 92 (file-name-nondirectory location)
95 ;; Print file location 93 'eieio-class-def class location)
96 (when (get class 'class-location) 94 (insert "'")))
97 (princ " in `") 95 (insert ".\n")
98 (princ (file-name-nondirectory (get class 'class-location))) 96 ;; Parents
99 (princ "'")) 97 (let ((pl (eieio-class-parents class))
100 (terpri) 98 cur)
101 ;; Inheritance tree information 99 (when pl
102 (let ((pl (eieio-class-parents class))) 100 (insert " Inherits from ")
103 (when pl 101 (while (setq cur (pop pl))
104 (princ " Inherits from ") 102 (insert "`")
105 (while pl 103 (help-insert-xref-button (symbol-name cur)
106 (princ "`") (prin1 (car pl)) (princ "'") 104 'help-function cur)
107 (setq pl (cdr pl)) 105 (insert (if pl "', " "'")))
108 (if pl (princ ", "))) 106 (insert ".\n")))
109 (terpri))) 107 ;; Children
110 (let ((ch (eieio-class-children class))) 108 (let ((ch (eieio-class-children class))
111 (when ch 109 cur)
112 (princ " Children ") 110 (when ch
113 (while ch 111 (insert " Children ")
114 (princ "`") (prin1 (car ch)) (princ "'") 112 (while (setq cur (pop ch))
115 (setq ch (cdr ch)) 113 (insert "`")
116 (if ch (princ ", "))) 114 (help-insert-xref-button (symbol-name cur)
117 (terpri))) 115 'help-function cur)
118 (terpri) 116 (insert (if ch "', " "'")))
119 ;; System documentation 117 (insert ".\n")))
120 (let ((doc (documentation-property class 'variable-documentation))) 118 ;; System documentation
121 (when doc 119 (let ((doc (documentation-property class 'variable-documentation)))
122 (princ "Documentation:") 120 (when doc
123 (terpri) 121 (insert "\n" doc "\n\n")))
124 (princ doc) 122 ;; Describe all the slots in this class.
125 (terpri) 123 (eieio-help-class-slots class)
126 (terpri))) 124 ;; Describe all the methods specific to this class.
127 ;; Describe all the slots in this class 125 (let ((methods (eieio-all-generic-functions class))
128 (eieio-describe-class-slots class) 126 (type [":STATIC" ":BEFORE" ":PRIMARY" ":AFTER"])
129 ;; Describe all the methods specific to this class. 127 counter doc argshl dochl)
130 (let ((methods (eieio-all-generic-functions class)) 128 (when methods
131 (doc nil)) 129 (insert (propertize "Specialized Methods:\n\n" 'face 'bold))
132 (if (not methods) nil 130 (while methods
133 (princ "Specialized Methods:") 131 (setq doc (eieio-method-documentation (car methods) class))
134 (terpri) 132 (insert "`")
135 (terpri) 133 (help-insert-xref-button (symbol-name (car methods))
136 (while methods 134 'help-function (car methods))
137 (setq doc (eieio-method-documentation (car methods) class)) 135 (insert "'")
138 (princ "`") 136 (if (not doc)
139 (prin1 (car methods)) 137 (insert " Undocumented")
140 (princ "'") 138 (setq counter 0)
141 (if (not doc) 139 (dolist (cur doc)
142 (princ " Undocumented") 140 (when cur
143 (if (car doc) 141 (insert " " (aref type counter) " "
144 (progn 142 (prin1-to-string (car cur) (current-buffer))
145 (princ " :STATIC ") 143 "\n"
146 (prin1 (car (car doc))) 144 (cdr cur)))
147 (terpri) 145 (setq counter (1+ counter))))
148 (princ (cdr (car doc))))) 146 (insert "\n\n")
149 (setq doc (cdr doc)) 147 (setq methods (cdr methods))))))
150 (if (car doc) 148
151 (progn 149(defun eieio-help-class-slots (class)
152 (princ " :BEFORE ") 150 "Print help description for the slots in CLASS.
153 (prin1 (car (car doc))) 151Outputs to the current buffer."
154 (terpri)
155 (princ (cdr (car doc)))))
156 (setq doc (cdr doc))
157 (if (car doc)
158 (progn
159 (princ " :PRIMARY ")
160 (prin1 (car (car doc)))
161 (terpri)
162 (princ (cdr (car doc)))))
163 (setq doc (cdr doc))
164 (if (car doc)
165 (progn
166 (princ " :AFTER ")
167 (prin1 (car (car doc)))
168 (terpri)
169 (princ (cdr (car doc)))))
170 (terpri)
171 (terpri))
172 (setq methods (cdr methods))))))
173 (with-current-buffer (help-buffer)
174 (buffer-string)))
175
176(defun eieio-describe-class-slots (class)
177 "Describe the slots in CLASS.
178Outputs to the standard output."
179 (let* ((cv (class-v class)) 152 (let* ((cv (class-v class))
180 (docs (eieio--class-public-doc cv)) 153 (docs (eieio--class-public-doc cv))
181 (names (eieio--class-public-a cv)) 154 (names (eieio--class-public-a cv))
@@ -185,28 +158,27 @@ Outputs to the standard output."
185 (i 0) 158 (i 0)
186 (prot (eieio--class-protection cv)) 159 (prot (eieio--class-protection cv))
187 ) 160 )
188 (princ "Instance Allocated Slots:") 161 (insert (propertize "Instance Allocated Slots:\n\n"
189 (terpri) 162 'face 'bold))
190 (terpri)
191 (while names 163 (while names
192 (if (car prot) (princ "Private ")) 164 (insert
193 (princ "Slot: ") 165 (concat
194 (prin1 (car names)) 166 (when (car prot)
195 (when (not (eq (aref types i) t)) 167 (propertize "Private " 'face 'bold))
196 (princ " type = ") 168 (propertize "Slot: " 'face 'bold)
197 (prin1 (aref types i))) 169 (prin1-to-string (car names))
198 (unless (eq (car deflt) eieio-unbound) 170 (unless (eq (aref types i) t)
199 (princ " default = ") 171 (concat " type = "
200 (prin1 (car deflt))) 172 (prin1-to-string (aref types i))))
201 (when (car publp) 173 (unless (eq (car deflt) eieio-unbound)
202 (princ " printer = ") 174 (concat " default = "
203 (prin1 (car publp))) 175 (prin1-to-string (car deflt))))
204 (when (car docs) 176 (when (car publp)
205 (terpri) 177 (concat " printer = "
206 (princ " ") 178 (prin1-to-string (car publp))))
207 (princ (car docs)) 179 (when (car docs)
208 (terpri)) 180 (concat "\n " (car docs) "\n"))
209 (terpri) 181 "\n"))
210 (setq names (cdr names) 182 (setq names (cdr names)
211 docs (cdr docs) 183 docs (cdr docs)
212 deflt (cdr deflt) 184 deflt (cdr deflt)
@@ -219,61 +191,30 @@ Outputs to the standard output."
219 i 0 191 i 0
220 prot (eieio--class-class-allocation-protection cv)) 192 prot (eieio--class-class-allocation-protection cv))
221 (when names 193 (when names
222 (terpri) 194 (insert (propertize "\nClass Allocated Slots:\n\n" 'face 'bold)))
223 (princ "Class Allocated Slots:"))
224 (terpri)
225 (terpri)
226 (while names 195 (while names
227 (when (car prot) 196 (insert
228 (princ "Private ")) 197 (concat
229 (princ "Slot: ") 198 (when (car prot)
230 (prin1 (car names)) 199 "Private ")
231 (unless (eq (aref types i) t) 200 "Slot: "
232 (princ " type = ") 201 (prin1-to-string (car names))
233 (prin1 (aref types i))) 202 (unless (eq (aref types i) t)
234 (condition-case nil 203 (concat " type = "
235 (let ((value (eieio-oref class (car names)))) 204 (prin1-to-string (aref types i))))
236 (princ " value = ") 205 (condition-case nil
237 (prin1 value)) 206 (let ((value (eieio-oref class (car names))))
207 (concat " value = "
208 (prin1-to-string value)))
238 (error nil)) 209 (error nil))
239 (when (car docs) 210 (when (car docs)
240 (terpri) 211 (concat "\n\n " (car docs) "\n"))
241 (princ " ") 212 "\n"))
242 (princ (car docs))
243 (terpri))
244 (terpri)
245 (setq names (cdr names) 213 (setq names (cdr names)
246 docs (cdr docs) 214 docs (cdr docs)
247 prot (cdr prot) 215 prot (cdr prot)
248 i (1+ i))))) 216 i (1+ i)))))
249 217
250;;;###autoload
251(defun eieio-describe-constructor (fcn)
252 "Describe the constructor function FCN.
253Uses `eieio-describe-class' to describe the class being constructed."
254 (interactive
255 ;; Use eieio-read-class since all constructors have the same name as
256 ;; the class they create.
257 (list (eieio-read-class "Class: ")))
258 (eieio-describe-class
259 fcn (lambda ()
260 ;; Describe the constructor part.
261 (prin1 fcn)
262 (princ " is an object constructor function")
263 ;; Print file location
264 (when (get fcn 'class-location)
265 (princ " in `")
266 (princ (file-name-nondirectory (get fcn 'class-location)))
267 (princ "'"))
268 (terpri)
269 (princ "Creates an object of class ")
270 (prin1 fcn)
271 (princ ".")
272 (terpri)
273 (terpri)
274 ))
275 )
276
277(defun eieio-build-class-list (class) 218(defun eieio-build-class-list (class)
278 "Return a list of all classes that inherit from CLASS." 219 "Return a list of all classes that inherit from CLASS."
279 (if (class-p class) 220 (if (class-p class)
@@ -326,91 +267,112 @@ are not abstract."
326 267
327;;; METHOD COMPLETION / DOC 268;;; METHOD COMPLETION / DOC
328 269
329(defalias 'describe-method 'eieio-describe-generic) 270(define-button-type 'eieio-method-def
330;;;###autoload(defalias 'describe-generic 'eieio-describe-generic) 271 :supertype 'help-xref
331(defalias 'eieio-describe-method 'eieio-describe-generic) 272 'help-function (lambda (class method file)
273 (eieio-help-find-method-definition class method file))
274 'help-echo (purecopy "mouse-2, RET: find method's definition"))
275
276(define-button-type 'eieio-class-def
277 :supertype 'help-xref
278 'help-function (lambda (class file)
279 (eieio-help-find-class-definition class file))
280 'help-echo (purecopy "mouse-2, RET: find class definition"))
332 281
333;;;###autoload 282;;;###autoload
334(defun eieio-describe-generic (generic) 283(defun eieio-help-constructor (ctr)
335 "Describe the generic function GENERIC. 284 "Describe CTR if it is a class constructor."
336Also extracts information about all methods specific to this generic." 285 (when (class-p ctr)
337 (interactive (list (eieio-read-generic "Generic Method: "))) 286 (erase-buffer)
338 (eieio--check-type generic-p generic) 287 (let ((location (get ctr 'class-location))
339 (with-output-to-temp-buffer (help-buffer) ; "*Help*" 288 (def (symbol-function ctr)))
340 (help-setup-xref (list #'eieio-describe-generic generic) 289 (goto-char (point-min))
341 (called-interactively-p 'interactive)) 290 (prin1 ctr)
342 291 (insert (format " is an %s object constructor function"
343 (prin1 generic) 292 (if (autoloadp def)
344 (princ " is a generic function") 293 "autoloaded"
345 (when (generic-primary-only-p generic) 294 "")))
346 (princ " with only ") 295 (when (and (autoloadp def)
347 (when (generic-primary-only-one-p generic) 296 (null location))
348 (princ "one ")) 297 (setq location
349 (princ "primary method") 298 (find-lisp-object-file-name ctr def)))
350 (when (not (generic-primary-only-one-p generic)) 299 (when location
351 (princ "s")) 300 (insert " in `")
352 ) 301 (help-insert-xref-button
353 (princ ".") 302 (file-name-nondirectory location)
354 (terpri) 303 'eieio-class-def ctr location)
355 (terpri) 304 (insert "'"))
356 (let ((d (documentation generic))) 305 (insert ".\nCreates an object of class " (symbol-name ctr) ".")
357 (if (not d) 306 (goto-char (point-max))
358 (princ "The generic is not documented.\n") 307 (if (autoloadp def)
359 (princ "Documentation:") 308 (insert "\n\n[Class description not available until class definition is loaded.]\n")
360 (terpri) 309 (save-excursion
361 (princ d) 310 (insert (propertize "\n\nClass description:\n" 'face 'bold))
362 (terpri) 311 (eieio-help-class ctr))
363 (terpri))) 312 ))))
364 (princ "Implementations:") 313
365 (terpri) 314
366 (terpri) 315;;;###autoload
367 (let ((i 4) 316(defun eieio-help-generic (generic)
368 (prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] )) 317 "Describe GENERIC if it is a generic function."
369 ;; Loop over fanciful generics 318 (when (generic-p generic)
370 (while (< i 7) 319 (save-excursion
371 (let ((gm (aref (get generic 'eieio-method-tree) i))) 320 (goto-char (point-min))
372 (when gm 321 (when (re-search-forward " in `.+'.$" nil t)
373 (princ "Generic ") 322 (replace-match ".")))
374 (princ (aref prefix (- i 3))) 323 (save-excursion
375 (terpri) 324 (insert "\n\nThis is a generic function"
376 (princ (or (nth 2 gm) "Undocumented")) 325 (cond
377 (terpri) 326 ((and (generic-primary-only-p generic)
378 (terpri))) 327 (generic-primary-only-one-p generic))
379 (setq i (1+ i))) 328 " with only one primary method")
380 (setq i 0) 329 ((generic-primary-only-p generic)
381 ;; Loop over defined class-specific methods 330 " with only primary methods")
382 (while (< i 4) 331 (t ""))
383 (let ((gm (reverse (aref (get generic 'eieio-method-tree) i))) 332 ".\n\n")
384 location) 333 (insert (propertize "Implementations:\n\n" 'face 'bold))
385 (while gm 334 (let ((i 4)
386 (princ "`") 335 (prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] ))
387 (prin1 (car (car gm))) 336 ;; Loop over fanciful generics
388 (princ "'") 337 (while (< i 7)
389 ;; prefix type 338 (let ((gm (aref (get generic 'eieio-method-tree) i)))
390 (princ " ") 339 (when gm
391 (princ (aref prefix i)) 340 (insert "Generic "
392 (princ " ") 341 (aref prefix (- i 3))
393 ;; argument list 342 "\n"
394 (let* ((func (cdr (car gm))) 343 (or (nth 2 gm) "Undocumented")
395 (arglst (eieio-lambda-arglist func))) 344 "\n\n")))
396 (prin1 arglst)) 345 (setq i (1+ i)))
397 (terpri) 346 (setq i 0)
398 ;; 3 because of cdr 347 ;; Loop over defined class-specific methods
399 (princ (or (documentation (cdr (car gm))) 348 (while (< i 4)
400 "Undocumented")) 349 (let* ((gm (reverse (aref (get generic 'eieio-method-tree) i)))
401 ;; Print file location if available 350 cname location)
402 (when (and (setq location (get generic 'method-locations)) 351 (while gm
403 (setq location (assoc (caar gm) location))) 352 (setq cname (caar gm))
404 (setq location (cadr location)) 353 (insert "`")
405 (princ "\n\nDefined in `") 354 (help-insert-xref-button (symbol-name cname)
406 (princ (file-name-nondirectory location)) 355 'help-variable cname)
407 (princ "'\n")) 356 (insert "' " (aref prefix i) " ")
408 (setq gm (cdr gm)) 357 ;; argument list
409 (terpri) 358 (let* ((func (cdr (car gm)))
410 (terpri))) 359 (arglst (eieio-lambda-arglist func)))
411 (setq i (1+ i))))) 360 (prin1 arglst (current-buffer)))
412 (with-current-buffer (help-buffer) 361 (insert "\n"
413 (buffer-string))) 362 (or (documentation (cdr (car gm)))
363 "Undocumented"))
364 ;; Print file location if available
365 (when (and (setq location (get generic 'method-locations))
366 (setq location (assoc cname location)))
367 (setq location (cadr location))
368 (insert "\n\nDefined in `")
369 (help-insert-xref-button
370 (file-name-nondirectory location)
371 'eieio-method-def cname generic location)
372 (insert "'\n"))
373 (setq gm (cdr gm))
374 (insert "\n")))
375 (setq i (1+ i)))))))
414 376
415(defun eieio-lambda-arglist (func) 377(defun eieio-lambda-arglist (func)
416 "Return the argument list of FUNC, a function body." 378 "Return the argument list of FUNC, a function body."
@@ -584,21 +546,13 @@ Optional argument HISTORYVAR is the variable to use as history."
584 546
585;;; HELP AUGMENTATION 547;;; HELP AUGMENTATION
586;; 548;;
587(define-button-type 'eieio-method-def
588 :supertype 'help-xref
589 'help-function (lambda (class method file)
590 (eieio-help-find-method-definition class method file))
591 'help-echo (purecopy "mouse-2, RET: find method's definition"))
592
593(define-button-type 'eieio-class-def
594 :supertype 'help-xref
595 'help-function (lambda (class file)
596 (eieio-help-find-class-definition class file))
597 'help-echo (purecopy "mouse-2, RET: find class definition"))
598
599(defun eieio-help-find-method-definition (class method file) 549(defun eieio-help-find-method-definition (class method file)
600 (let ((filename (find-library-name file)) 550 (let ((filename (find-library-name file))
601 location buf) 551 location buf)
552 (when (symbolp class)
553 (setq class (symbol-name class)))
554 (when (symbolp method)
555 (setq method (symbol-name method)))
602 (when (null filename) 556 (when (null filename)
603 (error "Cannot find library %s" file)) 557 (error "Cannot find library %s" file))
604 (setq buf (find-file-noselect filename)) 558 (setq buf (find-file-noselect filename))
@@ -622,6 +576,8 @@ Optional argument HISTORYVAR is the variable to use as history."
622 (beginning-of-line)))) 576 (beginning-of-line))))
623 577
624(defun eieio-help-find-class-definition (class file) 578(defun eieio-help-find-class-definition (class file)
579 (when (symbolp class)
580 (setq class (symbol-name class)))
625 (let ((filename (find-library-name file)) 581 (let ((filename (find-library-name file))
626 location buf) 582 location buf)
627 (when (null filename) 583 (when (null filename)
@@ -642,71 +598,6 @@ Optional argument HISTORYVAR is the variable to use as history."
642 (recenter) 598 (recenter)
643 (beginning-of-line)))) 599 (beginning-of-line))))
644 600
645
646(defun eieio-help-mode-augmentation-maybee (&rest unused)
647 "For buffers thrown into help mode, augment for EIEIO.
648Arguments UNUSED are not used."
649 ;; Scan created buttons so far if we are in help mode.
650 (when (eq major-mode 'help-mode)
651 (save-excursion
652 (goto-char (point-min))
653 (let ((pos t) (inhibit-read-only t))
654 (while pos
655 (if (get-text-property (point) 'help-xref) ; move off reference
656 (goto-char
657 (or (next-single-property-change (point) 'help-xref)
658 (point))))
659 (setq pos (next-single-property-change (point) 'help-xref))
660 (when pos
661 (goto-char pos)
662 (let* ((help-data (get-text-property (point) 'help-xref))
663 ;(method (car help-data))
664 (args (cdr help-data)))
665 (when (symbolp (car args))
666 (cond ((class-p (car args))
667 (setcar help-data 'eieio-describe-class))
668 ((generic-p (car args))
669 (setcar help-data 'eieio-describe-generic))
670 (t nil))
671 ))))
672 ;; start back at the beginning, and highlight some sections
673 (goto-char (point-min))
674 (while (re-search-forward "^\\(Documentation\\|Implementations\\):$" nil t)
675 (put-text-property (match-beginning 0) (match-end 0) 'face 'bold))
676 (goto-char (point-min))
677 (if (re-search-forward "^Specialized Methods:$" nil t)
678 (put-text-property (match-beginning 0) (match-end 0) 'face 'bold))
679 (goto-char (point-min))
680 (while (re-search-forward "^\\(Instance\\|Class\\) Allocated Slots:$" nil t)
681 (put-text-property (match-beginning 0) (match-end 0) 'face 'bold))
682 (goto-char (point-min))
683 (while (re-search-forward ":\\(STATIC\\|BEFORE\\|AFTER\\|PRIMARY\\)" nil t)
684 (put-text-property (match-beginning 0) (match-end 0) 'face 'bold))
685 (goto-char (point-min))
686 (while (re-search-forward "^\\(Private \\)?Slot:" nil t)
687 (put-text-property (match-beginning 0) (match-end 0) 'face 'bold))
688 (goto-char (point-min))
689 (cond
690 ((looking-at "\\(.+\\) is a generic function")
691 (let ((mname (match-string 1))
692 cname)
693 (while (re-search-forward "^`\\(.+\\)'[^\0]+?Defined in `\\(.+\\)'" nil t)
694 (setq cname (match-string-no-properties 1))
695 (help-xref-button 2 'eieio-method-def cname
696 mname
697 (cadr (assoc (intern cname)
698 (get (intern mname)
699 'method-locations)))))))
700 ((looking-at "\\(.+\\) is an object constructor function in `\\(.+\\)'")
701 (let ((cname (match-string-no-properties 1)))
702 (help-xref-button 2 'eieio-class-def cname
703 (get (intern cname) 'class-location))))
704 ((looking-at "\\(.+\\) is a\\(n abstract\\)? class in `\\(.+\\)'")
705 (let ((cname (match-string-no-properties 1)))
706 (help-xref-button 3 'eieio-class-def cname
707 (get (intern cname) 'class-location)))))
708 ))))
709
710;;; SPEEDBAR SUPPORT 601;;; SPEEDBAR SUPPORT
711;; 602;;
712 603
@@ -796,7 +687,7 @@ Argument INDENT is the depth of indentation."
796 "Describe the class TEXT in TOKEN. 687 "Describe the class TEXT in TOKEN.
797INDENT is the current indentation level." 688INDENT is the current indentation level."
798 (dframe-with-attached-buffer 689 (dframe-with-attached-buffer
799 (eieio-describe-class token)) 690 (describe-function token))
800 (dframe-maybee-jump-to-attached-frame)) 691 (dframe-maybee-jump-to-attached-frame))
801 692
802(provide 'eieio-opt) 693(provide 'eieio-opt)
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index 3b1ba003d94..4d572601243 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -865,6 +865,10 @@ This may create or delete slots, but does not affect the return value
865of `eq'." 865of `eq'."
866 (error "EIEIO: `change-class' is unimplemented")) 866 (error "EIEIO: `change-class' is unimplemented"))
867 867
868;; Hook ourselves into help system for describing classes and methods.
869(add-hook 'help-fns-describe-function-functions 'eieio-help-generic)
870(add-hook 'help-fns-describe-function-functions 'eieio-help-constructor)
871
868;;; Interfacing with edebug 872;;; Interfacing with edebug
869;; 873;;
870(defun eieio-edebug-prin1-to-string (object &optional noescape) 874(defun eieio-edebug-prin1-to-string (object &optional noescape)
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 7b9e1783bad..2252c700fea 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -32,6 +32,12 @@
32 32
33;;; Code: 33;;; Code:
34 34
35(defvar help-fns-describe-function-functions nil
36 "List of functions to run in help buffer in `describe-function'.
37Those functions will be run after the header line and argument
38list was inserted, and before the documentation will be inserted.
39The functions will receive the function name as argument.")
40
35;; Functions 41;; Functions
36 42
37;;;###autoload 43;;;###autoload
@@ -649,14 +655,15 @@ FILE is the file where FUNCTION was probably defined."
649 (help-fns--key-bindings function) 655 (help-fns--key-bindings function)
650 (with-current-buffer standard-output 656 (with-current-buffer standard-output
651 (setq doc (help-fns--signature function doc real-def real-function)) 657 (setq doc (help-fns--signature function doc real-def real-function))
652 658 (run-hook-with-args 'help-fns-describe-function-functions function)
653 (help-fns--compiler-macro function)
654 (help-fns--parent-mode function)
655 (help-fns--obsolete function)
656
657 (insert "\n" 659 (insert "\n"
658 (or doc "Not documented."))))))) 660 (or doc "Not documented.")))))))
659 661
662;; Add defaults to `help-fns-describe-function-functions'.
663(add-hook 'help-fns-describe-function-functions 'help-fns--obsolete)
664(add-hook 'help-fns-describe-function-functions 'help-fns--parent-mode)
665(add-hook 'help-fns-describe-function-functions 'help-fns--compiler-macro)
666
660 667
661;; Variables 668;; Variables
662 669