Mercurial > emacs
comparison lisp/help-fns.el @ 54749:f7424850240d
(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.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Wed, 07 Apr 2004 19:38:54 +0000 |
parents | bce4d57a18d7 |
children | 8041d88f98b5 |
comparison
equal
deleted
inserted
replaced
54748:8143853620d8 | 54749:f7424850240d |
---|---|
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 |
7 ;; Keywords: help, internal | 7 ;; Keywords: help, internal |
8 | 8 |
212 arg) | 212 arg) |
213 (let ((name (symbol-name arg))) | 213 (let ((name (symbol-name arg))) |
214 (if (string-match "\\`&" name) arg | 214 (if (string-match "\\`&" name) arg |
215 (intern (upcase name)))))) | 215 (intern (upcase name)))))) |
216 arglist))) | 216 arglist))) |
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. | |
223 If nil, do not try to find the source code of functions and variables | |
224 defined 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. | |
234 KIND 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. | |
253 KIND 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)))) | |
217 | 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) |
221 (symbol-function function) | 276 (symbol-function function) |
278 (with-current-buffer (car location) | 333 (with-current-buffer (car location) |
279 (goto-char (cdr location)) | 334 (goto-char (cdr location)) |
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. |
288 (princ file-name) | 345 (princ file-name) |
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) |
298 (let* ((remapped (command-remapping function)) | 355 (let* ((remapped (command-remapping function)) |
299 (keys (where-is-internal | 356 (keys (where-is-internal |
498 (with-current-buffer (car location) | 555 (with-current-buffer (car location) |
499 (goto-char (cdr location)) | 556 (goto-char (cdr location)) |
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) |
506 (princ "'.") | 570 (princ "'.") |
507 (with-current-buffer standard-output | 571 (with-current-buffer standard-output |