diff options
| author | Bastien | 2017-07-03 09:06:29 +0200 |
|---|---|---|
| committer | Bastien | 2017-07-03 09:06:29 +0200 |
| commit | 5ca1888fe670aee7febd4d42665d7372ab2ffebc (patch) | |
| tree | 1f7f8d8a7580e556fc83cf3a6aaeec567b33a090 /lisp/help.el | |
| parent | 20e006ffee41062f1b551a92c24d9edc53cd0f56 (diff) | |
| parent | 1b4f0a92ff3505ef9a465b9b391756e3a73a6443 (diff) | |
| download | emacs-5ca1888fe670aee7febd4d42665d7372ab2ffebc.tar.gz emacs-5ca1888fe670aee7febd4d42665d7372ab2ffebc.zip | |
Merge branch 'master' into scratch/org-mode-merge
Diffstat (limited to 'lisp/help.el')
| -rw-r--r-- | lisp/help.el | 257 |
1 files changed, 109 insertions, 148 deletions
diff --git a/lisp/help.el b/lisp/help.el index 361ab2a01ee..0fb1c2dab77 100644 --- a/lisp/help.el +++ b/lisp/help.el | |||
| @@ -593,6 +593,39 @@ If INSERT (the prefix arg) is non-nil, insert the message in the buffer." | |||
| 593 | string | 593 | string |
| 594 | (format "%s (translated from %s)" string otherstring)))))) | 594 | (format "%s (translated from %s)" string otherstring)))))) |
| 595 | 595 | ||
| 596 | (defun help--analyze-key (key untranslated) | ||
| 597 | "Get information about KEY its corresponding UNTRANSLATED events. | ||
| 598 | Returns a list of the form (BRIEF-DESC DEFN EVENT MOUSE-MSG)." | ||
| 599 | (if (numberp untranslated) | ||
| 600 | (setq untranslated (this-single-command-raw-keys))) | ||
| 601 | (let* ((event (aref key (if (and (symbolp (aref key 0)) | ||
| 602 | (> (length key) 1) | ||
| 603 | (consp (aref key 1))) | ||
| 604 | 1 | ||
| 605 | 0))) | ||
| 606 | (modifiers (event-modifiers event)) | ||
| 607 | (mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers) | ||
| 608 | (memq 'drag modifiers)) " at that spot" "")) | ||
| 609 | (defn (key-binding key t))) | ||
| 610 | ;; Handle the case where we faked an entry in "Select and Paste" menu. | ||
| 611 | (when (and (eq defn nil) | ||
| 612 | (stringp (aref key (1- (length key)))) | ||
| 613 | (eq (key-binding (substring key 0 -1)) 'yank-menu)) | ||
| 614 | (setq defn 'menu-bar-select-yank)) | ||
| 615 | ;; Don't bother user with strings from (e.g.) the select-paste menu. | ||
| 616 | (when (stringp (aref key (1- (length key)))) | ||
| 617 | (aset key (1- (length key)) "(any string)")) | ||
| 618 | (when (and untranslated | ||
| 619 | (stringp (aref untranslated (1- (length untranslated))))) | ||
| 620 | (aset untranslated (1- (length untranslated)) "(any string)")) | ||
| 621 | (list | ||
| 622 | ;; Now describe the key, perhaps as changed. | ||
| 623 | (let ((key-desc (help-key-description key untranslated))) | ||
| 624 | (if (or (null defn) (integerp defn) (equal defn 'undefined)) | ||
| 625 | (format "%s%s is undefined" key-desc mouse-msg) | ||
| 626 | (format "%s%s runs the command %S" key-desc mouse-msg defn))) | ||
| 627 | defn event mouse-msg))) | ||
| 628 | |||
| 596 | (defun describe-key-briefly (&optional key insert untranslated) | 629 | (defun describe-key-briefly (&optional key insert untranslated) |
| 597 | "Print the name of the function KEY invokes. KEY is a string. | 630 | "Print the name of the function KEY invokes. KEY is a string. |
| 598 | If INSERT (the prefix arg) is non-nil, insert the message in the buffer. | 631 | If INSERT (the prefix arg) is non-nil, insert the message in the buffer. |
| @@ -603,73 +636,12 @@ the last key hit are used. | |||
| 603 | If KEY is a menu item or a tool-bar button that is disabled, this command | 636 | If KEY is a menu item or a tool-bar button that is disabled, this command |
| 604 | temporarily enables it to allow getting help on disabled items and buttons." | 637 | temporarily enables it to allow getting help on disabled items and buttons." |
| 605 | (interactive | 638 | (interactive |
| 606 | (let ((enable-disabled-menus-and-buttons t) | 639 | ;; Ignore mouse movement events because it's too easy to miss the |
| 607 | (cursor-in-echo-area t) | 640 | ;; message while moving the mouse. |
| 608 | saved-yank-menu) | 641 | (pcase-let ((`(,key ,_up-event) (help-read-key-sequence 'no-mouse-movement))) |
| 609 | (unwind-protect | 642 | `(,key ,current-prefix-arg 1))) |
| 610 | (let (key) | 643 | (princ (car (help--analyze-key key untranslated)) |
| 611 | ;; If yank-menu is empty, populate it temporarily, so that | 644 | (if insert (current-buffer) standard-output))) |
| 612 | ;; "Select and Paste" menu can generate a complete event. | ||
| 613 | (when (null (cdr yank-menu)) | ||
| 614 | (setq saved-yank-menu (copy-sequence yank-menu)) | ||
| 615 | (menu-bar-update-yank-menu "(any string)" nil)) | ||
| 616 | (while | ||
| 617 | (progn | ||
| 618 | (setq key (read-key-sequence "Describe the following key, mouse click, or menu item: ")) | ||
| 619 | (and (vectorp key) | ||
| 620 | (consp (aref key 0)) | ||
| 621 | (symbolp (car (aref key 0))) | ||
| 622 | (string-match "\\(mouse\\|down\\|click\\|drag\\)" | ||
| 623 | (symbol-name (car (aref key 0)))) | ||
| 624 | (not (sit-for (/ double-click-time 1000.0) t))))) | ||
| 625 | ;; Clear the echo area message (Bug#7014). | ||
| 626 | (message nil) | ||
| 627 | ;; If KEY is a down-event, read and discard the | ||
| 628 | ;; corresponding up-event. Note that there are also | ||
| 629 | ;; down-events on scroll bars and mode lines: the actual | ||
| 630 | ;; event then is in the second element of the vector. | ||
| 631 | (and (vectorp key) | ||
| 632 | (let ((last-idx (1- (length key)))) | ||
| 633 | (and (eventp (aref key last-idx)) | ||
| 634 | (memq 'down (event-modifiers (aref key last-idx))))) | ||
| 635 | (read-event)) | ||
| 636 | (list | ||
| 637 | key | ||
| 638 | (if current-prefix-arg (prefix-numeric-value current-prefix-arg)) | ||
| 639 | 1)) | ||
| 640 | ;; Put yank-menu back as it was, if we changed it. | ||
| 641 | (when saved-yank-menu | ||
| 642 | (setq yank-menu (copy-sequence saved-yank-menu)) | ||
| 643 | (fset 'yank-menu (cons 'keymap yank-menu)))))) | ||
| 644 | (if (numberp untranslated) | ||
| 645 | (setq untranslated (this-single-command-raw-keys))) | ||
| 646 | (let* ((event (if (and (symbolp (aref key 0)) | ||
| 647 | (> (length key) 1) | ||
| 648 | (consp (aref key 1))) | ||
| 649 | (aref key 1) | ||
| 650 | (aref key 0))) | ||
| 651 | (modifiers (event-modifiers event)) | ||
| 652 | (standard-output (if insert (current-buffer) standard-output)) | ||
| 653 | (mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers) | ||
| 654 | (memq 'drag modifiers)) " at that spot" "")) | ||
| 655 | (defn (key-binding key t)) | ||
| 656 | key-desc) | ||
| 657 | ;; Handle the case where we faked an entry in "Select and Paste" menu. | ||
| 658 | (if (and (eq defn nil) | ||
| 659 | (stringp (aref key (1- (length key)))) | ||
| 660 | (eq (key-binding (substring key 0 -1)) 'yank-menu)) | ||
| 661 | (setq defn 'menu-bar-select-yank)) | ||
| 662 | ;; Don't bother user with strings from (e.g.) the select-paste menu. | ||
| 663 | (if (stringp (aref key (1- (length key)))) | ||
| 664 | (aset key (1- (length key)) "(any string)")) | ||
| 665 | (if (and (> (length untranslated) 0) | ||
| 666 | (stringp (aref untranslated (1- (length untranslated))))) | ||
| 667 | (aset untranslated (1- (length untranslated)) "(any string)")) | ||
| 668 | ;; Now describe the key, perhaps as changed. | ||
| 669 | (setq key-desc (help-key-description key untranslated)) | ||
| 670 | (if (or (null defn) (integerp defn) (equal defn 'undefined)) | ||
| 671 | (princ (format "%s%s is undefined" key-desc mouse-msg)) | ||
| 672 | (princ (format "%s%s runs the command %S" key-desc mouse-msg defn))))) | ||
| 673 | 645 | ||
| 674 | (defun help--key-binding-keymap (key &optional accept-default no-remap position) | 646 | (defun help--key-binding-keymap (key &optional accept-default no-remap position) |
| 675 | "Return a keymap holding a binding for KEY within current keymaps. | 647 | "Return a keymap holding a binding for KEY within current keymaps. |
| @@ -734,6 +706,59 @@ function `key-binding'." | |||
| 734 | (throw 'found x)))) | 706 | (throw 'found x)))) |
| 735 | nil))))) | 707 | nil))))) |
| 736 | 708 | ||
| 709 | (defun help-read-key-sequence (&optional no-mouse-movement) | ||
| 710 | "Reads a key sequence from the user. | ||
| 711 | Returns a list of the form (KEY UP-EVENT), where KEY is the key | ||
| 712 | sequence, and UP-EVENT is the up-event that was discarded by | ||
| 713 | reading KEY, or nil. | ||
| 714 | If NO-MOUSE-MOVEMENT is non-nil, ignore key sequences starting | ||
| 715 | with `mouse-movement' events." | ||
| 716 | (let ((enable-disabled-menus-and-buttons t) | ||
| 717 | (cursor-in-echo-area t) | ||
| 718 | saved-yank-menu) | ||
| 719 | (unwind-protect | ||
| 720 | (let (key) | ||
| 721 | ;; If yank-menu is empty, populate it temporarily, so that | ||
| 722 | ;; "Select and Paste" menu can generate a complete event. | ||
| 723 | (when (null (cdr yank-menu)) | ||
| 724 | (setq saved-yank-menu (copy-sequence yank-menu)) | ||
| 725 | (menu-bar-update-yank-menu "(any string)" nil)) | ||
| 726 | (while | ||
| 727 | (pcase (setq key (read-key-sequence "\ | ||
| 728 | Describe the following key, mouse click, or menu item: ")) | ||
| 729 | ((and (pred vectorp) (let `(,key0 . ,_) (aref key 0)) | ||
| 730 | (guard (symbolp key0)) (let keyname (symbol-name key0))) | ||
| 731 | (if no-mouse-movement | ||
| 732 | (string-match "mouse-movement" keyname) | ||
| 733 | (and (string-match "\\(mouse\\|down\\|click\\|drag\\)" | ||
| 734 | keyname) | ||
| 735 | (not (sit-for (/ double-click-time 1000.0) t))))))) | ||
| 736 | (list | ||
| 737 | key | ||
| 738 | ;; If KEY is a down-event, read and include the | ||
| 739 | ;; corresponding up-event. Note that there are also | ||
| 740 | ;; down-events on scroll bars and mode lines: the actual | ||
| 741 | ;; event then is in the second element of the vector. | ||
| 742 | (and (vectorp key) | ||
| 743 | (let ((last-idx (1- (length key)))) | ||
| 744 | (and (eventp (aref key last-idx)) | ||
| 745 | (memq 'down (event-modifiers (aref key last-idx))))) | ||
| 746 | (or (and (eventp (aref key 0)) | ||
| 747 | (memq 'down (event-modifiers (aref key 0))) | ||
| 748 | ;; However, for the C-down-mouse-2 popup | ||
| 749 | ;; menu, there is no subsequent up-event. In | ||
| 750 | ;; this case, the up-event is the next | ||
| 751 | ;; element in the supplied vector. | ||
| 752 | (= (length key) 1)) | ||
| 753 | (and (> (length key) 1) | ||
| 754 | (eventp (aref key 1)) | ||
| 755 | (memq 'down (event-modifiers (aref key 1))))) | ||
| 756 | (read-event)))) | ||
| 757 | ;; Put yank-menu back as it was, if we changed it. | ||
| 758 | (when saved-yank-menu | ||
| 759 | (setq yank-menu (copy-sequence saved-yank-menu)) | ||
| 760 | (fset 'yank-menu (cons 'keymap yank-menu)))))) | ||
| 761 | |||
| 737 | (defun describe-key (&optional key untranslated up-event) | 762 | (defun describe-key (&optional key untranslated up-event) |
| 738 | "Display documentation of the function invoked by KEY. | 763 | "Display documentation of the function invoked by KEY. |
| 739 | KEY can be any kind of a key sequence; it can include keyboard events, | 764 | KEY can be any kind of a key sequence; it can include keyboard events, |
| @@ -748,83 +773,20 @@ UP-EVENT is the up-event that was discarded by reading KEY, or nil. | |||
| 748 | If KEY is a menu item or a tool-bar button that is disabled, this command | 773 | If KEY is a menu item or a tool-bar button that is disabled, this command |
| 749 | temporarily enables it to allow getting help on disabled items and buttons." | 774 | temporarily enables it to allow getting help on disabled items and buttons." |
| 750 | (interactive | 775 | (interactive |
| 751 | (let ((enable-disabled-menus-and-buttons t) | 776 | (pcase-let ((`(,key ,up-event) (help-read-key-sequence))) |
| 752 | (cursor-in-echo-area t) | 777 | `(,key ,(prefix-numeric-value current-prefix-arg) ,up-event))) |
| 753 | saved-yank-menu) | 778 | (pcase-let ((`(,brief-desc ,defn ,event ,mouse-msg) |
| 754 | (unwind-protect | 779 | (help--analyze-key key untranslated)) |
| 755 | (let (key) | 780 | (defn-up nil) (defn-up-tricky nil) |
| 756 | ;; If yank-menu is empty, populate it temporarily, so that | 781 | (key-locus-up nil) (key-locus-up-tricky nil) |
| 757 | ;; "Select and Paste" menu can generate a complete event. | 782 | (mouse-1-remapped nil) (mouse-1-tricky nil) |
| 758 | (when (null (cdr yank-menu)) | 783 | (ev-type nil)) |
| 759 | (setq saved-yank-menu (copy-sequence yank-menu)) | 784 | (if (or (null defn) |
| 760 | (menu-bar-update-yank-menu "(any string)" nil)) | 785 | (integerp defn) |
| 761 | (while | 786 | (equal defn 'undefined)) |
| 762 | (progn | 787 | (message "%s" brief-desc) |
| 763 | (setq key (read-key-sequence "Describe the following key, mouse click, or menu item: ")) | ||
| 764 | (and (vectorp key) | ||
| 765 | (consp (aref key 0)) | ||
| 766 | (symbolp (car (aref key 0))) | ||
| 767 | (string-match "\\(mouse\\|down\\|click\\|drag\\)" | ||
| 768 | (symbol-name (car (aref key 0)))) | ||
| 769 | (not (sit-for (/ double-click-time 1000.0) t))))) | ||
| 770 | (list | ||
| 771 | key | ||
| 772 | (prefix-numeric-value current-prefix-arg) | ||
| 773 | ;; If KEY is a down-event, read and include the | ||
| 774 | ;; corresponding up-event. Note that there are also | ||
| 775 | ;; down-events on scroll bars and mode lines: the actual | ||
| 776 | ;; event then is in the second element of the vector. | ||
| 777 | (and (vectorp key) | ||
| 778 | (let ((last-idx (1- (length key)))) | ||
| 779 | (and (eventp (aref key last-idx)) | ||
| 780 | (memq 'down (event-modifiers (aref key last-idx))))) | ||
| 781 | (or (and (eventp (aref key 0)) | ||
| 782 | (memq 'down (event-modifiers (aref key 0))) | ||
| 783 | ;; However, for the C-down-mouse-2 popup | ||
| 784 | ;; menu, there is no subsequent up-event. In | ||
| 785 | ;; this case, the up-event is the next | ||
| 786 | ;; element in the supplied vector. | ||
| 787 | (= (length key) 1)) | ||
| 788 | (and (> (length key) 1) | ||
| 789 | (eventp (aref key 1)) | ||
| 790 | (memq 'down (event-modifiers (aref key 1))))) | ||
| 791 | (read-event)))) | ||
| 792 | ;; Put yank-menu back as it was, if we changed it. | ||
| 793 | (when saved-yank-menu | ||
| 794 | (setq yank-menu (copy-sequence saved-yank-menu)) | ||
| 795 | (fset 'yank-menu (cons 'keymap yank-menu)))))) | ||
| 796 | (if (numberp untranslated) | ||
| 797 | (setq untranslated (this-single-command-raw-keys))) | ||
| 798 | (let* ((event (aref key (if (and (symbolp (aref key 0)) | ||
| 799 | (> (length key) 1) | ||
| 800 | (consp (aref key 1))) | ||
| 801 | 1 | ||
| 802 | 0))) | ||
| 803 | (modifiers (event-modifiers event)) | ||
| 804 | (mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers) | ||
| 805 | (memq 'drag modifiers)) " at that spot" "")) | ||
| 806 | (defn (key-binding key t)) | ||
| 807 | key-locus key-locus-up key-locus-up-tricky | ||
| 808 | defn-up defn-up-tricky ev-type | ||
| 809 | mouse-1-remapped mouse-1-tricky) | ||
| 810 | |||
| 811 | ;; Handle the case where we faked an entry in "Select and Paste" menu. | ||
| 812 | (when (and (eq defn nil) | ||
| 813 | (stringp (aref key (1- (length key)))) | ||
| 814 | (eq (key-binding (substring key 0 -1)) 'yank-menu)) | ||
| 815 | (setq defn 'menu-bar-select-yank)) | ||
| 816 | (if (or (null defn) (integerp defn) (equal defn 'undefined)) | ||
| 817 | (message "%s%s is undefined" | ||
| 818 | (help-key-description key untranslated) mouse-msg) | ||
| 819 | (help-setup-xref (list #'describe-function defn) | 788 | (help-setup-xref (list #'describe-function defn) |
| 820 | (called-interactively-p 'interactive)) | 789 | (called-interactively-p 'interactive)) |
| 821 | ;; Don't bother user with strings from (e.g.) the select-paste menu. | ||
| 822 | (when (stringp (aref key (1- (length key)))) | ||
| 823 | (aset key (1- (length key)) "(any string)")) | ||
| 824 | (when (and untranslated | ||
| 825 | (stringp (aref untranslated (1- (length untranslated))))) | ||
| 826 | (aset untranslated (1- (length untranslated)) | ||
| 827 | "(any string)")) | ||
| 828 | ;; Need to do this before erasing *Help* buffer in case event | 790 | ;; Need to do this before erasing *Help* buffer in case event |
| 829 | ;; is a mouse click in an existing *Help* buffer. | 791 | ;; is a mouse click in an existing *Help* buffer. |
| 830 | (when up-event | 792 | (when up-event |
| @@ -849,13 +811,12 @@ temporarily enables it to allow getting help on disabled items and buttons." | |||
| 849 | (aset sequence 0 'mouse-1) | 811 | (aset sequence 0 'mouse-1) |
| 850 | (setq defn-up-tricky (key-binding sequence nil nil (event-start up-event))) | 812 | (setq defn-up-tricky (key-binding sequence nil nil (event-start up-event))) |
| 851 | (setq key-locus-up-tricky (help--binding-locus sequence (event-start up-event)))))) | 813 | (setq key-locus-up-tricky (help--binding-locus sequence (event-start up-event)))))) |
| 852 | (setq key-locus (help--binding-locus key (event-start event))) | ||
| 853 | (with-help-window (help-buffer) | 814 | (with-help-window (help-buffer) |
| 854 | (princ (help-key-description key untranslated)) | 815 | (princ brief-desc) |
| 855 | (princ (format "%s runs the command %S%s, which is " | 816 | (let ((key-locus (help--binding-locus key (event-start event)))) |
| 856 | mouse-msg defn (if key-locus | 817 | (when key-locus |
| 857 | (format " (found in %s)" key-locus) | 818 | (princ (format " (found in %s)" key-locus)))) |
| 858 | ""))) | 819 | (princ ", which is ") |
| 859 | (describe-function-1 defn) | 820 | (describe-function-1 defn) |
| 860 | (when up-event | 821 | (when up-event |
| 861 | (unless (or (null defn-up) | 822 | (unless (or (null defn-up) |