diff options
| author | Stefan Monnier | 2012-08-06 17:05:48 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-08-06 17:05:48 -0400 |
| commit | f91b35be6020fd9efd8e2d0f7555f5d6f5e998d1 (patch) | |
| tree | 39ca7cc0d68173a781638cde2e9550b6e191f226 | |
| parent | a4fe537621e0e1f817eedadbf7f78295fb0261c2 (diff) | |
| download | emacs-f91b35be6020fd9efd8e2d0f7555f5d6f5e998d1.tar.gz emacs-f91b35be6020fd9efd8e2d0f7555f5d6f5e998d1.zip | |
* lisp/help-fns.el (help-fns--key-bindings, help-fns--signature)
(help-fns--parent-mode, help-fns--obsolete): New funs, extracted from
describe-function-1.
(describe-function-1): Use them. Move compiler macro after sig.
(help-fns--compiler-macro): Use function-get. Assume we're already in
standard-output. Adjust layout to new call order.
| -rw-r--r-- | lisp/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/help-fns.el | 249 |
2 files changed, 134 insertions, 122 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 23f8b3ec831..ebaea892a19 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,12 @@ | |||
| 1 | 2012-08-06 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2012-08-06 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * help-fns.el (help-fns--key-bindings, help-fns--signature) | ||
| 4 | (help-fns--parent-mode, help-fns--obsolete): New funs, extracted from | ||
| 5 | describe-function-1. | ||
| 6 | (describe-function-1): Use them. Move compiler macro after sig. | ||
| 7 | (help-fns--compiler-macro): Use function-get. Assume we're already in | ||
| 8 | standard-output. Adjust layout to new call order. | ||
| 9 | |||
| 3 | * emacs-lisp/cl-macs.el (cl--sm-macroexpand): Fix handling of | 10 | * emacs-lisp/cl-macs.el (cl--sm-macroexpand): Fix handling of |
| 4 | re-binding a symbol that has a symbol-macro (bug#12119). | 11 | re-binding a symbol that has a symbol-macro (bug#12119). |
| 5 | 12 | ||
diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 495063fb17c..4b1480444c2 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el | |||
| @@ -380,26 +380,125 @@ suitable file is found, return nil." | |||
| 380 | 380 | ||
| 381 | (declare-function ad-get-advice-info "advice" (function)) | 381 | (declare-function ad-get-advice-info "advice" (function)) |
| 382 | 382 | ||
| 383 | (defun help-fns--key-bindings (function) | ||
| 384 | (when (commandp function) | ||
| 385 | (let ((pt2 (with-current-buffer standard-output (point))) | ||
| 386 | (remapped (command-remapping function))) | ||
| 387 | (unless (memq remapped '(ignore undefined)) | ||
| 388 | (let ((keys (where-is-internal | ||
| 389 | (or remapped function) overriding-local-map nil nil)) | ||
| 390 | non-modified-keys) | ||
| 391 | (if (and (eq function 'self-insert-command) | ||
| 392 | (vectorp (car-safe keys)) | ||
| 393 | (consp (aref (car keys) 0))) | ||
| 394 | (princ "It is bound to many ordinary text characters.\n") | ||
| 395 | ;; Which non-control non-meta keys run this command? | ||
| 396 | (dolist (key keys) | ||
| 397 | (if (member (event-modifiers (aref key 0)) '(nil (shift))) | ||
| 398 | (push key non-modified-keys))) | ||
| 399 | (when remapped | ||
| 400 | (princ "Its keys are remapped to `") | ||
| 401 | (princ (symbol-name remapped)) | ||
| 402 | (princ "'.\n")) | ||
| 403 | |||
| 404 | (when keys | ||
| 405 | (princ (if remapped | ||
| 406 | "Without this remapping, it would be bound to " | ||
| 407 | "It is bound to ")) | ||
| 408 | ;; If lots of ordinary text characters run this command, | ||
| 409 | ;; don't mention them one by one. | ||
| 410 | (if (< (length non-modified-keys) 10) | ||
| 411 | (princ (mapconcat 'key-description keys ", ")) | ||
| 412 | (dolist (key non-modified-keys) | ||
| 413 | (setq keys (delq key keys))) | ||
| 414 | (if keys | ||
| 415 | (progn | ||
| 416 | (princ (mapconcat 'key-description keys ", ")) | ||
| 417 | (princ ", and many ordinary text characters")) | ||
| 418 | (princ "many ordinary text characters")))) | ||
| 419 | (when (or remapped keys non-modified-keys) | ||
| 420 | (princ ".") | ||
| 421 | (terpri))))) | ||
| 422 | |||
| 423 | (with-current-buffer standard-output | ||
| 424 | (fill-region-as-paragraph pt2 (point)) | ||
| 425 | (unless (looking-back "\n\n") | ||
| 426 | (terpri)))))) | ||
| 427 | |||
| 383 | (defun help-fns--compiler-macro (function) | 428 | (defun help-fns--compiler-macro (function) |
| 384 | (let ((handler nil)) | 429 | (let ((handler (function-get function 'compiler-macro))) |
| 385 | ;; FIXME: Copied from macroexp.el. | ||
| 386 | (while (and (symbolp function) | ||
| 387 | (not (setq handler (get function 'compiler-macro))) | ||
| 388 | (fboundp function)) | ||
| 389 | ;; Follow the sequence of aliases. | ||
| 390 | (setq function (symbol-function function))) | ||
| 391 | (when handler | 430 | (when handler |
| 392 | (princ "This function has a compiler macro") | 431 | (insert "\nThis function has a compiler macro") |
| 393 | (let ((lib (get function 'compiler-macro-file))) | 432 | (let ((lib (get function 'compiler-macro-file))) |
| 394 | ;; FIXME: rather than look at the compiler-macro-file property, | 433 | ;; FIXME: rather than look at the compiler-macro-file property, |
| 395 | ;; just look at `handler' itself. | 434 | ;; just look at `handler' itself. |
| 396 | (when (stringp lib) | 435 | (when (stringp lib) |
| 397 | (princ (format " in `%s'" lib)) | 436 | (insert (format " in `%s'" lib)) |
| 398 | (with-current-buffer standard-output | 437 | (save-excursion |
| 399 | (save-excursion | 438 | (re-search-backward "`\\([^`']+\\)'" nil t) |
| 400 | (re-search-backward "`\\([^`']+\\)'" nil t) | 439 | (help-xref-button 1 'help-function-cmacro function lib)))) |
| 401 | (help-xref-button 1 'help-function-cmacro function lib))))) | 440 | (insert ".\n")))) |
| 402 | (princ ".\n\n")))) | 441 | |
| 442 | (defun help-fns--signature (function doc real-def real-function) | ||
| 443 | (unless (keymapp function) ; If definition is a keymap, skip arglist note. | ||
| 444 | (let* ((advertised (gethash real-def advertised-signature-table t)) | ||
| 445 | (arglist (if (listp advertised) | ||
| 446 | advertised (help-function-arglist real-def))) | ||
| 447 | (usage (help-split-fundoc doc function))) | ||
| 448 | (if usage (setq doc (cdr usage))) | ||
| 449 | (let* ((use (cond | ||
| 450 | ((and usage (not (listp advertised))) (car usage)) | ||
| 451 | ((listp arglist) | ||
| 452 | (format "%S" (help-make-usage function arglist))) | ||
| 453 | ((stringp arglist) arglist) | ||
| 454 | ;; Maybe the arglist is in the docstring of a symbol | ||
| 455 | ;; this one is aliased to. | ||
| 456 | ((let ((fun real-function)) | ||
| 457 | (while (and (symbolp fun) | ||
| 458 | (setq fun (symbol-function fun)) | ||
| 459 | (not (setq usage (help-split-fundoc | ||
| 460 | (documentation fun) | ||
| 461 | function))))) | ||
| 462 | usage) | ||
| 463 | (car usage)) | ||
| 464 | ((or (stringp real-def) | ||
| 465 | (vectorp real-def)) | ||
| 466 | (format "\nMacro: %s" (format-kbd-macro real-def))) | ||
| 467 | (t "[Missing arglist. Please make a bug report.]"))) | ||
| 468 | (high (help-highlight-arguments use doc))) | ||
| 469 | (let ((fill-begin (point))) | ||
| 470 | (insert (car high) "\n") | ||
| 471 | (fill-region fill-begin (point))) | ||
| 472 | (cdr high))))) | ||
| 473 | |||
| 474 | (defun help-fns--parent-mode (function) | ||
| 475 | ;; If this is a derived mode, link to the parent. | ||
| 476 | (let ((parent-mode (and (symbolp function) | ||
| 477 | (get function | ||
| 478 | 'derived-mode-parent)))) | ||
| 479 | (when parent-mode | ||
| 480 | (insert "\nParent mode: `") | ||
| 481 | (let ((beg (point))) | ||
| 482 | (insert (format "%s" parent-mode)) | ||
| 483 | (make-text-button beg (point) | ||
| 484 | 'type 'help-function | ||
| 485 | 'help-args (list parent-mode))) | ||
| 486 | (insert "'.\n")))) | ||
| 487 | |||
| 488 | (defun help-fns--obsolete (function) | ||
| 489 | (let* ((obsolete (and | ||
| 490 | ;; `function' might be a lambda construct. | ||
| 491 | (symbolp function) | ||
| 492 | (get function 'byte-obsolete-info))) | ||
| 493 | (use (car obsolete))) | ||
| 494 | (when obsolete | ||
| 495 | (insert "\nThis function is obsolete") | ||
| 496 | (when (nth 2 obsolete) | ||
| 497 | (insert (format " since %s" (nth 2 obsolete)))) | ||
| 498 | (insert (cond ((stringp use) (concat ";\n" use)) | ||
| 499 | (use (format ";\nuse `%s' instead." use)) | ||
| 500 | (t ".")) | ||
| 501 | "\n")))) | ||
| 403 | 502 | ||
| 404 | ;; We could use `symbol-file' but this is a wee bit more efficient. | 503 | ;; We could use `symbol-file' but this is a wee bit more efficient. |
| 405 | (defun help-fns--autoloaded-p (function file) | 504 | (defun help-fns--autoloaded-p (function file) |
| @@ -510,54 +609,8 @@ FILE is the file where FUNCTION was probably defined." | |||
| 510 | (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point)) | 609 | (fill-region-as-paragraph (save-excursion (goto-char pt1) (forward-line 0) (point)) |
| 511 | (point))) | 610 | (point))) |
| 512 | (terpri)(terpri) | 611 | (terpri)(terpri) |
| 513 | (when (commandp function) | 612 | |
| 514 | (let ((pt2 (with-current-buffer (help-buffer) (point))) | 613 | (let* ((doc-raw (condition-case err |
| 515 | (remapped (command-remapping function))) | ||
| 516 | (unless (memq remapped '(ignore undefined)) | ||
| 517 | (let ((keys (where-is-internal | ||
| 518 | (or remapped function) overriding-local-map nil nil)) | ||
| 519 | non-modified-keys) | ||
| 520 | (if (and (eq function 'self-insert-command) | ||
| 521 | (vectorp (car-safe keys)) | ||
| 522 | (consp (aref (car keys) 0))) | ||
| 523 | (princ "It is bound to many ordinary text characters.\n") | ||
| 524 | ;; Which non-control non-meta keys run this command? | ||
| 525 | (dolist (key keys) | ||
| 526 | (if (member (event-modifiers (aref key 0)) '(nil (shift))) | ||
| 527 | (push key non-modified-keys))) | ||
| 528 | (when remapped | ||
| 529 | (princ "Its keys are remapped to `") | ||
| 530 | (princ (symbol-name remapped)) | ||
| 531 | (princ "'.\n")) | ||
| 532 | |||
| 533 | (when keys | ||
| 534 | (princ (if remapped | ||
| 535 | "Without this remapping, it would be bound to " | ||
| 536 | "It is bound to ")) | ||
| 537 | ;; If lots of ordinary text characters run this command, | ||
| 538 | ;; don't mention them one by one. | ||
| 539 | (if (< (length non-modified-keys) 10) | ||
| 540 | (princ (mapconcat 'key-description keys ", ")) | ||
| 541 | (dolist (key non-modified-keys) | ||
| 542 | (setq keys (delq key keys))) | ||
| 543 | (if keys | ||
| 544 | (progn | ||
| 545 | (princ (mapconcat 'key-description keys ", ")) | ||
| 546 | (princ ", and many ordinary text characters")) | ||
| 547 | (princ "many ordinary text characters")))) | ||
| 548 | (when (or remapped keys non-modified-keys) | ||
| 549 | (princ ".") | ||
| 550 | (terpri))))) | ||
| 551 | |||
| 552 | (with-current-buffer (help-buffer) | ||
| 553 | (fill-region-as-paragraph pt2 (point)) | ||
| 554 | (unless (looking-back "\n\n") | ||
| 555 | (terpri))))) | ||
| 556 | (help-fns--compiler-macro function) | ||
| 557 | (let* ((advertised (gethash real-def advertised-signature-table t)) | ||
| 558 | (arglist (if (listp advertised) | ||
| 559 | advertised (help-function-arglist real-def))) | ||
| 560 | (doc-raw (condition-case err | ||
| 561 | (documentation function t) | 614 | (documentation function t) |
| 562 | (error (format "No Doc! %S" err)))) | 615 | (error (format "No Doc! %S" err)))) |
| 563 | ;; If the function is autoloaded, and its docstring has | 616 | ;; If the function is autoloaded, and its docstring has |
| @@ -568,66 +621,18 @@ FILE is the file where FUNCTION was probably defined." | |||
| 568 | (string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]" | 621 | (string-match "\\([^\\]=\\|[^=]\\|\\`\\)\\\\[[{<]" |
| 569 | doc-raw) | 622 | doc-raw) |
| 570 | (load (cadr real-def) t)) | 623 | (load (cadr real-def) t)) |
| 571 | (substitute-command-keys doc-raw))) | 624 | (substitute-command-keys doc-raw)))) |
| 572 | (usage (help-split-fundoc doc function))) | 625 | |
| 573 | (with-current-buffer standard-output | 626 | (help-fns--key-bindings function) |
| 574 | ;; If definition is a keymap, skip arglist note. | 627 | (with-current-buffer standard-output |
| 575 | (unless (keymapp function) | 628 | (setq doc (help-fns--signature function doc real-def real-function)) |
| 576 | (if usage (setq doc (cdr usage))) | 629 | |
| 577 | (let* ((use (cond | 630 | (help-fns--compiler-macro function) |
| 578 | ((and usage (not (listp advertised))) (car usage)) | 631 | (help-fns--parent-mode function) |
| 579 | ((listp arglist) | 632 | (help-fns--obsolete function) |
| 580 | (format "%S" (help-make-usage function arglist))) | 633 | |
| 581 | ((stringp arglist) arglist) | 634 | (insert "\n" |
| 582 | ;; Maybe the arglist is in the docstring of a symbol | 635 | (or doc "Not documented."))))))) |
| 583 | ;; this one is aliased to. | ||
| 584 | ((let ((fun real-function)) | ||
| 585 | (while (and (symbolp fun) | ||
| 586 | (setq fun (symbol-function fun)) | ||
| 587 | (not (setq usage (help-split-fundoc | ||
| 588 | (documentation fun) | ||
| 589 | function))))) | ||
| 590 | usage) | ||
| 591 | (car usage)) | ||
| 592 | ((or (stringp real-def) | ||
| 593 | (vectorp real-def)) | ||
| 594 | (format "\nMacro: %s" (format-kbd-macro real-def))) | ||
| 595 | (t "[Missing arglist. Please make a bug report.]"))) | ||
| 596 | (high (help-highlight-arguments use doc))) | ||
| 597 | (let ((fill-begin (point))) | ||
| 598 | (insert (car high) "\n") | ||
| 599 | (fill-region fill-begin (point))) | ||
| 600 | (setq doc (cdr high)))) | ||
| 601 | |||
| 602 | ;; If this is a derived mode, link to the parent. | ||
| 603 | (let ((parent-mode (and (symbolp real-function) | ||
| 604 | (get real-function | ||
| 605 | 'derived-mode-parent)))) | ||
| 606 | (when parent-mode | ||
| 607 | (with-current-buffer standard-output | ||
| 608 | (insert "\nParent mode: `") | ||
| 609 | (let ((beg (point))) | ||
| 610 | (insert (format "%s" parent-mode)) | ||
| 611 | (make-text-button beg (point) | ||
| 612 | 'type 'help-function | ||
| 613 | 'help-args (list parent-mode)))) | ||
| 614 | (princ "'.\n"))) | ||
| 615 | |||
| 616 | (let* ((obsolete (and | ||
| 617 | ;; function might be a lambda construct. | ||
| 618 | (symbolp function) | ||
| 619 | (get function 'byte-obsolete-info))) | ||
| 620 | (use (car obsolete))) | ||
| 621 | (when obsolete | ||
| 622 | (princ "\nThis function is obsolete") | ||
| 623 | (when (nth 2 obsolete) | ||
| 624 | (insert (format " since %s" (nth 2 obsolete)))) | ||
| 625 | (insert (cond ((stringp use) (concat ";\n" use)) | ||
| 626 | (use (format ";\nuse `%s' instead." use)) | ||
| 627 | (t ".")) | ||
| 628 | "\n")) | ||
| 629 | (insert "\n" | ||
| 630 | (or doc "Not documented.")))))))) | ||
| 631 | 636 | ||
| 632 | 637 | ||
| 633 | ;; Variables | 638 | ;; Variables |