;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
;;; Commentary:
;;; Code:
+(defgroup apropos nil
+ "Apropos commands for users and programmers"
+ :group 'Help
+ :prefix "apropos")
+
;; I see a degradation of maybe 10-20% only.
-(defvar apropos-do-all nil
+(defcustom apropos-do-all nil
"*Whether the apropos commands should do more.
-Slows them down more or less. Set this non-nil if you have a fast machine.")
+
+Slows them down more or less. Set this non-nil if you have a fast machine."
+ :group 'apropos
+ :type 'boolean)
-(defvar apropos-symbol-face (if window-system 'bold)
- "*Face for symbol name in apropos output or `nil'.
-This looks good, but slows down the commands several times.")
+(defcustom apropos-symbol-face (if window-system 'bold)
+ "*Face for symbol name in apropos output or `nil'.
+This looks good, but slows down the commands several times."
+ :group 'apropos
+ :type 'face)
-(defvar apropos-keybinding-face (if window-system 'underline)
+(defcustom apropos-keybinding-face (if window-system 'underline)
"*Face for keybinding display in apropos output or `nil'.
-This looks good, but slows down the commands several times.")
+This looks good, but slows down the commands several times."
+ :group 'apropos
+ :type 'face)
-(defvar apropos-label-face (if window-system 'italic)
+(defcustom apropos-label-face (if window-system 'italic)
"*Face for label (Command, Variable ...) in apropos output or `nil'.
If this is `nil' no mouse highlighting occurs.
This looks good, but slows down the commands several times.
When this is a face name, as it is initially, it gets transformed to a
-text-property list for efficiency.")
+text-property list for efficiency."
+ :group 'apropos
+ :type 'face)
-(defvar apropos-property-face (if window-system 'bold-italic)
+(defcustom apropos-property-face (if window-system 'bold-italic)
"*Face for property name in apropos output or `nil'.
-This looks good, but slows down the commands several times.")
+This looks good, but slows down the commands several times."
+ :group 'apropos
+ :type 'face)
-(defvar apropos-match-face (if window-system 'secondary-selection)
+(defcustom apropos-match-face (if window-system 'secondary-selection)
"*Face for matching part in apropos-documentation/value output or `nil'.
-This looks good, but slows down the commands several times.")
+This looks good, but slows down the commands several times."
+ :group 'apropos
+ :type 'face)
(defvar apropos-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-m" 'apropos-follow)
+ (define-key map " " 'scroll-up)
+ (define-key map "\177" 'scroll-down)
(define-key map [mouse-2] 'apropos-mouse-follow)
(define-key map [down-mouse-2] nil)
map)
(setq major-mode 'apropos-mode
mode-name "Apropos"))
+;;;###autoload
+(defun apropos-variable (regexp)
+ (interactive (list (read-string "Apropos variable (regexp): ")))
+ (apropos-command regexp nil t))
;; For auld lang syne:
;;;###autoload
(fset 'command-apropos 'apropos-command)
;;;###autoload
-(defun apropos-command (apropos-regexp &optional do-all)
- "Shows commands (interactively callable functions) that match REGEXP.
-With optional prefix ARG or if `apropos-do-all' is non-nil, also show
-variables."
- (interactive (list (read-string (concat "Apropos command "
- (if (or current-prefix-arg
- apropos-do-all)
- "or variable ")
- "(regexp): "))
+(defun apropos-command (apropos-regexp &optional do-all just-vars)
+ "Show commands (interactively callable functions) that match REGEXP.
+With optional prefix ARG, or if `apropos-do-all' is non-nil, also show
+variables. If JUST-VARS is non-nil, show only variables."
+ (interactive (list (read-string (concat
+ "Apropos command "
+ (if (or current-prefix-arg
+ apropos-do-all)
+ "or variable ")
+ "(regexp): "))
current-prefix-arg))
(let ((message
(let ((standard-output (get-buffer-create "*Apropos*")))
(if do-all
(lambda (symbol) (or (commandp symbol)
(user-variable-p symbol)))
- 'commandp)))
+ (if just-vars 'user-variable-p
+ 'commandp))))
+ (let ((tem apropos-accumulator))
+ (while tem
+ (if (get (car tem) 'apropos-inhibit)
+ (setq apropos-accumulator (delq (car tem) apropos-accumulator)))
+ (setq tem (cdr tem))))
(if (apropos-print
t
(lambda (p)
(while p
(setcar p (list
(setq symbol (car p))
- (if (commandp symbol)
- (if (setq doc (documentation symbol t))
- (substring doc 0 (string-match "\n" doc))
- "(not documented)"))
+ (if (or do-all (not just-vars))
+ (if (commandp symbol)
+ (if (setq doc (documentation symbol t))
+ (substring doc 0 (string-match "\n" doc))
+ "(not documented)")))
(and do-all
(user-variable-p symbol)
(if (setq doc (documentation-property
(lambda (symbol)
(or (fboundp symbol)
(boundp symbol)
+ (facep symbol)
(symbol-plist symbol))))))
+ (let ((tem apropos-accumulator))
+ (while tem
+ (if (get (car tem) 'apropos-inhibit)
+ (setq apropos-accumulator (delq (car tem) apropos-accumulator)))
+ (setq tem (cdr tem))))
(apropos-print
(or do-all apropos-do-all)
(lambda (p)
- (let (symbol doc)
+ (let (symbol doc properties)
(while p
(setcar p (list
(setq symbol (car p))
- (if (fboundp symbol)
- (if (setq doc (documentation symbol t))
- (substring doc 0 (string-match "\n" doc))
- "(not documented)"))
- (if (boundp symbol)
- (if (setq doc (documentation-property
- symbol 'variable-documentation t))
- (substring doc 0
- (string-match "\n" doc))
- "(not documented)"))
- (if (setq doc (symbol-plist symbol))
- (if (eq (/ (length doc) 2) 1)
- (format "1 property (%s)" (car doc))
- (concat (/ (length doc) 2) " properties")))))
+ (when (fboundp symbol)
+ (if (setq doc (documentation symbol t))
+ (substring doc 0 (string-match "\n" doc))
+ "(not documented)"))
+ (when (boundp symbol)
+ (if (setq doc (documentation-property
+ symbol 'variable-documentation t))
+ (substring doc 0 (string-match "\n" doc))
+ "(not documented)"))
+ (when (setq properties (symbol-plist symbol))
+ (setq doc (list (car properties)))
+ (while (setq properties (cdr (cdr properties)))
+ (setq doc (cons (car properties) doc)))
+ (mapconcat #'symbol-name (nreverse doc) " "))
+ (when (get symbol 'widget-type)
+ (if (setq doc (documentation-property
+ symbol 'widget-documentation t))
+ (substring doc 0
+ (string-match "\n" doc))
+ "(not documented)"))
+ (when (facep symbol)
+ (if (setq doc (documentation-property
+ symbol 'face-documentation t))
+ (substring doc 0
+ (string-match "\n" doc))
+ "(not documented)"))
+ (when (get symbol 'custom-group)
+ (if (setq doc (documentation-property
+ symbol 'group-documentation t))
+ (substring doc 0
+ (string-match "\n" doc))
+ "(not documented)"))))
(setq p (cdr p)))))
nil))
(set-buffer standard-output)
(apropos-mode)
(if window-system
- (insert (substitute-command-keys
- "If you move the mouse over text that changes color,\n"
+ (insert "If you move the mouse over text that changes color,\n"
+ (substitute-command-keys
"you can click \\[apropos-mouse-follow] to get more information.\n")))
(insert (substitute-command-keys
"In this buffer, type \\[apropos-follow] to get full documentation.\n\n"))
point1 (point))
(princ symbol) ; print symbol name
(setq point2 (point))
- ;; don't calculate key-bindings unless needed
+ ;; Calculate key-bindings if we want them.
(and do-keys
(commandp symbol)
(indent-to 30 1)
- (insert
- (if (setq item (save-excursion
- (set-buffer old-buffer)
- (where-is-internal symbol)))
+ (if (let ((keys
+ (save-excursion
+ (set-buffer old-buffer)
+ (where-is-internal symbol)))
+ filtered)
+ ;; Copy over the list of key sequences,
+ ;; omitting any that contain a buffer or a frame.
+ (while keys
+ (let ((key (car keys))
+ (i 0)
+ loser)
+ (while (< i (length key))
+ (if (or (framep (aref key i))
+ (bufferp (aref key i)))
+ (setq loser t))
+ (setq i (1+ i)))
+ (or loser
+ (setq filtered (cons key filtered))))
+ (setq keys (cdr keys)))
+ (setq item filtered))
+ ;; Convert the remaining keys to a string and insert.
+ (insert
(mapconcat
- (if apropos-keybinding-face
- (lambda (key)
- (setq key (key-description key))
+ (lambda (key)
+ (setq key (key-description key))
+ (if apropos-keybinding-face
(put-text-property 0 (length key)
'face apropos-keybinding-face
- key)
- key)
- 'key-description)
- item ", ")
- "(not bound to any keys)")))
+ key))
+ key)
+ item ", "))
+ (insert "M-x")
+ (put-text-property (- (point) 3) (point)
+ 'face apropos-keybinding-face)
+ (insert " " (symbol-name symbol) " ")
+ (insert "RET")
+ (put-text-property (- (point) 3) (point)
+ 'face apropos-keybinding-face)))
(terpri)
;; only now so we don't propagate text attributes all over
(put-text-property point1 point2 'item
(if (apropos-macrop symbol)
"Macro"
"Function"))
- do-keys)
- (apropos-print-doc 'describe-variable 2
- "Variable" do-keys)
+ t)
+ (if (get symbol 'custom-type)
+ (apropos-print-doc 'customize-variable-other-window 2
+ "User Option" t)
+ (apropos-print-doc 'describe-variable 2
+ "Variable" t))
+ (apropos-print-doc 'customize-group-other-window 6 "Group" t)
+ (apropos-print-doc 'customize-face-other-window 5 "Face" t)
+ (apropos-print-doc 'widget-browse-other-window 4 "Widget" t)
(apropos-print-doc 'apropos-describe-plist 3
"Plist" nil)))))
(prog1 apropos-accumulator
(princ ")")
(print-help-return-message)))
+(provide 'apropos)
+
;;; apropos.el ends here