Merge branch 'lisp-repl'
[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            (when (search string (symbol-name symbol) :test #'char-equal)
21              (funcall function symbol))))
22     (if package
23         (if external-only
24             (do-external-symbols (symbol package) (handle-symbol symbol))
25             (do-symbols (symbol package) (handle-symbol symbol)))
26         (if external-only
27             (do-all-external-symbols (symbol) (handle-symbol symbol))
28             (do-all-symbols (symbol) (handle-symbol symbol))))))
29
30 (defun apropos-list (string &optional package external-only)
31   (let (symbols)
32     (map-apropos-symbols
33      (lambda (symbol)
34        (pushnew symbol symbols :test #'eq))
35      string package external-only)
36     symbols))
37
38 (defun apropos (string &optional package external-only)
39   (map-apropos-symbols
40    (lambda (symbol)
41      (format t "~S" symbol)
42      (when (boundp symbol)
43        (format t " (bound)"))
44      (when (fboundp symbol)
45        (format t " (fbound)"))
46      (terpri))
47    (string string) package external-only))
48
49 ;;; DESCRIBE
50
51 ;; TODO: this needs DESCRIBE-OBJECT as generic method
52 ;; TODO: indentation for nested paragraphs
53 (defun describe (object &optional stream)
54   (declare (ignore stream))
55   (typecase object
56     (cons
57      (format t "~S~%  [cons]~%" object))
58     (integer
59      (format t "~S~%  [integer]~%" object))
60     (symbol
61      (format t "~S~%  [symbol]~%" object)
62      (when (boundp object)
63        (format t "~%~A names a special variable:~%  Value: ~A~%"
64                object (symbol-value object))
65        (let ((documentation (documentation object 'variable)))
66          (when documentation
67            (format t "  Documentation:~%~A~%" documentation))))
68      (when (fboundp object)
69        (format t "~%~A names a function:~%" object)
70        (let ((documentation (documentation object 'function)))
71          (when documentation
72            (format t "  Documentation:~%~A~%" documentation)))))
73     (string
74      (format t "~S~%  [string]~%~%Length: ~D~%"
75              object (length object)))
76     (float
77      (format t "~S~%  [float]~%" object))
78     (array
79      (format t "~S~%  [array]~%" object))
80     (function
81      (format t "~S~%  [function]~%" object)
82      (let ((documentation (documentation object 'function)))
83        (when documentation
84          (format t "  Documentation:~%~A~%" documentation))))
85     (T
86      (warn "~A not implemented yet for ~A" 'describe object)))
87   (values))