89e3404cd981a43eae534a47d2804d4d192de872
[jscl.git] / src / documentation.lisp
1 ;;; documentation.lisp --- Accessing DOCUMENTATION
2
3 ;;; Documentation.
4 (defun documentation (x type)
5   "Return the documentation of X. TYPE must be the symbol VARIABLE or FUNCTION."
6   (ecase type
7     (function
8      (let ((func (fdefinition x)))
9        (oget func "docstring")))
10     (variable
11      (unless (symbolp x)
12        (error "The type of documentation `~S' is not a symbol." type))
13      (oget x "vardoc"))))
14
15
16 ;;; APROPOS and friends
17
18 (defun map-apropos-symbols (function string package external-only)
19   (flet ((handle-symbol (symbol)
20            ;; TODO: it's implementation-dependent, though CHAR-EQUAL seems
21            ;; more reasonable nevertheless
22            (when (search string (symbol-name symbol) :test #'char=)
23              (funcall function symbol))))
24     (if package
25         (if external-only
26             (do-external-symbols (symbol package) (handle-symbol symbol))
27             (do-symbols (symbol package) (handle-symbol symbol)))
28         (if external-only
29             (do-all-external-symbols (symbol) (handle-symbol symbol))
30             (do-all-symbols (symbol) (handle-symbol symbol))))))
31
32 (defun apropos-list (string &optional package external-only)
33   (let (symbols)
34     (map-apropos-symbols
35      (lambda (symbol)
36        (pushnew symbol symbols :test #'eq))
37      string package external-only)
38     symbols))
39
40 (defun apropos (string &optional package external-only)
41   (map-apropos-symbols
42    (lambda (symbol)
43      (format t "~S" symbol)
44      (when (boundp symbol)
45        (format t " (bound)"))
46      (when (fboundp symbol)
47        (format t " (fbound)"))
48      (terpri))
49    string package external-only))
50
51 ;;; DESCRIBE
52
53 ;; TODO: this needs DESCRIBE-OBJECT as generic method
54 ;; TODO: indentation for nested paragraphs
55 (defun describe (object &optional stream)
56   (declare (ignore stream))
57   (typecase object
58     (cons
59      (format t "~S~%  [cons]~%" object))
60     (integer
61      (format t "~S~%  [integer]~%" object))
62     (symbol
63      (format t "~S~%  [symbol]~%" object)
64      (when (boundp object)
65        (format t "~%~A names a special variable:~%  Value: ~A~%"
66                object (symbol-value object))
67        (let ((documentation (documentation object 'variable)))
68          (when documentation
69            (format t "  Documentation:~%~A~%" documentation))))
70      (when (fboundp object)
71        (format t "~%~A names a function:~%" object)
72        (let ((documentation (documentation object 'function)))
73          (when documentation
74            (format t "  Documentation:~%~A~%" documentation)))))
75     (string
76      (format t "~S~%  [string]~%~%Length: ~D~%"
77              object (length object)))
78     (float
79      (format t "~S~%  [float]~%" object))
80     (array
81      (format t "~S~%  [array]~%" object))
82     (function
83      (format t "~S~%  [function]~%" object)
84      (let ((documentation (documentation object 'function)))
85        (when documentation
86          (format t "  Documentation:~%~A~%" documentation))))
87     (T
88      (warn "~A not implemented yet for ~A" 'describe object)))
89   (values))