[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

help+.el - extensions to GNU `help.el'

From: Drew Adams
Subject: help+.el - extensions to GNU `help.el'
Date: Tue, 16 Jan 2001 21:35:20 -0500

;;; help+.el --- Extensions to `help.el'.
;; Emacs Lisp Archive Entry
;; Filename: help+.el
;; Description: Extensions to `help.el'.
;; Author: Drew Adams
;; Maintainer: Drew Adams
;; Copyright (C) 1999-2001, Drew Adams, all rights reserved.
;; Created: Tue Mar 16 14:18:11 1999
;; Version: $Id: help+.el,v 1.6 2001/01/10 18:46:49 dadams Exp $
;; Last-Updated: Wed Jan 10 10:45:19 2001
;;           By: dadams
;;     Update #: 1465
;; Keywords: help
;; Compatibility: GNU Emacs 20.x
;;; Commentary: 
;;    Extensions to `help.el'.
;;  Main new functions defined here:
;;    `help-on-click/key', `help-on-click/key-lookup',
;;    `mouse-help-on-click', `mouse-help-on-mode-line-click',
;;    `remove-help-window', `view-emacs-lisp-news',
;;    `save-*Help*-buffer'.
;;  ***** NOTE: The following functions defined in `help.el' have
;;              been REDEFINED HERE:
;;  `describe-function', `describe-key', `describe-mode',
;;  `describe-project', `describe-variable', `help-with-tutorial',
;;  `locate-library', `view-emacs-FAQ', `view-emacs-news', `where-is'.
;;  ***** NOTE: The doc string for `help-for-help' has been
;;              REDEFINED HERE
;;              (see `make-help-screen help-for-help')
;;  The following bindings are made here:
;;    `C-h RET'        `help-on-click/key'
;;    `C-h o'          `edit-options'
;;    `C-h u'          `manual-entry'
;;    `C-h C-a'        `apropos'
;;    `C-h M-a'        `apropos-documentation'
;;    `C-h M-C-a'      `tags-apropos'
;;    `C-h C-l'        `locate-library'
;;    `C-h C-n'        `view-emacs-lisp-news'
;;    `C-h C-s'        `save-*Help*-buffer'
;;    [mouse-1]        `mouse-help-on-click' (non-mode-line)
;;    [mouse-1]        `mouse-help-on-mode-line-click' (mode-line)
;;; Change log:
;; RCS $Log: help+.el,v $
;; RCS Revision 1.6  2001/01/10 18:46:49  dadams
;; RCS 1. Added soft require of frame-cmds.el.
;; RCS 2. Protected remove-windows-on via fboundp.
;; RCS
;; RCS Revision 1.5  2001/01/08 23:04:49  dadams
;; RCS Adapted file header for Emacs Lisp Archive.
;; RCS
;; RCS Revision 1.4  2001/01/03 17:37:20  dadams
;; RCS *** empty log message ***
;; RCS
;; RCS Revision 1.3  2001/01/03 00:39:17  dadams
;; RCS *** empty log message ***
;; RCS
;; RCS Revision 1.2  2000/11/28 20:20:06  dadams
;; RCS Optional require's via 3rd arg=t now.
;; RCS
;; RCS Revision 1.1  2000/09/14 17:20:19  dadams
;; RCS Initial revision
;; RCS
; Revision 1.11  1999/08/12  07:47:02  dadams
; Added doc strings for help-on-click/key(-lookup) and updated header.
; Revision 1.10  1999/04/09  07:26:56  dadams
; help-on-click/key: Treat mouse click on symbol via apropos.
; Revision 1.9  1999/04/08  14:25:36  dadams
; help-on-click/key: 1. Treat mouse menus.
;                    2. Corrected: flush extra mode-line mouse events.
; Revision 1.8  1999/04/08  10:06:20  dadams
; 1. Require info+.el, not info.el.
; 2. help-on-click/key: Bound temp-buffer-show-function so use other win.
; Revision 1.7  1999/04/08  08:44:21  dadams
; 1. Added require: info.el.
; 2. Added require (when compile): help-macro.el.
; 3. Added binding: help-on-click/key.
; 4. Added ###autoloads for bindings.
; 5. Removed fboundp for apropos bindings.
; 6. Added: make-help-screen help-for-help.
; 7. help-on-click/key-lookup: show-*Help*-buffer.
; 8. help-on-click/key: Prompt. Corrected: event->key. show-*Help*-buffer.
; Revision 1.6  1999/04/07  15:39:20  dadams
; 1. Added: (replacement) describe-key.
; 2. Added: help-on-click/key-lookup, help-on-click/key.
; Revision 1.5  1999/04/06  15:23:46  dadams
; Added binding for save-*Help*-buffer.
; Revision 1.4  1999/04/06  15:19:40  dadams
; 1. Added some key bindings: o, u, C-l, C-a, M-a, C-M-a.
; 2. Added: save-*Help*-buffer.
; Revision 1.3  1999/03/31  15:11:46  dadams
; 1. Added autoload.
; 2. Protected symbol-nearest-point with fboundp.
; Revision 1.2  1999/03/17  14:15:39  dadams
; 1. Added header.
; 2. Added require cl & provide help+.
; 3. Added (from old, updated w/ Emacs 34.1 version): remove-help-window,
;    help-with-tutorial, describe-project, view-emacs-FAQ, view-emacs-news,
;    describe-function, describe-variable, where-is, locate-library,
;    view-emacs-lisp-news.
; 4. help-iso-prefix: Treat unbound iso-transl-char-map error. Removed
;    highlighting.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Code:

(require 'cl) ;; unless, when

(require 'info nil t) ;; (no error if not found):
                      ;; Info-exit, Info-goto-node, 
(require 'info+ nil t) ;; (no error if not found):
                       ;; Info-goto-emacs-key-command-node (returns found-p)
                       ;; NOTE: `info+.el' requires `def-face-const.el'
(require 'thingatpt nil t) ;; (no error if not found): symbol-at-point
(require 'thingatpt+ nil t) ;; (no error if not found): symbol-nearest-point
(require 'frame-cmds nil t) ;; (no error if not found): remove-windows-on
(require 'frame-fns nil t) ;; (no error if not found): 1-window-frames-on

;; Get macro `make-help-screen' when this is compiled,
;; or run interpreted, but not when the compiled code is loaded.
  (require 'help-macro nil t) ;; (no error if not found) make-help-screen
  (require 'help-macro+ nil t)) ;; (no error if not found): make-help-screen

(provide 'help+)


(define-key help-map [?\C-m] 'help-on-click/key) ; RET
(define-key help-map [?\C-n] 'view-emacs-lisp-news)
(define-key help-map "o" 'edit-options) ; in `options.el'
(define-key help-map "u" 'manual-entry) ; in `man.el'
(define-key help-map "\C-l" 'locate-library)
(define-key help-map "\C-s" 'save-*Help*-buffer)
(define-key help-map "\C-a" 'apropos)
(define-key help-map "\M-a" 'apropos-documentation)
(define-key help-map "\M-\C-a" 'tags-apropos)
(define-key help-map [down-mouse-1] 'mouse-help-on-click)
(define-key help-map [mode-line down-mouse-1] 'mouse-help-on-mode-line-click)

(defsubst remove-help-window ()
  "If called from `help-for-help', remove display of help window."
  (when (and (eq 'help-for-help this-command)
             (fboundp 'remove-windows-on)) ; Defined in `frame-cmds.el'.
    (remove-windows-on "*Help*")))

;; REPLACES ORIGINAL in `help.el':
;; 1. Uses other window. 
;; 2. Calls `remove-help-window'. 
;; 3. Messages added.
(defun help-with-tutorial (&optional arg)
  "Select the Emacs learn-by-doing tutorial.
If there is a tutorial version written in the language
of the selected language environment, that version is used.
If there's no tutorial in that language, `TUTORIAL' is selected.
With arg, you are asked to choose which language."
  (interactive "P")
  (message "Looking for Emacs Tutorial file ...")
  (let ((lang (if arg
                  (read-language-name 'tutorial "Language: " "English")
                (if (get-language-info current-language-environment 'tutorial)
        file filename)
    (setq filename (get-language-info lang 'tutorial))
    (setq file (expand-file-name (concat "~/" filename)))
    (if (get-file-buffer file)
        (switch-to-buffer-other-window (get-file-buffer file))
      (switch-to-buffer-other-window (create-file-buffer file))
      (setq buffer-file-name file)
      (setq default-directory (expand-file-name "~/"))
      (setq buffer-auto-save-file-name nil)
      (insert-file-contents (expand-file-name filename data-directory))
      (goto-char (point-min))
      (search-forward "\n<<")
      (delete-region (point) (progn (end-of-line) (point)))
      (let ((n (- (window-height (selected-window))
                  (count-lines (point-min) (point))
        (if (< n 12)
            (newline n)
          ;; Some people get confused by the large gap.
          (newline (/ n 2))
          (insert "[Middle of page left blank for didactic purposes.  "
                  "Text continues below]")
          (newline (- n (/ n 2)))))
      (goto-char (point-min))
      (set-buffer-modified-p nil)))
  (message "Looking for Emacs Tutorial file ... done."))

;; REPLACES ORIGINAL in `help.el':
;; Returns nil if KEY is undefined; else returns t.
(defun describe-key (key)
  "Describe the command that a keyboard/menu/mouse sequence invokes.
Argument KEY is a string."
  (interactive "kDescribe command bound to keyboard/menu/mouse sequence: ")
;;;@@@Emacs20  ;; If this key seq ends with a down event, discard the
;;;@@@Emacs20  ;; following click or drag event.  Otherwise that would
;;;@@@Emacs20  ;; erase the message.
;;;@@@Emacs20  (let ((type (aref key (1- (length key)))))
;;;@@@Emacs20    (when (listp type) (setq type (car type)))
;;;@@@Emacs20    (when (and (symbolp type) (memq 'down (event-modifiers type)))
;;;@@@Emacs20      (read-event)))
    (let ((modifiers (event-modifiers (aref key 0)))
          window position)
      ;; For a mouse button event, go to the button it applies to
      ;; to get the right key bindings.  And go to the right place
      ;; in case the keymap depends on where you clicked.
      (if (or (memq 'click modifiers) (memq 'down modifiers)
              (memq 'drag modifiers))
          (setq window (posn-window (event-start (aref key 0)))
                position (posn-point (event-start (aref key 0)))))
      (if (windowp window)
            (set-buffer (window-buffer window))
            (goto-char position)))
      (let ((defn (key-binding key)))
        (cond ((or (null defn) (integerp defn))
               (message "`%s' is undefined." (key-description key))
               nil)                     ; Return nil: undefined.
               (with-output-to-temp-buffer "*Help*"
                 (princ (key-description key))
                 (if (windowp window)
                     (princ " at that spot"))
                 (princ " runs the command ")
                 (prin1 defn)
                 (princ "\n   which is ")
                 (if (>= 20 emacs-major-version)
                     (describe-function-1 defn nil (interactive-p))
                   (describe-function-1 defn nil))
;;;@@@Emacs20                  (save-excursion
;;;@@@Emacs20                    (set-buffer standard-output)
;;;@@@Emacs20                    (help-mode))
               t))))))                  ; Return t: defined.

;; REPLACES ORIGINAL in `help.el':
;; 1. Uses other window.
;; 2. Calls `remove-help-window'. 
;; 3. Messages.
(defun describe-project ()
  "Display information on the GNU project."
  (message "Looking for file describing GNU project ...")
  (find-file-read-only-other-window (expand-file-name "GNU" data-directory))
  (message "Looking for file describing GNU project ... done."))

;; REPLACES ORIGINAL in `help.el':
;; 1. Uses other window. 
;; 2. Calls `remove-help-window'.
;; 3. Messages added. 
;; 4. Turns off `auto-save-mode'.
(defun view-emacs-news (&optional arg)
  "Display information on recent changes to Emacs.
With numeric argument display information on correspondingly older changes."
  (interactive "P")
  (message "Looking for Emacs Changes file ...")
  (let* ((arg (if arg (prefix-numeric-value arg) 0)))
     (expand-file-name (concat (make-string arg ?O) "NEWS")
    (auto-save-mode nil)                  ; Turn it off.
  (message "Looking for Emacs Changes file ... done."))

;; REPLACES ORIGINAL in `help.el':
;; 1. Uses other window. 
;; 2. Calls `remove-help-window'. 
;; 3. Turns off `auto-save-mode'.
(defun view-emacs-FAQ ()
  "Display Frequently Asked Questions about Emacs (with answers)."
  (message "Looking for Emacs FAQ file ...")
  (find-file-read-only-other-window (expand-file-name "FAQ" data-directory))
  (auto-save-mode nil)                  ; Turn it off.
  (message "Looking for Emacs FAQ file ... done."))

;; REPLACES ORIGINAL in `help.el':
;; Updated key bindings.
(make-help-screen help-for-help
  "RET [abcCfFhiIklLmnopstuvw] C-[acdfiklnpsw] M-a C-M-a (? for more help):"
  "This is the Emacs `help-command', accessible via `%THIS-KEY%'.
Type a Help option (below) now, for help on a particular topic.
Use \\<help-map>`\\[scroll-up]' or `\\[scroll-down]' to scroll this text.  \
Type `\\[help-quit]' to exit Help.
\(A \"command\" is any function that you can execute via `M-x'.)

\\[help-on-click/key] `help-on-click/key': Help on any key sequence or anything 
    click with the mouse.
\\[describe-mode]   `describe-mode': Describes the current major and minor \
\\[describe-bindings]   `describe-bindings': Shows all current bindings \
\(mode-local and
    global): keyboard, menu bar, and mouse sequences.
\\[apropos-command]   `apropos-command': Gives commands that contain a \
given string.
    (see `\\[apropos]' and `\\[apropos-documentation]', below)
\\[describe-key-briefly]   `describe-key-briefly': Identifies the command \
bound to a given
    keyboard/menu/mouse sequence.  (see `\\[describe-key]', below)
\\[describe-key]   `describe-key': Describes the command that is bound to \
a given
    keyboard/menu/mouse sequence.
\\[Info-goto-emacs-key-command-node] `Info-goto-emacs-key-command-node': \
Shows the Info doc for the
    command bound to a given keyboard/menu/mouse sequence. (see `\\[info]')
\\[describe-function]   `describe-function': Shows the doc on an Emacs \
\\[Info-goto-emacs-command-node] `Info-goto-emacs-command-node'.  Takes you \
to the Info doc node
    for a given command.  (see `\\[info]')
\\[info]   `info': Enters the Info hypertext documentation browser.
\\[view-lossage]   `view-lossage': Shows what you just did (last 100 

\\[help-with-tutorial]   `help-with-tutorial': Starts up a tutorial for \
learning Emacs.
\\[view-emacs-FAQ]   `view-emacs-FAQ': Explains Frequently Asked Emacs \

\\[edit-options]   `edit-options': Edit user options (vars), with values \
and doc.
\\[save-*Help*-buffer] `save-*Help*-buffer': Rename *Help* buffer as \
buffer *Help*<N>.
\\[describe-variable]   `describe-variable': Gives a variable's value & \
\\[where-is]   `where-is': Identifies keyboard/menu/mouse sequences that \
    a given command.
\\[apropos] `apropos': Gives functions and variables containing a
    given string.  (see `\\[command-apropos]' and `\\[apropos-documentation]')
\\[apropos-documentation] `apropos-documentation': Gives fns and vars whose \
doc contains a
    given string. (see `\\[command-apropos]' and `\\[apropos]')
\\[tags-apropos] `tags-apropos'.  Shows the tags matched by a given string.
\\[describe-syntax]   `describe-syntax': Explains the current syntax table.
\\[manual-entry]   `manual-entry': Gives the Unix Manual entry for a given \
\\[finder-by-keyword]   `finder-by-keyword':  Finds Lisp libraries matching \
a topic.
\\[locate-library] `locate-library': Gives the path name of an Emacs Lisp \
\\[view-emacs-news]   `view-emacs-news': Describes the latest Emacs changes.
\\[view-emacs-lisp-news] `view-emacs-lisp-news'; Describes latest Emacs \
Lisp changes.
\\[describe-copying] `describe-copying': Show GNU Emacs General Public License.
\\[describe-distribution] `describe-distribution': Show Emacs ordering 
\\[describe-project] `describe-project': Show information about the GNU project.
\\[describe-no-warranty] `describe-no-warranty': Show information on absence of 

\\[describe-coding-system]   `describe-coding-system': Describes a specific 
coding system
    (if you type its name) or the coding systems currently in use
    (if you type just RET).
\\[describe-input-method]   `describe-input-method' Describes a specific input 
    (if you type its name) or the current input method (if you type just RET).
\\[info-lookup-symbol]  `info-lookup-symbol' Displays the definition of a symbol
    as found in the manual for the language this buffer is written in.
\\[describe-language-environment]   `describe-language-environment' Describes a
    specific language environment (if you type its name)
    or the current language environment (if you type just RET).
h   Display the HELLO file which illustrates various scripts.

(or (fboundp 'old-describe-mode)
    (fset 'old-describe-mode (symbol-function 'describe-mode)))

;; REPLACES ORIGINAL in `help.el':
;; 1. Provides message telling how to change pages in *Help* buffer.
;; 2. Doc string also explains this.
;;    Really, the text at the beginning of *Help* should explain this - TO BE 
(defun describe-mode ()
  "Display documentation of current major mode and minor modes.  
Each mode (minor or major) is displayed on a different \"page\" in the
*Help* buffer (the pages are separated by `^L' characters).
You can change pages with `\\[forward-page]' and `\\[backward-page]'.

Note: For a minor mode to be described correctly here, the mode's
indicator variable (listed in `minor-mode-alist') must also be a
function whose documentation describes the minor mode."
  (let ((font-lock-verbose nil));; This should inhibit msgs, but doesn't!
    (message (substitute-command-keys
              "You can use `\\[forward-page]' and `\\[backward-page]' \
in *Help* buffer to change pages."))))

;; REPLACES ORIGINAL in `help.el':
;; Preferred candidate is `symbol-nearest-point'.
(defun describe-function (function)
  "Display the full documentation of FUNCTION (a symbol).
FUNCTION names an Emacs Lisp function, possibly a user command.
Default candidate is: preferably the `symbol-nearest-point', or else
the innermost function call surrounding point
\(`function-called-at-point').  Returns the description that was
displayed, as a string."
   (let ((fn (or (and (fboundp 'symbol-nearest-point)(symbol-nearest-point))
         (enable-recursive-minibuffers t))
     (list (intern (completing-read
                    "Describe function: " obarray 'fboundp t
                    (and fn (symbol-name fn)) nil
                    (and fn (symbol-name fn)) t)))))
  (unless (fboundp function)
    (error "Not a defined Emacs function: `%s'." function))
  (with-output-to-temp-buffer "*Help*"
    (prin1 function)
    ;; Use " is " instead of a colon so that
    ;; it is easier to get out the function name using forward-sexp.
    (princ " is ")
    (if (>= 20 emacs-major-version)
        (describe-function-1 function nil (interactive-p))
      (describe-function-1 function nil))
      (set-buffer standard-output)
;;;@@@Emacs20       (help-mode) 
      ;; Return the text we displayed.

;; REPLACES ORIGINAL in `help.el':
;; Preferred candidate is `symbol-nearest-point'.
;; Uses `substitute-command-keys' on doc string.
(defun describe-variable (variable)
  "Display the full documentation of VARIABLE (a symbol).
VARIABLE names an Emacs Lisp variable, possibly a user option.
Default candidate is the `symbol-nearest-point'.
Returns the documentation as a string."
   (let ((symb (or (and (fboundp 'symbol-nearest-point)(symbol-nearest-point))
                   (and (symbolp (variable-at-point)))))
         (enable-recursive-minibuffers t))
     (list (intern (completing-read
                    "Describe variable: " obarray 'boundp t
                    (and symb (symbol-name symb)) nil
                    (and symb (symbol-name symb)) t)))))
  (unless (boundp variable)
    (error "Not a defined Emacs variable: `%s'." variable))
  (let (valvoid)
    (with-output-to-temp-buffer "*Help*"
      (prin1 variable)
      (if (not (boundp variable))
            (princ " is void")
            (setq valvoid t))
        (princ "'s value is ")
        (pp (symbol-value variable))
      (if (local-variable-p variable)
            (princ (format "Local in buffer %s; " (buffer-name)))
            (if (not (default-boundp variable))
                (princ "globally void")
              (princ "global value is ")
              (pp (default-value variable)))
       (set-buffer standard-output)
       (if (> (count-lines (point-min) (point-max)) 10)
             (goto-char (point-min))
             (if valvoid
                 (forward-line 1)
               (forward-sexp 1)
               (delete-region (point) (progn (end-of-line) (point)))
               (insert "'s value is shown below.\n\n")
                 (insert "\n\nValue:"))))))
      (princ "Documentation:")
      (let ((doc (documentation-property variable 'variable-documentation)))
        (if (and doc (not (string= "" doc)))
            (princ (substitute-command-keys doc))
          (princ "Not documented as a variable.")))
      (when (>= 20 emacs-major-version)
        (help-setup-xref (list #'describe-variable variable) (interactive-p))

        ;; Make a link to customize if this variable can be customized.
        ;; Note, it is not reliable to test only for a custom-type property
        ;; because those are only present after the var's definition
        ;; has been loaded.
        (if (or (get variable 'custom-type) ; after defcustom
                (get variable 'custom-loads) ; from loaddefs.el
                (get variable 'standard-value)) ; from cus-start.el
            (let ((customize-label "customize"))
              (princ (concat "You can " customize-label " this variable."))
              (with-current-buffer "*Help*"
                   (concat "\\(" customize-label "\\)") nil t)
                  (help-xref-button 1 #'(lambda (v)
                                          (customize-variable v)) variable)
        ;; Make a hyperlink to the library if appropriate.  (Don't
        ;; change the format of the buffer's initial line in case
        ;; anything expects the current format.)
        (when (string-match "20.6" emacs-version)
          (let ((file-name (symbol-file variable)))
            (when file-name
              (princ "\n\nDefined in `")
              (princ file-name)
              (princ "'.")
              (with-current-buffer "*Help*"
                  (re-search-backward "`\\([^`']+\\)'" nil t)
                  (help-xref-button 1 (lambda (arg)
                                        (let ((location
                                               (find-variable-noselect arg)))
                                          (pop-to-buffer (car location))
                                          (goto-char (cdr location))))

        (set-buffer standard-output)
;;;@@@Emacs20         (help-mode)
        ;; Return the text we displayed.

;; REPLACES ORIGINAL in `help.el':
;; 1. Preferred candidate is `symbol-nearest-point'.
;; 2. Must be a command, not just a function.
;; 3. Calls `remove-help-window'.
(defun where-is (definition &optional insert)
  "Give keyboard/menu/mouse sequences that invoke specified command.
Argument DEFINITION is a command definition, usually a symbol with a
function definition.  Default candidate is: preferably the
`symbol-nearest-point', or else the innermost function call
surrounding point (`function-called-at-point').
Non-nil prefix arg INSERT means insert the message in the buffer."
   (let ((fn (or (and (fboundp 'symbol-nearest-point)(symbol-nearest-point))
         (enable-recursive-minibuffers t))
     (list (intern (completing-read "Where is command: " obarray 'commandp t
                                    (and fn (symbol-name fn)) nil
                                    (and fn (symbol-name fn)) t)))))
  (let* ((keys (where-is-internal definition overriding-local-map nil nil))
         (keys1 (mapconcat 'key-description keys ", "))
         (standard-output (if insert (current-buffer) t)))
    (if insert
        (if (> (length keys1) 0)
            (princ (format "%s (%s)" keys1 definition))
          (princ (format "M-x %s RET" definition)))
      (if (> (length keys1) 0)
          (princ (format "`%s' is on `%s'" definition keys1))
        (princ (format "`%s' is not on any key" definition)))))

;; REPLACES ORIGINAL in `help.el': 
;; Calls `remove-help-window'. 
(defun locate-library (library &optional nosuffix path interactive-call)
  "Show the full path name of Emacs library LIBRARY.
This command searches the directories in your `load-path' like
`M-x load-library' to find the file that would be loaded by
`M-x load-library RET LIBRARY RET'.

Optional second arg NOSUFFIX non-nil means don't add suffixes `.elc'
or `.el' to the specified name LIBRARY (like calling `load' instead of

If the optional third arg PATH is specified, that list of directories
is used instead of `load-path'.

When called from a program, the file name is normaly returned as a
string.  When run interactively, the argument INTERACTIVE-CALL is t,
and the file name is displayed in the echo area."
  (interactive (list (read-string "Locate library: ")
                     nil nil
  (let (result)
    (catch 'answer
       (lambda (dir)
         (mapcar (lambda (suf)
                   (let ((try (expand-file-name
                               (concat library suf)
                     (when (and (file-readable-p try)
                                (null (file-directory-p try)))
                       (setq result try)
                       (message "Library is file `%s'." try)
                       (throw 'answer try))))

                 (if nosuffix
                   '(".elc" ".el" "")
;;; load doesn't handle this yet.
;;;         (let ((basic '(".elc" ".el" ""))
;;;               (compressed '(".Z" ".gz" "")))
;;;           ;; If autocompression mode is on,
;;;           ;; consider all combinations of library suffixes
;;;           ;; and compression suffixes.
;;;           (if (rassq 'jka-compr-handler file-name-handler-alist)
;;;               (apply 'nconc
;;;                      (mapcar (lambda (compelt)
;;;                                (mapcar (lambda (baselt)
;;;                                          (concat baselt compelt))
;;;                                        basic))
;;;                              compressed))
;;;             basic))
       (or path load-path)))
    (and interactive-call
         (if result
             (message "Library is file `%s'" result)
           (message "No library `%s' in search path." library)))

(defun view-emacs-lisp-news ()
  "Display information on recent changes to Emacs Lisp."
  (message "Looking for Emacs Lisp Changes file ...")
  (find-file-read-only-other-window (expand-file-name "LNEWS" data-directory))
  (auto-save-mode nil)                  ; Turn it off.
  (message "Looking for Emacs Lisp Changes file ... done."))

;;;@@@Emacs20 (defvar iso-transl-char-map)              ; To quiet byte compiler

;;;@@@Emacs20 ;;;###autoload
;;;@@@Emacs20 (defun help-iso-prefix ()
;;;@@@Emacs20   "Displays commands bound to ISO (pseudo-)prefix key sequences.
;;;@@@Emacs20 That is, displays a list of the alternatives that can follow the
;;;@@@Emacs20 ISO prefix key.
;;;@@@Emacs20 This is the same behavior that you get for the \"C-x\" prefix 
when you
;;;@@@Emacs20 type `C-x C-h'.  Whatever the ISO prefix key is now, it is 
treated the
;;;@@@Emacs20 same way by this command.  Normally, then, `help-iso-prefix' 
should be
;;;@@@Emacs20 bound to `KEY C-h', where KEY is the ISO prefix key."
;;;@@@Emacs20   (interactive)
;;;@@@Emacs20   (unless (boundp 'iso-transl-char-map)
;;;@@@Emacs20     (error "No ISO prefix key defined."))
;;;@@@Emacs20   (let* ((key (this-command-keys))
;;;@@@Emacs20          (prefix (make-vector (1- (length key)) nil))
;;;@@@Emacs20          (prefix-len (length prefix))
;;;@@@Emacs20          (i 0))
;;;@@@Emacs20     (while (< i prefix-len) (aset prefix i (aref key i)) (incf i))
;;;@@@Emacs20     (setq prefix (key-description prefix)) ; Reuse vars prefix & 
;;;@@@Emacs20     (setq prefix-len (- 15 (length prefix)))
;;;@@@Emacs20     (with-output-to-temp-buffer "*Help*"
;;;@@@Emacs20       (princ "Global Bindings Starting With ")
;;;@@@Emacs20       (princ prefix) (princ ":") (terpri)
;;;@@@Emacs20       (princ "key             binding") (terpri)
;;;@@@Emacs20       (princ "---             -------") (terpri) (terpri)
;;;@@@Emacs20       (dolist (seq iso-transl-char-map)
;;;@@@Emacs20         (setq i 0) (princ prefix) (princ " ") (princ (car seq)) ; 
Reuse var i.
;;;@@@Emacs20         (while (< i (- prefix-len (length (car seq)))) (princ " 
") (incf i))
;;;@@@Emacs20         (princ (key-description (cdr seq))) (terpri))))
;;;@@@Emacs20   (when (fboundp 'show-*Help*-buffer) (show-*Help*-buffer))) ; In 

(defun save-*Help*-buffer ()
  "Rename *Help* buffer as new buffer *Help*<N>, N=2,3...."
  (let ((notifying-user-of-mode nil)    ; No msg on mode (in `misc-fns.el').
        (saved-help (buffer-name (generate-new-buffer "*Help*"))))
      (set-buffer "*Help*")
      (copy-to-buffer saved-help (point-min) (point-max))
      (when (interactive-p)
        (message "Saved contents of *Help* buffer to buffer %s."

(defun help-on-click/key-lookup (key &optional pp-key where)
  "Look up information on KEY via `describe-key' and `info'.
Optional args PP-KEY and WHERE are strings naming KEY and its type.
Their defaults are KEY's `key-description' and \"Key sequence\".
Function `Info-goto-emacs-key-command-node' is used to look up KEY."
  (sit-for 0 200) ;; HACK to fix bug if click on scroll bar in 
  (setq where (or where "Key sequence "))
  (setq pp-key (or pp-key (key-description key)))
  (let* ((described-p (describe-key key))
         ;; The version of `Info-goto-emacs-key-command-node' defined in 
`info+.el' will return
         ;; non-nil if Info doc is found.  The standard version defined 
`info.el' will not.
         (documented-p (Info-goto-emacs-key-command-node key))) ; NIL if only 
have std version.
    (when (and (not documented-p)(get-buffer-window "*info*" 'visible)) 
    (cond ((and described-p documented-p)
           (when (fboundp 'show-*Help*-buffer) (show-*Help*-buffer))
           (message "%s`%s': summary in *Help* buffer; doc in *info* buffer."
                    where pp-key))
           (when (fboundp 'show-*Help*-buffer) (show-*Help*-buffer))
           (message "%s`%s': summary in *Help* buffer." where pp-key))
           (message "%s`%s': doc in *info* buffer." where pp-key))
           (message "%s`%s' is undefined." where pp-key)))))

(defun help-on-click/key (key)
  "Give help on a key/menu sequence or object clicked with the mouse.
The object can be any part of an Emacs window or a name appearing in a
buffer.  You can do any of the following:

    type a key sequence (e.g. `C-M-s')
    choose a menu item (e.g. [menu-bar files open-file])
    click on a scroll bar
    click on the mode line
    click in the minibuffer
    click on an Emacs-related name in a buffer: apropos is called
    click anywhere else in a buffer: its modes are described

Help is generally provided using `describe-key' and the Emacs online
manual (via `Info-goto-emacs-key-command-node').  If no entry is found
in the index of the Emacs manual, then the manual is searched from the
beginning for literal occurrences of KEY.

For example, the KEY `C-g' is not in the index (for some reason), so
the manual is searched.  (Once an occurrence is found, you can
repeatedly type `s' in *Info* to search for additional occurrences.)

If you click on a name in a buffer, then `apropos-documentation' and
`apropos' are used to find information on the name.  These functions
are not used when you do something besides click on a name.

If you click elsewhere in a buffer other than the minibuffer, then
`describe-mode' is used to describe the buffer's current mode(s)."
  (interactive "kClick mouse on something or type a key sequence.")
  (let ((temp-buffer-show-function 'switch-to-buffer-other-window)
        (font-lock-verbose nil)
        (global-font-lock-mode nil))
    ;; DEBUG (message "KEY: `%s'" key)(sit-for 4) ; DEBUG
    (cond ((stringp key)
           (help-on-click/key-lookup key))
          (t                            ; Vector.
           (let ((type (aref key 0)))
             (cond ((or (symbolp type)(integerp type))
                    (cond ((eq 'mode-line type) ; Click on the mode line.
                           (Info-goto-node "(emacs)Mode Line")
                           (message "Mode line: decribed in *info* buffer."))
                          (t            ; Normal key sequence.
                           (help-on-click/key-lookup key))))
                   ((eq 'menu-bar (car type))

                    (help-on-click/key-lookup key (aref key (1- (length key))) 
"Menu item "))
                   ((not (eq 'down (car (event-modifiers (car type))))) ; e.g. 
mouse menus
                    (help-on-click/key-lookup key))
                   (t                   ; Mouse click.
                    (setq key type)
                    (cond ((window-minibuffer-p ; Click in minibuffer.
                            (posn-window (event-start key)))
                           (Info-goto-node "(emacs)Minibuffer")
                           (message "Minibuffer: decribed in *info* buffer."))
                           (let ((symb (save-excursion (mouse-set-point key)
                                 (apropos-do-all t)
                                 (found-doc nil)
                                 (found nil)
                                 (symb-regexp nil))
                             (cond (symb
                                    (message "Looking for info apropos `%s'..." 
                                    (when (get-buffer "*Apropos Doc*")
                                      (kill-buffer (get-buffer "*Apropos 
                                    (setq found-doc
                                           (setq symb-regexp
                                                  (setq symb (format "%s" 
                                    (when found-doc 
                                        (set-buffer (get-buffer "*Apropos*"))
                                        (rename-buffer "*Apropos Doc*"))
                                      (when (fboundp '1-window-frames-on) ; In 
                                        (let ((frames (1-window-frames-on 
"*Apropos Doc*")))
                                          (while frames
                                              (select-frame (car frames))
                                              (rename-frame nil "*Apropos Doc*")
                                              (pop frames))))))
                                    (setq found (apropos symb-regexp))
                                    ;; Remove empty stuff.
                                    (setq found
                                          (and (consp found) (or (cdr found) 
(cadr found))))
                                    ;; Remove *Apropos* window that was 
displayed needlessly.
                                    (unless (or found (not (fboundp 
                                      (remove-windows-on "*Apropos*"))
                                     ((and found-doc found)
                                       "See *Apropos* and *Apropos Doc* 
                                       "See information on `%s' in the 
*Apropos* buffer."
                                       "See information on `%s' in the *Apropos 
Doc* buffer."
                                       "No information found regarding `%s'."
                                   (t   ; User clicked in buffer, but not on a 
                                    (let ((bufname (buffer-name 
                                          (fboundp 'show-*Help*-buffer) 
                                       "Mode(s) of buffer `%s' are described in 
*Help* buffer."

(defun mouse-help-on-click (click)
  "Give help on an object clicked with the mouse."
  (interactive "e")
  (help-on-click/key (vector click)))

(defun mouse-help-on-mode-line-click (click)
  "Give help on the mode line."
  (interactive "e")
  (help-on-click/key (vector 'mode-line click)))

;;; `help+.el' ends here

reply via email to

[Prev in Thread] Current Thread [Next in Thread]