Mercurial > hg > xemacs-beta
diff lisp/packages/hyper-apropos.el @ 30:ec9a17fef872 r19-15b98
Import from CVS: tag r19-15b98
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:52:29 +0200 |
parents | 0293115a14e9 |
children | 8d2a9b52c682 |
line wrap: on
line diff
--- a/lisp/packages/hyper-apropos.el Mon Aug 13 08:51:58 2007 +0200 +++ b/lisp/packages/hyper-apropos.el Mon Aug 13 08:52:29 2007 +0200 @@ -54,6 +54,7 @@ ;; additions by Ben Wing <wing@666.com> July 1995: ;; added support for function aliases, made programmer's apropos be the ;; default, various other hacking. +;; Massive changes by Christoph Wedler <wedler@fmi.uni-passau.de> ;;; Code: @@ -67,6 +68,9 @@ "*If non-nil, `hyper-apropos' will display some documentation in the \"*Hyper Apropos*\" buffer. Setting this to nil will speed up searches.") +(defvar hypropos-shrink-window nil + "*If non-nil, shrink *Hyper Help* buffer if possible.") + (defvar hypropos-prettyprint-long-values t "*If non-nil, then try to beautify the printing of very long values.") @@ -77,6 +81,7 @@ output. If nil, then only functions that are interactive and variables that are user variables are found by `hyper-apropos'.") +(defvar hypropos-ref-buffer) (defvar hypropos-prev-wconfig) ;; #### - move this to subr.el @@ -174,7 +179,7 @@ (defvar hypropos-map (let ((map (make-sparse-keymap))) (set-keymap-name map 'hypropos-map) (set-keymap-parents map (list hypropos-help-map)) - ;; slightly differrent scrolling... + ;; slightly different scrolling... (define-key map " " 'hypropos-scroll-up) (define-key map "b" 'hypropos-scroll-down) ;; act on the current line... @@ -201,6 +206,10 @@ (defvar hypropos-currently-showing nil) ; symbol documented in help buffer now (defvar hypropos-help-history nil) ; chain of symbols followed as links in ; help buffer +(defvar hypropos-face-history nil) +;;;(defvar hypropos-variable-history nil) +;;;(defvar hypropos-function-history nil) +(defvar hypropos-regexp-history nil) (defvar hypropos-last-regexp nil) ; regex used for last apropos (defconst hypropos-apropos-buf "*Hyper Apropos*") (defconst hypropos-help-buf "*Hyper Help*") @@ -211,7 +220,9 @@ in buffer \"*Hyper Apropos*\". If optional prefix arg is given, then the value of `hypropos-programming-apropos' is toggled for this search. See also `hyper-apropos-mode'." - (interactive "sList symbols matching regexp: \nP") + (interactive (list (read-from-minibuffer "List symbols matching regexp: " + nil nil nil 'hypropos-regexp-history) + current-prefix-arg)) (or (memq major-mode '(hyper-apropos-mode hyper-help-mode)) (setq hypropos-prev-wconfig (current-window-configuration))) (if (string= "" regexp) @@ -255,7 +266,7 @@ (hyper-apropos hypropos-last-regexp nil)) (defun hypropos-grok-functions (fns) - (let (fn bind type) + (let (fn bind doc type) (while (setq fn (car fns)) (setq bind (symbol-function fn) type (cond ((subrp bind) ?i) @@ -269,36 +280,30 @@ (insert type (if (commandp fn) "* " " ")) (insert-face (format "%-30S" fn) 'hyperlink) (and hypropos-show-brief-docs - (if (function-obsolete-p fn) - (insert-face " - Obsolete." 'documentation) - (let ((doc (documentation fn))) - (if (not doc) - (insert-face " - Not documented." 'documentation) - (insert-face (concat " - " - (substring doc 0 - (string-match "\n" doc))) - 'documentation))))) + (setq doc (documentation fn)) + (insert-face (if doc + (concat " - " + (substring doc 0 (string-match "\n" doc))) + " Not documented.") + 'documentation)) (insert ?\n) (setq fns (cdr fns)) ))) (defun hypropos-grok-variables (vars) - (let (var userp) + (let (var doc userp) (while (setq var (car vars)) (setq userp (user-variable-p var) vars (cdr vars)) (insert (if userp " * " " ")) (insert-face (format "%-30S" var) 'hyperlink) (and hypropos-show-brief-docs - (if (variable-obsolete-p var) - (insert-face " - Obsolete." 'documentation) - (let ((doc (documentation-property var 'variable-documentation))) - (if (not doc) - (insert-face " - Not documented." 'documentation) - (insert-face (concat " - " - (substring doc (if userp 1 0) - (string-match "\n" doc))) - 'documentation))))) + (setq doc (documentation-property var 'variable-documentation)) + (insert-face (if doc + (concat " - " (substring doc (if userp 1 0) + (string-match "\n" doc))) + " - Not documented.") + 'documentation)) (insert ?\n) ))) @@ -345,66 +350,258 @@ ;; ---------------------------------------------------------------------- ;; +;; similar to `describe-key-briefly', copied from prim/help.el by CW + ;;;###autoload -(defun hyper-describe-variable (symbol) - "Hypertext drop-in replacement for `describe-variable'. +(defun hyper-describe-key (key) + (interactive "kDescribe key: ") + (hyper-describe-key-briefly key t)) + +;;;###autoload +(defun hyper-describe-key-briefly (key &optional show) + (interactive "kDescribe key briefly: \nP") + (let (menup defn interm final msg) + (setq defn (key-or-menu-binding key 'menup)) + (if (or (null defn) (integerp defn)) + (or (numberp show) (message "%s is undefined" (key-description key))) + (cond ((stringp defn) + (setq interm defn + final (key-binding defn))) + ((vectorp defn) + (setq interm (append defn nil)) + (while (and interm + (member (key-binding (vector (car interm))) + '(universal-argument digit-argument))) + (setq interm (cdr interm))) + (while (and interm + (not (setq final (key-binding (vconcat interm))))) + (setq interm (butlast interm))) + (if final + (setq interm (vconcat interm)) + (setq interm defn + final (key-binding defn))))) + (setq msg (format + "%s runs %s%s%s" + ;; This used to say 'This menu item' but it could also + ;; be a scrollbar event. We can't distinguish at the + ;; moment. + (if menup "This item" (key-description key)) + ;;(if (symbolp defn) defn (key-description defn)) + (if (symbolp defn) defn (prin1-to-string defn)) + (if final (concat ", " (key-description interm) " runs ") "") + (if final + (if (symbolp final) final (prin1-to-string final)) + ""))) + (if (numberp show) + (or (not (symbolp defn)) + (memq (symbol-function defn) + '(zkey-init-kbd-macro zkey-init-kbd-fn)) + (progn (princ msg) (princ "\n"))) + (message "%s" msg) + (if final (setq defn final)) + (if (and (or (symbolp defn) (symbolp (setq defn (car-safe defn)))) + defn + show) + (hypropos-get-doc defn t)))))) + +;;;###autoload +(defun hyper-describe-face (symbol &optional this-ref-buffer) + "Describe face.. See also `hyper-apropos' and `hyper-describe-function'." ;; #### - perhaps a prefix arg should suppress the prompt... - (interactive - (let* ((v (variable-at-point)) - (val (let ((enable-recursive-minibuffers t)) + (interactive + (let (v val) + (setq v (hypropos-this-symbol)) ; symbol under point + (or (find-face v) + (setq v (variable-at-point))) + (setq val (let ((enable-recursive-minibuffers t)) (completing-read - (if v - (format "Describe variable (default %s): " v) - "Describe variable: ") - obarray 'boundp t)))) - (list (if (string= val "") v (intern-soft val))))) + (concat (if (hypropos-follow-ref-buffer current-prefix-arg) + "Follow face" + "Describe face") + (if v + (format " (default %s): " v) + ": ")) + (mapcar (function (lambda (x) (list (symbol-name x)))) + (face-list)) + nil t nil 'hypropos-face-history))) + (list (if (string= val "") + (progn (push (symbol-name v) hypropos-face-history) v) + (intern-soft val)) + current-prefix-arg))) (if (null symbol) (message "Sorry, nothing to describe.") (or (memq major-mode '(hyper-apropos-mode hyper-help-mode)) (setq hypropos-prev-wconfig (current-window-configuration))) - (hypropos-get-doc symbol t))) + (hypropos-get-doc symbol t nil this-ref-buffer))) ;;;###autoload -(defun hyper-describe-function (symbol) +(defun hyper-describe-variable (symbol &optional this-ref-buffer) + "Hypertext drop-in replacement for `describe-variable'. +See also `hyper-apropos' and `hyper-describe-function'." + ;; #### - perhaps a prefix arg should suppress the prompt... + (interactive (list (hypropos-read-variable-symbol + (if (hypropos-follow-ref-buffer current-prefix-arg) + "Follow variable" + "Describe variable")) + current-prefix-arg)) + (if (null symbol) + (message "Sorry, nothing to describe.") + (or (memq major-mode '(hyper-apropos-mode hyper-help-mode)) + (setq hypropos-prev-wconfig (current-window-configuration))) + (hypropos-get-doc symbol t nil this-ref-buffer))) + +(defun hyper-where-is (symbol) + "Print message listing key sequences that invoke specified command." + (interactive (list (hypropos-read-function-symbol "Where is function"))) + (if (null symbol) + (message "Sorry, nothing to describe.") + (where-is symbol))) + +;;;###autoload +(defun hyper-describe-function (symbol &optional this-ref-buffer) "Hypertext replacement for `describe-function'. Unlike `describe-function' in that the symbol under the cursor is the default if it is a function. See also `hyper-apropos' and `hyper-describe-variable'." ;; #### - perhaps a prefix arg should suppress the prompt... - (interactive - (let (fn val) - (setq fn (hypropos-this-symbol)) ; symbol under point - (or (fboundp fn) - (setq fn (function-called-at-point))) - (setq val (let ((enable-recursive-minibuffers t)) - (completing-read - (if fn - (format "Describe function (default %s): " fn) - "Describe function: ") - obarray 'fboundp t))) - (list (if (equal val "") fn (intern-soft val))))) + (interactive (list (hypropos-read-function-symbol + (if (hypropos-follow-ref-buffer current-prefix-arg) + "Follow function" + "Describe function")) + current-prefix-arg)) (if (null symbol) (message "Sorry, nothing to describe.") (or (memq major-mode '(hyper-apropos-mode hyper-help-mode)) (setq hypropos-prev-wconfig (current-window-configuration))) - (hypropos-get-doc symbol t))) + (hypropos-get-doc symbol t nil this-ref-buffer))) + +;;;###autoload +(defun hypropos-read-variable-symbol (prompt &optional predicate) + "Hypertext drop-in replacement for `describe-variable'. +See also `hyper-apropos' and `hyper-describe-function'." + ;; #### - perhaps a prefix arg should suppress the prompt... + (or predicate (setq predicate 'boundp)) + (let (v val) + (setq v (hypropos-this-symbol)) ; symbol under point + (or (funcall predicate v) + (setq v (variable-at-point))) + (or (funcall predicate v) + (setq v nil)) + (setq val (let ((enable-recursive-minibuffers t)) + (completing-read + (concat prompt + (if v + (format " (default %s): " v) + ": ")) + obarray predicate t nil 'variable-history))) + (if (string= val "") + (progn (push (symbol-name v) variable-history) v) + (intern-soft val)))) + +(defun hypropos-read-function-symbol (prompt) + "Read function symbol from minibuffer." + (let ((fn (hypropos-this-symbol)) + val) + (or (fboundp fn) + (setq fn (function-called-at-point))) + (setq val (let ((enable-recursive-minibuffers t)) + (completing-read (if fn + (format "%s (default %s): " prompt fn) + (format "%s: " prompt)) + obarray 'fboundp t nil + 'function-history))) + (if (equal val "") + (progn (push (symbol-name fn) function-history) fn) + (intern-soft val)))) (defun hypropos-last-help (arg) "Go back to the last symbol documented in the *Hyper Help* buffer." (interactive "P") - (let ((win (get-buffer-window hypropos-help-buf)) - (n (prefix-numeric-value arg))) - (cond ((and (not win) (not arg)) - ;; don't alter the help-history, just redisplay - ) - ((<= (length hypropos-help-history) n) + (let ((win (get-buffer-window hypropos-help-buf))) + (or arg (setq arg (if win 1 0))) + (cond ((= arg 0)) + ((<= (length hypropos-help-history) arg) ;; go back as far as we can... (setcdr (nreverse hypropos-help-history) nil)) (t - (setq hypropos-help-history (nthcdr n hypropos-help-history)))) - (hypropos-get-doc (car hypropos-help-history) t))) + (setq hypropos-help-history (nthcdr arg hypropos-help-history)))) + (if (or win (> arg 0)) + (hypropos-get-doc (car hypropos-help-history) t) + (display-buffer hypropos-help-buf)))) + +(defun hypropos-insert-face (string &optional face) + "Insert STRING and fontify some parts with face `hyperlink'." + (let ((beg (point)) end) + (insert-face string (or face 'documentation)) + (setq end (point)) + (goto-char beg) + (while (re-search-forward + "`\\([-a-zA-Z0-9_][-a-zA-Z0-9_][-a-zA-Z0-9_.]+\\)'" + end 'limit) + (set-extent-face (make-extent (match-beginning 1) (match-end 1)) + 'hyperlink)) + (goto-char beg) + (while (re-search-forward + "M-x \\([-a-zA-Z0-9_][-a-zA-Z0-9_][-a-zA-Z0-9_.]+\\)" + end 'limit) + (set-extent-face (make-extent (match-beginning 1) (match-end 1)) + 'hyperlink)))) + +(defun hypropos-insert-keybinding (keys string) + (if keys + (insert " (" string " bound to \"" + (mapconcat 'key-description + (sort keys #'(lambda (x y) + (< (length x) (length y)))) + "\", \"") + "\")\n"))) -(defun hypropos-get-doc (&optional symbol force type) +(defun hypropos-insert-section-heading (alias-desc &optional desc) + (or desc (setq desc alias-desc + alias-desc nil)) + (if alias-desc + (setq desc (concat alias-desc + (if (memq (aref desc 0) + '(?a ?e ?i ?o ?u)) + ", an " ", a ") + desc))) + (aset desc 0 (upcase (aref desc 0))) ; capitalize + (goto-char (point-max)) + (newline 3) (delete-blank-lines) (newline 2) + (hypropos-insert-face desc 'section-heading)) + +(defun hypropos-insert-value (string symbol val) + (insert-face string 'heading) + (insert (if (symbol-value symbol) + (if (or (null val) (eq val t) (integerp val)) + (prog1 + (symbol-value symbol) + (set symbol nil)) + "see below") + "is void"))) + +(defun hypropos-follow-ref-buffer (this-ref-buffer) + (and (not this-ref-buffer) + (eq major-mode 'hyper-help-mode) + hypropos-ref-buffer + (buffer-live-p hypropos-ref-buffer))) + +(defun hypropos-get-alias (symbol alias-p next-symbol &optional use) + "Return (TERMINAL-SYMBOL . ALIAS-DESC)." + (let (aliases) + (while (funcall alias-p symbol) + (setq aliases (cons (if use (funcall use symbol) symbol) aliases)) + (setq symbol (funcall next-symbol symbol))) + (cons symbol + (and aliases + (concat "an alias for `" + (mapconcat 'symbol-name + (nreverse aliases) + "',\nwhich is an alias for `") + "'"))))) + +;;;###autoload +(defun hypropos-get-doc (&optional symbol force type this-ref-buffer) ;; #### - update this docstring "Toggle display of documentation for the symbol on the current line." ;; SYMBOL is the symbol to document. FORCE, if non-nil, means to @@ -436,167 +633,291 @@ ;; otherwise clear the history because it's a new search. (list symbol)))) (save-excursion - (set-buffer (get-buffer-create hypropos-help-buf)) - (setq buffer-read-only nil) - (erase-buffer) - (let ((standard-output (current-buffer)) - ok beg desc - ftype macrop fndef - keys val doc - obsolete aliases alias-desc) - (insert-face (format "`%s'\n\n" symbol) 'major-heading) + (if (hypropos-follow-ref-buffer this-ref-buffer) + (set-buffer hypropos-ref-buffer) + (setq hypropos-ref-buffer (current-buffer))) + (let (standard-output + ok beg + newsym symtype doc obsolete + (local mode-name) + global local-str global-str + font fore back undl + aliases alias-desc desc) + (save-excursion + (set-buffer (get-buffer-create hypropos-help-buf)) + ;;(setq standard-output (current-buffer)) + (setq buffer-read-only nil) + (erase-buffer) + (insert-face (format "`%s'" symbol) 'major-heading) + (insert (format " (buffer: %s, mode: %s)\n" + (buffer-name hypropos-ref-buffer) + local))) + ;; function ---------------------------------------------------------- (and (memq 'function type) (fboundp symbol) - (progn - (setq ok t - fndef (symbol-function symbol)) - (while (symbolp fndef) - (setq aliases (cons fndef aliases)) - (setq fndef (symbol-function fndef))) - (if (eq 'macro (car-safe fndef)) - (setq macrop t - fndef (cdr fndef))) - (setq aliases (nreverse aliases)) - ;; #### - the gods of internationalization shall strike me down! - (while aliases - (if alias-desc - (setq alias-desc (concat alias-desc ",\nwhich is "))) - (setq alias-desc (concat alias-desc - (format "an alias for `%s'" - (car aliases)))) - (setq aliases (cdr aliases))) - (setq ftype (cond ((subrp fndef) 'subr) - ((compiled-function-p fndef) 'bytecode) - ((eq (car-safe fndef) 'autoload) 'autoload) - ((eq (car-safe fndef) 'lambda) 'lambda)) + (progn + (setq ok t) + (setq aliases (hypropos-get-alias (symbol-function symbol) + 'symbolp + 'symbol-function) + newsym (car aliases) + alias-desc (cdr aliases)) + (if (eq 'macro (car-safe newsym)) + (setq desc "macro" + newsym (cdr newsym)) + (setq desc "function")) + (setq symtype (cond ((subrp newsym) 'subr) + ((compiled-function-p newsym) 'bytecode) + ((eq (car-safe newsym) 'autoload) 'autoload) + ((eq (car-safe newsym) 'lambda) 'lambda)) desc (concat (if (commandp symbol) "interactive ") - (cdr (assq ftype + (cdr (assq symtype '((subr . "built-in ") (bytecode . "compiled Lisp ") (autoload . "autoloaded Lisp ") (lambda . "Lisp ")))) - (if macrop "macro" "function") - )) - (if alias-desc - (setq desc (concat alias-desc - (if (memq (aref desc 0) - '(?a ?e ?i ?o ?u)) - ", an " ", a ") - desc))) - (aset desc 0 (upcase (aref desc 0))) ; capitalize - (insert-face desc 'section-heading) - (and (eq ftype 'autoload) - (insert (format ", (autoloaded from \"%s\")" - (nth 1 fndef)))) - ;; #### - should also show local binding in some other - ;; buffer so that this function can be used in place of - ;; describe-function and describe-variable. - (if (setq keys (where-is-internal symbol (current-global-map) - nil nil nil)) - (insert (format ", (globally bound to %s)" - (mapconcat - #'(lambda (x) - (format "\"%s\"" - (key-description x))) - (sort keys #'(lambda (x y) - (< (length x) (length y)))) - ", ")))) - (insert ":\n\n") - (setq beg (point) + desc) + local (current-local-map) + global (current-global-map) + obsolete (get symbol 'byte-obsolete-info) doc (or (documentation symbol) "function not documented")) - (insert-face "arguments: " 'heading) - (cond ((eq ftype 'lambda) - (princ (or (nth 1 fndef) "()"))) - ((eq ftype 'bytecode) - (princ (or (if (fboundp 'compiled-function-arglist) - (compiled-function-arglist fndef) - (aref fndef 0)) "()"))) - ((and (eq ftype 'subr) - (string-match - "[\n\t ]*\narguments: ?\\((.*)\\)\n?\\'" - doc)) - (insert (substring doc - (match-beginning 1) - (match-end 1))) - (setq doc (substring doc 0 (match-beginning 0)))) - (t (princ "[not available]"))) - (insert "\n\n") - (let ((new - ;; cookbook from bytecomp.el - (get symbol 'byte-obsolete-info))) - (and new - (insert-face - (format "%s is an obsolete function; %s\n\n" symbol - (if (stringp (car new)) - (car new) - (format "use %s instead." (car new)))) - 'warning))) - (insert-face doc 'documentation) - (indent-rigidly beg (point) 1) - (insert"\n\n") - )) + (save-excursion + (set-buffer hypropos-help-buf) + (goto-char (point-max)) + (setq standard-output (current-buffer)) + (hypropos-insert-section-heading alias-desc desc) + (and (eq symtype 'autoload) + (insert (format ", (autoloaded from \"%s\")" + (nth 1 newsym)))) + (insert ":\n") + (if local + (hypropos-insert-keybinding + (where-is-internal symbol (list local) nil nil nil) + "locally")) + (hypropos-insert-keybinding + (where-is-internal symbol (list global) nil nil nil) + "globally") + (insert "\n") + (if obsolete + (hypropos-insert-face + (format "%s is an obsolete function; %s\n\n" symbol + (if (stringp (car obsolete)) + (car obsolete) + (format "use `%s' instead." (car obsolete)))) + 'warning)) + (setq beg (point)) + (insert-face "arguments: " 'heading) + (cond ((eq symtype 'lambda) + (princ (or (nth 1 newsym) "()"))) + ((eq symtype 'bytecode) + (princ (or (aref newsym 0) "()"))) + ((and (eq symtype 'subr) + (string-match + "[\n\t ]*\narguments: ?\\((.*)\\)\n?\\'" + doc)) + (insert (substring doc + (match-beginning 1) + (match-end 1))) + (setq doc (substring doc 0 (match-beginning 0)))) + ((and (eq symtype 'subr) + (string-match + "[\n\t ]*([^\n\t )]+[\t ]*\\([^\n)]+\\)?)\\(:[\t ]*\\|\n?\\'\\)" + doc)) + (insert "(" + (if (match-end 1) + (substring doc + (match-beginning 1) + (match-end 1))) + ")") + (setq doc (substring doc (match-end 0)))) + (t (princ "[not available]"))) + (insert "\n\n") + (hypropos-insert-face doc) + (insert "\n") + (indent-rigidly beg (point) 2)))) + ;; variable ---------------------------------------------------------- (and (memq 'variable type) - (boundp symbol) + (or (boundp symbol) (default-boundp symbol)) (progn (setq ok t) - (insert-face (if (user-variable-p symbol) - "User variable" - "Variable") - 'section-heading) - (and (local-variable-p symbol nil t) - (insert ", local when set")) - (insert ":\n\n") - (setq beg (point) - val (prin1-to-string (symbol-value symbol)) - doc (or (documentation-property - symbol 'variable-documentation) + (setq aliases (hypropos-get-alias symbol + 'variable-alias + 'variable-alias + 'variable-alias) + newsym (car aliases) + alias-desc (cdr aliases)) + (setq symtype (or (local-variable-p newsym (current-buffer)) + (and (local-variable-p newsym + (current-buffer) t) + 'auto-local)) + desc (concat (if (user-variable-p newsym) + "user variable" + "variable") + (cond ((eq symtype t) ", buffer-local") + ((eq symtype 'auto-local) + ", local when set"))) + local (and (boundp newsym) + (symbol-value newsym)) + local-str (and (boundp newsym) + (prin1-to-string local)) + global (and (eq symtype t) + (default-boundp newsym) + (default-value newsym)) + global-str (and (eq symtype t) + (default-boundp newsym) + (prin1-to-string global)) + obsolete (get symbol 'byte-obsolete-variable) + doc (or (documentation-property symbol + 'variable-documentation) "variable not documented")) - - (let ((ob (get symbol 'byte-obsolete-variable))) - (setq obsolete - (and ob (format "%s is an obsolete variable; %s\n\n" - symbol - (if (stringp ob) - ob - (format "use %s instead." ob)))))) - ;; generally, the value of the variable is short and the - ;; documentation of the variable long, so it's desirable - ;; to see all of the value and the start of the - ;; documentation. Some variables, though, have huge and - ;; nearly meaningless values that force you to page - ;; forward just to find the doc string. That is - ;; undesirable. - (if (< (length val) 69) ; 80 cols. docstrings assume this. - (progn (insert-face "value: " 'heading) - (insert (format "%s\n\n" val)) - (and obsolete (insert-face obsolete 'warning)) - (insert-face doc 'documentation)) - (insert "(see below for value)\n\n") - (and obsolete (insert-face obsolete 'warning)) - (insert-face doc 'documentation) - (insert "\n\n") - (insert-face "value: " 'heading) - (if hypropos-prettyprint-long-values - (let ((pp-print-readably nil)) - (pprint (symbol-value symbol))) - (insert val))) - (indent-rigidly beg (point) 2) - )) + (save-excursion + (set-buffer hypropos-help-buf) + (goto-char (point-max)) + (setq standard-output (current-buffer)) + (hypropos-insert-section-heading alias-desc desc) + (insert ":\n\n") + (setq beg (point)) + (if obsolete + (hypropos-insert-face + (format "%s is an obsolete function; %s\n\n" symbol + (if (stringp obsolete) + obsolete + (format "use `%s' instead." obsolete))) + 'warning)) + ;; generally, the value of the variable is short and the + ;; documentation of the variable long, so it's desirable + ;; to see all of the value and the start of the + ;; documentation. Some variables, though, have huge and + ;; nearly meaningless values that force you to page + ;; forward just to find the doc string. That is + ;; undesirable. + (if (and (or (null local-str) (< (length local-str) 69)) + (or (null global-str) (< (length global-str) 69))) + ; 80 cols. docstrings assume this. + (progn (insert-face "value: " 'heading) + (insert (or local-str "is void")) + (if (eq symtype t) + (progn + (insert "\n") + (insert-face "default value: " 'heading) + (insert (or global-str "is void")))) + (insert "\n\n") + (hypropos-insert-face doc)) + (hypropos-insert-value "value: " 'local-str local) + (if (eq symtype t) + (progn + (insert ", ") + (hypropos-insert-value "default-value: " + 'global-str global))) + (insert "\n\n") + (hypropos-insert-face doc) + (if local-str + (progn + (newline 3) (delete-blank-lines) (newline 1) + (insert-face "value: " 'heading) + (if hypropos-prettyprint-long-values + (condition-case nil + (let ((pp-print-readably nil)) (pprint local)) + (error (insert local-str))) + (insert local-str)))) + (if global-str + (progn + (newline 3) (delete-blank-lines) (newline 1) + (insert-face "default value: " 'heading) + (if hypropos-prettyprint-long-values + (condition-case nil + (let ((pp-print-readably nil)) (pprint global)) + (error (insert global-str))) + (insert global-str))))) + (indent-rigidly beg (point) 2)))) + ;; face -------------------------------------------------------------- (and (memq 'face type) (find-face symbol) (progn (setq ok t) + (copy-face symbol 'hypropos-temp-face 'global) + (mapcar (function + (lambda (property) + (setq symtype (face-property-instance symbol + property)) + (if symtype + (set-face-property 'hypropos-temp-face + property + symtype)))) + built-in-face-specifiers) + (setq font (cons (face-property-instance symbol 'font nil 0 t) + (face-property-instance symbol 'font)) + fore (cons (face-foreground-instance symbol nil 0 t) + (face-foreground-instance symbol)) + back (cons (face-background-instance symbol nil 0 t) + (face-background-instance symbol)) + undl (cons (face-underline-p symbol nil 0 t) + (face-underline-p symbol)) + doc (face-doc-string symbol)) ;; #### - add some code here - (insert "Face documentation is \"To be implemented.\"\n\n") - ) - ) - (or ok (insert-face "symbol is not currently bound" 'heading))) + (save-excursion + (set-buffer hypropos-help-buf) + (setq standard-output (current-buffer)) + (hypropos-insert-section-heading "Face:\n\n ") + (insert-face "ABCDEFHIJKLMNOPQRSTUVWXYZ abcdefhijklmnopqrstuvwxyz 0123456789" + 'hypropos-temp-face) + (newline 2) + (insert-face " Font: " 'heading) + (insert (format (if (numberp (car font)) "(%s)\n" "%s\n") + (and (cdr font) + (font-instance-name (cdr font))))) + (insert-face " Foreground: " 'heading) + (insert (format (if (numberp (car fore)) "(%s)\n" "%s\n") + (and (cdr fore) + (color-instance-name (cdr fore))))) + (insert-face " Background: " 'heading) + (insert (format (if (numberp (car back)) "(%s)\n" "%s\n") + (and (cdr back) + (color-instance-name (cdr back))))) + (insert-face " Underline: " 'heading) + (insert (format (if (numberp (car undl)) "(%s)\n" "%s\n") + (cdr undl))) + (if doc + (progn + (newline) + (setq beg (point)) + (insert doc) + (indent-rigidly beg (point) 2)))))) + ;; not bound & property list ----------------------------------------- + (or ok + (save-excursion + (set-buffer hypropos-help-buf) + (hypropos-insert-section-heading + "symbol is not currently bound\n"))) + (if (and (setq symtype (symbol-plist symbol)) + (or (> (length symtype) 2) + (not (memq 'variable-documentation symtype)))) + (save-excursion + (set-buffer hypropos-help-buf) + (goto-char (point-max)) + (setq standard-output (current-buffer)) + (hypropos-insert-section-heading "property-list:\n\n") + (while symtype + (if (memq (car symtype) + '(variable-documentation byte-obsolete-info)) + (setq symtype (cdr symtype)) + (insert-face (concat " " (symbol-name (car symtype)) + ": ") + 'heading) + (setq symtype (cdr symtype)) + (indent-to 32) + (insert (prin1-to-string (car symtype)) "\n")) + (setq symtype (cdr symtype))))))) + (save-excursion + (set-buffer hypropos-help-buf) (goto-char (point-min)) ;; pop up window and shrink it if it's wasting space - (shrink-window-if-larger-than-buffer - (display-buffer (current-buffer))) - (hyper-help-mode)) ) - (setq hypropos-currently-showing symbol)) + (if hypropos-shrink-window + (shrink-window-if-larger-than-buffer + (display-buffer (current-buffer))) + (display-buffer (current-buffer))) + (hyper-help-mode)) + (setq hypropos-currently-showing symbol))) ; ----------------------------------------------------------------------------- @@ -737,7 +1058,7 @@ (point))) (en (progn (skip-syntax-forward "w_") - (skip-chars-backward ".") + (skip-chars-backward ".':") ; : for Local Variables (point)))) (and (not (eq st en)) (intern-soft (buffer-substring st en)))))))) @@ -755,35 +1076,69 @@ (t (call-interactively fn)))) ;;;###autoload -(defun hypropos-set-variable (var val) +(defun hyper-set-variable (var val &optional this-ref-buffer) + (interactive + (let ((var (hypropos-read-variable-symbol + (if (hypropos-follow-ref-buffer current-prefix-arg) + "In ref buffer, set user option" + "Set user option") + 'user-variable-p))) + (list var (hypropos-read-variable-value var) current-prefix-arg))) + (hypropos-set-variable var val this-ref-buffer)) + +;;;###autoload +(defun hypropos-set-variable (var val &optional this-ref-buffer) "Interactively set the variable on the current line." (interactive - (let ((var (save-excursion - (and (eq major-mode 'hypropos-help-mode) - (goto-char (point-min))) - (hypropos-this-symbol)))) - (or (boundp var) - (setq var (completing-read "Set variable: " - obarray 'boundp t))) - (hypropos-get-doc var t) - (list var - (let ((prop (get var 'variable-interactive)) - (print-readably t) - (val (symbol-value var))) - (if prop - (call-interactively (list 'lambda '(arg) - (list 'interactive prop) - 'arg)) - (eval-minibuffer - (format "Set `%s' to value (evaluated): " var) - (format (if (or (consp val) - (and (symbolp val) - (not (memq val '(t nil))))) - "'%s" "%s") - (prin1-to-string val)))))) - )) - (set var val) - (hypropos-get-doc var t)) + (let ((var (hypropos-this-symbol))) + (or (and var (boundp var)) + (and (setq var (and (eq major-mode 'hyper-help-mode) + (save-excursion + (goto-char (point-min)) + (hypropos-this-symbol)))) + (boundp var)) + (setq var nil)) + (list var (hypropos-read-variable-value var)))) + (and var + (boundp var) + (progn + (if (hypropos-follow-ref-buffer this-ref-buffer) + (save-excursion + (set-buffer hypropos-ref-buffer) + (set var val)) + (set var val)) + (hypropos-get-doc var t '(variable) this-ref-buffer)))) + +(defun hypropos-read-variable-value (var &optional this-ref-buffer) + (and var + (boundp var) + (let ((prop (get var 'variable-interactive)) + (print-readably t) + val str) + (hypropos-get-doc var t '(variable) current-prefix-arg) + (if prop + (call-interactively (list 'lambda '(arg) + (list 'interactive prop) + 'arg)) + (setq val (if (hypropos-follow-ref-buffer this-ref-buffer) + (save-excursion + (set-buffer hypropos-ref-buffer) + (symbol-value var)) + (symbol-value var)) + str (prin1-to-string val)) + (eval-minibuffer + (format "Set %s `%s' to value (evaluated): " + (if (user-variable-p var) "user option" "Variable") + var) + (condition-case nil + (progn + (read str) + (format (if (or (consp val) + (and (symbolp val) + (not (memq val '(t nil))))) + "'%s" "%s") + str)) + (error nil))))))) ;; ---------------------------------------------------------------------- ;; @@ -886,4 +1241,3 @@ (provide 'hyper-apropos) ;; end of hyper-apropos.el -