Commit 5f13016c authored by Andrea Corallo's avatar Andrea Corallo

Merge remote-tracking branch 'savannah/master' into wip2

parents 02bf2e08 19cf8e5b
Pipeline #6039 failed with stage
in 79 minutes and 25 seconds
......@@ -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
@item eldoc-documentation-functions
This abnormal hook holds documentation functions. It acts as a
......@@ -469,9 +469,10 @@ variable @code{imenu-generic-expression}, for the two variables
@code{imenu-create-index-function} (@pxref{Imenu}).
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
The mode can specify how to complete various keywords by adding one or
......@@ -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' 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
*** '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
......@@ -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))
(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))
;; 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
macro (format "==> %s %s" expander doc) 'default))
(setq semantic-grammar-eldoc-last-data (cons expander doc)))
((fboundp 'elisp-get-fnsym-args-string) ;; Emacs≥25
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 ()
......@@ -919,7 +919,7 @@ condition, the function may return string longer than WIDTH, see
(t name)))))))
(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.
(unless (eq eldoc-echo-area-use-multiline-p t)
This diff is collapsed.
......@@ -515,7 +515,7 @@ Ask the user for confirmation."
(message "Current address is %d/0x%08x" 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)))
......@@ -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
......@@ -1294,10 +1294,10 @@ Calls `cfengine-cf-promises' with \"-s json\"."
(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)
(add-hook 'eldoc-documentation-functions
#'cfengine3-documentation-function nil t)
(add-hook 'completion-at-point-functions
#'cfengine3-completion-function nil t)
......@@ -280,7 +280,9 @@ Blank lines separate paragraphs. Semicolons start comments.
(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)
((eq current-symbol (car current-fnsym))
(or (apply #'elisp-get-fnsym-args-string current-fnsym)
(elisp-get-var-docstring current-symbol)))
(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)
(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)
;; Highlight, truncate.
;; Highlight
(if argstring
sym argstring index
(or prefix
(concat (propertize (symbol-name sym) 'face
(if (functionp sym)
": "))))))
(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))
;; 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'."
(let ((doc (documentation-property sym 'variable-documentation t)))
(when doc
(let ((doc (eldoc-docstring-format-sym-doc
sym (elisp--docstring-first-line doc)
(let ((doc (elisp--docstring-first-line doc)))
(elisp--last-data-store sym doc 'variable)))))))
(defun elisp--last-data-store (symbol doc type)
......@@ -4,9 +4,9 @@
;; Author: Pavel Kobyakov <>
;; Maintainer: João Távora <>
;; 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-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
......@@ -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))
......@@ -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."
(^ '(- (1+ (current-indentation))))))
(if (null eldoc-documentation-function)
;; Emacs<25
(set (make-local-variable 'eldoc-documentation-function)
(if (boundp 'eldoc-documentation-functions)
(add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t)
(add-function :before-until (local 'eldoc-documentation-function)
;; supress warnings about eldoc-documentation-function being obsolete
(if (null eldoc-documentation-function)
;; Emacs<25
(set (make-local-variable 'eldoc-documentation-function)
(if (boundp 'eldoc-documentation-functions)
(add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t)
(add-function :before-until (local 'eldoc-documentation-function)
......@@ -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;
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;
......@@ -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;
......@@ -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 '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)
......@@ -194,7 +194,7 @@
(dotimes (i 3)
(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)
'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)
'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))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment