branch: externals/elpa
commit 8dd0a159d7103984e4d5f18849a49d49f2444818
Author: João Távora <joaotav...@gmail.com>
Commit: João Távora <joaotav...@gmail.com>

    Fix #367: Robustify previous fix of onChange breakage
    
    From the in-code comments:
    
    ;; github#259 and github#367: With `capitalize-word' or somesuch,
    ;; `before-change-functions' always records the whole word's `b-beg'
    ;; and `b-end'.  Similarly, when coalescing two lines into one,
    ;; `fill-paragraph' they mark the end of the first line up to the end
    ;; of the second line.  In both situations, args received here
    ;; contradict that information: `beg' and `end' will differ by 1 and
    ;; will likely only encompass the letter that was capitalized or, in
    ;; the sentence-joining situation, the replacement of the newline with
    ;; a space.  That's we keep markers _and_ positions so we're able to
    ;; detect and correct this.  We ignore `beg', `len' and
    ;; `pre-change-len' and send "fuller" information about the region
    ;; from the markers.  I've also experimented with doing this
    ;; unconditionally but it seems to break when newlines are added.
    
    * eglot.el (eglot--after-change): Robustify fix.
---
 eglot.el | 42 ++++++++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/eglot.el b/eglot.el
index aa89ae9..3ebdd04 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1729,8 +1729,8 @@ THINGS are either registrations or unregisterations 
(sic)."
     ;; (github#259)
     (push `(,(eglot--pos-to-lsp-position beg)
             ,(eglot--pos-to-lsp-position end)
-            (,beg . ,(copy-marker beg))
-            (,end . ,(copy-marker end)))
+            (,beg . ,(copy-marker beg nil))
+            (,end . ,(copy-marker end t)))
           eglot--recent-changes)))
 
 (defun eglot--after-change (beg end pre-change-length)
@@ -1742,23 +1742,29 @@ Records BEG, END and PRE-CHANGE-LENGTH locally."
     (`(,lsp-beg ,lsp-end
                 (,b-beg . ,b-beg-marker)
                 (,b-end . ,b-end-marker))
-     ;; github#259: With `upcase-word' or somesuch,
+     ;; github#259 and github#367: With `capitalize-word' or somesuch,
      ;; `before-change-functions' always records the whole word's
-     ;; `beg' and `end'.  Not only is this longer than needed but
-     ;; conflicts with the args received here, which encompass just
-     ;; the parts of the word that changed (if any).  We detect this
-     ;; using markers recorded earlier and at looking
-     ;; `pre-change-len'.  We also ensure that the before bounds
-     ;; indeed belong to the same line (if we don't, we get could get
-     ;; #367).
-     (when (and (= b-end b-end-marker) (= b-beg b-beg-marker)
-                (not (zerop pre-change-length))
-                (= (plist-get lsp-beg :line) (plist-get lsp-end :line)))
-       (setq lsp-end (eglot--pos-to-lsp-position end)
-             lsp-beg (eglot--pos-to-lsp-position beg)))
-     (setcar eglot--recent-changes
-             `(,lsp-beg ,lsp-end ,pre-change-length
-                        ,(buffer-substring-no-properties beg end))))
+     ;; `b-beg' and `b-end'.  Similarly, when coalescing two lines
+     ;; into one, `fill-paragraph' they mark the end of the first line
+     ;; up to the end of the second line.  In both situations, args
+     ;; received here contradict that information: `beg' and `end'
+     ;; will differ by 1 and will likely only encompass the letter
+     ;; that was capitalized or, in the sentence-joining situation,
+     ;; the replacement of the newline with a space.  That's we keep
+     ;; markers _and_ positions so we're able to detect and correct
+     ;; this.  We ignore `beg', `len' and `pre-change-len' and send
+     ;; "fuller" information about the region from the markers.  I've
+     ;; also experimented with doing this unconditionally but it seems
+     ;; to break when newlines are added.
+     (if (and (= b-end b-end-marker) (= b-beg b-beg-marker)
+              (or (/= beg b-beg) (/= end b-end)))
+         (setcar eglot--recent-changes
+                 `(,lsp-beg ,lsp-end ,(- b-end-marker b-beg-marker)
+                            ,(buffer-substring-no-properties b-beg-marker
+                                                             b-end-marker)))
+       (setcar eglot--recent-changes
+                 `(,lsp-beg ,lsp-end ,pre-change-length
+                            ,(buffer-substring-no-properties beg end)))))
     (_ (setf eglot--recent-changes :emacs-messup)))
   (when eglot--change-idle-timer (cancel-timer eglot--change-idle-timer))
   (let ((buf (current-buffer)))

Reply via email to