[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot b511b7d 036/139: Redesign and simplify parser
From: |
João Távora |
Subject: |
[elpa] externals/eglot b511b7d 036/139: Redesign and simplify parser |
Date: |
Mon, 14 May 2018 09:54:49 -0400 (EDT) |
branch: externals/eglot
commit b511b7d2da0e48a460bbcf4e7e9380a7253aa5d1
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Redesign and simplify parser
Fix horrible bugs. This is the correct way.
* eglot.el (eglot--process-filter): Redesign.
---
eglot.el | 106 ++++++++++++++++++++++++++++-----------------------------------
1 file changed, 47 insertions(+), 59 deletions(-)
diff --git a/eglot.el b/eglot.el
index 71dab80..b9aa94c 100644
--- a/eglot.el
+++ b/eglot.el
@@ -234,71 +234,59 @@ INTERACTIVE is t if called interactively."
(when (buffer-live-p (process-buffer proc))
(with-current-buffer (process-buffer proc)
(let ((inhibit-read-only t)
- (pre-insertion-mark (copy-marker (process-mark proc)))
(expected-bytes (eglot--expected-bytes proc)))
;; Insert the text, advancing the process marker.
- (goto-char (process-mark proc))
- (insert string)
- (set-marker (process-mark proc) (point))
-
- ;; goto point just before insertion
;;
- (goto-char pre-insertion-mark)
-
- ;; loop for each message (more than one might have arrived)
+ (save-excursion
+ (goto-char (process-mark proc))
+ (insert string)
+ (set-marker (process-mark proc) (point)))
+ ;; Loop (more than one message might have arrived)
;;
(catch 'done
(while t
- (let* ((match (search-forward-regexp
- "\\(?:.*: .*\r\n\\)*Content-Length:
\\([[:digit:]]+\\)\r\n\\(?:.*: .*\r\n\\)*\r\n"
- (+ (point) 100)
- t))
- (new-expected-bytes (and match
- (string-to-number (match-string
1)))))
- (when new-expected-bytes
- (when expected-bytes
- (eglot--warn
- (concat "Unexpectedly starting new message but %s bytes "
- "reportedly remaining from previous one")
- expected-bytes))
- (setf (eglot--expected-bytes proc) new-expected-bytes)
- (setq expected-bytes new-expected-bytes)))
-
- ;; check for message body
- ;;
- (let ((available-bytes (- (position-bytes (process-mark proc))
- (position-bytes (point)))))
- (cond ((not expected-bytes) ; previous search didn't match
- (eglot--warn
- "Skipping %s bytes of unexpected garbage from process %s"
- available-bytes
- proc)
- (goto-char (process-mark proc))
- (throw 'done :skipping-garbage))
- ((>= available-bytes
- expected-bytes)
- (let* ((message-end (byte-to-position
- (+ (position-bytes (point))
- expected-bytes))))
- (unwind-protect
- (save-restriction
- (narrow-to-region (point)
- message-end)
- (let* ((json-object-type 'plist)
- (json-message (json-read)))
- ;; process in another buffer, shielding
- ;; buffer from tamper
- (with-temp-buffer
- (eglot--process-receive proc json-message))))
- (goto-char message-end)
- (setf (eglot--expected-bytes proc) nil
- expected-bytes nil)))
- (when (= (point) (process-mark proc))
- (throw 'done :clean-done)))
- (t
- ;; just adding some stuff to the end that doesn't yet
- ;; complete the message
- (throw 'done :waiting-for-more-bytes))))))))))
+ (cond ((not expected-bytes)
+ ;; Starting a new message
+ ;;
+ (setq expected-bytes
+ (and (search-forward-regexp
+ "\\(?:.*: .*\r\n\\)*Content-Length:
*\\([[:digit:]]+\\)\r\n\\(?:.*: .*\r\n\\)*\r\n"
+ (+ (point) 100)
+ t)
+ (string-to-number (match-string 1))))
+ (unless expected-bytes
+ (throw 'done :waiting-for-new-message)))
+ (t
+ ;; Attempt to complete a message body
+ ;;
+ (let ((available-bytes (- (position-bytes (process-mark
proc))
+ (position-bytes (point)))))
+ (cond
+ ((>= available-bytes
+ expected-bytes)
+ (let* ((message-end (byte-to-position
+ (+ (position-bytes (point))
+ expected-bytes))))
+ (unwind-protect
+ (save-restriction
+ (narrow-to-region (point) message-end)
+ (let* ((json-object-type 'plist)
+ (json-message (json-read)))
+ ;; Process content in another buffer,
+ ;; shielding buffer from tamper
+ ;;
+ (with-temp-buffer
+ (eglot--process-receive proc
json-message))))
+ (goto-char message-end)
+ (delete-region (point-min) (point))
+ (setq expected-bytes nil))))
+ (t
+ ;; Message is still incomplete
+ ;;
+ (throw 'done
:waiting-for-more-bytes-in-this-message))))))))
+ ;; Saved parsing state for next visit to this filter
+ ;;
+ (setf (eglot--expected-bytes proc) expected-bytes)))))
(defmacro eglot--obj (&rest what)
"Make WHAT a suitable argument for `json-encode'."
- [elpa] externals/eglot 8bd634c 016/139: Start working on this again, (continued)
- [elpa] externals/eglot 8bd634c 016/139: Start working on this again, João Távora, 2018/05/14
- [elpa] externals/eglot 3403f86 027/139: Correctly report what we currently are capable of, João Távora, 2018/05/14
- [elpa] externals/eglot 7c82a03 024/139: Start experimenting with python, João Távora, 2018/05/14
- [elpa] externals/eglot 8e6488f 023/139: Don't switch to possibly dead buffer in sentinel, João Távora, 2018/05/14
- [elpa] externals/eglot e1d36d2 014/139: Fix some byte-compilation warnings, João Távora, 2018/05/14
- [elpa] externals/eglot 6f6f01d 018/139: Doc fixes, João Távora, 2018/05/14
- [elpa] externals/eglot 7ec0dcf 029/139: Events buffer uses eglot-mode, source buffers use eglot-editing-mode, João Távora, 2018/05/14
- [elpa] externals/eglot 22dc2f7 034/139: Ready to start fixing flymake integration, João Távora, 2018/05/14
- [elpa] externals/eglot e8f859e 031/139: Rework commands for connecting and reconnecting, João Távora, 2018/05/14
- [elpa] externals/eglot 92bf3a0 038/139: Signal textDocument/didClose, João Távora, 2018/05/14
- [elpa] externals/eglot b511b7d 036/139: Redesign and simplify parser,
João Távora <=
- [elpa] externals/eglot 328c7ae 025/139: Auto update mode-line after setting some process properties, João Távora, 2018/05/14
- [elpa] externals/eglot 2b61a3b 048/139: Delete two useless forward declarations, João Távora, 2018/05/14
- [elpa] externals/eglot 88e3655 040/139: Appease checkdoc.el, João Távora, 2018/05/14
- [elpa] externals/eglot c948713 035/139: Auto-reconnect on unexpected connection loss, João Távora, 2018/05/14
- [elpa] externals/eglot 1dc2a9f 021/139: Implement spinners and RLS's window/progress, João Távora, 2018/05/14
- [elpa] externals/eglot 931093e 032/139: Don't clutter UI with warnings, João Távora, 2018/05/14
- [elpa] externals/eglot 95983c9 028/139: Change status to error everytime an error is found, João Távora, 2018/05/14
- [elpa] externals/eglot be52e1e 037/139: Rework connection restarting again, João Távora, 2018/05/14
- [elpa] externals/eglot d2eca65 045/139: Fix another Flymake sync bug, João Távora, 2018/05/14
- [elpa] externals/eglot f7f77e1 044/139: Make M-x eglot the main entry point, João Távora, 2018/05/14