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

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

[nongnu] elpa/inf-clojure 675e9be 290/313: Handle newlines between forms


From: ELPA Syncer
Subject: [nongnu] elpa/inf-clojure 675e9be 290/313: Handle newlines between forms for `inf-clojure-eval-buffer`
Date: Wed, 11 Aug 2021 10:00:35 -0400 (EDT)

branch: elpa/inf-clojure
commit 675e9bed1503b7a1161ed1c1f517803bef929077
Author: dan sutton <dan@dpsutton.com>
Commit: Bozhidar Batsov <bozhidar.batsov@gmail.com>

    Handle newlines between forms for `inf-clojure-eval-buffer`
    
    This sends the contents of the buffer. However, newlines cause the
    prompt to be returned. You can see this with even a regular clojure
    repl:
    ```bash
    ❯❯❯ clojure
    Clojure 1.10.2
    user=>
    user=>
    user=>
    ```
    (note using `clj` has rlwrap which hides a bit of this so make sure to
    use `clojure`).
    
    But what we can do is make sure to transform
    ```clojure
    (defn foo [] ...)
    
    (defn bar [] ...)
    ```
    
    into
    
    ```clojure
    (defn foo [] ...)
    (defn bar [] ...)
    ```
    
    So that the newlines don't trigger more repl prompts. Real world usage 
below:
    
    Before:
    ```clojure
    parse=>
    nil
    parse=> parse=> nil
    parse=> parse=> #'parse/data
    parse=> parse=> #'parse/parse-where
    parse=> parse=> #'parse/keywords
    parse=> parse=> #'parse/tokenize
    parse=>
    parse=> #'parse/parse
    parse=> parse=> #'parse/translate-where
    parse=> parse=> nil
    parse=> parse=> #'parse/query
    parse=> parse=> #'parse/query-test
    parse=> parse=> #'parse/bonus-points-test
    parse=>
    ```
    
    After:
    ```clojure
    user=>
    nil
    parse=> nil
    parse=> #'parse/data
    parse=> #'parse/parse-where
    parse=> #'parse/keywords
    parse=>
    parse=> #'parse/parse
    parse=> #'parse/translate-where
    parse=> nil
    parse=> #'parse/query
    parse=> #'parse/query-test
    parse=> #'parse/bonus-points-test
    parse=>
    ```
---
 inf-clojure.el            | 34 +++++++++++++++++++++++++++++-----
 test/inf-clojure-tests.el | 29 +++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/inf-clojure.el b/inf-clojure.el
index 4d32d06..a97066b 100644
--- a/inf-clojure.el
+++ b/inf-clojure.el
@@ -683,16 +683,40 @@ HOST is the host the process is running on, PORT is where 
it's listening."
   (interactive "shost: \nnport: ")
   (inf-clojure (cons host port)))
 
+(defun inf-clojure--forms-without-newlines (str)
+  "Remove newlines between toplevel forms.
+STR is a string of contents to be evaluated.  When sending
+multiple forms to a socket repl, each newline triggers a prompt.
+So we replace all newlines between top level forms but not inside
+of forms."
+  (condition-case nil
+      (with-temp-buffer
+        (progn
+          (clojurec-mode)
+          (insert str)
+          (whitespace-cleanup)
+          (goto-char (point-min))
+          (while (not (eobp))
+            (while (looking-at "\n")
+              (delete-char 1))
+            (unless (eobp)
+              (clojure-forward-logical-sexp))
+            (unless (eobp)
+              (forward-char)))
+          (buffer-substring-no-properties (point-min) (point-max))))
+    (scan-error str)))
+
 (defun inf-clojure-eval-region (start end &optional and-go)
   "Send the current region to the inferior Clojure process.
 Sends substring between START and END.  Prefix argument AND-GO
 means switch to the Clojure buffer afterwards."
   (interactive "r\nP")
-  ;; drops newlines at the end of the region
-  (let ((str (replace-regexp-in-string
-              "[\n]+\\'" ""
-              (buffer-substring-no-properties start end))))
-    (inf-clojure--send-string (inf-clojure-proc) str))
+  (let* ((str (buffer-substring-no-properties start end))
+         ;; newlines over a socket repl between top level forms cause
+         ;; a prompt to be returned. so here we dump the region into a
+         ;; temp buffer, and delete all newlines between the forms
+         (formatted (inf-clojure--forms-without-newlines str)))
+    (inf-clojure--send-string (inf-clojure-proc) formatted))
   (when and-go (inf-clojure-switch-to-repl t)))
 
 (defun inf-clojure-eval-string (code)
diff --git a/test/inf-clojure-tests.el b/test/inf-clojure-tests.el
index 71f9266..635ac2c 100644
--- a/test/inf-clojure-tests.el
+++ b/test/inf-clojure-tests.el
@@ -119,6 +119,35 @@
   (it "only removes whitespace at the end of the command - fix 152"
     (expect (inf-clojure--sanitize-command "1   5") :to-equal "1   5\n")))
 
+(describe "inf-clojure--forms-without-newlines"
+  (it "removes newlines between toplevel forms"
+    (expect (inf-clojure--forms-without-newlines
+             "(def foo 3)\n\n\n(def bar 4)")
+            :to-equal "(def foo 3)\n(def bar 4)"))
+  (it "doesn't remove newlines inside forms or strings"
+    (expect (inf-clojure--forms-without-newlines
+             "
+
+(defn foo []
+
+  :foo)
+
+
+(def thing \"this
+
+is a string\")
+
+(defn bar [])")
+            ;; note no leading newline, newlines inside defn remain,
+            ;; newlines inside string remain
+            :to-equal "(defn foo []
+
+  :foo)
+(def thing \"this
+
+is a string\")
+(defn bar [])")))
+
 
 (describe "inf-clojure--update-feature"
   (it "updates new forms correctly"



reply via email to

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