eldoc.el (39342B)
1 ;;; eldoc.el --- Show function arglist or variable docstring in echo area -*- lexical-binding:t; -*- 2 3 ;; Copyright (C) 1996-2020 Free Software Foundation, Inc. 4 5 ;; Author: Noah Friedman <friedman@splode.com> 6 ;; Keywords: extensions 7 ;; Created: 1995-10-06 8 ;; Version: 1.11.0 9 ;; Package-Requires: ((emacs "26.3")) 10 11 ;; This is a GNU ELPA :core package. Avoid functionality that is not 12 ;; compatible with the version of Emacs recorded above. 13 14 ;; This file is part of GNU Emacs. 15 16 ;; GNU Emacs is free software: you can redistribute it and/or modify 17 ;; it under the terms of the GNU General Public License as published by 18 ;; the Free Software Foundation, either version 3 of the License, or 19 ;; (at your option) any later version. 20 21 ;; GNU Emacs is distributed in the hope that it will be useful, 22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 ;; GNU General Public License for more details. 25 26 ;; You should have received a copy of the GNU General Public License 27 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 28 29 ;;; Commentary: 30 31 ;; This program was inspired by the behavior of the "mouse documentation 32 ;; window" on many Lisp Machine systems; as you type a function's symbol 33 ;; name as part of a sexp, it will print the argument list for that 34 ;; function. Behavior is not identical; for example, you need not actually 35 ;; type the function name, you need only move point around in a sexp that 36 ;; calls it. Also, if point is over a documented variable, it will print 37 ;; the one-line documentation for that variable instead, to remind you of 38 ;; that variable's meaning. 39 40 ;; This mode is now enabled by default in all major modes that provide 41 ;; support for it, such as `emacs-lisp-mode'. 42 ;; This is controlled by `global-eldoc-mode'. 43 44 ;; Major modes for other languages may use ElDoc by adding an 45 ;; appropriate function to the buffer-local value of 46 ;; `eldoc-documentation-functions'. 47 48 ;;; Code: 49 50 (eval-when-compile (require 'cl-lib)) 51 52 (defgroup eldoc nil 53 "Show function arglist or variable docstring in echo area." 54 :group 'lisp 55 :group 'extensions) 56 57 (defcustom eldoc-idle-delay 0.50 58 "Number of seconds of idle time to wait before printing. 59 If user input arrives before this interval of time has elapsed after the 60 last input, no documentation will be printed. 61 62 If this variable is set to 0, no idle time is required." 63 :type 'number) 64 65 (defcustom eldoc-print-after-edit nil 66 "If non-nil eldoc info is only shown when editing. 67 Changing the value requires toggling `eldoc-mode'." 68 :type 'boolean) 69 70 (defcustom eldoc-echo-area-display-truncation-message t 71 "If non-nil, provide verbose help when a message has been truncated. 72 If nil, truncated messages will just have \"...\" appended." 73 :type 'boolean 74 :version "28.1") 75 76 ;;;###autoload 77 (defcustom eldoc-minor-mode-string (purecopy " ElDoc") 78 "String to display in mode line when ElDoc Mode is enabled; nil for none." 79 :type '(choice string (const :tag "None" nil))) 80 81 (defcustom eldoc-argument-case #'identity 82 "Case to display argument names of functions, as a symbol. 83 This has two preferred values: `upcase' or `downcase'. 84 Actually, any name of a function which takes a string as an argument and 85 returns another string is acceptable. 86 87 Note that this variable has no effect, unless 88 `eldoc-documentation-strategy' handles it explicitly." 89 :type '(radio (function-item upcase) 90 (function-item downcase) 91 function)) 92 (make-obsolete-variable 'eldoc-argument-case nil "25.1") 93 94 (defcustom eldoc-echo-area-use-multiline-p 'truncate-sym-name-if-fit 95 "Allow long ElDoc doc strings to resize echo area display. 96 If value is t, never attempt to truncate messages, even if the 97 echo area must be resized to fit. 98 99 If the value is a positive number, it is used to calculate a 100 number of logical lines of documentation that ElDoc is allowed to 101 put in the echo area. If a positive integer, the number is used 102 directly, while a float specifies the number of lines as a 103 proporting of the echo area frame's height. 104 105 If value is the symbol `truncate-sym-name-if-fit' t, the part of 106 the doc string that represents a symbol's name may be truncated 107 if it will enable the rest of the doc string to fit on a single 108 line, without resizing the echo area. 109 110 If value is nil, a doc string is always truncated to fit in a 111 single line of display in the echo area. 112 113 Any resizing of the echo area additionally respects 114 `max-mini-window-height'." 115 :type '(radio (const :tag "Always" t) 116 (float :tag "Fraction of frame height" 0.25) 117 (integer :tag "Number of lines" 5) 118 (const :tag "Never" nil) 119 (const :tag "Yes, but ask major-mode to truncate 120 symbol names if it will\ enable argument list to fit on one 121 line" truncate-sym-name-if-fit))) 122 123 (defcustom eldoc-echo-area-prefer-doc-buffer nil 124 "Prefer ElDoc's documentation buffer if it is showing in some frame. 125 If this variable's value is t, ElDoc will skip showing 126 documentation in the echo area if the dedicated documentation 127 buffer (given by `eldoc-doc-buffer') is being displayed in some 128 window. If the value is the symbol `maybe', then the echo area 129 is only skipped if the documentation doesn't fit there." 130 :type 'boolean) 131 132 (defface eldoc-highlight-function-argument 133 '((t (:inherit bold))) 134 "Face used for the argument at point in a function's argument list. 135 Note that this face has no effect unless the `eldoc-documentation-strategy' 136 handles it explicitly.") 137 138 ;;; No user options below here. 139 140 (defvar eldoc-message-commands-table-size 31 141 "Used by `eldoc-add-command' to initialize `eldoc-message-commands' obarray. 142 It should probably never be necessary to do so, but if you 143 choose to increase the number of buckets, you must do so before loading 144 this file since the obarray is initialized at load time. 145 Remember to keep it a prime number to improve hash performance.") 146 147 (defvar eldoc-message-commands 148 ;; Don't define as `defconst' since it would then go to (read-only) purespace. 149 (make-vector eldoc-message-commands-table-size 0) 150 "Commands after which it is appropriate to print in the echo area. 151 ElDoc does not try to print function arglists, etc., after just any command, 152 because some commands print their own messages in the echo area and these 153 functions would instantly overwrite them. But `self-insert-command' as well 154 as most motion commands are good candidates. 155 This variable contains an obarray of symbols; do not manipulate it 156 directly. Instead, use `eldoc-add-command' and `eldoc-remove-command'.") 157 158 ;; Not a constant. 159 (defvar eldoc-last-data (make-vector 3 nil) 160 ;; Don't define as `defconst' since it would then go to (read-only) purespace. 161 "Bookkeeping; elements are as follows: 162 0 - contains the last symbol read from the buffer. 163 1 - contains the string last displayed in the echo area for variables, 164 or argument string for functions. 165 2 - `function' if function args, `variable' if variable documentation.") 166 (make-obsolete-variable 'eldoc-last-data "use your own instead" "25.1") 167 168 (defvar eldoc-last-message nil) 169 170 (defvar eldoc-timer nil "ElDoc's timer object.") 171 172 (defvar eldoc-current-idle-delay eldoc-idle-delay 173 "Idle time delay currently in use by timer. 174 This is used to determine if `eldoc-idle-delay' is changed by the user.") 175 176 (defvar eldoc-message-function #'eldoc-minibuffer-message 177 "The function used by `eldoc--message' to display messages. 178 It should receive the same arguments as `message'.") 179 180 (defun eldoc-edit-message-commands () 181 "Return an obarray containing common editing commands. 182 183 When `eldoc-print-after-edit' is non-nil, ElDoc messages are only 184 printed after commands contained in this obarray." 185 (let ((cmds (make-vector 31 0)) 186 (re (regexp-opt '("delete" "insert" "edit" "electric" "newline")))) 187 (mapatoms (lambda (s) 188 (and (commandp s) 189 (string-match-p re (symbol-name s)) 190 (intern (symbol-name s) cmds))) 191 obarray) 192 cmds)) 193 194 195 ;;;###autoload 196 (define-minor-mode eldoc-mode 197 "Toggle echo area display of Lisp objects at point (ElDoc mode). 198 199 ElDoc mode is a buffer-local minor mode. When enabled, the echo 200 area displays information about a function or variable in the 201 text where point is. If point is on a documented variable, it 202 displays the first line of that variable's doc string. Otherwise 203 it displays the argument list of the function called in the 204 expression point is on." :lighter eldoc-minor-mode-string 205 (setq eldoc-last-message nil) 206 (cond 207 ((not (eldoc--supported-p)) 208 (when (called-interactively-p 'any) 209 (message "There is no ElDoc support in this buffer")) 210 (setq eldoc-mode nil)) 211 (eldoc-mode 212 (when eldoc-print-after-edit 213 (setq-local eldoc-message-commands (eldoc-edit-message-commands))) 214 (add-hook 'post-command-hook #'eldoc-schedule-timer nil t) 215 (add-hook 'pre-command-hook #'eldoc-pre-command-refresh-echo-area nil t)) 216 (t 217 (kill-local-variable 'eldoc-message-commands) 218 (remove-hook 'post-command-hook #'eldoc-schedule-timer t) 219 (remove-hook 'pre-command-hook #'eldoc-pre-command-refresh-echo-area t) 220 (when eldoc-timer 221 (cancel-timer eldoc-timer) 222 (setq eldoc-timer nil))))) 223 224 ;;;###autoload 225 (define-globalized-minor-mode global-eldoc-mode eldoc-mode turn-on-eldoc-mode 226 :initialize 'custom-initialize-delay 227 :init-value t 228 ;; For `read--expression', the usual global mode mechanism of 229 ;; `change-major-mode-hook' runs in the minibuffer before 230 ;; `eldoc-documentation-strategy' is set, so `turn-on-eldoc-mode' 231 ;; does nothing. Configure and enable eldoc from 232 ;; `eval-expression-minibuffer-setup-hook' instead. 233 (if global-eldoc-mode 234 (add-hook 'eval-expression-minibuffer-setup-hook 235 #'eldoc--eval-expression-setup) 236 (remove-hook 'eval-expression-minibuffer-setup-hook 237 #'eldoc--eval-expression-setup))) 238 239 (defun eldoc--eval-expression-setup () 240 ;; Setup `eldoc', similar to `emacs-lisp-mode'. FIXME: Call 241 ;; `emacs-lisp-mode' itself? 242 (cond ((<= emacs-major-version 27) 243 (declare-function elisp-eldoc-documentation-function "elisp-mode") 244 (add-function :before-until (local 'eldoc-documentation-function) 245 #'elisp-eldoc-documentation-function)) 246 (t (add-hook 'eldoc-documentation-functions 247 #'elisp-eldoc-var-docstring nil t) 248 (add-hook 'eldoc-documentation-functions 249 #'elisp-eldoc-funcall nil t) 250 (setq eldoc-documentation-strategy 'eldoc-documentation-default))) 251 (eldoc-mode +1)) 252 253 ;;;###autoload 254 (defun turn-on-eldoc-mode () 255 "Turn on `eldoc-mode' if the buffer has ElDoc support enabled. 256 See `eldoc-documentation-strategy' for more detail." 257 (when (eldoc--supported-p) 258 (eldoc-mode 1))) 259 260 261 (defun eldoc-schedule-timer () 262 "Ensure `eldoc-timer' is running. 263 264 If the user has changed `eldoc-idle-delay', update the timer to 265 reflect the change." 266 (or (and eldoc-timer 267 (memq eldoc-timer timer-idle-list)) ;FIXME: Why? 268 (setq eldoc-timer 269 (run-with-idle-timer 270 eldoc-idle-delay nil 271 (lambda () 272 (when (or eldoc-mode 273 (and global-eldoc-mode 274 (eldoc--supported-p))) 275 ;; Don't ignore, but also don't full-on signal errors 276 (with-demoted-errors "eldoc error: %s" 277 (eldoc-print-current-symbol-info)) ))))) 278 279 ;; If user has changed the idle delay, update the timer. 280 (cond ((not (= eldoc-idle-delay eldoc-current-idle-delay)) 281 (setq eldoc-current-idle-delay eldoc-idle-delay) 282 (timer-set-idle-time eldoc-timer eldoc-idle-delay t)))) 283 284 (defvar eldoc-mode-line-string nil) 285 (put 'eldoc-mode-line-string 'risky-local-variable t) 286 287 (defun eldoc-minibuffer-message (format-string &rest args) 288 "Display messages in the mode-line when in the minibuffer. 289 Otherwise work like `message'." 290 (if (minibufferp) 291 (progn 292 (add-hook 'minibuffer-exit-hook 293 (lambda () (setq eldoc-mode-line-string nil 294 ;; https://debbugs.gnu.org/16920 295 eldoc-last-message nil)) 296 nil t) 297 (with-current-buffer 298 (window-buffer 299 (or (window-in-direction 'above (minibuffer-window)) 300 (minibuffer-selected-window) 301 (get-largest-window))) 302 (when (and mode-line-format 303 (not (and (listp mode-line-format) 304 (assq 'eldoc-mode-line-string mode-line-format)))) 305 (setq mode-line-format 306 (list "" '(eldoc-mode-line-string 307 (" " eldoc-mode-line-string " ")) 308 mode-line-format))) 309 (setq eldoc-mode-line-string 310 (when (stringp format-string) 311 (apply #'format-message format-string args))) 312 (force-mode-line-update))) 313 (apply #'message format-string args))) 314 315 (make-obsolete 316 'eldoc-message "use `eldoc-documentation-functions' instead." "eldoc-1.1.0") 317 (defun eldoc-message (&optional string) (eldoc--message string)) 318 (defun eldoc--message (&optional string) 319 "Display STRING as an ElDoc message if it's non-nil. 320 321 Also store it in `eldoc-last-message' and return that value." 322 (let ((omessage eldoc-last-message)) 323 (setq eldoc-last-message string) 324 ;; Do not put eldoc messages in the log since they are Legion. 325 ;; Emacs way of preventing log messages. 326 (let ((message-log-max nil)) 327 (cond (eldoc-last-message 328 (funcall eldoc-message-function "%s" eldoc-last-message)) 329 (omessage (funcall eldoc-message-function nil))))) 330 eldoc-last-message) 331 332 (defun eldoc--message-command-p (command) 333 "Return non-nil if COMMAND is in `eldoc-message-commands'." 334 (and (symbolp command) 335 (intern-soft (symbol-name command) eldoc-message-commands))) 336 337 ;; This function goes on pre-command-hook. 338 ;; Motion commands clear the echo area for some reason, 339 ;; which make eldoc messages flicker or disappear just before motion 340 ;; begins. This function reprints the last eldoc message immediately 341 ;; before the next command executes, which does away with the flicker. 342 ;; This doesn't seem to be required for Emacs 19.28 and earlier. 343 ;; FIXME: The above comment suggests we don't really understand why 344 ;; this is needed. Maybe it's not needed any more, but if it is 345 ;; we should figure out why. 346 (defun eldoc-pre-command-refresh-echo-area () 347 "Reprint `eldoc-last-message' in the echo area." 348 (and eldoc-last-message 349 (not (minibufferp)) ;We don't use the echo area when in minibuffer. 350 (if (and (eldoc-display-message-no-interference-p) 351 (eldoc--message-command-p this-command)) 352 (eldoc--message eldoc-last-message) 353 ;; No need to call eldoc--message since the echo area will be cleared 354 ;; for us, but do note that the last-message will be gone. 355 (setq eldoc-last-message nil)))) 356 357 ;; The point of `eldoc--request-state' is not to over-request, which 358 ;; can happen if the idle timer is restarted on execution of command 359 ;; which is guaranteed not to change the conditions that warrant a new 360 ;; request for documentation. 361 (defvar eldoc--last-request-state nil 362 "Tuple containing information about last ElDoc request.") 363 (defun eldoc--request-state () 364 "Compute information to store in `eldoc--last-request-state'." 365 (list (current-buffer) (buffer-modified-tick) (point))) 366 367 (defun eldoc-display-message-p () 368 "Tell if ElDoc can use the echo area." 369 (and (eldoc-display-message-no-interference-p) 370 (not this-command) 371 (eldoc--message-command-p last-command))) 372 373 (make-obsolete 'eldoc-display-message-p 374 "Use `eldoc-documentation-functions' instead." 375 "eldoc-1.6.0") 376 377 ;; Check various conditions about the current environment that might make 378 ;; it undesirable to print eldoc messages right this instant. 379 (defun eldoc-display-message-no-interference-p () 380 "Return nil if displaying a message would cause interference." 381 (not (or executing-kbd-macro (bound-and-true-p edebug-active)))) 382 383 384 (defvar eldoc-documentation-functions nil 385 "Hook of functions that produce doc strings. 386 387 A doc string is typically relevant if point is on a function-like 388 name, inside its arg list, or on any object with some associated 389 information. 390 391 Each hook function is called with at least one argument CALLBACK, 392 a function, and decides whether to display a doc short string 393 about the context around point. 394 395 - If that decision can be taken quickly, the hook function may 396 call CALLBACK immediately following the protocol described 397 below. Alternatively it may ignore CALLBACK entirely and 398 return either the doc string, or nil if there's no doc 399 appropriate for the context. 400 401 - If the computation of said doc string (or the decision whether 402 there is one at all) is expensive or can't be performed 403 directly, the hook function should return a non-nil, non-string 404 value and arrange for CALLBACK to be called at a later time, 405 using asynchronous processes or other asynchronous mechanisms. 406 407 To call the CALLBACK function, the hook function must pass it an 408 obligatory argument DOCSTRING, a string containing the 409 documentation, followed by an optional list of arbitrary 410 keyword-value pairs of the form (:KEY VALUE :KEY2 VALUE2...). 411 The information contained in these pairs is understood by members 412 of `eldoc-display-functions', allowing the 413 documentation-producing backend to cooperate with specific 414 documentation-displaying frontends. For example, KEY can be: 415 416 * `:thing', VALUE being a short string or symbol designating what 417 is being reported on. It can, for example be the name of the 418 function whose signature is being documented, or the name of 419 the variable whose docstring is being documented. 420 `eldoc-display-in-echo-area', a member of 421 `eldoc-display-functions', sometimes omits this information 422 depending on space constraints; 423 424 * `:face', VALUE being a symbol designating a face which both 425 `eldoc-display-in-echo-area' and `eldoc-display-in-buffer' will 426 use when displaying `:thing''s value. 427 428 Finally, major modes should modify this hook locally, for 429 example: 430 (add-hook \\='eldoc-documentation-functions #\\='foo-mode-eldoc nil t) 431 so that the global value (i.e. the default value of the hook) is 432 taken into account if the major mode specific function does not 433 return any documentation.") 434 435 (defvar eldoc-display-functions 436 '(eldoc-display-in-echo-area eldoc-display-in-buffer) 437 "Hook of functions tasked with displaying ElDoc results. 438 Each function is passed two arguments: DOCS and INTERACTIVE. DOCS 439 is a list (DOC ...) where DOC looks like (STRING :KEY VALUE :KEY2 440 VALUE2 ...). STRING is a string containing the documentation's 441 text and the remainder of DOC is an optional list of 442 keyword-value pairs denoting additional properties of that 443 documentation. For commonly recognized properties, see 444 `eldoc-documentation-functions'. 445 446 INTERACTIVE says if the request to display doc strings came 447 directly from the user or from ElDoc's automatic mechanisms'.") 448 449 (defvar eldoc--doc-buffer nil "Buffer displaying latest ElDoc-produced docs.") 450 451 (defvar eldoc--doc-buffer-docs nil "Documentation items in `eldoc--doc-buffer'.") 452 453 (defun eldoc-doc-buffer (&optional interactive) 454 (interactive (list t)) 455 "Display ElDoc documentation buffer. 456 This holds the results of the last documentation request." 457 (unless (buffer-live-p eldoc--doc-buffer) 458 (setq eldoc--doc-buffer (get-buffer-create "*eldoc*"))) 459 (when interactive 460 (display-buffer eldoc--doc-buffer))) 461 462 (defun eldoc--format-doc-buffer (docs) 463 "Ensure DOCS are displayed in an *eldoc* buffer." 464 (interactive (list t)) 465 (eldoc-doc-buffer) ;; ensure buffer exists 466 (with-current-buffer eldoc--doc-buffer 467 (unless (eq docs eldoc--doc-buffer-docs) 468 (setq-local eldoc--doc-buffer-docs docs) 469 (let ((inhibit-read-only t) 470 (things-reported-on)) 471 (erase-buffer) (setq buffer-read-only t) 472 (local-set-key "q" 'quit-window) 473 (cl-loop for (docs . rest) on docs 474 for (this-doc . plist) = docs 475 for thing = (plist-get plist :thing) 476 when thing do 477 (cl-pushnew thing things-reported-on) 478 (setq this-doc 479 (concat 480 (propertize (format "%s" thing) 481 'face (plist-get plist :face)) 482 ": " 483 this-doc)) 484 do (insert this-doc) 485 when rest do (insert "\n")) 486 ;; Maybe rename the buffer. 487 (rename-buffer (if things-reported-on 488 (format "*eldoc for %s*" 489 (mapconcat (lambda (s) (format "%s" s)) 490 things-reported-on 491 ", ")) 492 "*eldoc*"))))) 493 eldoc--doc-buffer) 494 495 (defun eldoc--echo-area-substring (available) 496 "Given AVAILABLE lines, get buffer substring to display in echo area. 497 Helper for `eldoc-display-in-echo-area'." 498 (let ((start (prog1 (progn 499 (goto-char (point-min)) 500 (skip-chars-forward " \t\n") 501 (point)) 502 (goto-char (line-end-position available)) 503 (skip-chars-backward " \t\n"))) 504 (truncated (save-excursion 505 (skip-chars-forward " \t\n") 506 (not (eobp))))) 507 (cond ((eldoc--echo-area-prefer-doc-buffer-p truncated) 508 nil) 509 ((and truncated 510 (> available 1) 511 eldoc-echo-area-display-truncation-message) 512 (goto-char (line-end-position 0)) 513 (concat (buffer-substring start (point)) 514 (format 515 "\n(Documentation truncated. Use `%s' to see rest)" 516 (substitute-command-keys "\\[eldoc-doc-buffer]")))) 517 (t 518 (buffer-substring start (point)))))) 519 520 (defun eldoc--echo-area-prefer-doc-buffer-p (truncatedp) 521 "Tell if display in the echo area should be skipped. 522 Helper for `eldoc-display-in-echo-area'. If TRUNCATEDP the 523 documentation to potentially appear in the echo are is truncated." 524 (and (or (eq eldoc-echo-area-prefer-doc-buffer t) 525 (and truncatedp 526 (eq eldoc-echo-area-prefer-doc-buffer 527 'maybe))) 528 (get-buffer-window eldoc--doc-buffer))) 529 530 (defun eldoc-display-in-echo-area (docs _interactive) 531 "Display DOCS in echo area. 532 Honor `eldoc-echo-area-use-multiline-p' and 533 `eldoc-echo-area-prefer-doc-buffer'." 534 (cond 535 (;; Check if he wave permission to mess with echo area at all. For 536 ;; example, if this-command is non-nil while running via an idle 537 ;; timer, we're still in the middle of executing a command, e.g. a 538 ;; query-replace where it would be annoying to overwrite the echo 539 ;; area. 540 (or 541 (not (eldoc-display-message-no-interference-p)) 542 this-command 543 (not (eldoc--message-command-p last-command)))) 544 (;; If we do but nothing to report, clear the echo area. 545 (null docs) 546 (eldoc--message nil)) 547 (t 548 ;; Otherwise, establish some parameters. 549 (let* 550 ((width (1- (window-width (minibuffer-window)))) 551 (val (if (and (symbolp eldoc-echo-area-use-multiline-p) 552 eldoc-echo-area-use-multiline-p) 553 max-mini-window-height 554 eldoc-echo-area-use-multiline-p)) 555 (available (cl-typecase val 556 (float (truncate (* (frame-height) val))) 557 (integer val) 558 (t 'just-one-line))) 559 single-doc single-doc-sym) 560 (let ((echo-area-message 561 (cond 562 (;; To output to the echo area, we handle the 563 ;; `truncate-sym-name-if-fit' special case first, by 564 ;; checking for a lot of special conditions. 565 (and 566 (eq 'truncate-sym-name-if-fit eldoc-echo-area-use-multiline-p) 567 (null (cdr docs)) 568 (setq single-doc (caar docs)) 569 (setq single-doc-sym 570 (format "%s" (plist-get (cdar docs) :thing))) 571 (< (length single-doc) width) 572 (not (string-match "\n" single-doc)) 573 (> (+ (length single-doc) (length single-doc-sym) 2) width)) 574 single-doc) 575 ((and (numberp available) 576 (cl-plusp available)) 577 ;; Else, given a positive number of logical lines, we 578 ;; format the *eldoc* buffer, using as most of its 579 ;; contents as we know will fit. 580 (with-current-buffer (eldoc--format-doc-buffer docs) 581 (eldoc--echo-area-substring available))) 582 (t ;; this is the "truncate brutally" situation 583 (let ((string 584 (with-current-buffer (eldoc--format-doc-buffer docs) 585 (buffer-substring (goto-char (point-min)) 586 (line-end-position 1))))) 587 (if (> (length string) width) ; truncation to happen 588 (unless (eldoc--echo-area-prefer-doc-buffer-p t) 589 (truncate-string-to-width string width)) 590 (unless (eldoc--echo-area-prefer-doc-buffer-p nil) 591 string))))))) 592 (when echo-area-message 593 (eldoc--message echo-area-message))))))) 594 595 (defun eldoc-display-in-buffer (docs interactive) 596 "Display DOCS in a dedicated buffer. 597 If INTERACTIVE is t, also display the buffer." 598 (let ((buf (eldoc--format-doc-buffer docs))) 599 (when interactive 600 (display-buffer buf)))) 601 602 (defun eldoc-documentation-default () 603 "Show first doc string for item at point. 604 Default value for `eldoc-documentation-strategy'." 605 (run-hook-with-args-until-success 'eldoc-documentation-functions 606 (eldoc--make-callback :patient))) 607 608 (defun eldoc--documentation-compose-1 (eagerlyp) 609 "Helper function for composing multiple doc strings. 610 If EAGERLYP is non-nil show documentation as soon as possible, 611 else wait for all doc strings." 612 (run-hook-wrapped 'eldoc-documentation-functions 613 (lambda (f) 614 (let* ((callback (eldoc--make-callback 615 (if eagerlyp :eager :patient))) 616 (str (funcall f callback))) 617 (if (or (null str) (stringp str)) (funcall callback str)) 618 nil))) 619 t) 620 621 (defun eldoc-documentation-compose () 622 "Show multiple doc strings at once after waiting for all. 623 Meant as a value for `eldoc-documentation-strategy'." 624 (eldoc--documentation-compose-1 nil)) 625 626 (defun eldoc-documentation-compose-eagerly () 627 "Show multiple doc strings at once as soon as possible. 628 Meant as a value for `eldoc-documentation-strategy'." 629 (eldoc--documentation-compose-1 t)) 630 631 (defun eldoc-documentation-enthusiast () 632 "Show most important doc string produced so far. 633 Meant as a value for `eldoc-documentation-strategy'." 634 (run-hook-wrapped 'eldoc-documentation-functions 635 (lambda (f) 636 (let* ((callback (eldoc--make-callback :enthusiast)) 637 (str (funcall f callback))) 638 (if (stringp str) (funcall callback str)) 639 nil))) 640 t) 641 642 ;; JT@2020-07-10: ElDoc is pre-loaded, so in Emacs < 28 we can't 643 ;; make the "old" `eldoc-documentation-function' point to the new 644 ;; `eldoc-documentation-strategy', so we do the reverse. This allows 645 ;; for ElDoc to be loaded in those older Emacs versions and work with 646 ;; whomever (major-modes, extensions, user) sets one or the other 647 ;; variable. 648 (defmacro eldoc--documentation-strategy-defcustom 649 (main secondary value docstring &rest more) 650 "Defcustom helper macro for sorting `eldoc-documentation-strategy'." 651 (declare (indent 2)) 652 `(if (< emacs-major-version 28) 653 (progn 654 (defcustom ,secondary ,value ,docstring ,@more) 655 (define-obsolete-variable-alias ',main ',secondary "eldoc-1.1.0")) 656 (progn 657 (defcustom ,main ,value ,docstring ,@more) 658 (defvaralias ',secondary ',main ,docstring)))) 659 660 (eldoc--documentation-strategy-defcustom eldoc-documentation-strategy 661 eldoc-documentation-function 662 #'eldoc-documentation-default 663 "How to collect and organize results of `eldoc-documentation-functions'. 664 665 This variable controls how `eldoc-documentation-functions', which 666 specifies the sources of documentation, is queried and how its 667 results are organized before being displayed to the user. The 668 following values are allowed: 669 670 - `eldoc-documentation-default': calls functions in the special 671 hook in order until one is found that produces a doc string 672 value. Display only that value; 673 674 - `eldoc-documentation-compose': calls all functions in the 675 special hook and displays all of the resulting doc strings 676 together. Wait for all strings to be ready, and preserve their 677 relative as specified by the order of functions in the hook; 678 679 - `eldoc-documentation-compose-eagerly': calls all functions in 680 the special hook and display as many of the resulting doc 681 strings as possible, as soon as possibl. Preserving the 682 relative order of doc strings; 683 684 - `eldoc-documentation-enthusiast': calls all functions in the 685 special hook and displays only the most important resulting 686 docstring one at any given time. A function appearing first in 687 the special hook is considered more important. 688 689 This variable can also be set to a function of no args that 690 returns something other than a string or nil and allows for some 691 or all of the special hook `eldoc-documentation-functions' to be 692 run. In that case, the strategy function should follow that 693 other variable's protocol closely and endeavor to display the 694 resulting doc strings itself. 695 696 For backward compatibility to the \"old\" protocol, this variable 697 can also be set to a function that returns nil or a doc string, 698 depending whether or not there is documentation to display at 699 all." 700 :link '(info-link "(emacs) Lisp Doc") 701 :type '(radio (function-item eldoc-documentation-default) 702 (function-item eldoc-documentation-compose) 703 (function-item eldoc-documentation-compose-eagerly) 704 (function-item eldoc-documentation-enthusiast) 705 (function :tag "Other function")) 706 :version "28.1") 707 708 (defun eldoc--supported-p () 709 "Non-nil if an ElDoc function is set for this buffer." 710 (and (not (memq eldoc-documentation-strategy '(nil ignore))) 711 (or eldoc-documentation-functions 712 ;; The old API had major modes set `eldoc-documentation-function' 713 ;; to provide eldoc support. It's impossible now to determine 714 ;; reliably whether the `eldoc-documentation-strategy' provides 715 ;; eldoc support (as in the old API) or whether it just provides 716 ;; a way to combine the results of the 717 ;; `eldoc-documentation-functions' (as in the new API). 718 ;; But at least if it's set buffer-locally it's a good hint that 719 ;; there's some eldoc support in the current buffer. 720 (local-variable-p 'eldoc-documentation-strategy)))) 721 722 (defvar eldoc--enthusiasm-curbing-timer nil 723 "Timer used by the `eldoc-documentation-enthusiast' strategy. 724 When a doc string is encountered, it must endure a certain amount 725 of time unchallenged until it is displayed to the user. This 726 prevents blinking if a lower priority docstring comes in shortly 727 before a higher priority one.") 728 729 (defalias 'eldoc #'eldoc-print-current-symbol-info) 730 731 ;; This variable should be unbound, but that confuses 732 ;; `describe-symbol' for some reason. 733 (defvar eldoc--make-callback nil "Helper for function `eldoc--make-callback'.") 734 735 ;; JT@2020-07-08: the below docstring for the internal function 736 ;; `eldoc--invoke-strategy' could be moved to 737 ;; `eldoc-documentation-strategy' or thereabouts if/when we decide to 738 ;; extend or publish the `make-callback' protocol. 739 (defun eldoc--make-callback (method) 740 "Make callback suitable for `eldoc-documentation-functions'. 741 The return value is a function FN whose lambda list is (STRING 742 &rest PLIST) and can be called by those functions. Its 743 responsibility is always to register the docstring STRING along 744 with options specified in PLIST as the documentation to display 745 for each particular situation. 746 747 METHOD specifies how the callback behaves relative to other 748 competing elements in `eldoc-documentation-functions'. It can 749 have the following values: 750 751 - `:enthusiast' says to display STRING as soon as possible if 752 there's no higher priority doc string; 753 754 - `:patient' says to display STRING along with all other 755 competing strings but only when all of all 756 `eldoc-documentation-functions' have been collected; 757 758 - `:eager' says to display STRING along with all other competing 759 strings so far, as soon as possible." 760 (funcall eldoc--make-callback method)) 761 762 (defun eldoc--invoke-strategy (interactive) 763 "Invoke `eldoc-documentation-strategy' function. 764 765 If INTERACTIVE is non-nil, the request came directly from a user 766 command, otherwise it came from ElDoc's idle 767 timer, `eldoc-timer'. 768 769 That function's job is to run the `eldoc-documentation-functions' 770 special hook, using the `run-hook' family of functions. ElDoc's 771 built-in strategy functions play along with the 772 `eldoc--make-callback' protocol, using it to produce a callback 773 argument to feed the functions that the user places in 774 `eldoc-documentation-functions'. Whenever the strategy 775 determines it has information to display to the user, this 776 function passes responsibility to the functions in 777 `eldoc-display-functions'. 778 779 Other third-party values of `eldoc-documentation-strategy' should 780 not use `eldoc--make-callback'. They must find some alternate 781 way to produce callbacks to feed to 782 `eldoc-documentation-function' and should endeavour to display 783 the docstrings eventually produced, using 784 `eldoc-display-functions'." 785 (let* (;; How many callbacks have been created by the strategy 786 ;; function and passed to elements of 787 ;; `eldoc-documentation-functions'. 788 (howmany 0) 789 ;; How many calls to callbacks we're still waiting on. Used 790 ;; by `:patient'. 791 (want 0) 792 ;; The doc strings and corresponding options registered so 793 ;; far. 794 (docs-registered '())) 795 (cl-labels 796 ((register-doc 797 (pos string plist) 798 (when (and string (> (length string) 0)) 799 (push (cons pos (cons string plist)) docs-registered))) 800 (display-doc 801 () 802 (run-hook-with-args 803 'eldoc-display-functions (mapcar #'cdr 804 (setq docs-registered 805 (sort docs-registered 806 (lambda (a b) (< (car a) (car b)))))) 807 interactive)) 808 (make-callback 809 (method) 810 (let ((pos (prog1 howmany (cl-incf howmany)))) 811 (cl-ecase method 812 (:enthusiast 813 (lambda (string &rest plist) 814 (when (and string (cl-loop for (p) in docs-registered 815 never (< p pos))) 816 (setq docs-registered '()) 817 (register-doc pos string plist)) 818 (when (and (timerp eldoc--enthusiasm-curbing-timer) 819 (memq eldoc--enthusiasm-curbing-timer 820 timer-list)) 821 (cancel-timer eldoc--enthusiasm-curbing-timer)) 822 (setq eldoc--enthusiasm-curbing-timer 823 (run-at-time (unless (zerop pos) 0.3) 824 nil #'display-doc)) 825 t)) 826 (:patient 827 (cl-incf want) 828 (lambda (string &rest plist) 829 (register-doc pos string plist) 830 (when (zerop (cl-decf want)) (display-doc)) 831 t)) 832 (:eager 833 (lambda (string &rest plist) 834 (register-doc pos string plist) 835 (display-doc) 836 t)))))) 837 (let* ((eldoc--make-callback #'make-callback) 838 (res (funcall eldoc-documentation-strategy))) 839 ;; Observe the old and the new protocol: 840 (cond (;; Old protocol: got string, output immediately; 841 (stringp res) (register-doc 0 res nil) (display-doc)) 842 (;; Old protocol: got nil, clear the echo area; 843 (null res) (eldoc--message nil)) 844 (;; New protocol: trust callback will be called; 845 t)))))) 846 847 (defun eldoc-print-current-symbol-info (&optional interactive) 848 "Document thing at point." 849 (interactive '(t)) 850 (let (token) 851 (cond (interactive 852 (eldoc--invoke-strategy t)) 853 ((not (equal (setq token (eldoc--request-state)) 854 eldoc--last-request-state)) 855 (let ((non-essential t)) 856 (setq eldoc--last-request-state token) 857 ;; Only keep looking for the info as long as the user hasn't 858 ;; requested our attention. This also locally disables 859 ;; inhibit-quit. 860 (while-no-input 861 (eldoc--invoke-strategy nil))))))) 862 863 864 ;; This section only affects ElDoc output to the echo area, as in 865 ;; `eldoc-display-in-echo-area'. 866 ;; 867 ;; When point is in a sexp, the function args are not reprinted in the echo 868 ;; area after every possible interactive command because some of them print 869 ;; their own messages in the echo area; the eldoc functions would instantly 870 ;; overwrite them unless it is more restrained. 871 ;; These functions do display-command table management. 872 873 (defun eldoc-add-command (&rest cmds) 874 "Add each of CMDS to the obarray `eldoc-message-commands'." 875 (dolist (name cmds) 876 (and (symbolp name) 877 (setq name (symbol-name name))) 878 (set (intern name eldoc-message-commands) t))) 879 880 (defun eldoc-add-command-completions (&rest names) 881 "Pass every prefix completion of NAMES to `eldoc-add-command'." 882 (dolist (name names) 883 (apply #'eldoc-add-command (all-completions name obarray 'commandp)))) 884 885 (defun eldoc-remove-command (&rest cmds) 886 "Remove each of CMDS from the obarray `eldoc-message-commands'." 887 (dolist (name cmds) 888 (and (symbolp name) 889 (setq name (symbol-name name))) 890 (unintern name eldoc-message-commands))) 891 892 (defun eldoc-remove-command-completions (&rest names) 893 "Pass every prefix completion of NAMES to `eldoc-remove-command'." 894 (dolist (name names) 895 (apply #'eldoc-remove-command 896 (all-completions name eldoc-message-commands)))) 897 898 ;; Prime the command list. 899 (eldoc-add-command-completions 900 "back-to-indentation" 901 "backward-" "beginning-of-" "delete-other-windows" "delete-window" 902 "down-list" "end-of-" "exchange-point-and-mark" "forward-" "goto-" 903 "handle-select-window" "indent-for-tab-command" "left-" "mark-page" 904 "mark-paragraph" "mouse-set-point" "move-" "move-beginning-of-" 905 "move-end-of-" "newline" "next-" "other-window" "pop-global-mark" 906 "previous-" "recenter" "right-" "scroll-" "self-insert-command" 907 "split-window-" "up-list") 908 909 ;;;; ChangeLog: 910 911 912 913 (provide 'eldoc) 914 915 ;;; eldoc.el ends here