aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2008-08-30 03:26:14 +0000
committerGlenn Morris2008-08-30 03:26:14 +0000
commitdbe6b8bb06480970fea2cf551ca95c7216954ddc (patch)
tree843687dbd46bea4feac15e4dfaba4b025c2cb787
parent7cb78ecd636d513a4ef95b677034512caf6424d3 (diff)
downloademacs-dbe6b8bb06480970fea2cf551ca95c7216954ddc.tar.gz
emacs-dbe6b8bb06480970fea2cf551ca95c7216954ddc.zip
(describe-function-1): Handle broken aliases. (Bug#825)
-rw-r--r--lisp/ChangeLog5
-rw-r--r--lisp/help-fns.el264
2 files changed, 140 insertions, 129 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b18bd684032..c3773c1664c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,8 @@
12008-08-30 Glenn Morris <rgm@gnu.org>
2
3 * apropos.el (apropos-command): Ignore documentation errors.
4 * help-fns.el (describe-function-1): Handle broken aliases. (Bug#825)
5
12008-08-29 Chong Yidong <cyd@stupidchicken.com> 62008-08-29 Chong Yidong <cyd@stupidchicken.com>
2 7
3 * isearch.el (isearch-highlight-regexp): Fix case of highlighted 8 * isearch.el (isearch-highlight-regexp): Fix case of highlighted
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index d251ab0e349..bb97ef42173 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -268,7 +268,8 @@ face (according to `face-differs-from-default-p')."
268 function)) 268 function))
269 file-name string 269 file-name string
270 (beg (if (commandp def) "an interactive " "a ")) 270 (beg (if (commandp def) "an interactive " "a "))
271 (pt1 (with-current-buffer (help-buffer) (point)))) 271 (pt1 (with-current-buffer (help-buffer) (point)))
272 errtype)
272 (setq string 273 (setq string
273 (cond ((or (stringp def) 274 (cond ((or (stringp def)
274 (vectorp def)) 275 (vectorp def))
@@ -280,8 +281,11 @@ face (according to `face-differs-from-default-p')."
280 ((byte-code-function-p def) 281 ((byte-code-function-p def)
281 (concat beg "compiled Lisp function")) 282 (concat beg "compiled Lisp function"))
282 ((symbolp def) 283 ((symbolp def)
283 (while (symbolp (symbol-function def)) 284 (while (and (fboundp def)
285 (symbolp (symbol-function def)))
284 (setq def (symbol-function def))) 286 (setq def (symbol-function def)))
287 ;; Handle (defalias 'foo 'bar), where bar is undefined.
288 (or (fboundp def) (setq errtype 'alias))
285 (format "an alias for `%s'" def)) 289 (format "an alias for `%s'" def))
286 ((eq (car-safe def) 'lambda) 290 ((eq (car-safe def) 'lambda)
287 (concat beg "Lisp function")) 291 (concat beg "Lisp function"))
@@ -307,135 +311,137 @@ face (according to `face-differs-from-default-p')."
307 "a sparse keymap"))) 311 "a sparse keymap")))
308 (t ""))) 312 (t "")))
309 (princ string) 313 (princ string)
310 (with-current-buffer standard-output 314 (if (eq errtype 'alias)
311 (save-excursion 315 (princ ",\nwhich is not defined. Please make a bug report.")
312 (save-match-data
313 (if (re-search-backward "alias for `\\([^`']+\\)'" nil t)
314 (help-xref-button 1 'help-function def)))))
315 (or file-name
316 (setq file-name (symbol-file function 'defun)))
317 (setq file-name (describe-simplify-lib-file-name file-name))
318 (when (equal file-name "loaddefs.el")
319 ;; Find the real def site of the preloaded function.
320 ;; This is necessary only for defaliases.
321 (let ((location
322 (condition-case nil
323 (find-function-search-for-symbol function nil "loaddefs.el")
324 (error nil))))
325 (when location
326 (with-current-buffer (car location)
327 (goto-char (cdr location))
328 (when (re-search-backward
329 "^;;; Generated autoloads from \\(.*\\)" nil t)
330 (setq file-name (match-string 1)))))))
331 (when (and (null file-name) (subrp def))
332 ;; Find the C source file name.
333 (setq file-name (if (get-buffer " *DOC*")
334 (help-C-file-name def 'subr)
335 'C-source)))
336 (when file-name
337 (princ " in `")
338 ;; We used to add .el to the file name,
339 ;; but that's completely wrong when the user used load-file.
340 (princ (if (eq file-name 'C-source) "C source code" file-name))
341 (princ "'")
342 ;; See if lisp files are present where they where installed from.
343 (if (not (eq file-name 'C-source))
344 (setq file-name (find-source-lisp-file file-name)))
345
346 ;; Make a hyperlink to the library.
347 (with-current-buffer standard-output 316 (with-current-buffer standard-output
348 (save-excursion 317 (save-excursion
349 (re-search-backward "`\\([^`']+\\)'" nil t) 318 (save-match-data
350 (help-xref-button 1 'help-function-def real-function file-name)))) 319 (if (re-search-backward "alias for `\\([^`']+\\)'" nil t)
351 (princ ".") 320 (help-xref-button 1 'help-function def)))))
352 (with-current-buffer (help-buffer) 321 (or file-name
353 (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point)) 322 (setq file-name (symbol-file function 'defun)))
354 (point))) 323 (setq file-name (describe-simplify-lib-file-name file-name))
355 (terpri)(terpri) 324 (when (equal file-name "loaddefs.el")
356 (when (commandp function) 325 ;; Find the real def site of the preloaded function.
357 (let ((pt2 (with-current-buffer (help-buffer) (point)))) 326 ;; This is necessary only for defaliases.
358 (if (and (eq function 'self-insert-command) 327 (let ((location
359 (eq (key-binding "a") 'self-insert-command) 328 (condition-case nil
360 (eq (key-binding "b") 'self-insert-command) 329 (find-function-search-for-symbol function nil "loaddefs.el")
361 (eq (key-binding "c") 'self-insert-command)) 330 (error nil))))
362 (princ "It is bound to many ordinary text characters.\n") 331 (when location
363 (let* ((remapped (command-remapping function)) 332 (with-current-buffer (car location)
364 (keys (where-is-internal 333 (goto-char (cdr location))
365 (or remapped function) overriding-local-map nil nil)) 334 (when (re-search-backward
366 non-modified-keys) 335 "^;;; Generated autoloads from \\(.*\\)" nil t)
367 ;; Which non-control non-meta keys run this command? 336 (setq file-name (match-string 1)))))))
368 (dolist (key keys) 337 (when (and (null file-name) (subrp def))
369 (if (member (event-modifiers (aref key 0)) '(nil (shift))) 338 ;; Find the C source file name.
370 (push key non-modified-keys))) 339 (setq file-name (if (get-buffer " *DOC*")
371 (when remapped 340 (help-C-file-name def 'subr)
372 (princ "It is remapped to `") 341 'C-source)))
373 (princ (symbol-name remapped)) 342 (when file-name
374 (princ "'")) 343 (princ " in `")
375 344 ;; We used to add .el to the file name,
376 (when keys 345 ;; but that's completely wrong when the user used load-file.
377 (princ (if remapped ", which is bound to " "It is bound to ")) 346 (princ (if (eq file-name 'C-source) "C source code" file-name))
378 ;; If lots of ordinary text characters run this command, 347 (princ "'")
379 ;; don't mention them one by one. 348 ;; See if lisp files are present where they where installed from.
380 (if (< (length non-modified-keys) 10) 349 (if (not (eq file-name 'C-source))
381 (princ (mapconcat 'key-description keys ", ")) 350 (setq file-name (find-source-lisp-file file-name)))
382 (dolist (key non-modified-keys) 351
383 (setq keys (delq key keys))) 352 ;; Make a hyperlink to the library.
384 (if keys 353 (with-current-buffer standard-output
385 (progn 354 (save-excursion
355 (re-search-backward "`\\([^`']+\\)'" nil t)
356 (help-xref-button 1 'help-function-def real-function file-name))))
357 (princ ".")
358 (with-current-buffer (help-buffer)
359 (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point))
360 (point)))
361 (terpri)(terpri)
362 (when (commandp function)
363 (let ((pt2 (with-current-buffer (help-buffer) (point))))
364 (if (and (eq function 'self-insert-command)
365 (eq (key-binding "a") 'self-insert-command)
366 (eq (key-binding "b") 'self-insert-command)
367 (eq (key-binding "c") 'self-insert-command))
368 (princ "It is bound to many ordinary text characters.\n")
369 (let* ((remapped (command-remapping function))
370 (keys (where-is-internal
371 (or remapped function) overriding-local-map nil nil))
372 non-modified-keys)
373 ;; Which non-control non-meta keys run this command?
374 (dolist (key keys)
375 (if (member (event-modifiers (aref key 0)) '(nil (shift)))
376 (push key non-modified-keys)))
377 (when remapped
378 (princ "It is remapped to `")
379 (princ (symbol-name remapped))
380 (princ "'"))
381
382 (when keys
383 (princ (if remapped ", which is bound to " "It is bound to "))
384 ;; If lots of ordinary text characters run this command,
385 ;; don't mention them one by one.
386 (if (< (length non-modified-keys) 10)
386 (princ (mapconcat 'key-description keys ", ")) 387 (princ (mapconcat 'key-description keys ", "))
387 (princ ", and many ordinary text characters")) 388 (dolist (key non-modified-keys)
388 (princ "many ordinary text characters")))) 389 (setq keys (delq key keys)))
389 (when (or remapped keys non-modified-keys) 390 (if keys
390 (princ ".") 391 (progn
391 (terpri)))) 392 (princ (mapconcat 'key-description keys ", "))
392 (with-current-buffer (help-buffer) (fill-region-as-paragraph pt2 (point))) 393 (princ ", and many ordinary text characters"))
393 (terpri))) 394 (princ "many ordinary text characters"))))
394 (let* ((arglist (help-function-arglist def)) 395 (when (or remapped keys non-modified-keys)
395 (doc (documentation function)) 396 (princ ".")
396 (usage (help-split-fundoc doc function))) 397 (terpri))))
397 (with-current-buffer standard-output 398 (with-current-buffer (help-buffer) (fill-region-as-paragraph pt2 (point)))
398 ;; If definition is a keymap, skip arglist note. 399 (terpri)))
399 (unless (keymapp function) 400 (let* ((arglist (help-function-arglist def))
400 (let* ((use (cond 401 (doc (documentation function))
401 (usage (setq doc (cdr usage)) (car usage)) 402 (usage (help-split-fundoc doc function)))
402 ((listp arglist) 403 (with-current-buffer standard-output
403 (format "%S" (help-make-usage function arglist))) 404 ;; If definition is a keymap, skip arglist note.
404 ((stringp arglist) arglist) 405 (unless (keymapp function)
405 ;; Maybe the arglist is in the docstring of a symbol 406 (let* ((use (cond
406 ;; this one is aliased to. 407 (usage (setq doc (cdr usage)) (car usage))
407 ((let ((fun real-function)) 408 ((listp arglist)
408 (while (and (symbolp fun) 409 (format "%S" (help-make-usage function arglist)))
409 (setq fun (symbol-function fun)) 410 ((stringp arglist) arglist)
410 (not (setq usage (help-split-fundoc 411 ;; Maybe the arglist is in the docstring of a symbol
411 (documentation fun) 412 ;; this one is aliased to.
412 function))))) 413 ((let ((fun real-function))
413 usage) 414 (while (and (symbolp fun)
414 (car usage)) 415 (setq fun (symbol-function fun))
415 ((or (stringp def) 416 (not (setq usage (help-split-fundoc
416 (vectorp def)) 417 (documentation fun)
417 (format "\nMacro: %s" (format-kbd-macro def))) 418 function)))))
418 (t "[Missing arglist. Please make a bug report.]"))) 419 usage)
419 (high (help-highlight-arguments use doc))) 420 (car usage))
420 (let ((fill-begin (point))) 421 ((or (stringp def)
421 (insert (car high) "\n") 422 (vectorp def))
422 (fill-region fill-begin (point))) 423 (format "\nMacro: %s" (format-kbd-macro def)))
423 (setq doc (cdr high)))) 424 (t "[Missing arglist. Please make a bug report.]")))
424 (let* ((obsolete (and 425 (high (help-highlight-arguments use doc)))
425 ;; function might be a lambda construct. 426 (let ((fill-begin (point)))
426 (symbolp function) 427 (insert (car high) "\n")
427 (get function 'byte-obsolete-info))) 428 (fill-region fill-begin (point)))
428 (use (car obsolete))) 429 (setq doc (cdr high))))
429 (when obsolete 430 (let* ((obsolete (and
430 (princ "\nThis function is obsolete") 431 ;; function might be a lambda construct.
431 (when (nth 2 obsolete) 432 (symbolp function)
432 (insert (format " since %s" (nth 2 obsolete)))) 433 (get function 'byte-obsolete-info)))
433 (insert (cond ((stringp use) (concat ";\n" use)) 434 (use (car obsolete)))
434 (use (format ";\nuse `%s' instead." use)) 435 (when obsolete
435 (t ".")) 436 (princ "\nThis function is obsolete")
436 "\n")) 437 (when (nth 2 obsolete)
437 (insert "\n" 438 (insert (format " since %s" (nth 2 obsolete))))
438 (or doc "Not documented."))))))) 439 (insert (cond ((stringp use) (concat ";\n" use))
440 (use (format ";\nuse `%s' instead." use))
441 (t "."))
442 "\n"))
443 (insert "\n"
444 (or doc "Not documented."))))))))
439 445
440 446
441;; Variables 447;; Variables