[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/native-comp 5f13016 14/14: Merge remote-tracking branch 'savanna
From: |
Andrea Corallo |
Subject: |
feature/native-comp 5f13016 14/14: Merge remote-tracking branch 'savannah/master' into wip2 |
Date: |
Thu, 9 Jul 2020 11:57:54 -0400 (EDT) |
branch: feature/native-comp
commit 5f13016cedd245a7388ffafddffa20268afaf023
Merge: 02bf2e0 19cf8e5
Author: Andrea Corallo <akrl@sdf.org>
Commit: Andrea Corallo <akrl@sdf.org>
Merge remote-tracking branch 'savannah/master' into wip2
---
doc/emacs/programs.texi | 10 +-
doc/lispref/modes.texi | 7 +-
etc/NEWS | 27 +-
lisp/cedet/semantic/grammar.el | 45 ++-
lisp/descr-text.el | 13 +-
lisp/emacs-lisp/eldoc.el | 508 ++++++++++++++++++++++++--------
lisp/hexl.el | 2 +-
lisp/progmodes/cc-engine.el | 2 +-
lisp/progmodes/cfengine.el | 17 +-
lisp/progmodes/elisp-mode.el | 61 ++--
lisp/progmodes/flymake.el | 14 +-
lisp/progmodes/octave.el | 6 +-
lisp/progmodes/python.el | 20 +-
src/fns.c | 14 +
test/lisp/descr-text-tests.el | 6 +-
test/lisp/progmodes/elisp-mode-tests.el | 6 +-
16 files changed, 551 insertions(+), 207 deletions(-)
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 865a3a6..2757c84 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1273,17 +1273,19 @@ Eldoc mode, which is turned on by default, and affects
buffers whose
major mode sets the variables described below. Use @w{@kbd{M-x
global-eldoc-mode}} to turn it off globally.
-@vindex eldoc-documentation-function
+@vindex eldoc-documentation-strategy
@vindex eldoc-documentation-functions
These variables can be used to configure ElDoc mode:
@table @code
-@item eldoc-documentation-function
+@item eldoc-documentation-strategy
This variable holds the function which is used to retrieve
documentation for the item at point from the functions in the hook
@code{eldoc-documentation-functions}. By default,
-@code{eldoc-documentation-function} returns the first documentation
-string produced by the @code{eldoc-documentation-functions} hook.
+@code{eldoc-documentation-strategy} returns the first documentation
+string produced by the @code{eldoc-documentation-functions} hook, but
+it may be customized to compose those functions' results in other
+ways.
@item eldoc-documentation-functions
This abnormal hook holds documentation functions. It acts as a
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index eaee56f..17e9607 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -469,9 +469,10 @@ variable @code{imenu-generic-expression}, for the two
variables
@code{imenu-create-index-function} (@pxref{Imenu}).
@item
-The mode can specify a local value for
-@code{eldoc-documentation-function} to tell ElDoc mode how to handle
-this mode.
+The mode can tell Eldoc mode how to retrieve different types of
+documentation for whatever is at point, by adding one or more
+buffer-local entries to the special hook
+@code{eldoc-documentation-functions}.
@item
The mode can specify how to complete various keywords by adding one or
diff --git a/etc/NEWS b/etc/NEWS
index fc5c215..07403f2 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -247,14 +247,25 @@ supplied error message.
+++
** ElDoc
-*** New hook 'eldoc-documentation-functions' to be used for registering
-doc string functions. This makes the results of all doc string
-functions accessible to the user through the existing single function hook
-'eldoc-documentation-function'.
-
-*** 'eldoc-documentation-function' is now a user option.
-Modes should use the new hook instead of this user option to register
-their backends.
+*** New hook 'eldoc-documentation-functions'.
+This hook is intended to be used for registering doc string functions.
+These functions don't need to produce the doc string right away, they
+may arrange for it to be produced asynchronously. The results of all
+doc string functions are accessible to the user through the existing
+variable 'eldoc-documentation-strategy'.
+
+*** New user option 'eldoc-documentation-strategy'.
+The built-in choices available for this user option let users compose
+the results of 'eldoc-documentation-functions' in various ways, even
+if some of those functions are sychronous and some asynchchronous.
+The user option replaces 'eldoc-documentation-function', which is now
+obsolete.
+
+*** 'eldoc-echo-area-use-multiline-p' is now handled by ElDoc.
+The user option 'eldoc-echo-area-use-multiline-p' is now handled
+by the Eldoc library itself. Functions in
+'eldoc-documentation-functions' don't need to worry about consulting
+it when producing a doc string.
** Eshell
diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el
index 2c3b24b..1ed1833 100644
--- a/lisp/cedet/semantic/grammar.el
+++ b/lisp/cedet/semantic/grammar.el
@@ -1663,6 +1663,42 @@ Select the buffer containing the tag's definition, and
move point there."
(defvar semantic-grammar-eldoc-last-data (cons nil nil))
+(defun semantic--docstring-format-sym-doc (prefix doc &optional face)
+ "Combine PREFIX and DOC, and shorten the result to fit in the echo area.
+
+When PREFIX is a symbol, propertize its symbol name with FACE
+before combining it with DOC. If FACE is not provided, just
+apply the nil face.
+
+See also: `eldoc-echo-area-use-multiline-p'."
+ ;; Hoisted from old `eldoc-docstring-format-sym-doc'.
+ ;; If the entire line cannot fit in the echo area, the symbol name may be
+ ;; truncated or eliminated entirely from the output to make room for the
+ ;; description.
+ (when (symbolp prefix)
+ (setq prefix (concat (propertize (symbol-name prefix) 'face face) ": ")))
+ (let* ((ea-multi eldoc-echo-area-use-multiline-p)
+ ;; Subtract 1 from window width since emacs will not write
+ ;; any chars to the last column, or in later versions, will
+ ;; cause a wraparound and resize of the echo area.
+ (ea-width (1- (window-width (minibuffer-window))))
+ (strip (- (+ (length prefix)
+ (length doc))
+ ea-width)))
+ (cond ((or (<= strip 0)
+ (eq ea-multi t)
+ (and ea-multi (> (length doc) ea-width)))
+ (concat prefix doc))
+ ((> (length doc) ea-width)
+ (substring (format "%s" doc) 0 ea-width))
+ ((>= strip (string-match-p ":? *\\'" prefix))
+ doc)
+ (t
+ ;; Show the end of the partial symbol name, rather
+ ;; than the beginning, since the former is more likely
+ ;; to be unique given package namespace conventions.
+ (concat (substring prefix strip) doc)))))
+
(defun semantic-grammar-eldoc-get-macro-docstring (macro expander)
"Return a one-line docstring for the given grammar MACRO.
EXPANDER is the name of the function that expands MACRO."
@@ -1681,19 +1717,18 @@ EXPANDER is the name of the function that expands
MACRO."
(setq doc (eldoc-function-argstring expander))))
(when doc
(setq doc
- (eldoc-docstring-format-sym-doc
+ (semantic--docstring-format-sym-doc
macro (format "==> %s %s" expander doc) 'default))
(setq semantic-grammar-eldoc-last-data (cons expander doc)))
doc))
((fboundp 'elisp-get-fnsym-args-string) ;; Emacs≥25
- (elisp-get-fnsym-args-string
- expander nil
- (concat (propertize (symbol-name macro)
+ (concat (propertize (symbol-name macro)
'face 'font-lock-keyword-face)
" ==> "
(propertize (symbol-name macro)
'face 'font-lock-function-name-face)
- ": ")))))
+ ": "
+ (elisp-get-fnsym-args-string expander nil )))))
(define-mode-local-override semantic-idle-summary-current-symbol-info
semantic-grammar-mode ()
diff --git a/lisp/descr-text.el b/lisp/descr-text.el
index 1dbbd42..776ce76 100644
--- a/lisp/descr-text.el
+++ b/lisp/descr-text.el
@@ -919,7 +919,7 @@ condition, the function may return string longer than
WIDTH, see
(t name)))))))
;;;###autoload
-(defun describe-char-eldoc ()
+(defun describe-char-eldoc (_callback &rest _)
"Return a description of character at point for use by ElDoc mode.
Return nil if character at point is a printable ASCII
@@ -929,10 +929,17 @@ Otherwise return a description formatted by
of `eldoc-echo-area-use-multiline-p' variable and width of
minibuffer window for width limit.
-This function is meant to be used as a value of
-`eldoc-documentation-function' variable."
+This function can be used as a value of
+`eldoc-documentation-functions' variable."
(let ((ch (following-char)))
(when (and (not (zerop ch)) (or (< ch 32) (> ch 127)))
+ ;; TODO: investigate if the new `eldoc-documentation-functions'
+ ;; API could significantly improve this. JT@2020-07-07: Indeed,
+ ;; instead of returning a string tailored here for the echo area
+ ;; exclusively, we could call the (now unused) argument
+ ;; _CALLBACK with hints on how to shorten the string if needed,
+ ;; or with multiple usable strings which Eldoc picks according
+ ;; to its space contraints.
(describe-char-eldoc--format
ch
(unless (eq eldoc-echo-area-use-multiline-p t)
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index ef5dbf8..9efd770 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -5,7 +5,7 @@
;; Author: Noah Friedman <friedman@splode.com>
;; Keywords: extensions
;; Created: 1995-10-06
-;; Version: 1.0.0
+;; Version: 1.1.0
;; Package-Requires: ((emacs "26.3"))
;; This is a GNU ELPA :core package. Avoid functionality that is not
@@ -47,6 +47,8 @@
;;; Code:
+(eval-when-compile (require 'cl-lib))
+
(defgroup eldoc nil
"Show function arglist or variable docstring in echo area."
:group 'lisp
@@ -77,38 +79,50 @@ Actually, any name of a function which takes a string as an
argument and
returns another string is acceptable.
Note that this variable has no effect, unless
-`eldoc-documentation-function' handles it explicitly."
+`eldoc-documentation-strategy' handles it explicitly."
:type '(radio (function-item upcase)
(function-item downcase)
function))
(make-obsolete-variable 'eldoc-argument-case nil "25.1")
(defcustom eldoc-echo-area-use-multiline-p 'truncate-sym-name-if-fit
- "Allow long ElDoc messages to resize echo area display.
-If value is t, never attempt to truncate messages; complete symbol name
-and function arglist or 1-line variable documentation will be displayed
-even if echo area must be resized to fit.
-
-If value is any non-nil value other than t, symbol name may be truncated
-if it will enable the function arglist or documentation string to fit on a
-single line without resizing window. Otherwise, behavior is just like
-former case.
-
-If value is nil, messages are always truncated to fit in a single line of
-display in the echo area. Function or variable symbol name may be
-truncated to make more of the arglist or documentation string visible.
-
-Note that this variable has no effect, unless
-`eldoc-documentation-function' handles it explicitly."
- :type '(radio (const :tag "Always" t)
- (const :tag "Never" nil)
- (const :tag "Yes, but truncate symbol names if it will\
- enable argument list to fit on one line" truncate-sym-name-if-fit)))
+ "Allow long ElDoc doc strings to resize echo area display.
+If value is t, never attempt to truncate messages, even if the
+echo area must be resized to fit.
+
+If value is a number (integer or floating point), it has the
+semantics of `max-mini-window-height', constraining the resizing
+for Eldoc purposes only.
+
+Any resizing respects `max-mini-window-height'.
+
+If value is any non-nil symbol other than t, the part of the doc
+string that represents the symbol's name may be truncated if it
+will enable the rest of the doc string to fit on a single line,
+without resizing the echo area.
+
+If value is nil, a doc string is always truncated to fit in a
+single line of display in the echo area."
+ :type '(radio (const :tag "Always" t)
+ (float :tag "Fraction of frame height" 0.25)
+ (integer :tag "Number of lines" 5)
+ (const :tag "Never" nil)
+ (const :tag "Yes, but ask major-mode to truncate
+ symbol names if it will\ enable argument list to fit on one
+ line" truncate-sym-name-if-fit)))
+
+(defcustom eldoc-prefer-doc-buffer nil
+ "Prefer Eldoc's documentation buffer if it is showing in some frame.
+If this variable's value is t and a piece of documentation needs
+to be truncated to fit in the echo area, do so if Eldoc's
+documentation buffer is not already showing, since the buffer
+always holds the full documentation."
+ :type 'boolean)
(defface eldoc-highlight-function-argument
'((t (:inherit bold)))
"Face used for the argument at point in a function's argument list.
-Note that this face has no effect unless the `eldoc-documentation-function'
+Note that this face has no effect unless the `eldoc-documentation-strategy'
handles it explicitly.")
;;; No user options below here.
@@ -150,7 +164,7 @@ directly. Instead, use `eldoc-add-command' and
`eldoc-remove-command'.")
This is used to determine if `eldoc-idle-delay' is changed by the user.")
(defvar eldoc-message-function #'eldoc-minibuffer-message
- "The function used by `eldoc-message' to display messages.
+ "The function used by `eldoc--message' to display messages.
It should receive the same arguments as `message'.")
(defun eldoc-edit-message-commands ()
@@ -203,7 +217,7 @@ expression point is on." :lighter eldoc-minor-mode-string
:init-value t
;; For `read--expression', the usual global mode mechanism of
;; `change-major-mode-hook' runs in the minibuffer before
- ;; `eldoc-documentation-function' is set, so `turn-on-eldoc-mode'
+ ;; `eldoc-documentation-strategy' is set, so `turn-on-eldoc-mode'
;; does nothing. Configure and enable eldoc from
;; `eval-expression-minibuffer-setup-hook' instead.
(if global-eldoc-mode
@@ -216,13 +230,16 @@ expression point is on." :lighter eldoc-minor-mode-string
;; Setup `eldoc', similar to `emacs-lisp-mode'. FIXME: Call
;; `emacs-lisp-mode' itself?
(add-hook 'eldoc-documentation-functions
- #'elisp-eldoc-documentation-function nil t)
+ #'elisp-eldoc-var-docstring nil t)
+ (add-hook 'eldoc-documentation-functions
+ #'elisp-eldoc-funcall nil t)
+ (setq eldoc-documentation-strategy 'eldoc-documentation-default)
(eldoc-mode +1))
;;;###autoload
(defun turn-on-eldoc-mode ()
"Turn on `eldoc-mode' if the buffer has ElDoc support enabled.
-See `eldoc-documentation-function' for more detail."
+See `eldoc-documentation-strategy' for more detail."
(when (eldoc--supported-p)
(eldoc-mode 1)))
@@ -241,7 +258,9 @@ reflect the change."
(when (or eldoc-mode
(and global-eldoc-mode
(eldoc--supported-p)))
- (eldoc-print-current-symbol-info))))))
+ ;; Don't ignore, but also don't full-on signal errors
+ (with-demoted-errors "eldoc error: %s"
+ (eldoc-print-current-symbol-info)) )))))
;; If user has changed the idle delay, update the timer.
(cond ((not (= eldoc-idle-delay eldoc-current-idle-delay))
@@ -279,7 +298,10 @@ Otherwise work like `message'."
(force-mode-line-update)))
(apply #'message format-string args)))
-(defun eldoc-message (&optional string)
+(make-obsolete
+ 'eldoc-message "use `eldoc-documentation-functions' instead." "eldoc-1.1.0")
+(defun eldoc-message (&optional string) (eldoc--message string))
+(defun eldoc--message (&optional string)
"Display STRING as an ElDoc message if it's non-nil.
Also store it in `eldoc-last-message' and return that value."
@@ -313,8 +335,8 @@ Also store it in `eldoc-last-message' and return that
value."
(not (minibufferp)) ;We don't use the echo area when in minibuffer.
(if (and (eldoc-display-message-no-interference-p)
(eldoc--message-command-p this-command))
- (eldoc-message eldoc-last-message)
- ;; No need to call eldoc-message since the echo area will be cleared
+ (eldoc--message eldoc-last-message)
+ ;; No need to call eldoc--message since the echo area will be cleared
;; for us, but do note that the last-message will be gone.
(setq eldoc-last-message nil))))
@@ -338,12 +360,39 @@ Also store it in `eldoc-last-message' and return that
value."
(defvar eldoc-documentation-functions nil
- "Hook for functions to call to return doc string.
-Each function should accept no arguments and return a one-line
-string for displaying doc about a function etc. appropriate to
-the context around point. It should return nil if there's no doc
-appropriate for the context. Typically doc is returned if point
-is on a function-like name or in its arg list.
+ "Hook of functions that produce doc strings.
+
+A doc string is typically relevant if point is on a function-like
+name, inside its arg list, or on any object with some associated
+information.
+
+Each hook function is called with at least one argument CALLBACK,
+a function, and decides whether to display a doc short string
+about the context around point.
+
+- If that decision can be taken quickly, the hook function may
+ call CALLBACK immediately following the protocol described
+ berlow. Alternatively it may ignore CALLBACK entirely and
+ return either the doc string, or nil if there's no doc
+ appropriate for the context.
+
+- If the computation of said doc string (or the decision whether
+ there is one at all) is expensive or can't be performed
+ directly, the hook function should return a non-nil, non-string
+ value and arrange for CALLBACK to be called at a later time,
+ using asynchronous processes or other asynchronous mechanisms.
+
+To call the CALLBACK function, the hook function must pass it an
+obligatory argument DOCSTRING, a string containing the
+documentation, followed by an optional list of keyword-value
+pairs of the form (:KEY VALUE :KEY2 VALUE2...). KEY can be:
+
+* `:thing', VALUE is a short string or symbol designating what is
+ being reported on. The documentation display engine can elect
+ to remove this information depending on space contraints;
+
+* `:face', VALUE is a symbol designating a face to use when
+ displaying `:thing''s value.
Major modes should modify this hook locally, for example:
(add-hook \\='eldoc-documentation-functions #\\='foo-mode-eldoc nil t)
@@ -351,110 +400,331 @@ so that the global value (i.e. the default value of the
hook) is
taken into account if the major mode specific function does not
return any documentation.")
+(defvar eldoc--doc-buffer nil "Buffer holding latest eldoc-produced docs.")
+(defun eldoc-doc-buffer (&optional interactive)
+ "Get latest *eldoc* help buffer. Interactively, display it."
+ (interactive (list t))
+ (prog1
+ (if (and eldoc--doc-buffer (buffer-live-p eldoc--doc-buffer))
+ eldoc--doc-buffer
+ (setq eldoc--doc-buffer (get-buffer-create "*eldoc*")))
+ (when interactive (display-buffer eldoc--doc-buffer))))
+
+(defun eldoc--handle-docs (docs)
+ "Display multiple DOCS in echo area.
+DOCS is a list of (STRING PLIST...). It is already sorted.
+Honor most of `eldoc-echo-area-use-multiline-p'."
+ ;; If there's nothing to report clear the echo area, but don't erase
+ ;; the last *eldoc* buffer.
+ (if (null docs) (eldoc--message nil)
+ (let*
+ ;; Otherwise, establish some parameters.
+ ((width (1- (window-width (minibuffer-window))))
+ (val (if (and (symbolp eldoc-echo-area-use-multiline-p)
+ eldoc-echo-area-use-multiline-p)
+ max-mini-window-height
+ eldoc-echo-area-use-multiline-p))
+ (available (cl-typecase val
+ (float (truncate (* (frame-height) val)))
+ (integer val)
+ (t 1)))
+ (things-reported-on)
+ single-sym-name)
+ ;; Then, compose the contents of the `*eldoc*' buffer.
+ (with-current-buffer (eldoc-doc-buffer)
+ (let ((inhibit-read-only t))
+ (erase-buffer) (setq buffer-read-only t)
+ (local-set-key "q" 'quit-window)
+ (cl-loop for (docs . rest) on docs
+ for (this-doc . plist) = docs
+ for thing = (plist-get plist :thing)
+ when thing do
+ (cl-pushnew thing things-reported-on)
+ (setq this-doc
+ (concat
+ (propertize (format "%s" thing)
+ 'face (plist-get plist :face))
+ ": "
+ this-doc))
+ do (insert this-doc)
+ when rest do (insert "\n")))
+ ;; Rename the buffer.
+ (when things-reported-on
+ (rename-buffer (format "*eldoc for %s*"
+ (mapconcat (lambda (s) (format "%s" s))
+ things-reported-on
+ ", ")))))
+ ;; Finally, output to the echo area. We handle the
+ ;; `truncate-sym-name-if-fit' special case first, by selecting a
+ ;; top-section of the `*eldoc' buffer. I'm pretty sure nicer
+ ;; strategies can be used here, probably by splitting this
+ ;; function into some `eldoc-display-functions' special hook.
+ (if (and (eq 'truncate-sym-name-if-fit eldoc-echo-area-use-multiline-p)
+ (null (cdr docs))
+ (setq single-sym-name
+ (format "%s" (plist-get (cdar docs) :thing)))
+ (> (+ (length (caar docs)) (length single-sym-name) 2) width))
+ (eldoc--message (caar docs))
+ (with-current-buffer (eldoc-doc-buffer)
+ (goto-char (point-min))
+ (cond
+ ;; Potentially truncate a long message into less lines,
+ ;; then display it in the echo area;
+ ((> available 1)
+ (cl-loop
+ initially (goto-char (line-end-position (1+ available)))
+ for truncated = nil then t
+ for needed
+ = (let ((truncate-lines message-truncate-lines))
+ (count-screen-lines (point-min) (point) t
(minibuffer-window)))
+ while (> needed (if truncated (1- available) available))
+ do (goto-char (line-end-position (if truncated 0 -1)))
+ (while (bolp) (goto-char (line-end-position 0)))
+ finally
+ (unless (and truncated
+ eldoc-prefer-doc-buffer
+ (get-buffer-window eldoc--doc-buffer))
+ (eldoc--message
+ (concat (buffer-substring (point-min) (point))
+ (and truncated
+ (format
+ "\n(Documentation truncated. Use `%s' to see
rest)"
+ (substitute-command-keys
"\\[eldoc-doc-buffer]"))))))))
+ ((= available 1)
+ ;; Truncate "brutally." ; FIXME: use `eldoc-prefer-doc-buffer' too?
+ (eldoc--message
+ (truncate-string-to-width
+ (buffer-substring (point-min) (line-end-position 1))
width)))))))))
+
(defun eldoc-documentation-default ()
"Show first doc string for item at point.
-Default value for `eldoc-documentation-function'."
- (let ((res (run-hook-with-args-until-success
'eldoc-documentation-functions)))
- (when res
- (if eldoc-echo-area-use-multiline-p res
- (truncate-string-to-width
- res (1- (window-width (minibuffer-window))))))))
+Default value for `eldoc-documentation-strategy'."
+ (run-hook-with-args-until-success 'eldoc-documentation-functions
+ (eldoc--make-callback :patient)))
+
+(defun eldoc--documentation-compose-1 (eagerlyp)
+ "Helper function for composing multiple doc strings.
+If EAGERLYP is non-nil show documentation as soon as possible,
+else wait for all doc strings."
+ (run-hook-wrapped 'eldoc-documentation-functions
+ (lambda (f)
+ (let* ((callback (eldoc--make-callback
+ (if eagerlyp :eager :patient)))
+ (str (funcall f callback)))
+ (if (or (null str) (stringp str)) (funcall callback
str))
+ nil)))
+ t)
(defun eldoc-documentation-compose ()
- "Show multiple doc string results at once.
-Meant as a value for `eldoc-documentation-function'."
- (let (res)
- (run-hook-wrapped
- 'eldoc-documentation-functions
- (lambda (f)
- (let ((str (funcall f)))
- (when str (push str res))
- nil)))
- (when res
- (setq res (mapconcat #'identity (nreverse res) ", "))
- (if eldoc-echo-area-use-multiline-p res
- (truncate-string-to-width
- res (1- (window-width (minibuffer-window))))))))
-
-(defcustom eldoc-documentation-function #'eldoc-documentation-default
- "Function to call to return doc string.
-The function of no args should return a one-line string for displaying
-doc about a function etc. appropriate to the context around point.
-It should return nil if there's no doc appropriate for the context.
-Typically doc is returned if point is on a function-like name or in its
-arg list.
-
-The result is used as is, so the function must explicitly handle
-the variables `eldoc-argument-case' and `eldoc-echo-area-use-multiline-p',
-and the face `eldoc-highlight-function-argument', if they are to have any
-effect."
+ "Show multiple doc strings at once after waiting for all.
+Meant as a value for `eldoc-documentation-strategy'."
+ (eldoc--documentation-compose-1 nil))
+
+(defun eldoc-documentation-compose-eagerly ()
+ "Show multiple doc strings at once as soon as possible.
+Meant as a value for `eldoc-documentation-strategy'."
+ (eldoc--documentation-compose-1 t))
+
+(defun eldoc-documentation-enthusiast ()
+ "Show most important doc string produced so far.
+Meant as a value for `eldoc-documentation-strategy'."
+ (run-hook-wrapped 'eldoc-documentation-functions
+ (lambda (f)
+ (let* ((callback (eldoc--make-callback :enthusiast))
+ (str (funcall f callback)))
+ (if (stringp str) (funcall callback str))
+ nil))))
+
+(define-obsolete-variable-alias 'eldoc-documentation-function
+ 'eldoc-documentation-strategy "eldoc-1.1.0")
+
+(defcustom eldoc-documentation-strategy #'eldoc-documentation-default
+ "How to collect and organize results of `eldoc-documentation-functions'.
+
+This variable controls how `eldoc-documentation-functions', which
+specifies the sources of documentation, is queried and how its
+results are organized before being displayed to the user. The
+following values are allowed:
+
+- `eldoc-documentation-default': calls functions in the special
+ hook in order until one is found that produces a doc string
+ value. Display only that value;
+
+- `eldoc-documentation-compose': calls all functions in the
+ special hook and displays all of the resulting doc strings
+ together. Wait for all strings to be ready, and preserve their
+ relative as specified by the order of functions in the hook;
+
+- `eldoc-documentation-compose-eagerly': calls all functions in
+ the special hook and display as many of the resulting doc
+ strings as possible, as soon as possibl. Preserving the
+ relative order of doc strings;
+
+- `eldoc-documentation-enthusiast': calls all functions in the
+ special hook and displays only the most important resulting
+ docstring one at any given time. A function appearing first in
+ the special hook is considered more important.
+
+This variable can also be set to a function of no args that
+returns something other than a string or nil and allows for some
+or all of the special hook `eldoc-documentation-functions' to be
+run. In that case, the strategy function should follow that
+other variable's protocol closely and endeavor to display the
+resulting doc strings itself.
+
+For backward compatibility to the \"old\" protocol, this variable
+can also be set to a function that returns nil or a doc string,
+depending whether or not there is documentation to display at
+all."
:link '(info-link "(emacs) Lisp Doc")
:type '(radio (function-item eldoc-documentation-default)
(function-item eldoc-documentation-compose)
+ (function-item eldoc-documentation-compose-eagerly)
+ (function-item eldoc-documentation-enthusiast)
(function :tag "Other function"))
:version "28.1")
(defun eldoc--supported-p ()
"Non-nil if an ElDoc function is set for this buffer."
- (and (not (memq eldoc-documentation-function '(nil ignore)))
+ (and (not (memq eldoc-documentation-strategy '(nil ignore)))
(or eldoc-documentation-functions
;; The old API had major modes set `eldoc-documentation-function'
;; to provide eldoc support. It's impossible now to determine
- ;; reliably whether the `eldoc-documentation-function' provides
+ ;; reliably whether the `eldoc-documentation-strategy' provides
;; eldoc support (as in the old API) or whether it just provides
;; a way to combine the results of the
;; `eldoc-documentation-functions' (as in the new API).
;; But at least if it's set buffer-locally it's a good hint that
;; there's some eldoc support in the current buffer.
- (local-variable-p 'eldoc-documentation-function))))
+ (local-variable-p 'eldoc-documentation-strategy))))
+
+(defvar eldoc--enthusiasm-curbing-timer nil
+ "Timer used by the `eldoc-documentation-enthusiast' strategy.
+When a doc string is encountered, it must endure a certain amount
+of time unchallenged until it is displayed to the user. This
+prevents blinking if a lower priority docstring comes in shortly
+before a higher priority one.")
+
+(defalias 'eldoc #'eldoc-print-current-symbol-info)
+
+;; This variable should be unbound, but that confuses
+;; `describe-symbol' for some reason.
+(defvar eldoc--make-callback nil "Helper for function `eldoc--make-callback'.")
+
+;; JT@2020-07-08: the below docstring for the internal function
+;; `eldoc--invoke-strategy' could be moved to
+;; `eldoc-documentation-strategy' or thereabouts if/when we decide to
+;; extend or publish the `make-callback' protocol.
+(defun eldoc--make-callback (method)
+ "Make callback suitable for `eldoc-documentation-functions'.
+The return value is a function FN whose lambda list is (STRING
+&rest PLIST) and can be called by those functions. Its
+responsibility is always to register the docstring STRING along
+with options specified in PLIST as the documentation to display
+for each particular situation.
+
+METHOD specifies how the callback behaves relative to other
+competing elements in `eldoc-documentation-functions'. It can
+have the following values:
+
+- `:enthusiast' says to display STRING as soon as possible if
+ there's no higher priority doc string;
+
+- `:patient' says to display STRING along with all other
+ competing strings but only when all of all
+ `eldoc-documentation-functions' have been collected;
+
+- `:eager' says to display STRING along with all other competing
+ strings so far, as soon as possible."
+ (funcall eldoc--make-callback method))
+
+(defun eldoc--invoke-strategy ()
+ "Invoke `eldoc-documentation-strategy' function.
+
+That function's job is to run the `eldoc-documentation-functions'
+special hook, using the `run-hook' family of functions. The way
+we invoke it here happens in a way strategy function can itself
+call `eldoc--make-callback' to produce values to give to the
+elements of the special hook `eldoc-documentation-functions'.
+
+For each element of `eldoc-documentation-functions' invoked a
+corresponding call to `eldoc--make-callback' must be made. See
+docstring of `eldoc--make-callback' for the types of callback
+that can be produced.
+
+If the strategy function does not use `eldoc--make-callback', it
+must find some alternate way to produce callbacks to feed to
+`eldoc-documentation-function', and those callbacks should
+endeavour to display the docstrings given to them."
+ (let* (;; how many docstrings callbaks have been
+ (howmany 0)
+ ;; how many calls to callbacks we're waiting on. Used by
+ ;; `:patient'.
+ (want 0)
+ ;; how many doc strings and corresponding options have been
+ ;; registered it.
+ (docs-registered '()))
+ (cl-labels
+ ((register-doc (pos string plist)
+ (when (and string (> (length string) 0))
+ (push (cons pos (cons string plist)) docs-registered)))
+ (display-doc ()
+ (eldoc--handle-docs
+ (mapcar #'cdr
+ (setq docs-registered
+ (sort docs-registered
+ (lambda (a b) (< (car a) (car b))))))))
+ (make-callback (method)
+ (let ((pos (prog1 howmany (cl-incf howmany))))
+ (cl-ecase method
+ (:enthusiast
+ (lambda (string &rest plist)
+ (when (and string (cl-loop for (p) in docs-registered
+ never (< p pos)))
+ (setq docs-registered '())
+ (register-doc pos string plist)
+ (when (and (timerp eldoc--enthusiasm-curbing-timer)
+ (memq eldoc--enthusiasm-curbing-timer
+ timer-list))
+ (cancel-timer eldoc--enthusiasm-curbing-timer))
+ (setq eldoc--enthusiasm-curbing-timer
+ (run-at-time (unless (zerop pos) 0.3)
+ nil #'display-doc)))
+ t))
+ (:patient
+ (cl-incf want)
+ (lambda (string &rest plist)
+ (register-doc pos string plist)
+ (when (zerop (cl-decf want)) (display-doc))
+ t))
+ (:eager
+ (lambda (string &rest plist)
+ (register-doc pos string plist)
+ (display-doc)
+ t))))))
+ (let* ((eldoc--make-callback #'make-callback)
+ (res (funcall eldoc-documentation-strategy)))
+ ;; Observe the old and the new protocol:
+ (cond (;; Old protocol: got string, output immediately;
+ (stringp res) (register-doc 0 res nil) (display-doc))
+ (;; Old protocol: got nil, clear the echo area;
+ (null res) (eldoc--message nil))
+ (;; New protocol: trust callback will be called;
+ t))))))
(defun eldoc-print-current-symbol-info ()
- "Print the text produced by `eldoc-documentation-function'."
- ;; This is run from post-command-hook or some idle timer thing,
- ;; so we need to be careful that errors aren't ignored.
- (with-demoted-errors "eldoc error: %s"
- (if (not (eldoc-display-message-p))
- ;; Erase the last message if we won't display a new one.
- (when eldoc-last-message
- (eldoc-message nil))
- (let ((non-essential t))
- ;; Only keep looking for the info as long as the user hasn't
- ;; requested our attention. This also locally disables inhibit-quit.
- (while-no-input
- (eldoc-message (funcall eldoc-documentation-function)))))))
-
-;; If the entire line cannot fit in the echo area, the symbol name may be
-;; truncated or eliminated entirely from the output to make room for the
-;; description.
-(defun eldoc-docstring-format-sym-doc (prefix doc &optional face)
- "Combine PREFIX and DOC, and shorten the result to fit in the echo area.
-
-When PREFIX is a symbol, propertize its symbol name with FACE
-before combining it with DOC. If FACE is not provided, just
-apply the nil face.
-
-See also: `eldoc-echo-area-use-multiline-p'."
- (when (symbolp prefix)
- (setq prefix (concat (propertize (symbol-name prefix) 'face face) ": ")))
- (let* ((ea-multi eldoc-echo-area-use-multiline-p)
- ;; Subtract 1 from window width since emacs will not write
- ;; any chars to the last column, or in later versions, will
- ;; cause a wraparound and resize of the echo area.
- (ea-width (1- (window-width (minibuffer-window))))
- (strip (- (+ (length prefix) (length doc)) ea-width)))
- (cond ((or (<= strip 0)
- (eq ea-multi t)
- (and ea-multi (> (length doc) ea-width)))
- (concat prefix doc))
- ((> (length doc) ea-width)
- (substring (format "%s" doc) 0 ea-width))
- ((>= strip (string-match-p ":? *\\'" prefix))
- doc)
- (t
- ;; Show the end of the partial symbol name, rather
- ;; than the beginning, since the former is more likely
- ;; to be unique given package namespace conventions.
- (concat (substring prefix strip) doc)))))
+ "Document thing at point."
+ (interactive)
+ (if (not (eldoc-display-message-p))
+ ;; Erase the last message if we won't display a new one.
+ (when eldoc-last-message
+ (eldoc--message nil))
+ (let ((non-essential t))
+ ;; Only keep looking for the info as long as the user hasn't
+ ;; requested our attention. This also locally disables
+ ;; inhibit-quit.
+ (while-no-input
+ (eldoc--invoke-strategy)))))
;; When point is in a sexp, the function args are not reprinted in the echo
;; area after every possible interactive command because some of them print
diff --git a/lisp/hexl.el b/lisp/hexl.el
index cf7118f..38eca77 100644
--- a/lisp/hexl.el
+++ b/lisp/hexl.el
@@ -515,7 +515,7 @@ Ask the user for confirmation."
(message "Current address is %d/0x%08x" hexl-address hexl-address))
hexl-address))
-(defun hexl-print-current-point-info ()
+(defun hexl-print-current-point-info (&rest _ignored)
"Return current hexl-address in string.
This function is intended to be used as eldoc callback."
(let ((addr (hexl-current-address)))
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 784a6c7..c3a98d9 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1582,7 +1582,7 @@ comment at the start of cc-engine.el for more info."
(save-excursion (backward-char)
(looking-at "\\s("))
(c-crosses-statement-barrier-p (point) end)))))
-(make-obsolete 'c-at-expression-start-p nil "5.35")
+(make-obsolete 'c-at-expression-start-p nil "CC mode 5.35")
;; A set of functions that covers various idiosyncrasies in
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index f25b3cb..a8fe485 100644
--- a/lisp/progmodes/cfengine.el
+++ b/lisp/progmodes/cfengine.el
@@ -1294,10 +1294,10 @@ Calls `cfengine-cf-promises' with \"-s json\"."
'symbols))
syntax)))
-(defun cfengine3-documentation-function ()
+(defun cfengine3-documentation-function (&rest _ignored)
"Document CFengine 3 functions around point.
-Intended as the value of `eldoc-documentation-function', which see.
-Use it by enabling `eldoc-mode'."
+Intended as the value of `eldoc-documentation-functions', which
+see. Use it by enabling `eldoc-mode'."
(let ((fdef (cfengine3--current-function)))
(when fdef
(cfengine3-format-function-docstring fdef))))
@@ -1390,15 +1390,8 @@ to the action header."
(when buffer-file-name
(shell-quote-argument buffer-file-name)))))
- (if (boundp 'eldoc-documentation-functions)
- (add-hook 'eldoc-documentation-functions
- #'cfengine3-documentation-function nil t)
- ;; For emacs < 25.1 where `eldoc-documentation-function' defaults
- ;; to nil.
- (or eldoc-documentation-function
- (setq-local eldoc-documentation-function #'ignore))
- (add-function :before-until (local 'eldoc-documentation-function)
- #'cfengine3-documentation-function))
+ (add-hook 'eldoc-documentation-functions
+ #'cfengine3-documentation-function nil t)
(add-hook 'completion-at-point-functions
#'cfengine3-completion-function nil t)
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 8812c49..6df5411 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -280,7 +280,9 @@ Blank lines separate paragraphs. Semicolons start comments.
electric-pair-text-pairs))
(add-hook 'electric-pair-mode-hook #'emacs-lisp-set-electric-text-pairs))
(add-hook 'eldoc-documentation-functions
- #'elisp-eldoc-documentation-function nil t)
+ #'elisp-eldoc-var-docstring nil t)
+ (add-hook 'eldoc-documentation-functions
+ #'elisp-eldoc-funcall nil t)
(add-hook 'xref-backend-functions #'elisp--xref-backend nil t)
(setq-local project-vc-external-roots-function #'elisp-load-path-roots)
(add-hook 'completion-at-point-functions
@@ -1403,20 +1405,27 @@ which see."
or argument string for functions.
2 - `function' if function args, `variable' if variable documentation.")
-(defun elisp-eldoc-documentation-function ()
- "`eldoc-documentation-function' (which see) for Emacs Lisp."
- (let ((current-symbol (elisp--current-symbol))
- (current-fnsym (elisp--fnsym-in-current-sexp)))
- (cond ((null current-fnsym)
- nil)
- ((eq current-symbol (car current-fnsym))
- (or (apply #'elisp-get-fnsym-args-string current-fnsym)
- (elisp-get-var-docstring current-symbol)))
- (t
- (or (elisp-get-var-docstring current-symbol)
- (apply #'elisp-get-fnsym-args-string current-fnsym))))))
-
-(defun elisp-get-fnsym-args-string (sym &optional index prefix)
+(defun elisp-eldoc-funcall (callback &rest _ignored)
+ "Document function call at point.
+Intended for `eldoc-documentation-functions' (which see)."
+ (let* ((sym-info (elisp--fnsym-in-current-sexp))
+ (fn-sym (car sym-info)))
+ (when fn-sym
+ (funcall callback (apply #'elisp-get-fnsym-args-string sym-info)
+ :thing fn-sym
+ :face (if (functionp fn-sym)
+ 'font-lock-function-name-face
+ 'font-lock-keyword-face)))))
+
+(defun elisp-eldoc-var-docstring (callback &rest _ignored)
+ "Document variable at point.
+Intended for `eldoc-documentation-functions' (which see)."
+ (let ((sym (elisp--current-symbol)))
+ (when sym (funcall callback (elisp-get-var-docstring sym)
+ :thing sym
+ :face 'font-lock-variable-name-face))))
+
+(defun elisp-get-fnsym-args-string (sym &optional index)
"Return a string containing the parameter list of the function SYM.
If SYM is a subr and no arglist is obtainable from the docstring
or elsewhere, return a 1-line docstring."
@@ -1442,20 +1451,13 @@ or elsewhere, return a 1-line docstring."
;; Stringify, and store before highlighting, downcasing, etc.
(elisp--last-data-store sym (elisp-function-argstring args)
'function))))))
- ;; Highlight, truncate.
+ ;; Highlight
(if argstring
(elisp--highlight-function-argument
- sym argstring index
- (or prefix
- (concat (propertize (symbol-name sym) 'face
- (if (functionp sym)
- 'font-lock-function-name-face
- 'font-lock-keyword-face))
- ": "))))))
-
-(defun elisp--highlight-function-argument (sym args index prefix)
- "Highlight argument INDEX in ARGS list for function SYM.
-In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
+ sym argstring index))))
+
+(defun elisp--highlight-function-argument (sym args index)
+ "Highlight argument INDEX in ARGS list for function SYM."
;; FIXME: This should probably work on the list representation of `args'
;; rather than its string representation.
;; FIXME: This function is much too long, we need to split it up!
@@ -1558,7 +1560,6 @@ In the absence of INDEX, just call
`eldoc-docstring-format-sym-doc'."
(when start
(setq doc (copy-sequence args))
(add-text-properties start end (list 'face argument-face) doc))
- (setq doc (eldoc-docstring-format-sym-doc prefix doc))
doc)))
;; Return a string containing a brief (one-line) documentation string for
@@ -1571,9 +1572,7 @@ In the absence of INDEX, just call
`eldoc-docstring-format-sym-doc'."
(t
(let ((doc (documentation-property sym 'variable-documentation t)))
(when doc
- (let ((doc (eldoc-docstring-format-sym-doc
- sym (elisp--docstring-first-line doc)
- 'font-lock-variable-name-face)))
+ (let ((doc (elisp--docstring-first-line doc)))
(elisp--last-data-store sym doc 'variable)))))))
(defun elisp--last-data-store (symbol doc type)
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 4ca5c65..37e7324 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -4,9 +4,9 @@
;; Author: Pavel Kobyakov <pk_at_work@yahoo.com>
;; Maintainer: João Távora <joaotavora@gmail.com>
-;; Version: 1.0.8
+;; Version: 1.0.9
;; Keywords: c languages tools
-;; Package-Requires: ((emacs "26.1"))
+;; Package-Requires: ((emacs "26.1") (eldoc "1.1.0"))
;; This is a GNU ELPA :core package. Avoid functionality that is not
;; compatible with the version of Emacs recorded above.
@@ -1002,6 +1002,7 @@ special *Flymake log* buffer." :group 'flymake :lighter
(add-hook 'after-change-functions 'flymake-after-change-function nil t)
(add-hook 'after-save-hook 'flymake-after-save-hook nil t)
(add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook nil t)
+ (add-hook 'eldoc-documentation-functions 'flymake-eldoc-function nil t)
;; If Flymake happened to be alrady already ON, we must cleanup
;; existing diagnostic overlays, lest we forget them by blindly
@@ -1019,6 +1020,7 @@ special *Flymake log* buffer." :group 'flymake :lighter
(remove-hook 'after-save-hook 'flymake-after-save-hook t)
(remove-hook 'kill-buffer-hook 'flymake-kill-buffer-hook t)
;;+(remove-hook 'find-file-hook (function flymake-find-file-hook) t)
+ (remove-hook 'eldoc-documentation-functions 'flymake-eldoc-function t)
(mapc #'delete-overlay (flymake--overlays))
@@ -1086,6 +1088,14 @@ START and STOP and LEN are as in
`after-change-functions'."
(flymake-mode)
(flymake-log :warning "Turned on in `flymake-find-file-hook'")))
+(defun flymake-eldoc-function (report-doc &rest _)
+ "Document diagnostics at point.
+Intended for `eldoc-documentation-functions' (which see)."
+ (let ((diags (flymake-diagnostics (point))))
+ (when diags
+ (funcall report-doc
+ (mapconcat #'flymake-diagnostic-text diags "\n")))))
+
(defun flymake-goto-next-error (&optional n filter interactive)
"Go to Nth next Flymake diagnostic that matches FILTER.
Interactively, always move to the next diagnostic. With a prefix
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index 352c181..e07f818 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -755,7 +755,7 @@ Key bindings:
(setq font-lock-defaults '(inferior-octave-font-lock-keywords nil nil))
(setq-local info-lookup-mode 'octave-mode)
- (setq-local eldoc-documentation-function 'octave-eldoc-function)
+ (add-hook 'eldoc-documentation-functions 'octave-eldoc-function nil t)
(setq-local comint-input-ring-file-name
(or (getenv "OCTAVE_HISTFILE") "~/.octave_hist"))
@@ -1639,8 +1639,8 @@ code line."
(nreverse result)))))
(cdr octave-eldoc-cache))
-(defun octave-eldoc-function ()
- "A function for `eldoc-documentation-function' (which see)."
+(defun octave-eldoc-function (&rest _ignored)
+ "A function for `eldoc-documentation-functions' (which see)."
(when (inferior-octave-process-live-p)
(let* ((ppss (syntax-ppss))
(paren-pos (cadr ppss))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 22248f0..165463a 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -4573,7 +4573,7 @@ returns will be used. If not FORCE-PROCESS is passed what
:type 'boolean
:version "25.1")
-(defun python-eldoc-function ()
+(defun python-eldoc-function (&rest _ignored)
"`eldoc-documentation-function' for Python.
For this to work as best as possible you should call
`python-shell-send-buffer' from time to time so context in
@@ -5553,14 +5553,16 @@ REPORT-FN is Flymake's callback function."
(current-column))))
(^ '(- (1+ (current-indentation))))))
- (if (null eldoc-documentation-function)
- ;; Emacs<25
- (set (make-local-variable 'eldoc-documentation-function)
- #'python-eldoc-function)
- (if (boundp 'eldoc-documentation-functions)
- (add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t)
- (add-function :before-until (local 'eldoc-documentation-function)
- #'python-eldoc-function)))
+ (with-no-warnings
+ ;; supress warnings about eldoc-documentation-function being obsolete
+ (if (null eldoc-documentation-function)
+ ;; Emacs<25
+ (set (make-local-variable 'eldoc-documentation-function)
+ #'python-eldoc-function)
+ (if (boundp 'eldoc-documentation-functions)
+ (add-hook 'eldoc-documentation-functions #'python-eldoc-function nil
t)
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'python-eldoc-function))))
(add-to-list
'hs-special-modes-alist
diff --git a/src/fns.c b/src/fns.c
index a95a4b6..811d6e8 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1530,11 +1530,21 @@ same_float (Lisp_Object x, Lisp_Object y)
return !neql;
}
+/* True if X can be compared using `eq'.
+ This predicate is approximative, for maximum speed. */
+static bool
+eq_comparable_value (Lisp_Object x)
+{
+ return SYMBOLP (x) || FIXNUMP (x);
+}
+
DEFUN ("member", Fmember, Smember, 2, 2, 0,
doc: /* Return non-nil if ELT is an element of LIST. Comparison done
with `equal'.
The value is actually the tail of LIST whose car is ELT. */)
(Lisp_Object elt, Lisp_Object list)
{
+ if (eq_comparable_value (elt))
+ return Fmemq (elt, list);
Lisp_Object tail = list;
FOR_EACH_TAIL (tail)
if (! NILP (Fequal (elt, XCAR (tail))))
@@ -1622,6 +1632,8 @@ The value is actually the first element of ALIST whose
car equals KEY.
Equality is defined by TESTFN if non-nil or by `equal' if nil. */)
(Lisp_Object key, Lisp_Object alist, Lisp_Object testfn)
{
+ if (eq_comparable_value (key) && NILP (testfn))
+ return Fassq (key, alist);
Lisp_Object tail = alist;
FOR_EACH_TAIL (tail)
{
@@ -1672,6 +1684,8 @@ DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0,
The value is actually the first element of ALIST whose cdr equals KEY. */)
(Lisp_Object key, Lisp_Object alist)
{
+ if (eq_comparable_value (key))
+ return Frassq (key, alist);
Lisp_Object tail = alist;
FOR_EACH_TAIL (tail)
{
diff --git a/test/lisp/descr-text-tests.el b/test/lisp/descr-text-tests.el
index 74fcdf5..b060dff 100644
--- a/test/lisp/descr-text-tests.el
+++ b/test/lisp/descr-text-tests.el
@@ -75,18 +75,18 @@
(goto-char (point-min))
(should (eq ?a (following-char))) ; make sure we are where we think we are
;; Function should return nil for an ASCII character.
- (should (not (describe-char-eldoc)))
+ (should (not (describe-char-eldoc 'ignore)))
(goto-char (1+ (point)))
(should (eq ?… (following-char)))
(let ((eldoc-echo-area-use-multiline-p t))
;; Function should return description of an Unicode character.
(should (equal "U+2026: Horizontal ellipsis (Po: Punctuation, Other)"
- (describe-char-eldoc))))
+ (describe-char-eldoc 'ignore))))
(goto-char (point-max))
;; At the end of the buffer, function should return nil and not blow up.
- (should (not (describe-char-eldoc)))))
+ (should (not (describe-char-eldoc 'ignore)))))
(provide 'descr-text-test)
diff --git a/test/lisp/progmodes/elisp-mode-tests.el
b/test/lisp/progmodes/elisp-mode-tests.el
index 2ba0065..2de533e 100644
--- a/test/lisp/progmodes/elisp-mode-tests.el
+++ b/test/lisp/progmodes/elisp-mode-tests.el
@@ -194,7 +194,7 @@
(dotimes (i 3)
(should
(equal (elisp-mode-tests--face-propertized-string
- (elisp--highlight-function-argument 'foo "(A B C)" (1+ i) "foo:
"))
+ (elisp--highlight-function-argument 'foo "(A B C)" (1+ i)))
(propertize (nth i '("A" "B" "C"))
'face 'eldoc-highlight-function-argument)))))
@@ -206,7 +206,7 @@
(cl-flet ((bold-arg (i)
(elisp-mode-tests--face-propertized-string
(elisp--highlight-function-argument
- 'foo "(PROMPT LST &key A B C)" i "foo: "))))
+ 'foo "(PROMPT LST &key A B C)" i))))
(should-not (bold-arg 0))
(progn (forward-sexp) (forward-char))
(should (equal (bold-arg 1) "PROMPT"))
@@ -226,7 +226,7 @@
(cl-flet ((bold-arg (i)
(elisp-mode-tests--face-propertized-string
(elisp--highlight-function-argument
- 'foo "(X &key A B C)" i "foo: "))))
+ 'foo "(X &key A B C)" i))))
(should-not (bold-arg 0))
;; The `:b' specifies positional arg `X'.
(progn (forward-sexp) (forward-char))
- feature/native-comp 0b81044 02/14: * Clean-up some const folding logic and add `comp-function-pure-p', (continued)
- feature/native-comp 0b81044 02/14: * Clean-up some const folding logic and add `comp-function-pure-p', Andrea Corallo, 2020/07/09
- feature/native-comp b31b0eb 03/14: * Rework some test logic for generality, Andrea Corallo, 2020/07/09
- feature/native-comp 3d43d45 01/14: Merge remote-tracking branch 'savannah/master' into HEAD, Andrea Corallo, 2020/07/09
- feature/native-comp 4348969 06/14: * test/src/comp-test-funcs.el (comp-tests-aref-aset-f) : Fix UB., Andrea Corallo, 2020/07/09
- feature/native-comp 5688739 07/14: * Add `comp-call-op-p', Andrea Corallo, 2020/07/09
- feature/native-comp 9aaca82 12/14: * Add `comp-disabled-passes', Andrea Corallo, 2020/07/09
- feature/native-comp e6ab4e3 04/14: * Add a test targeting forward propagation, Andrea Corallo, 2020/07/09
- feature/native-comp 3db6ace 05/14: * Define `comp-symbol-func-to-fun', Andrea Corallo, 2020/07/09
- feature/native-comp 7622740 08/14: * Introduce a new pass ipa-pure, Andrea Corallo, 2020/07/09
- feature/native-comp b4de6ba 09/14: * Optimize pure functions defined by the compilation environment, Andrea Corallo, 2020/07/09
- feature/native-comp 5f13016 14/14: Merge remote-tracking branch 'savannah/master' into wip2,
Andrea Corallo <=
- feature/native-comp a53b446 10/14: Add some tests for pure function optimization, Andrea Corallo, 2020/07/09
- feature/native-comp 92e744d 11/14: ; * test/src/comp-test-funcs-dyn.el: Fix comment header., Andrea Corallo, 2020/07/09
- feature/native-comp 02bf2e0 13/14: * Disable ipa-pure in comp-tests-tco, Andrea Corallo, 2020/07/09