home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-11-05 | 22.3 KB | 487 lines | [TEXT/CCL ] |
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;apropos-smart.Lisp
- ;;
- ;;copyright 1987, Coral Software Corp
- ;;
- ;; This file implements the fancy apropos dialog which was included in
- ;; Allegro CL version 1.0.
- ;;
- ;; If you prefer the fancy apropos dialog, load this file. The action of
- ;; the Apropos… menu-item will be changed.
- ;;
- ;;
-
- (defun apropos-smart (&key (string "")
- (packages :dont-care) (first-characters :dont-care)
- (binding-types :dont-care) (and-fn-var? nil)
- (symbol-types '(:internal :inherited :external))
- (upper-case-string? nil)
- (print-incrementally? nil) (return-list? t)
- &aux result constant? variable? function? macro? special-form?
- not-bound? not-fbound? first-char
- sym-name)
- "If return-list? is NIL, but apropos-smart finds some symbols, return T.
- Thus apropos-smart returns NIL only if it finds no symbols."
- (if (eq packages :dont-care)
- (setq packages (list-all-packages)))
- (if upper-case-string?
- (setq string (string-upcase string)))
- (cond ((not (eq binding-types :dont-care))
- (if (memq :variable binding-types)
- (setq variable? t))
- (if (memq :constant binding-types)
- (setq constant? t))
- (if (memq :not-bound binding-types)
- (setq not-bound? t))
-
- (if (memq :function binding-types)
- (setq function? t))
- (if (memq :macro binding-types)
- (setq macro? t))
- (if (memq :special-form binding-types)
- (setq special-form? t))
- (if (memq :not-fbound binding-types)
- (setq not-fbound? t))
- ))
- (dolist (package packages)
- (do-symbols (sym package)
- (setq sym-name (symbol-name sym))
- (if (and (ccl::%apropos-substring-p string sym-name)
- (or (eq binding-types :dont-care) ;includes unbound
- (and (not and-fn-var?) ;or everything
- (or
- (and function? (fboundp sym)
- (not (special-form-p sym))
- (not (macro-function sym)))
- (and macro? (macro-function sym))
- (and special-form? (special-form-p sym))
- (and not-fbound? (not (fboundp sym)))
-
- (and variable? (boundp sym) (not (constantp sym)))
- (and constant? (constantp sym))
- (and not-bound? (not (boundp sym)))
- ))
- (and (or
- (and function? (fboundp sym) (not (special-form-p sym))
- (not (macro-function sym)))
- (and macro? (macro-function sym))
- (and special-form? (special-form-p sym))
- (and not-fbound? (not (fboundp sym)))
- )
- (or
- (and variable? (boundp sym) (not (constantp sym)))
- (and constant? (constantp sym))
- (and not-bound? (not (boundp sym)))
- )
- ))
- (multiple-value-bind (ignore sym-type)
- (find-symbol sym-name package)
- (memq sym-type symbol-types))
-
- (or (eq first-characters :dont-care)
- (progn
- (setq first-char (if (> (length sym-name) 0)
- (aref (symbol-name sym) 0)))
- (cond (first-char ;watch out for "" name.
- (cond ((and (alpha-char-p first-char)
- (upper-case-p first-char))
- (setq first-char 'upper-alpha))
- ((not (memq first-char
- '(#\_ #\% #\* #\&)))
- (setq first-char 'other)))
- (memq first-char first-characters)))))
- )
- (progn
- (if return-list?
- (push sym result))
- (if print-incrementally?
- (progn (apropos-smart-symbol-print sym)
- (setq result t)))
- )
- )))
- (if (eq result t)
- (format t "? ")
- )
- result)
-
- (defun apropos-smart-symbol-print (sym)
- (format t "~S " sym)
- (if (boundp sym)
- (cond ((constantp sym)
- (format t "constant value: ~S" (eval sym)))
- (t (format t "value: ~S" (eval sym)))))
- (cond ((special-form-p sym)
- (format t "special form"))
- ((macro-function sym)
- (format t "macro"))
- ((fboundp sym)
- (format t "function")))
- (terpri))
-
-
- (defvar %apropos-smart-dialog)
-
- (setq %apropos-smart-dialog
- (let* ((the-dialog (oneof *dialog*
- :window-title "Apropos"
- :window-show nil
- :window-position #@(8 26)
- :window-size #@(366 309)
- :procid 1
- )))
- (ask the-dialog (add-dialog-items
- (oneof
- *static-text-dialog-item*
- :dialog-item-text "Apropos"
- :dialog-item-position #@(142 -1)
- :dialog-item-size #@(59 16))
- (oneof
- *static-text-dialog-item*
- :dialog-item-text "Value Binding Types"
- :dialog-item-position #@(3 15)
- :dialog-item-size #@(133 16))
- (have 'unbound-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "unbound"
- :Dialog-item-position #@(19 69)
- :dialog-item-size #@(76 16)
- :check-box-checked-p nil))
- (have 'variable-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "variable"
- :dialog-item-position #@(19 34)
- :dialog-item-size #@(81 16)
- :check-box-checked-p t))
- (have 'constant-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "constant"
- :dialog-item-position #@(19 52)
- :dialog-item-size #@(85 16)
- :check-box-checked-p t))
- (have 'and-item
- (oneof
- *radio-button-dialog-item*
- :dialog-item-text "and"
- :dialog-item-position #@(3 95)
- :dialog-item-size #@(44 16)
- :radio-button-cluster 'and-or
- :radio-button-pushed-p nil))
- (have 'or-item
- (oneof
- *radio-button-dialog-item*
- :dialog-item-text "or"
- :dialog-item-position #@(59 94)
- :dialog-item-size #@(34 16)
- :radio-button-cluster 'and-or
- :radio-button-pushed-p t))
- (oneof
- *static-text-dialog-item*
- :dialog-item-text "Function Binding Types"
- :dialog-item-position #@(3 117)
- :dialog-item-size #@(153 16))
- (have 'function-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "function"
- :dialog-item-position #@(20 135)
- :dialog-item-size #@(75 16)
- :check-box-checked-p t))
- (have 'macro-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "macro"
- :dialog-item-position #@(20 154)
- :dialog-item-size #@(61 16)
- :check-box-checked-p t))
- (have 'special-form-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text
- "special form"
- :dialog-item-position #@(20 173)
- :dialog-item-size #@(102 16)
- :check-box-checked-p t))
- (have 'unfbound-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "unfbound"
- :dialog-item-position #@(20 193)
- :dialog-item-size #@(82 16)
- :check-box-checked-p nil))
- (oneof
- *static-text-dialog-item*
- :dialog-item-text "Substring"
- :dialog-item-position #@(7 220)
- :dialog-item-size #@(66 16))
- (have 'substring-item
- (oneof
- *editable-text-dialog-item*
- :dialog-item-text ""
- :dialog-item-position #@(8 239)
- :dialog-item-size #@(164 16)
- :allow-returns nil))
- (have 'upper-case-substring-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "upper-case substring"
- :dialog-item-position #@(4 262)
- :dialog-item-size #@(164 16)
- :check-box-checked-p t))
- (have 'the-default-button
- (oneof
- *button-dialog-item*
- :dialog-item-text "OK"
- :dialog-item-position #@(250 286)
- :dialog-item-size #@(46 17)
- :dialog-item-action
- '(return-from-modal-dialog t)))
- (oneof
- *button-dialog-item*
- :dialog-item-text "Cancel"
- :dialog-item-position #@(307 288)
- :dialog-item-size #@(53 16)
- :dialog-item-action
- '(return-from-modal-dialog nil))
- (have '&-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "&"
- :dialog-item-position #@(225 239)
- :dialog-item-size #@(30 16)
- :check-box-checked-p t))
- (have '_-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "_"
- :dialog-item-position #@(226 259)
- :dialog-item-size #@(28 16)
- :check-box-checked-p t))
- (have '*-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "*"
- :dialog-item-position #@(192 239)
- :dialog-item-size #@(27 16)
- :check-box-checked-p t))
- (have '%-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "%"
- :dialog-item-position #@(192 259)
- :dialog-item-size #@(31 16)
- :check-box-checked-p t))
- (have 'upper-alphas-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "upper-alphas"
- :dialog-item-position #@(260 239)
- :dialog-item-size #@(108 16)
- :check-box-checked-p t))
- (have 'others-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "others"
- :dialog-item-position #@(260 259)
- :dialog-item-size #@(63 16)
- :check-box-checked-p t))
- (oneof
- *static-text-dialog-item*
- :dialog-item-text "First Character"
- :dialog-item-position #@(200 220)
- :dialog-item-size #@(103 16))
- (oneof
- *static-text-dialog-item*
- :dialog-item-text "Packages"
- :dialog-item-position #@(224 15)
- :dialog-item-size #@(82 16))
- (have 'inherited-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "inherited"
- :dialog-item-position #@(221 150)
- :dialog-item-size #@(80 16)
- :check-box-checked-p nil)) ;if not nil and you
- ;have lots of pkgs selected, you'll get duplications in the
- ;output symbols, which take too much time to remove
- (have 'internal-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "internal"
- :dialog-item-position #@(221 171)
- :dialog-item-size #@(72 16)
- :check-box-checked-p t))
- (have 'external-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "external"
- :dialog-item-position #@(221 192)
- :dialog-item-size #@(76 16)
- :check-box-checked-p t))
- (have 'sort-output-item
- (oneof
- *check-box-dialog-item*
- :dialog-item-text "sort output"
- :dialog-item-position #@(3 286)
- :dialog-item-size #@(95 16)
- :check-box-checked-p nil))
- (have 'print-item
- (oneof
- *radio-button-dialog-item*
- :dialog-item-text "print"
- :dialog-item-position #@(108 286)
- :dialog-item-size #@(52 16)
- :radio-button-cluster 'output
- :radio-button-pushed-p t))
- (have 'inspect-item
- (oneof
- *radio-button-dialog-item*
- :dialog-item-text "inspect"
- :dialog-item-position #@(164 286)
- :dialog-item-size #@(68 16)
- :radio-button-cluster 'output
- :radio-button-pushed-p nil))
- (have 'packages-item
- (oneof
- *sequence-dialog-item*
- :table-sequence
- (mapcar #'package-name (list-all-packages))
- :dialog-item-position #@(224 33)
- :dialog-item-size #@(130 111)
- :selection-type :disjoint
- :cell-size #@(115 16)))
- ))
- (ask the-dialog
- (set-default-button the-default-button))
- (dotimes (i (length (list-all-packages)))
- (ask (ask the-dialog packages-item)
- (cell-select (make-point 0 i))))
- the-dialog))
-
- (defobfun (window-show %apropos-smart-dialog) ()
- (declare (object-variable packages-item))
- (ask packages-item
- (set-table-sequence (mapcar #'package-name (list-all-packages))))
- (usual-window-show))
-
-
- (defun apropos-smart-dialog (&aux (asd %apropos-smart-dialog) selection
- the-substring
- pkg-item packages first-chars binding-types
- symbol-types print? sort? result-symbols)
- (declare (object-variable substring-item packages-item &-item _-item *-item
- %-item upper-alphas-item others-item variable-item
- constant-item unbound-item function-item macro-item
- special-form-item unfbound-item inherited-item
- internal-item external-item print-item
- sort-output-item and-item
- upper-case-substring-item))
- (setq selection (if (typep (front-window) *fred-window*)
- (ask (front-window) (get-selected-string))))
- (if selection (ask (ask asd substring-item) (set-dialog-item-text selection)))
- (cond ((modal-dialog asd nil) ;user didn't cancel out of dialog
- (setq the-substring (ask (ask asd substring-item)
- (dialog-item-text)))
- (setq pkg-item (ask asd packages-item))
- (setq packages (ask pkg-item
- (mapcar #'cell-contents (selected-cells))))
- (if (ask (ask asd &-item)
- (check-box-checked-p))
- (push #\& first-chars))
- (if (ask (ask asd _-item)
- (check-box-checked-p))
- (push #\_ first-chars))
- (if (ask (ask asd *-item)
- (check-box-checked-p))
- (push #\* first-chars))
- (if (ask (ask asd %-item)
- (check-box-checked-p))
- (push #\% first-chars))
- (if (ask (ask asd upper-alphas-item)
- (check-box-checked-p))
- (push 'upper-alpha first-chars))
- (if (ask (ask asd others-item)
- (check-box-checked-p))
- (push 'other first-chars))
- (if (ask (ask asd variable-item)
- (check-box-checked-p))
- (push :variable binding-types))
- (if (ask (ask asd constant-item)
- (check-box-checked-p))
- (push :constant binding-types))
- (if (ask (ask asd unbound-item)
- (check-box-checked-p))
- (push :not-bound binding-types))
- (if (ask (ask asd function-item)
- (check-box-checked-p))
- (push :function binding-types))
- (if (ask (ask asd macro-item)
- (check-box-checked-p))
- (push :macro binding-types))
- (if (ask (ask asd special-form-item)
- (check-box-checked-p))
- (push :special-form binding-types))
- (if (ask (ask asd unfbound-item)
- (check-box-checked-p))
- (push :not-fbound binding-types))
- (if (ask (ask asd inherited-item)
- (check-box-checked-p))
- (push :inherited symbol-types))
- (if (ask (ask asd internal-item)
- (check-box-checked-p))
- (push :internal symbol-types))
- (if (ask (ask asd external-item)
- (check-box-checked-p))
- (push :external symbol-types))
- (setq print? (ask (ask asd print-item)
- (radio-button-pushed-p)))
- (setq sort? (ask (ask asd sort-output-item)
- (check-box-checked-p)))
- (setq result-symbols
- (apropos-smart
- :string the-substring
- :packages packages
- :first-characters first-chars
- :binding-types binding-types
- :and-fn-var? (ask (ask asd and-item)
- (radio-button-pushed-p))
- :symbol-types symbol-types
- :upper-case-string? (ask (ask asd upper-case-substring-item)
- (check-box-checked-p))
- :print-incrementally? (and print? (not sort?))
- :return-list? (or sort? (not print?))
- )) ;returns NIL, T or a list of symbols
- (cond ((eq result-symbols t) ;symbols were found and printed
- )
- ((eq result-symbols nil) ; no symbols found
- (message-dialog "No symbols match the APROPOS pattern."))
- (t ;got some symbols that need to be output
- (if sort?
- (setq result-symbols
- (sort result-symbols #'string< :key #'symbol-name)))
- (if print? ;must not have been previously printed,
- ;presumably because they needed sorting.
- (progn
- (mapcar #'apropos-smart-symbol-print result-symbols)
- (format t "? ")
- )
- (inspect result-symbols))
- ))
- )))
-
- (let ((apropos-menu-item (ask *tools-menu* (find-menu-item "Apropos…"))))
- (if apropos-menu-item
- (defobfun (menu-item-action apropos-menu-item) ()
- (apropos-smart-dialog))
- (ask *tools-menu* (add-menu-items
- (oneof *menu-item*
- :menu-item-title "-")
- (oneof *menu-item*
- :menu-item-title "Apropos Smart…"
- :menu-item-action #'apropos-smart-dialog)))))
-
-
- (provide 'apropos-smart)
- (pushnew :apropos-smart *features*)