;;; help-fns.el --- Complex help functions -*- lexical-binding: t -*-
-;; Copyright (C) 1985-1986, 1993-1994, 1998-2014
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1993-1994, 1998-2015 Free Software
+;; Foundation, Inc.
;; Maintainer: emacs-devel@gnu.org
;; Keywords: help, internal
alternatively, it can be a function definition.
If TYPE is `defvar', search for a variable definition.
If TYPE is `defface', search for a face definition.
-If TYPE is the value returned by `symbol-function' for a function symbol,
- search for a function definition.
+If TYPE is not a symbol, search for a function definition.
The return value is the absolute name of a readable file where OBJECT is
defined. If several such files exist, preference is given to a file
(let* ((autoloaded (autoloadp type))
(file-name (or (and autoloaded (nth 1 type))
(symbol-file
- object (if (memq type (list 'defvar 'defface))
- type
- 'defun)))))
+ ;; FIXME: Why do we have this weird "If TYPE is the
+ ;; value returned by `symbol-function' for a function
+ ;; symbol" exception?
+ object (or (if (symbolp type) type) 'defun)))))
(cond
(autoloaded
;; An autoloaded function: Locate the file since `symbol-function'
(insert ".\n"))))
(defun help-fns--signature (function doc real-def real-function)
- (unless (keymapp function) ; If definition is a keymap, skip arglist note.
+ "Insert usage at point and return docstring. With highlighting."
+ (if (keymapp function)
+ doc ; If definition is a keymap, skip arglist note.
(let* ((advertised (gethash real-def advertised-signature-table t))
(arglist (if (listp advertised)
advertised (help-function-arglist real-def)))
(t "."))
"\n")))))
+(defun help-fns-short-filename (filename)
+ (let* ((abbrev (abbreviate-file-name filename))
+ (short abbrev))
+ (dolist (dir load-path)
+ (let ((rel (file-relative-name filename dir)))
+ (if (< (length rel) (length short))
+ (setq short rel)))
+ (let ((rel (file-relative-name abbrev dir)))
+ (if (< (length rel) (length short))
+ (setq short rel))))
+ short))
+
;;;###autoload
(defun describe-function-1 (function)
(let* ((advised (and (symbolp function)
(beg (if (and (or (byte-code-function-p def)
(keymapp def)
(memq (car-safe def) '(macro lambda closure)))
- file-name
+ (stringp file-name)
(help-fns--autoloaded-p function file-name))
(if (commandp def)
"an interactive autoloaded "
;; aliases before functions.
(aliased
(format "an alias for `%s'" real-def))
+ ((autoloadp def)
+ (format "%s autoloaded %s"
+ (if (commandp def) "an interactive" "an")
+ (if (eq (nth 4 def) 'keymap) "keymap"
+ (if (nth 4 def) "Lisp macro" "Lisp function"))))
((or (eq (car-safe def) 'macro)
;; For advised macros, def is a lambda
;; expression or a byte-code-function-p, so we
(concat beg "Lisp function"))
((eq (car-safe def) 'closure)
(concat beg "Lisp closure"))
- ((autoloadp def)
- (format "%s autoloaded %s"
- (if (commandp def) "an interactive" "an")
- (if (eq (nth 4 def) 'keymap) "keymap"
- (if (nth 4 def) "Lisp macro" "Lisp function"))))
((keymapp def)
(let ((is-full nil)
(elts (cdr-safe def)))
;; but that's completely wrong when the user used load-file.
(princ (if (eq file-name 'C-source)
"C source code"
- (file-name-nondirectory file-name)))
+ (help-fns-short-filename file-name)))
(princ "'")
;; Make a hyperlink to the library.
(with-current-buffer standard-output
help-enable-auto-load
(string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]"
doc-raw)
- (load (cadr real-def) t))
+ (autoload-do-load real-def))
(substitute-command-keys doc-raw))))
(help-fns--key-bindings function)
(buffer-string))))))))
+;;;###autoload
+(defun describe-function-or-variable (symbol &optional buffer frame)
+ "Display the full documentation of the function or variable SYMBOL.
+If SYMBOL is a variable and has a buffer-local value in BUFFER or FRAME
+\(default to the current buffer and current frame), it is displayed along
+with the global value."
+ (interactive
+ (let* ((v-or-f (variable-at-point))
+ (found (symbolp v-or-f))
+ (v-or-f (if found v-or-f (function-called-at-point)))
+ (found (or found v-or-f))
+ (enable-recursive-minibuffers t)
+ val)
+ (setq val (completing-read (if found
+ (format
+ "Describe function or variable (default %s): " v-or-f)
+ "Describe function or variable: ")
+ obarray
+ (lambda (vv)
+ (or (fboundp vv)
+ (get vv 'variable-documentation)
+ (and (boundp vv) (not (keywordp vv)))))
+ t nil nil
+ (if found (symbol-name v-or-f))))
+ (list (if (equal val "")
+ v-or-f (intern val)))))
+ (if (not (symbolp symbol)) (message "You didn't specify a function or variable")
+ (unless (buffer-live-p buffer) (setq buffer (current-buffer)))
+ (unless (frame-live-p frame) (setq frame (selected-frame)))
+ (help-xref-interned symbol buffer frame)))
+
;;;###autoload
(defun describe-syntax (&optional buffer)
"Describe the syntax specifications in the syntax table of BUFFER.