diff options
| author | Glenn Morris | 2008-08-30 03:26:14 +0000 |
|---|---|---|
| committer | Glenn Morris | 2008-08-30 03:26:14 +0000 |
| commit | dbe6b8bb06480970fea2cf551ca95c7216954ddc (patch) | |
| tree | 843687dbd46bea4feac15e4dfaba4b025c2cb787 | |
| parent | 7cb78ecd636d513a4ef95b677034512caf6424d3 (diff) | |
| download | emacs-dbe6b8bb06480970fea2cf551ca95c7216954ddc.tar.gz emacs-dbe6b8bb06480970fea2cf551ca95c7216954ddc.zip | |
(describe-function-1): Handle broken aliases. (Bug#825)
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/help-fns.el | 264 |
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 @@ | |||
| 1 | 2008-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 | |||
| 1 | 2008-08-29 Chong Yidong <cyd@stupidchicken.com> | 6 | 2008-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 |