emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/eldoc-async fbc3f86 5/5: Make more parts of Emacs use new Eldoc


From: João Távora
Subject: scratch/eldoc-async fbc3f86 5/5: Make more parts of Emacs use new Eldoc capabilities
Date: Mon, 15 Jun 2020 08:57:30 -0400 (EDT)

branch: scratch/eldoc-async
commit fbc3f862d645857a7c0bcf4fd563c6e786051a8d
Author: João Távora <joaotavora@gmail.com>
Commit: João Távora <joaotavora@gmail.com>

    Make more parts of Emacs use new Eldoc capabilities
    
    Elisp-mode was doing a lot of work that can now be delegated to Eldoc.
    Flymake uses the new Eldoc functionality, too, installing a global
    documentation function that may report on diagnostics under point.
    
    CEDET's grammar.el was left as the only user of an Eldoc-internal
    function.  That function was moved to grammar.el.  That file is still,
    somewhat reprehensibly, using an internal function of elisp-mode.el,
    but this was left unchanged.
    
    In other situations, eldoc-documentaiton-functions is used or
    recommended.
    
    The only other places where the obsolete eldoc-documentation-function
    is still used is in libraries which are presumably meant to remain
    compatible with previous Emacs versions.
    
    * lisp/progmodes/elisp-mode.el (elisp-eldoc-funcall)
    (elisp-eldoc-var-docstring): New functions.
    (emacs-lisp-mode): Put two elements in
    eldoc-documentation-functions.
    
    * lisp/emacs-lisp/eldoc.el (eldoc--eval-expression-setup): Setup
    new Elisp eldoc-documentation-functions.
    
    * lisp/progmodes/flymake.el (flymake-mode): Use
    flymake-eldoc-function.
    (flymake-eldoc-function): New function.
    (Package-Requires): Require eldoc 1.1.0
    
    * lisp/descr-text.el (describe-char-eldoc): Recommend
    eldoc-documentation-functions.
    
    * lisp/progmodes/cfengine.el (cfengine3-documentation-function):
    Recommend eldoc-documentation-functions
    
    * lisp/progmodes/octave.el (inferior-octave-mode): Use
    eldoc-documentation-functions.
    
    * lisp/cedet/semantic/grammar.el (semantic--docstring-format-sym-doc):
    New function.
    (semantic-grammar-eldoc-get-macro-docstring): Adjust.
---
 lisp/cedet/semantic/grammar.el | 45 ++++++++++++++++++++++++++----
 lisp/descr-text.el             |  6 ++--
 lisp/emacs-lisp/eldoc.el       | 38 +++----------------------
 lisp/progmodes/cfengine.el     |  4 +--
 lisp/progmodes/elisp-mode.el   | 63 ++++++++++++++++++++----------------------
 lisp/progmodes/flymake.el      | 12 +++++++-
 lisp/progmodes/octave.el       |  2 +-
 7 files changed, 92 insertions(+), 78 deletions(-)

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..22cfccb 100644
--- a/lisp/descr-text.el
+++ b/lisp/descr-text.el
@@ -929,10 +929,12 @@ 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.
       (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 37d4ce5..80c4e68 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -231,7 +231,10 @@ 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
@@ -659,39 +662,6 @@ documentation themselves."
                 (;; got something else, trust callback will be called
                  t)))))))))
 
-;; 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)))))
-
 ;; 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
 ;; their own messages in the echo area; the eldoc functions would instantly
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index 9a6d81c..acf70a5 100644
--- a/lisp/progmodes/cfengine.el
+++ b/lisp/progmodes/cfengine.el
@@ -1296,8 +1296,8 @@ Calls `cfengine-cf-promises' with \"-s json\"."
 
 (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))))
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 5e32b25..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,22 +1405,27 @@ which see."
       or argument string for functions.
   2 - `function' if function args, `variable' if variable documentation.")
 
-(defun elisp-eldoc-documentation-function (_ignored &rest _also-ignored)
-  "Contextual documentation function for Emacs Lisp.
-Intended to be placed in `eldoc-documentation-functions' (which
-see)."
-  (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."
@@ -1444,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!
@@ -1560,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
@@ -1573,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..58e8d56 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -6,7 +6,7 @@
 ;; Maintainer: João Távora <joaotavora@gmail.com>
 ;; Version: 1.0.8
 ;; 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 2cf305c..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"))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]