emacs-diffs
[Top][All Lists]
Advanced

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

emacs-29 5bbbd70f56e 1/3: Improve ergonomics of Eglot's inlay hints


From: João Távora
Subject: emacs-29 5bbbd70f56e 1/3: Improve ergonomics of Eglot's inlay hints
Date: Sun, 19 Mar 2023 15:57:55 -0400 (EDT)

branch: emacs-29
commit 5bbbd70f56e703a18a28666cf12b28e02ffc241f
Author: João Távora <joaotavora@gmail.com>
Commit: João Távora <joaotavora@gmail.com>

    Improve ergonomics of Eglot's inlay hints
    
    Instead of deleting inlay hints instantly as soon as the affected
    changes, make hint overlays span one character (instead of being
    length 0).  Give the overlays an "evaporate" property.
    
    Given an inlay hints at position POS, its attached to [POS, POS+1] if
    it's kind=1 (usually type hints) and [POS-1, POS] otherwise.  For
    kind=1 hints, the 'cursor position of the first such overlay is also
    tweaked, so that's it's less akward to edit around it.
    
    * lisp/progmodes/eglot.el (eglot--before-change): Don't delete hints
      here.
      (eglot--update-hints-1): Rework.
---
 lisp/progmodes/eglot.el | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 1a7c46c36c6..ccae764c130 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -2356,7 +2356,6 @@ THINGS are either registrations or unregisterations 
(sic)."
 
 (defun eglot--before-change (beg end)
   "Hook onto `before-change-functions' with BEG and END."
-  (remove-overlays beg end 'eglot--overlay t)
   (when (listp eglot--recent-changes)
     ;; Records BEG and END, crucially convert them into LSP
     ;; (line/char) positions before that information is lost (because
@@ -3612,31 +3611,41 @@ If NOERROR, return predicate, else erroring function."
           (eglot--lambda ((InlayHint) position kind label paddingLeft 
paddingRight)
             (goto-char (eglot--lsp-position-to-point position))
             (when (or (> (point) to) (< (point) from)) (cl-return))
-            (let ((left-pad (and paddingLeft
-                                 (not (eq paddingLeft :json-false))
-                                 (not (memq (char-before) '(32 9))) " "))
-                  (right-pad (and paddingRight
-                                  (not (eq paddingRight :json-false))
-                                  (not (memq (char-after) '(32 9))) " ")))
-              (cl-flet
-                  ((do-it (text lpad rpad)
-                     (let ((ov (make-overlay (point) (point))))
-                       (overlay-put ov 'before-string
+            (let* ((left-pad (and paddingLeft
+                                  (not (eq paddingLeft :json-false))
+                                  (not (memq (char-before) '(32 9))) " "))
+                   (right-pad (and paddingRight
+                                   (not (eq paddingRight :json-false))
+                                   (not (memq (char-after) '(32 9))) " "))
+                   (peg-after-p (eql kind 1)))
+              (cl-labels
+                  ((make-ov ()
+                     (if peg-after-p
+                         (make-overlay (point) (1+ (point)) nil t)
+                       (make-overlay (1- (point)) (point) nil nil nil)))
+                   (do-it (label lpad rpad firstp)
+                     (let* ((tweak-cursor-p (and firstp peg-after-p))
+                            (ov (make-ov))
+                            (text (concat lpad label rpad)))
+                       (when tweak-cursor-p (put-text-property 0 1 'cursor 1 
text))
+                       (overlay-put ov (if peg-after-p 'before-string 
'after-string)
                                     (propertize
-                                     (concat lpad text rpad)
+                                     text
                                      'face (pcase kind
                                              (1 'eglot-type-hint-face)
                                              (2 'eglot-parameter-hint-face)
                                              (_ 'eglot-inlay-hint-face))))
                        (overlay-put ov 'eglot--inlay-hint t)
+                       (overlay-put ov 'evaporate t)
                        (overlay-put ov 'eglot--overlay t))))
-                (if (stringp label) (do-it label left-pad right-pad)
+                (if (stringp label) (do-it label left-pad right-pad t)
                   (cl-loop
                    for i from 0 for ldetail across label
                    do (eglot--dbind ((InlayHintLabelPart) value) ldetail
                         (do-it value
                                (and (zerop i) left-pad)
-                               (and (= i (1- (length label))) 
right-pad))))))))))
+                               (and (= i (1- (length label))) right-pad)
+                               (zerop i))))))))))
     (jsonrpc-async-request
      (eglot--current-server-or-lose)
      :textDocument/inlayHint



reply via email to

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