LCOV - code coverage report
Current view: top level - lisp/emacs-lisp - eldoc.el (source / functions) Hit Total Coverage
Test: tramp-tests.info Lines: 18 117 15.4 %
Date: 2017-08-27 09:44:50 Functions: 5 20 25.0 %

          Line data    Source code
       1             : ;;; eldoc.el --- Show function arglist or variable docstring in echo area  -*- lexical-binding:t; -*-
       2             : 
       3             : ;; Copyright (C) 1996-2017 Free Software Foundation, Inc.
       4             : 
       5             : ;; Author: Noah Friedman <friedman@splode.com>
       6             : ;; Maintainer: friedman@splode.com
       7             : ;; Keywords: extensions
       8             : ;; Created: 1995-10-06
       9             : 
      10             : ;; This file is part of GNU Emacs.
      11             : 
      12             : ;; GNU Emacs is free software: you can redistribute it and/or modify
      13             : ;; it under the terms of the GNU General Public License as published by
      14             : ;; the Free Software Foundation, either version 3 of the License, or
      15             : ;; (at your option) any later version.
      16             : 
      17             : ;; GNU Emacs is distributed in the hope that it will be useful,
      18             : ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             : ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             : ;; GNU General Public License for more details.
      21             : 
      22             : ;; You should have received a copy of the GNU General Public License
      23             : ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
      24             : 
      25             : ;;; Commentary:
      26             : 
      27             : ;; This program was inspired by the behavior of the "mouse documentation
      28             : ;; window" on many Lisp Machine systems; as you type a function's symbol
      29             : ;; name as part of a sexp, it will print the argument list for that
      30             : ;; function.  Behavior is not identical; for example, you need not actually
      31             : ;; type the function name, you need only move point around in a sexp that
      32             : ;; calls it.  Also, if point is over a documented variable, it will print
      33             : ;; the one-line documentation for that variable instead, to remind you of
      34             : ;; that variable's meaning.
      35             : 
      36             : ;; One useful way to enable this minor mode is to put the following in your
      37             : ;; .emacs:
      38             : ;;
      39             : ;;      (add-hook 'emacs-lisp-mode-hook 'eldoc-mode)
      40             : ;;      (add-hook 'lisp-interaction-mode-hook 'eldoc-mode)
      41             : ;;      (add-hook 'ielm-mode-hook 'eldoc-mode)
      42             : ;;      (add-hook 'eval-expression-minibuffer-setup-hook 'eldoc-mode)
      43             : 
      44             : ;; Major modes for other languages may use ElDoc by defining an
      45             : ;; appropriate function as the buffer-local value of
      46             : ;; `eldoc-documentation-function'.
      47             : 
      48             : ;;; Code:
      49             : 
      50             : (defgroup eldoc nil
      51             :   "Show function arglist or variable docstring in echo area."
      52             :   :group 'lisp
      53             :   :group 'extensions)
      54             : 
      55             : (defcustom eldoc-idle-delay 0.50
      56             :   "Number of seconds of idle time to wait before printing.
      57             : If user input arrives before this interval of time has elapsed after the
      58             : last input, no documentation will be printed.
      59             : 
      60             : If this variable is set to 0, no idle time is required."
      61             :   :type 'number
      62             :   :group 'eldoc)
      63             : 
      64             : (defcustom eldoc-print-after-edit nil
      65             :   "If non-nil eldoc info is only shown when editing.
      66             : Changing the value requires toggling `eldoc-mode'."
      67             :   :type 'boolean
      68             :   :group 'eldoc)
      69             : 
      70             : ;;;###autoload
      71             : (defcustom eldoc-minor-mode-string (purecopy " ElDoc")
      72             :   "String to display in mode line when ElDoc Mode is enabled; nil for none."
      73             :   :type '(choice string (const :tag "None" nil))
      74             :   :group 'eldoc)
      75             : 
      76             : (defcustom eldoc-argument-case #'identity
      77             :   "Case to display argument names of functions, as a symbol.
      78             : This has two preferred values: `upcase' or `downcase'.
      79             : Actually, any name of a function which takes a string as an argument and
      80             : returns another string is acceptable.
      81             : 
      82             : Note that this variable has no effect, unless
      83             : `eldoc-documentation-function' handles it explicitly."
      84             :   :type '(radio (function-item upcase)
      85             :                 (function-item downcase)
      86             :                 function)
      87             :   :group 'eldoc)
      88             : (make-obsolete-variable 'eldoc-argument-case nil "25.1")
      89             : 
      90             : (defcustom eldoc-echo-area-use-multiline-p 'truncate-sym-name-if-fit
      91             :   "Allow long ElDoc messages to resize echo area display.
      92             : If value is t, never attempt to truncate messages; complete symbol name
      93             : and function arglist or 1-line variable documentation will be displayed
      94             : even if echo area must be resized to fit.
      95             : 
      96             : If value is any non-nil value other than t, symbol name may be truncated
      97             : if it will enable the function arglist or documentation string to fit on a
      98             : single line without resizing window.  Otherwise, behavior is just like
      99             : former case.
     100             : 
     101             : If value is nil, messages are always truncated to fit in a single line of
     102             : display in the echo area.  Function or variable symbol name may be
     103             : truncated to make more of the arglist or documentation string visible.
     104             : 
     105             : Note that this variable has no effect, unless
     106             : `eldoc-documentation-function' handles it explicitly."
     107             :   :type '(radio (const :tag "Always" t)
     108             :                 (const :tag "Never" nil)
     109             :                 (const :tag "Yes, but truncate symbol names if it will\
     110             :  enable argument list to fit on one line" truncate-sym-name-if-fit))
     111             :   :group 'eldoc)
     112             : 
     113             : (defface eldoc-highlight-function-argument
     114             :   '((t (:inherit bold)))
     115             :   "Face used for the argument at point in a function's argument list.
     116             : Note that this face has no effect unless the `eldoc-documentation-function'
     117             : handles it explicitly."
     118             :   :group 'eldoc)
     119             : 
     120             : ;;; No user options below here.
     121             : 
     122             : (defvar eldoc-message-commands-table-size 31
     123             :   "Used by `eldoc-add-command' to initialize `eldoc-message-commands' obarray.
     124             : It should probably never be necessary to do so, but if you
     125             : choose to increase the number of buckets, you must do so before loading
     126             : this file since the obarray is initialized at load time.
     127             : Remember to keep it a prime number to improve hash performance.")
     128             : 
     129             : (defvar eldoc-message-commands
     130             :   ;; Don't define as `defconst' since it would then go to (read-only) purespace.
     131             :   (make-vector eldoc-message-commands-table-size 0)
     132             :   "Commands after which it is appropriate to print in the echo area.
     133             : ElDoc does not try to print function arglists, etc., after just any command,
     134             : because some commands print their own messages in the echo area and these
     135             : functions would instantly overwrite them.  But `self-insert-command' as well
     136             : as most motion commands are good candidates.
     137             : This variable contains an obarray of symbols; do not manipulate it
     138             : directly.  Instead, use `eldoc-add-command' and `eldoc-remove-command'.")
     139             : 
     140             : ;; Not a constant.
     141             : (defvar eldoc-last-data (make-vector 3 nil)
     142             :   ;; Don't define as `defconst' since it would then go to (read-only) purespace.
     143             :   "Bookkeeping; elements are as follows:
     144             :   0 - contains the last symbol read from the buffer.
     145             :   1 - contains the string last displayed in the echo area for variables,
     146             :       or argument string for functions.
     147             :   2 - `function' if function args, `variable' if variable documentation.")
     148             : (make-obsolete-variable 'eldoc-last-data "use your own instead" "25.1")
     149             : 
     150             : (defvar eldoc-last-message nil)
     151             : 
     152             : (defvar eldoc-timer nil "ElDoc's timer object.")
     153             : 
     154             : (defvar eldoc-current-idle-delay eldoc-idle-delay
     155             :   "Idle time delay currently in use by timer.
     156             : This is used to determine if `eldoc-idle-delay' is changed by the user.")
     157             : 
     158             : (defvar eldoc-message-function #'eldoc-minibuffer-message
     159             :   "The function used by `eldoc-message' to display messages.
     160             : It should receive the same arguments as `message'.")
     161             : 
     162             : (defun eldoc-edit-message-commands ()
     163             :   "Return an obarray containing common editing commands.
     164             : 
     165             : When `eldoc-print-after-edit' is non-nil, ElDoc messages are only
     166             : printed after commands contained in this obarray."
     167           0 :   (let ((cmds (make-vector 31 0))
     168           0 :         (re (regexp-opt '("delete" "insert" "edit" "electric" "newline"))))
     169           0 :     (mapatoms (lambda (s)
     170           0 :                 (and (commandp s)
     171           0 :                      (string-match-p re (symbol-name s))
     172           0 :                      (intern (symbol-name s) cmds)))
     173           0 :               obarray)
     174           0 :     cmds))
     175             : 
     176             : 
     177             : ;;;###autoload
     178             : (define-minor-mode eldoc-mode
     179             :   "Toggle echo area display of Lisp objects at point (ElDoc mode).
     180             : With a prefix argument ARG, enable ElDoc mode if ARG is positive,
     181             : and disable it otherwise.  If called from Lisp, enable ElDoc mode
     182             : if ARG is omitted or nil.
     183             : 
     184             : ElDoc mode is a buffer-local minor mode.  When enabled, the echo
     185             : area displays information about a function or variable in the
     186             : text where point is.  If point is on a documented variable, it
     187             : displays the first line of that variable's doc string.  Otherwise
     188             : it displays the argument list of the function called in the
     189             : expression point is on."
     190             :   :group 'eldoc :lighter eldoc-minor-mode-string
     191          47 :   (setq eldoc-last-message nil)
     192          47 :   (cond
     193          47 :    ((not (eldoc--supported-p))
     194           0 :     (when (called-interactively-p 'any)
     195           0 :       (message "There is no ElDoc support in this buffer"))
     196           0 :     (setq eldoc-mode nil))
     197          47 :    (eldoc-mode
     198          47 :     (when eldoc-print-after-edit
     199          47 :       (setq-local eldoc-message-commands (eldoc-edit-message-commands)))
     200          47 :     (add-hook 'post-command-hook 'eldoc-schedule-timer nil t)
     201          47 :     (add-hook 'pre-command-hook 'eldoc-pre-command-refresh-echo-area nil t))
     202             :    (t
     203           0 :     (kill-local-variable 'eldoc-message-commands)
     204           0 :     (remove-hook 'post-command-hook 'eldoc-schedule-timer t)
     205           0 :     (remove-hook 'pre-command-hook 'eldoc-pre-command-refresh-echo-area t)
     206           0 :     (when eldoc-timer
     207           0 :       (cancel-timer eldoc-timer)
     208          47 :       (setq eldoc-timer nil)))))
     209             : 
     210             : ;;;###autoload
     211             : (define-globalized-minor-mode global-eldoc-mode eldoc-mode turn-on-eldoc-mode
     212             :   :group 'eldoc
     213             :   :initialize 'custom-initialize-delay
     214             :   :init-value t)
     215             : 
     216             : ;;;###autoload
     217             : (defun turn-on-eldoc-mode ()
     218             :   "Turn on `eldoc-mode' if the buffer has ElDoc support enabled.
     219             : See `eldoc-documentation-function' for more detail."
     220         112 :   (when (eldoc--supported-p)
     221         112 :     (eldoc-mode 1)))
     222             : 
     223             : (defun eldoc--supported-p ()
     224             :   "Non-nil if an ElDoc function is set for this buffer."
     225         159 :   (not (memq eldoc-documentation-function '(nil ignore))))
     226             : 
     227             : 
     228             : (defun eldoc-schedule-timer ()
     229             :   "Ensure `eldoc-timer' is running.
     230             : 
     231             : If the user has changed `eldoc-idle-delay', update the timer to
     232             : reflect the change."
     233           0 :   (or (and eldoc-timer
     234           0 :            (memq eldoc-timer timer-idle-list)) ;FIXME: Why?
     235           0 :       (setq eldoc-timer
     236           0 :             (run-with-idle-timer
     237           0 :              eldoc-idle-delay nil
     238             :              (lambda ()
     239           0 :                (when (or eldoc-mode
     240           0 :                          (and global-eldoc-mode
     241           0 :                               (eldoc--supported-p)))
     242           0 :                  (eldoc-print-current-symbol-info))))))
     243             : 
     244             :   ;; If user has changed the idle delay, update the timer.
     245           0 :   (cond ((not (= eldoc-idle-delay eldoc-current-idle-delay))
     246           0 :          (setq eldoc-current-idle-delay eldoc-idle-delay)
     247           0 :          (timer-set-idle-time eldoc-timer eldoc-idle-delay t))))
     248             : 
     249             : (defvar eldoc-mode-line-string nil)
     250             : (put 'eldoc-mode-line-string 'risky-local-variable t)
     251             : 
     252             : (defun eldoc-minibuffer-message (format-string &rest args)
     253             :   "Display messages in the mode-line when in the minibuffer.
     254             : Otherwise work like `message'."
     255           0 :   (if (minibufferp)
     256           0 :       (progn
     257           0 :         (add-hook 'minibuffer-exit-hook
     258           0 :                   (lambda () (setq eldoc-mode-line-string nil
     259             :                               ;; http://debbugs.gnu.org/16920
     260           0 :                               eldoc-last-message nil))
     261           0 :                   nil t)
     262           0 :         (with-current-buffer
     263           0 :             (window-buffer
     264           0 :              (or (window-in-direction 'above (minibuffer-window))
     265           0 :                  (minibuffer-selected-window)
     266           0 :                  (get-largest-window)))
     267           0 :           (unless (and (listp mode-line-format)
     268           0 :                        (assq 'eldoc-mode-line-string mode-line-format))
     269           0 :             (setq mode-line-format
     270           0 :                   (list "" '(eldoc-mode-line-string
     271             :                              (" " eldoc-mode-line-string " "))
     272           0 :                         mode-line-format)))
     273           0 :           (setq eldoc-mode-line-string
     274           0 :                 (when (stringp format-string)
     275           0 :                   (apply #'format-message format-string args)))
     276           0 :           (force-mode-line-update)))
     277           0 :     (apply 'message format-string args)))
     278             : 
     279             : (defun eldoc-message (&optional format-string &rest args)
     280             :   "Display FORMAT-STRING formatted with ARGS as an ElDoc message.
     281             : 
     282             : Store the message (if any) in `eldoc-last-message', and return it."
     283           0 :   (let ((omessage eldoc-last-message))
     284           0 :     (setq eldoc-last-message
     285           0 :           (cond ((eq format-string eldoc-last-message) eldoc-last-message)
     286           0 :                 ((null format-string) nil)
     287             :                 ;; If only one arg, no formatting to do, so put it in
     288             :                 ;; eldoc-last-message so eq test above might succeed on
     289             :                 ;; subsequent calls.
     290           0 :                 ((null args) format-string)
     291           0 :                 (t (apply #'format-message format-string args))))
     292             :     ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages
     293             :     ;; are recorded in a log.  Do not put eldoc messages in that log since
     294             :     ;; they are Legion.
     295             :     ;; Emacs way of preventing log messages.
     296           0 :     (let ((message-log-max nil))
     297           0 :       (cond (eldoc-last-message
     298           0 :              (funcall eldoc-message-function "%s" eldoc-last-message))
     299           0 :             (omessage (funcall eldoc-message-function nil)))))
     300           0 :   eldoc-last-message)
     301             : 
     302             : (defun eldoc--message-command-p (command)
     303             :   "Return non-nil if COMMAND is in `eldoc-message-commands'."
     304           0 :   (and (symbolp command)
     305           0 :        (intern-soft (symbol-name command) eldoc-message-commands)))
     306             : 
     307             : ;; This function goes on pre-command-hook for XEmacs or when using idle
     308             : ;; timers in Emacs.  Motion commands clear the echo area for some reason,
     309             : ;; which make eldoc messages flicker or disappear just before motion
     310             : ;; begins.  This function reprints the last eldoc message immediately
     311             : ;; before the next command executes, which does away with the flicker.
     312             : ;; This doesn't seem to be required for Emacs 19.28 and earlier.
     313             : (defun eldoc-pre-command-refresh-echo-area ()
     314             :   "Reprint `eldoc-last-message' in the echo area."
     315           0 :   (and eldoc-last-message
     316           0 :        (not (minibufferp))      ;We don't use the echo area when in minibuffer.
     317           0 :        (if (and (eldoc-display-message-no-interference-p)
     318           0 :                 (eldoc--message-command-p this-command))
     319           0 :            (eldoc-message eldoc-last-message)
     320             :          ;; No need to call eldoc-message since the echo area will be cleared
     321             :          ;; for us, but do note that the last-message will be gone.
     322           0 :          (setq eldoc-last-message nil))))
     323             : 
     324             : ;; Decide whether now is a good time to display a message.
     325             : (defun eldoc-display-message-p ()
     326             :   "Return non-nil when it is appropriate to display an ElDoc message."
     327           0 :   (and (eldoc-display-message-no-interference-p)
     328             :        ;; If this-command is non-nil while running via an idle
     329             :        ;; timer, we're still in the middle of executing a command,
     330             :        ;; e.g. a query-replace where it would be annoying to
     331             :        ;; overwrite the echo area.
     332           0 :        (not this-command)
     333           0 :        (eldoc--message-command-p last-command)))
     334             : 
     335             : 
     336             : ;; Check various conditions about the current environment that might make
     337             : ;; it undesirable to print eldoc messages right this instant.
     338             : (defun eldoc-display-message-no-interference-p ()
     339             :   "Return nil if displaying a message would cause interference."
     340           0 :   (not (or executing-kbd-macro (bound-and-true-p edebug-active))))
     341             : 
     342             : 
     343             : ;;;###autoload
     344             : (defvar eldoc-documentation-function #'ignore
     345             :   "Function to call to return doc string.
     346             : The function of no args should return a one-line string for displaying
     347             : doc about a function etc. appropriate to the context around point.
     348             : It should return nil if there's no doc appropriate for the context.
     349             : Typically doc is returned if point is on a function-like name or in its
     350             : arg list.
     351             : 
     352             : The result is used as is, so the function must explicitly handle
     353             : the variables `eldoc-argument-case' and `eldoc-echo-area-use-multiline-p',
     354             : and the face `eldoc-highlight-function-argument', if they are to have any
     355             : effect.
     356             : 
     357             : Major modes should modify this variable using `add-function', for example:
     358             :   (add-function :before-until (local \\='eldoc-documentation-function)
     359             :                 #\\='foo-mode-eldoc-function)
     360             : so that the global documentation function (i.e. the default value of the
     361             : variable) is taken into account if the major mode specific function does not
     362             : return any documentation.")
     363             : 
     364             : (defun eldoc-print-current-symbol-info ()
     365             :   "Print the text produced by `eldoc-documentation-function'."
     366             :   ;; This is run from post-command-hook or some idle timer thing,
     367             :   ;; so we need to be careful that errors aren't ignored.
     368           0 :   (with-demoted-errors "eldoc error: %s"
     369           0 :     (and (or (eldoc-display-message-p)
     370             :              ;; Erase the last message if we won't display a new one.
     371           0 :              (when eldoc-last-message
     372           0 :                (eldoc-message nil)
     373           0 :                nil))
     374           0 :          (eldoc-message (funcall eldoc-documentation-function)))))
     375             : 
     376             : ;; If the entire line cannot fit in the echo area, the symbol name may be
     377             : ;; truncated or eliminated entirely from the output to make room for the
     378             : ;; description.
     379             : (defun eldoc-docstring-format-sym-doc (prefix doc &optional face)
     380             :   "Combine PREFIX and DOC, and shorten the result to fit in the echo area.
     381             : 
     382             : When PREFIX is a symbol, propertize its symbol name with FACE
     383             : before combining it with DOC.  If FACE is not provided, just
     384             : apply the nil face.
     385             : 
     386             : See also: `eldoc-echo-area-use-multiline-p'."
     387           0 :   (when (symbolp prefix)
     388           0 :     (setq prefix (concat (propertize (symbol-name prefix) 'face face) ": ")))
     389           0 :   (let* ((ea-multi eldoc-echo-area-use-multiline-p)
     390             :          ;; Subtract 1 from window width since emacs will not write
     391             :          ;; any chars to the last column, or in later versions, will
     392             :          ;; cause a wraparound and resize of the echo area.
     393           0 :          (ea-width (1- (window-width (minibuffer-window))))
     394           0 :          (strip (- (+ (length prefix) (length doc)) ea-width)))
     395           0 :     (cond ((or (<= strip 0)
     396           0 :                (eq ea-multi t)
     397           0 :                (and ea-multi (> (length doc) ea-width)))
     398           0 :            (concat prefix doc))
     399           0 :           ((> (length doc) ea-width)
     400           0 :            (substring (format "%s" doc) 0 ea-width))
     401           0 :           ((>= strip (string-match-p ":? *\\'" prefix))
     402           0 :            doc)
     403             :           (t
     404             :            ;; Show the end of the partial symbol name, rather
     405             :            ;; than the beginning, since the former is more likely
     406             :            ;; to be unique given package namespace conventions.
     407           0 :            (concat (substring prefix strip) doc)))))
     408             : 
     409             : ;; When point is in a sexp, the function args are not reprinted in the echo
     410             : ;; area after every possible interactive command because some of them print
     411             : ;; their own messages in the echo area; the eldoc functions would instantly
     412             : ;; overwrite them unless it is more restrained.
     413             : ;; These functions do display-command table management.
     414             : 
     415             : (defun eldoc-add-command (&rest cmds)
     416             :   "Add each of CMDS to the obarray `eldoc-message-commands'."
     417          30 :   (dolist (name cmds)
     418         139 :     (and (symbolp name)
     419         139 :          (setq name (symbol-name name)))
     420         139 :     (set (intern name eldoc-message-commands) t)))
     421             : 
     422             : (defun eldoc-add-command-completions (&rest names)
     423             :   "Pass every prefix completion of NAMES to `eldoc-add-command'."
     424           1 :   (dolist (name names)
     425          30 :     (apply #'eldoc-add-command (all-completions name obarray 'commandp))))
     426             : 
     427             : (defun eldoc-remove-command (&rest cmds)
     428             :   "Remove each of CMDS from the obarray `eldoc-message-commands'."
     429           0 :   (dolist (name cmds)
     430           0 :     (and (symbolp name)
     431           0 :          (setq name (symbol-name name)))
     432           0 :     (unintern name eldoc-message-commands)))
     433             : 
     434             : (defun eldoc-remove-command-completions (&rest names)
     435             :   "Pass every prefix completion of NAMES to `eldoc-remove-command'."
     436           0 :   (dolist (name names)
     437           0 :     (apply #'eldoc-remove-command
     438           0 :            (all-completions name eldoc-message-commands))))
     439             : 
     440             : 
     441             : ;; Prime the command list.
     442             : (eldoc-add-command-completions
     443             :  "back-to-indentation"
     444             :  "backward-" "beginning-of-" "delete-other-windows" "delete-window"
     445             :  "down-list" "end-of-" "exchange-point-and-mark" "forward-" "goto-"
     446             :  "handle-select-window" "indent-for-tab-command" "left-" "mark-page"
     447             :  "mark-paragraph" "mouse-set-point" "move-" "move-beginning-of-"
     448             :  "move-end-of-" "newline" "next-" "other-window" "pop-global-mark"
     449             :  "previous-" "recenter" "right-" "scroll-" "self-insert-command"
     450             :  "split-window-" "up-list")
     451             : 
     452             : (provide 'eldoc)
     453             : 
     454             : ;;; eldoc.el ends here

Generated by: LCOV version 1.12