emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[elpa] externals/drepl a9702701ee 4/9: Add a new REPL state 'rawio' to a


From: ELPA Syncer
Subject: [elpa] externals/drepl a9702701ee 4/9: Add a new REPL state 'rawio' to avoid race conditions
Date: Thu, 4 Apr 2024 15:57:57 -0400 (EDT)

branch: externals/drepl
commit a9702701eea1d93b126f8da1403b9abe5c4e5a2e
Author: Augusto Stoffel <arstoffel@gmail.com>
Commit: Augusto Stoffel <arstoffel@gmail.com>

    Add a new REPL state 'rawio' to avoid race conditions
---
 README.org | 11 ++++++-----
 drepl.el   | 23 +++++++++++++++--------
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/README.org b/README.org
index ce8e6acf04..e7c4b09a60 100644
--- a/README.org
+++ b/README.org
@@ -89,12 +89,13 @@ The interpreter indicates whether or not it is ready to 
receive a
 framed operation message.
 
 Parameters:
-- =status=: Either =ready= (subprocess is expecting a framed message)
-  or =busy= (IO, if it occurs, should not be framed).
+- =status=: Either =ready= (subprocess is expecting a framed message),
+  =rawio= (IO, if it occurs, should not be framed) or =busy= (no IO is
+  allowed).
 
-Note: Some changes in the tracked state happen implicitly.  Most
-importantly, when an editor request is sent, tracked state changes to
-=busy=.
+Note: Some changes in the tracked state happen implicitly.  For
+instance, when an editor request is sent, the tracked state changes to
+=busy= or =rawio= depending on the operation type.
 
 *** =eval= (editor request)
 Evaluate some code, blocking until the computation is complete.
diff --git a/drepl.el b/drepl.el
index 26a83c6dfc..42e3d5271c 100644
--- a/drepl.el
+++ b/drepl.el
@@ -154,12 +154,19 @@ The message is formed by calling `format' with STRING and 
ARGS."
       (lambda (s) (json-serialize s :null-object nil))
     (error "Not implemented")))
 
+(defconst drepl--state-transitions
+  '((eval . rawio))
+  "Alist mapping a REPL operation to a new REPL state.
+The default new state is busy.")
+
 (cl-defgeneric drepl--send-request (repl data)
   "Send request data to REPL.
 REPL must be in `ready' state and transitions to `busy' state.
 DATA is a plist containing the request arguments, as well as :op
 and :id entries."
-  (setf (drepl--status repl) 'busy)
+  (setf (drepl--status repl) (alist-get (plist-get data :op)
+                                        drepl--state-transitions
+                                        'busy nil #'string-equal))
   (let* ((proc (drepl--process repl))
          (maxlen (when (process-tty-name proc)
                    (- comint-max-line-length 3))))
@@ -169,7 +176,7 @@ and :id entries."
           (let ((i (/ (length s) 2)))
             (recur nil (substring s 0 i))
             (recur last (substring s i)))
-        (drepl--log-message "send %s" s)
+        (drepl--log-message "send msg %s" s)
         (process-send-string proc (format "\e%s%s\n" (if last "=" "+") s))))))
 
 (defun drepl--communicate (repl callback op &rest args)
@@ -363,15 +370,15 @@ interactively."
   (drepl--communicate repl #'ignore 'eval :code code))
 
 (defun drepl--send-string (proc string)
-  "Like `comint-send-string', but check whether PROC's status is `ready'.
-If it is, then make an eval request, otherwise just send the raw
-STRING to the process."
+  "Like `comint-send-string', but check the REPL status first.
+If it is `rawio', then simply send the raw STRING to the process.
+Otherwise, make an eval request."
   (let ((repl (with-current-buffer
                   (if proc (process-buffer proc) (current-buffer))
-                (drepl--get-repl 'ready))))
-    (if repl
+                (drepl--get-repl nil t))))
+    (if (not (eq (drepl--status repl) 'rawio))
         (drepl--eval repl string)
-      (drepl--log-message "send %s" string)
+      (drepl--log-message "send raw %s" string)
       (comint-simple-send proc string))))
 
 (defun drepl-eval (code)



reply via email to

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