[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/elpa 3b01561 39/71: Close #459: rework computation of s
From: |
João Távora |
Subject: |
[elpa] externals/elpa 3b01561 39/71: Close #459: rework computation of string given to Eldoc (again) |
Date: |
Wed, 16 Dec 2020 11:42:22 -0500 (EST) |
branch: externals/elpa
commit 3b01561cef8fef78a2ca28af342bf473ef30b2e0
Author: muffinmad <andreyk.mad@gmail.com>
Commit: João Távora <joaotavora@gmail.com>
Close #459: rework computation of string given to Eldoc (again)
Co-authored-by: Andreii Kolomoiets <andreyk.mad@gmail.com>
Also do some refactoring to join similar logic in
eglot-doc-too-large-for-echo-area and eglot--truncate-string.
* eglot.el (eglot-doc-too-large-for-echo-area): Now returns the
number of lines available.
(eglot--truncate-string): New helper.
(eglot--first-line-of-doc, eglot--top-lines-of-doc): Remove.
(eglot--update-doc): Use new helpers.
* eglot-tests.el (hover-multiline-doc-locus): New test
---
eglot-tests.el | 26 ++++++++++++++++++++++
eglot.el | 68 +++++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 72 insertions(+), 22 deletions(-)
diff --git a/eglot-tests.el b/eglot-tests.el
index 919fc97..f701a01 100644
--- a/eglot-tests.el
+++ b/eglot-tests.el
@@ -573,6 +573,32 @@ def foobazquuz(d, e, f): pass
(while (not eldoc-last-message) (accept-process-output nil 0.1))
(should (string-match "^exit" eldoc-last-message))))))
+(ert-deftest hover-multiline-doc-locus ()
+ "Test if suitable amount of lines of hover info are shown."
+ (skip-unless (executable-find "pyls"))
+ (eglot--with-fixture
+ `(("project" . (("hover-first.py" . "from datetime import datetime")))
+ (eglot-put-doc-in-help-buffer nil)
+ ,@eglot--tests--python-mode-bindings)
+ (with-current-buffer
+ (eglot--find-file-noselect "project/hover-first.py")
+ (should (eglot--tests-connect))
+ (goto-char (point-max))
+ ;; one-line
+ (setq eldoc-last-message nil)
+ (setq-local eldoc-echo-area-use-multiline-p nil)
+ (eglot-eldoc-function)
+ (while (not eldoc-last-message) (accept-process-output nil 0.1))
+ (should (string-match "datetime" eldoc-last-message))
+ (should (not (cl-find ?\n eldoc-last-message)))
+ ;; multi-line
+ (setq eldoc-last-message nil)
+ (setq-local eldoc-echo-area-use-multiline-p t)
+ (eglot-eldoc-function)
+ (while (not eldoc-last-message) (accept-process-output nil 0.1))
+ (should (string-match "datetime" eldoc-last-message))
+ (should (cl-find ?\n eldoc-last-message)))))
+
(ert-deftest python-autopep-formatting ()
"Test formatting in the pyls python LSP.
pyls prefers autopep over yafp, despite its README stating the contrary."
diff --git a/eglot.el b/eglot.el
index 15fa2a1..cc60290 100644
--- a/eglot.el
+++ b/eglot.el
@@ -2282,24 +2282,47 @@ is not active."
(setq-local nobreak-char-display nil)))
(display-local-help)))))
-(defun eglot-doc-too-large-for-echo-area (string)
- "Return non-nil if STRING won't fit in echo area.
-Respects `max-mini-window-height' (which see)."
- (let ((max-height
- (cond ((floatp max-mini-window-height) (* (frame-height)
- max-mini-window-height))
- ((integerp max-mini-window-height) max-mini-window-height)
- (t 1))))
- (> (cl-count ?\n string) max-height)))
+(cl-defun eglot-doc-too-large-for-echo-area
+ (string &optional (height max-mini-window-height))
+ "Return non-nil if STRING won't fit in echo area of height HEIGHT.
+HEIGHT defaults to `max-mini-window-height' (which see) and is
+interpreted like that variable. If non-nil, the return value is
+the number of lines available."
+ (let ((available-lines (cl-typecase height
+ (float (truncate (* (frame-height) height)))
+ (integer height)
+ (t 1))))
+ (when (> (1+ (cl-count ?\n string)) available-lines)
+ available-lines)))
+
+(cl-defun eglot--truncate-string (string height &optional (width
(frame-width)))
+ "Return as much from STRING as fits in HEIGHT and WIDTH.
+WIDTH, if non-nil, truncates last line to those columns."
+ (cl-flet ((maybe-trunc
+ (str) (if width (truncate-string-to-width str width
+ nil nil "...")
+ str)))
+ (cl-loop
+ repeat height
+ for i from 1
+ for break-pos = (cl-position ?\n string)
+ for (line . rest) = (and break-pos
+ (cons (substring string 0 break-pos)
+ (substring string (1+ break-pos))))
+ concat (cond (line (if (= i height) (maybe-trunc line) (concat line
"\n")))
+ (t (maybe-trunc string)))
+ while rest do (setq string rest))))
(defcustom eglot-put-doc-in-help-buffer
+ ;; JT@2020-05-21: TODO: this variable should be renamed and the
+ ;; decision somehow be in eldoc.el itself.
#'eglot-doc-too-large-for-echo-area
"If non-nil, put \"hover\" documentation in separate `*eglot-help*' buffer.
If nil, use whatever `eldoc-message-function' decides, honouring
`eldoc-echo-area-use-multiline-p'. If t, use `*eglot-help*'
-unconditionally. If a function, it is called with the docstring
-to display and should a boolean producing one of the two previous
-values."
+unconditionally. If a function, it is called with the
+documentation string to display and returns a generalized boolean
+interpreted as one of the two preceding values."
:type '(choice (const :tag "Never use `*eglot-help*'" nil)
(const :tag "Always use `*eglot-help*'" t)
(function :tag "Ask a function")))
@@ -2310,11 +2333,6 @@ Buffer is displayed with `display-buffer', which obeys
`display-buffer-alist' & friends."
:type 'boolean)
-(defun eglot--first-line-of-doc (string)
- (truncate-string-to-width
- (replace-regexp-in-string "\\(.*\\)\n.*" "\\1" string)
- (frame-width) nil nil "..."))
-
(defun eglot--update-doc (string hint)
"Put updated documentation STRING where it belongs.
HINT is used to potentially rename EGLOT's help buffer. If
@@ -2337,16 +2355,22 @@ documentation. Honour `eglot-put-doc-in-help-buffer',
(if eglot-auto-display-help-buffer
(display-buffer (current-buffer))
(unless (get-buffer-window (current-buffer))
+ ;; This prints two lines. Should it print 1? Or
+ ;; honour max-mini-window-height?
(eglot--message
"%s\n(...truncated. Full help is in `%s')"
- (eglot--first-line-of-doc string)
+ (eglot--truncate-string string 1 (- (frame-width) 8))
(buffer-name eglot--help-buffer))))
(help-mode))))
- (eldoc-echo-area-use-multiline-p
- ;; Can't really honour non-t non-nil values if this var
- (eldoc-message string))
+ ((eq eldoc-echo-area-use-multiline-p t)
+ (if-let ((available (eglot-doc-too-large-for-echo-area string)))
+ (eldoc-message (eglot--truncate-string string available))
+ (eldoc-message string)))
+ ((eq eldoc-echo-area-use-multiline-p 'truncate-sym-name-if-fit)
+ (eldoc-message (eglot--truncate-string string 1 nil)))
(t
- (eldoc-message (eglot--first-line-of-doc string)))))
+ ;; Can't (yet?) honour non-t non-nil values of this var
+ (eldoc-message (eglot--truncate-string string 1)))))
(defun eglot-eldoc-function ()
"EGLOT's `eldoc-documentation-function' function."
- [elpa] externals/elpa 2f75da2 28/71: Fix #460: fix "free variable" warning, (continued)
- [elpa] externals/elpa 2f75da2 28/71: Fix #460: fix "free variable" warning, João Távora, 2020/12/16
- [elpa] externals/elpa 0f57efb 26/71: Simplify bug-reporting instructions, João Távora, 2020/12/16
- [elpa] externals/elpa 91a7cba 33/71: Fix #474, #478: prompt for executable if supplied name does not exist, João Távora, 2020/12/16
- [elpa] externals/elpa 9efe207 05/71: Make curl invocation fail more explicitly in .travis.yml, João Távora, 2020/12/16
- [elpa] externals/elpa 73bc752 11/71: Close #441: shield tests from some user customizations, João Távora, 2020/12/16
- [elpa] externals/elpa b6519a5 16/71: Per #446: Add tests for eglot-server-programs, João Távora, 2020/12/16
- [elpa] externals/elpa 9bc58df 17/71: Fix #446: unbreak eglot--guess-contact for host-and-port case, João Távora, 2020/12/16
- [elpa] externals/elpa 197984c 27/71: Remove trailing whitespaces, João Távora, 2020/12/16
- [elpa] externals/elpa a0249c8 23/71: Per #437: remap display-local-help (C-h .) to eglot-help-at-point, João Távora, 2020/12/16
- [elpa] externals/elpa ee87519 41/71: Replace uses of project-roots with project-root, João Távora, 2020/12/16
- [elpa] externals/elpa 3b01561 39/71: Close #459: rework computation of string given to Eldoc (again),
João Távora <=
- [elpa] externals/elpa bf75312 35/71: Require Xref, Project and Eldoc from GNU ELPA, João Távora, 2020/12/16
- [elpa] externals/elpa 2b16952 44/71: Try to make hover-multiline-doc-locus test pass on Travis, João Távora, 2020/12/16
- [elpa] externals/elpa ac9239b 46/71: Fix small problems around Eglot's help buffer, João Távora, 2020/12/16
- [elpa] externals/elpa 433779d 49/71: * eglot.el (Package-Requires): Require Flymake 1.0.9 and eldoc 1.2.0, João Távora, 2020/12/16
- [elpa] externals/elpa e3ce64a 54/71: Fix #510: use a hash-table for storing resolved completions, João Távora, 2020/12/16
- [elpa] externals/elpa e5fefc7 56/71: Really unbreak eldoc-related tests, João Távora, 2020/12/16
- [elpa] externals/elpa 2172641 65/71: Fix #558: Don't force eglot-strict-mode completely in eglot--dcase, João Távora, 2020/12/16
- [elpa] externals/elpa f9a11fe 63/71: Per #300: Don't send JSON null (Elisp nil) down the wire, João Távora, 2020/12/16
- [elpa] externals/elpa b19b294 64/71: Close #558: handle LSP 3.15's isPreferred code action property, João Távora, 2020/12/16
- [elpa] externals/elpa c34e2f6 50/71: Really install latest dependencies, João Távora, 2020/12/16