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