unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Mathieu Marques <mathieumarques78@gmail.com>
To: "João Távora" <joaotavora@gmail.com>
Cc: "Basil L. Contovounesios" <contovob@tcd.ie>, 47109@debbugs.gnu.org
Subject: bug#47109: eldoc.el: Allow custom separator between documentations in the echo area
Date: Thu, 18 Mar 2021 19:30:12 +0100	[thread overview]
Message-ID: <CANgONYK4+KqEmOT4L6iLC9=f9DbLkVUAnCZ2ZOCF1xQWJFLP7Q@mail.gmail.com> (raw)
In-Reply-To: <CALDnm5276bMNrZFrnRrk3RNMCe-QvAxCCpnsMhdo3fOzE1E_NA@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 1094 bytes --]

 Hello again,

Thanks for the feedback.  I agree with the will of allowing more freedom.

I joined a replacement patch with the different route that this is now
taking,
namely the removal of `eldoc--format-doc-buffer' in favor of
`eldoc-render-documentation'.  Is that closer to what you had in mind?

There's an issue however with the `-hr` format function that won't work with
terminal-based Emacs due to `:strike-through` apparently not supported
there.  I
was wondering whether a simple mention of that limitation in the docstring
would
be enough?  Terminal-based users would still be able to use the default
format
function.  Regarding the `:extend` keyword not being supported on 26, I
think
a better way than conditionally add it would be to provide a second `-hr`
formatting function that relies on something that is supported on 26 ie.
overlay.  Although I have little to no experience with overlays so I'm not
sure
what would be the preferred way of making a horizontal divider.
Furthermore, it
shouldn't break when the render function is used to return a string.
-- 
Mathieu Marques

[-- Attachment #1.2: Type: text/html, Size: 1314 bytes --]

[-- Attachment #2: 0002-Add-a-responsible-Eldoc-render-to-target-function.patch --]
[-- Type: text/x-patch, Size: 8473 bytes --]

From b1b251d27c6bdf765ed70a79dca7741e6effa99c Mon Sep 17 00:00:00 2001
From: Mathieu Marques <mathieumarques78@gmail.com>
Date: Fri, 12 Mar 2021 19:45:18 +0100
Subject: [PATCH] Add a responsible Eldoc render-to-target function

  * lisp/emacs-lisp/eldoc.el (eldoc-render-documentation):
  Replace eldoc--format-doc-buffer (bug#47109).
  (eldoc--format-doc-buffer): Removed.
  (eldoc-display-in-buffer): Use the new render function.
  (eldoc-display-in-echo-area): Use the new render function.
  (eldoc-documentation-format-function): New user option.
  (eldoc-documentation-format-concat): New format function.
  (eldoc-documentation-format-concat-hr): New format function.
---
 lisp/emacs-lisp/eldoc.el | 125 +++++++++++++++++++++++++--------------
 1 file changed, 81 insertions(+), 44 deletions(-)

diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 485ea26379..64c622039f 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -129,6 +129,19 @@ window.  If the value is the symbol `maybe', then the echo area
 is only skipped if the documentation doesn't fit there."
   :type 'boolean)
 
+(defcustom eldoc-documentation-format-function #'eldoc-documentation-format-concat
+  "Function used to format documentation in the *eldoc* buffer.
+
+- `eldoc-documentation-format-concat': concatenates documentations together
+  joining with a newline character'.
+
+- `eldoc-documentation-format-concat-hr': concatenates documentations together
+  joining with a horizontal rule."
+  :type '(radio (function-item eldoc-documentation-format-concat)
+                (function-item eldoc-documentation-format-concat-hr)
+                function)
+  :version "28.1")
+
 (defface eldoc-highlight-function-argument
   '((t (:inherit bold)))
   "Face used for the argument at point in a function's argument list.
@@ -466,44 +479,71 @@ This holds the results of the last documentation request."
                                              (buffer-name)))
     (display-buffer (current-buffer))))
 
-(defun eldoc--format-doc-buffer (docs)
-  "Ensure DOCS are displayed in an *eldoc* buffer."
-  (with-current-buffer (if (buffer-live-p eldoc--doc-buffer)
-                           eldoc--doc-buffer
-                         (setq eldoc--doc-buffer
-                               (get-buffer-create " *eldoc*")))
-    (unless (eq docs eldoc--doc-buffer-docs)
-      (setq-local eldoc--doc-buffer-docs docs)
-      (let ((inhibit-read-only t)
-            (things-reported-on))
-        (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")
-                 finally (goto-char (point-min)))
-        ;; Rename the buffer, taking into account whether it was
-        ;; hidden or not
-        (rename-buffer (format "%s*eldoc%s*"
-                               (if (string-match "^ " (buffer-name)) " " "")
-                               (if things-reported-on
-                                   (format " for %s"
-                                           (mapconcat
-                                            (lambda (s) (format "%s" s))
-                                            things-reported-on
-                                            ", "))
-                                 ""))))))
-  eldoc--doc-buffer)
+(defun eldoc-documentation-format-concat (items &optional separator)
+  "Return documentation ITEMS concatenated.
+Join with SEPARATOR which defaults to \n.
+See `eldoc-documentation-format-function'."
+  (mapconcat (lambda (item)
+               (pcase-let* ((`(,documentation . ,plist) item)
+                            (face (plist-get plist :face))
+                            (thing (plist-get plist :thing)))
+                 (concat (when thing
+                           (concat (propertize (format "%s" thing) 'face face) ": "))
+                         documentation)))
+             items
+             (or separator "\n")))
+
+(defun eldoc-documentation-format-concat-hr (items)
+  "Return ITEMS concatenated like `eldoc-documentation-format-concat' but join
+with a horizontal rule.
+See `eldoc-documentation-format-function'."
+  (let ((separator (concat
+                    "\n"
+                    (propertize "\n" 'face
+                                '(:extend t :inherit shadow :strike-through t)))))
+    (eldoc-documentation-format-concat items separator)))
+
+(defun eldoc--render-documentation-buffer (text buffer)
+  "Sub-routine to write documentation TEXT in BUFFER.  Return it afterwards."
+  (with-current-buffer buffer
+    (let ((inhibit-read-only t)
+          (things-reported-on))
+      (erase-buffer)
+      (setq-local buffer-read-only t)
+      (local-set-key "q" 'quit-window)
+      (insert text)
+      ;; Rename the buffer, taking into account whether it was hidden
+      (rename-buffer (format "%s*eldoc%s*"
+                             (if (string-match "^ " (buffer-name)) " " "")
+                             (if things-reported-on
+                                 (format " for %s"
+                                         (mapconcat
+                                          (lambda (s) (format "%s" s))
+                                          things-reported-on
+                                          ", "))
+                               "")))
+
+      ))
+  buffer)
+
+(defun eldoc-render-documentation (documentations &optional target)
+  "Render DOCUMENTATIONS onto TARGET.
+If optional TARGET is not provided, simply return the formatted string.  If it
+is t, render the documentation into the *eldoc* buffer `eldoc--doc-buffer'.
+Else, assume TARGET is a name that can be passed to `get-buffer-create'."
+  (unless (eq documentations eldoc--doc-buffer-docs)
+    (setq-local eldoc--doc-buffer-docs documentations)
+    (let ((buffer (when target
+                    (if (or (bufferp target) (stringp target))
+                        (get-buffer-create target)
+                      (setq eldoc--doc-buffer
+                            (get-buffer-create (if (buffer-live-p eldoc--doc-buffer)
+                                                   eldoc--doc-buffer
+                                                 " *eldoc*"))))))
+          (body (funcall eldoc-documentation-format-function documentations)))
+      (if buffer
+          (eldoc--render-documentation-buffer body buffer)
+        body))))
 
 (defun eldoc--echo-area-substring (available)
   "Given AVAILABLE lines, get buffer substring to display in echo area.
@@ -590,14 +630,11 @@ Honor `eldoc-echo-area-use-multiline-p' and
                ;; Else, given a positive number of logical lines, we
                ;; format the *eldoc* buffer, using as most of its
                ;; contents as we know will fit.
-               (with-current-buffer (eldoc--format-doc-buffer docs)
+               (with-current-buffer (eldoc-render-documentation docs t)
                  (save-excursion
                    (eldoc--echo-area-substring available))))
               (t ;; this is the "truncate brutally" situation
-               (let ((string
-                      (with-current-buffer (eldoc--format-doc-buffer docs)
-                        (buffer-substring (goto-char (point-min))
-                                          (line-end-position 1)))))
+               (let ((string (eldoc-render-documentation docs)))
                  (if (> (length string) width)  ; truncation to happen
                      (unless (eldoc--echo-area-prefer-doc-buffer-p t)
                        (truncate-string-to-width string width))
@@ -609,7 +646,7 @@ Honor `eldoc-echo-area-use-multiline-p' and
 (defun eldoc-display-in-buffer (docs interactive)
   "Display DOCS in a dedicated buffer.
 If INTERACTIVE is t, also display the buffer."
-  (eldoc--format-doc-buffer docs)
+  (eldoc-render-documentation docs t)
   (when interactive
     (eldoc-doc-buffer)))
 
-- 
2.30.1


  reply	other threads:[~2021-03-18 18:30 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-12 19:10 bug#47109: eldoc.el: Allow custom separator between documentations in the echo area Mathieu Marques
2021-03-12 21:13 ` Basil L. Contovounesios
2021-03-13 12:26   ` Mathieu Marques
2021-03-13 14:02     ` Basil L. Contovounesios
2021-03-13 14:35       ` João Távora
2021-03-18 18:30         ` Mathieu Marques [this message]
2021-05-17 15:37           ` Lars Ingebrigtsen
2021-05-17 15:44             ` João Távora
2021-05-18 13:39               ` Lars Ingebrigtsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CANgONYK4+KqEmOT4L6iLC9=f9DbLkVUAnCZ2ZOCF1xQWJFLP7Q@mail.gmail.com' \
    --to=mathieumarques78@gmail.com \
    --cc=47109@debbugs.gnu.org \
    --cc=contovob@tcd.ie \
    --cc=joaotavora@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).