[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/elpa b511b7d 036/139: Redesign and simplify parser
From: |
João Távora |
Subject: |
[elpa] externals/elpa b511b7d 036/139: Redesign and simplify parser |
Date: |
Mon, 14 May 2018 09:53:30 -0400 (EDT) |
branch: externals/elpa
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/elpa c95a0a4 041/139: Multiple servers per project are possible, (continued)
- [elpa] externals/elpa c95a0a4 041/139: Multiple servers per project are possible, João Távora, 2018/05/14
- [elpa] externals/elpa e60c7fc 013/139: Overhaul async mechanism safety, João Távora, 2018/05/14
- [elpa] externals/elpa a3545fb 050/139: Rename RPC methods for clarity, João Távora, 2018/05/14
- [elpa] externals/elpa 4d4b85d 061/139: eglot-editing-mode becomes eglot--managed-mode, João Távora, 2018/05/14
- [elpa] externals/elpa 4f246b5 017/139: * eglot.el (eglot-mode-map): Move up before minor mode., João Távora, 2018/05/14
- [elpa] externals/elpa a4f99e0 005/139: Introduce and use `eglot--current-process-or-lose', João Távora, 2018/05/14
- [elpa] externals/elpa 8e6488f 023/139: Don't switch to possibly dead buffer in sentinel, João Távora, 2018/05/14
- [elpa] externals/elpa be52e1e 037/139: Rework connection restarting again, João Távora, 2018/05/14
- [elpa] externals/elpa cc183a6 043/139: Fix assorted bugs, João Távora, 2018/05/14
- [elpa] externals/elpa e8f859e 031/139: Rework commands for connecting and reconnecting, João Távora, 2018/05/14
- [elpa] externals/elpa b511b7d 036/139: Redesign and simplify parser,
João Távora <=
- [elpa] externals/elpa b4dd4f8 022/139: Report server status in the mode-line, João Távora, 2018/05/14
- [elpa] externals/elpa 46bb1c0 049/139: Reorganize file, João Távora, 2018/05/14
- [elpa] externals/elpa b69302c 060/139: Make M-x eglot's interactive spec a separate function, João Távora, 2018/05/14
- [elpa] externals/elpa b657b32 068/139: Use rootUri instead of rootPath, João Távora, 2018/05/14
- [elpa] externals/elpa eebd32b 059/139: When user declines to reconnect, first quit existing server, João Távora, 2018/05/14
- [elpa] externals/elpa f1b6485 053/139: Trim some edges and add a bunch of boring RPC methods, João Távora, 2018/05/14
- [elpa] externals/elpa df5d76d 065/139: Reply to client/registerCapability (don't handle it yet), João Távora, 2018/05/14
- [elpa] externals/elpa f76f04e 057/139: More correctly keep track of didOpen/didClose per buffer, João Távora, 2018/05/14
- [elpa] externals/elpa a199c8e 070/139: Honour textDocumentSync, João Távora, 2018/05/14
- [elpa] externals/elpa 79a2a1e 069/139: Be quite explicit about our lack of capabilities right now, João Távora, 2018/05/14