[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/eglot 16be2fc 020/139: Fix parser to accept multiple me
From: |
João Távora |
Subject: |
[elpa] externals/eglot 16be2fc 020/139: Fix parser to accept multiple messages in one chunk |
Date: |
Mon, 14 May 2018 09:54:43 -0400 (EDT) |
branch: externals/eglot
commit 16be2fc884f6a450a31245789ec05969ae396177
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>
Fix parser to accept multiple messages in one chunk
* eglot.el (eglot--process-filter): Redesign slightly.
(eglot--message-mark): Remove. don't need this.
---
eglot.el | 130 +++++++++++++++++++++++++++++++--------------------------------
1 file changed, 64 insertions(+), 66 deletions(-)
diff --git a/eglot.el b/eglot.el
index cd213e7..ab13b3a 100644
--- a/eglot.el
+++ b/eglot.el
@@ -69,9 +69,6 @@
`(let ((proc (or ,process (eglot--current-process-or-lose))))
(process-put proc ',prop ,to-store))))))
-(eglot--define-process-var eglot--message-mark nil
- "Point where next unread message starts")
-
(eglot--define-process-var eglot--short-name nil
"A short name for the process")
@@ -139,9 +136,6 @@ INTERACTIVE is t if called interactively."
(setf (eglot--short-name proc) short-name)
(puthash (project-current) proc eglot--processes-by-project)
(erase-buffer)
- (let ((marker (point-marker)))
- (set-marker-insertion-type marker nil)
- (setf (eglot--message-mark proc) marker))
(read-only-mode t)
(with-current-buffer (eglot-events-buffer proc)
(let ((inhibit-read-only t))
@@ -170,71 +164,75 @@ INTERACTIVE is t if called interactively."
(delete-process process))))
(defun eglot--process-filter (proc string)
+ "Called when new data STRING has arrived for PROC."
(when (buffer-live-p (process-buffer proc))
(with-current-buffer (process-buffer proc)
- (let ((moving (= (point) (process-mark proc)))
- (inhibit-read-only t)
+ (let ((inhibit-read-only t)
(pre-insertion-mark (copy-marker (process-mark proc)))
- (expected-bytes (eglot--expected-bytes proc))
- (message-mark (eglot--message-mark proc)))
- (save-excursion
- ;; Insert the text, advancing the process marker.
- (goto-char (process-mark proc))
- (insert string)
- (set-marker (process-mark proc) (point)))
- (if moving (goto-char (process-mark proc)))
-
- ;; check for new message header
+ (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
;;
- (save-excursion
- (goto-char pre-insertion-mark)
- (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))
- (set-marker message-mark (point))
- (setf (eglot--expected-bytes proc) new-expected-bytes)
- (setq expected-bytes new-expected-bytes))))
-
- ;; check for message body
+ (goto-char pre-insertion-mark)
+
+ ;; loop for each message (more than one might have arrived)
;;
- (let ((available-bytes (- (position-bytes (process-mark proc))
- (position-bytes message-mark))))
- (cond ((not expected-bytes)
- (eglot--warn
- "Skipping %s bytes of unexpected garbage from process %s"
- available-bytes
- proc)
- (set-marker message-mark (process-mark proc)))
- ((>= available-bytes
- expected-bytes)
- (let* ((message-end (byte-to-position
- (+ (position-bytes message-mark)
- expected-bytes))))
- (unwind-protect
- (save-excursion
- (save-restriction
- (goto-char message-mark)
- (narrow-to-region message-mark
- message-end)
- (eglot--process-receive
- proc
- (let ((json-object-type 'plist))
- (json-read)))))
- (set-marker message-mark message-end)
- (setf (eglot--expected-bytes proc) nil))))
- (t
- ;; just adding some stuff to the end that doesn't yet
- ;; complete the message
- )))))))
+ (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))))))))))
(defmacro eglot--obj (&rest what)
"Make WHAT a suitable argument for `json-encode'."
- [elpa] branch externals/eglot created (now 4c0bfc3), João Távora, 2018/05/14
- [elpa] externals/eglot 3a8f9a1 002/139: Remove a couple of comments, João Távora, 2018/05/14
- [elpa] externals/eglot 72895ca 006/139: Handle notifications, João Távora, 2018/05/14
- [elpa] externals/eglot 0222e7e 007/139: Improve `eglot--current-process', João Távora, 2018/05/14
- [elpa] externals/eglot 2775dea 003/139: Rename eglot--continuations eglot--pending-continuations, João Távora, 2018/05/14
- [elpa] externals/eglot c417eb4 009/139: Cancel timeouts when process dies unexpectedly, João Távora, 2018/05/14
- [elpa] externals/eglot 6f0a8df 008/139: Organize a bit, João Távora, 2018/05/14
- [elpa] externals/eglot c222c3b 019/139: Lay groundwork for uniform treatment of network connections, João Távora, 2018/05/14
- [elpa] externals/eglot 3489176 004/139: Add a mode-line construct and some minor fanciness, João Távora, 2018/05/14
- [elpa] externals/eglot dfab9a0 011/139: Experimental diagnostic overlays, João Távora, 2018/05/14
- [elpa] externals/eglot 16be2fc 020/139: Fix parser to accept multiple messages in one chunk,
João Távora <=
- [elpa] externals/eglot 0ec7801 012/139: Simplify `eglot--protocol-initialize`, João Távora, 2018/05/14
- [elpa] externals/eglot 4f246b5 017/139: * eglot.el (eglot-mode-map): Move up before minor mode., João Távora, 2018/05/14
- [elpa] externals/eglot bc011d0 010/139: Minor cleanup, João Távora, 2018/05/14
- [elpa] externals/eglot e60c7fc 013/139: Overhaul async mechanism safety, João Távora, 2018/05/14
- [elpa] externals/eglot a4f99e0 005/139: Introduce and use `eglot--current-process-or-lose', João Távora, 2018/05/14
- [elpa] externals/eglot efd14d6 015/139: Fix mode line, João Távora, 2018/05/14
- [elpa] externals/eglot 63f2208 030/139: Less obstrusive flymake stuff for now, João Távora, 2018/05/14
- [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