aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2004-04-07 19:38:54 +0000
committerStefan Monnier2004-04-07 19:38:54 +0000
commit154ee9b7377983dcb37d84a1b39b145ae32fc16a (patch)
treea9217e2f1b735d223c04718323ce0666141ad6fd
parent0728ab11962b050a55d91872b149a9d86677e715 (diff)
downloademacs-154ee9b7377983dcb37d84a1b39b145ae32fc16a.tar.gz
emacs-154ee9b7377983dcb37d84a1b39b145ae32fc16a.zip
(help-C-source-directory): New var.
(help-subr-name, help-C-file-name, help-find-C-source): New funs. (describe-function-1, describe-variable): Use them.
-rw-r--r--lisp/help-fns.el74
1 files changed, 69 insertions, 5 deletions
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 4201a3de1a5..ab76b5eb232 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -1,6 +1,6 @@
1;;; help-fns.el --- Complex help functions 1;;; help-fns.el --- Complex help functions
2 2
3;; Copyright (C) 1985, 1986, 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003 3;; Copyright (C) 1985, 86, 93, 94, 98, 1999, 2000, 01, 02, 03, 2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Maintainer: FSF 6;; Maintainer: FSF
@@ -215,6 +215,61 @@ ARGLIST can also be t or a string of the form \"(fun ARG1 ARG2 ...)\"."
215 (intern (upcase name)))))) 215 (intern (upcase name))))))
216 arglist))) 216 arglist)))
217 217
218(defvar help-C-source-directory
219 (let ((dir (expand-file-name "src" source-directory)))
220 (when (and (file-directory-p dir) (file-readable-p dir))
221 dir))
222 "Directory where the C source files of Emacs can be found.
223If nil, do not try to find the source code of functions and variables
224defined in C.")
225
226(defun help-subr-name (subr)
227 (let ((name (prin1-to-string subr)))
228 (if (string-match "\\`#<subr \\(.*\\)>\\'" name)
229 (match-string 1 name)
230 (error "Unexpected subroutine print name: %s" name))))
231
232(defun help-C-file-name (subr-or-var kind)
233 "Return the name of the C file where SUBR-OR-VAR is defined.
234KIND should be `var' for a variable or `subr' for a subroutine."
235 (let ((docbuf (get-buffer-create " *DOC*"))
236 (name (if (eq 'var kind)
237 (concat "V" (symbol-name subr-or-var))
238 (concat "F" (help-subr-name subr-or-var)))))
239 (with-current-buffer docbuf
240 (goto-char (point-min))
241 (if (eobp)
242 (insert-file-contents-literally
243 (expand-file-name internal-doc-file-name doc-directory)))
244 (search-forward (concat "" name "\n"))
245 (re-search-backward "S\\(.*\\)")
246 (let ((file (match-string 1)))
247 (if (string-match "\\.\\(o\\|obj\\)\\'" file)
248 (replace-match ".c" t t file)
249 file)))))
250
251(defun help-find-C-source (fun-or-var file kind)
252 "Find the source location where SUBR-OR-VAR is defined in FILE.
253KIND should be `var' for a variable or `subr' for a subroutine."
254 (setq file (expand-file-name file help-C-source-directory))
255 (unless (file-readable-p file)
256 (error "The C source file %s is not available"
257 (file-name-nondirectory file)))
258 (if (eq 'fun kind)
259 (setq fun-or-var (indirect-function fun-or-var)))
260 (with-current-buffer (find-file-noselect file)
261 (goto-char (point-min))
262 (unless (re-search-forward
263 (if (eq 'fun kind)
264 (concat "DEFUN[ \t\n]*([ \t\n]*\""
265 (regexp-quote (help-subr-name fun-or-var))
266 "\"")
267 (concat "DEFVAR[A-Z_]*[ \t\n]*([ \t\n]*\""
268 (regexp-quote (symbol-name fun-or-var))))
269 nil t)
270 (error "Can't find source for %s" fun))
271 (cons (current-buffer) (match-beginning 0))))
272
218;;;###autoload 273;;;###autoload
219(defun describe-function-1 (function) 274(defun describe-function-1 (function)
220 (let* ((def (if (symbolp function) 275 (let* ((def (if (symbolp function)
@@ -280,8 +335,10 @@ ARGLIST can also be t or a string of the form \"(fun ARG1 ARG2 ...)\"."
280 (when (re-search-backward 335 (when (re-search-backward
281 "^;;; Generated autoloads from \\(.*\\)" nil t) 336 "^;;; Generated autoloads from \\(.*\\)" nil t)
282 (setq file-name (match-string 1))))))) 337 (setq file-name (match-string 1)))))))
283 (cond 338 (when (and (null file-name) (subrp def) help-C-source-directory)
284 (file-name 339 ;; Find the C source file name.
340 (setq file-name (concat "src/" (help-C-file-name def 'subr))))
341 (when file-name
285 (princ " in `") 342 (princ " in `")
286 ;; We used to add .el to the file name, 343 ;; We used to add .el to the file name,
287 ;; but that's completely wrong when the user used load-file. 344 ;; but that's completely wrong when the user used load-file.
@@ -289,9 +346,9 @@ ARGLIST can also be t or a string of the form \"(fun ARG1 ARG2 ...)\"."
289 (princ "'") 346 (princ "'")
290 ;; Make a hyperlink to the library. 347 ;; Make a hyperlink to the library.
291 (with-current-buffer standard-output 348 (with-current-buffer standard-output
292 (save-excursion 349 (save-excursion
293 (re-search-backward "`\\([^`']+\\)'" nil t) 350 (re-search-backward "`\\([^`']+\\)'" nil t)
294 (help-xref-button 1 'help-function-def function file-name))))) 351 (help-xref-button 1 'help-function-def function file-name))))
295 (princ ".") 352 (princ ".")
296 (terpri) 353 (terpri)
297 (when (commandp function) 354 (when (commandp function)
@@ -500,6 +557,13 @@ it is displayed along with the global value."
500 (when (re-search-backward 557 (when (re-search-backward
501 "^;;; Generated autoloads from \\(.*\\)" nil t) 558 "^;;; Generated autoloads from \\(.*\\)" nil t)
502 (setq file-name (match-string 1))))))) 559 (setq file-name (match-string 1)))))))
560 (when (and (null file-name)
561 (integerp (get variable 'variable-documentation)))
562 ;; It's a variable not defined in Elisp but in C.
563 (if help-C-source-directory
564 (setq file-name
565 (concat "src/" (help-C-file-name variable 'var)))
566 (princ "\n\nDefined in core C code.")))
503 (when file-name 567 (when file-name
504 (princ "\n\nDefined in `") 568 (princ "\n\nDefined in `")
505 (princ file-name) 569 (princ file-name)