Skip to content
This repository
Browse code

Handle interrupts properly in the latest jline

Multiline forms now can be killed mid-form without closing them. No more
printing "^C" and not actually killing the input line!
  • Loading branch information...
commit b75f5f109e872a12e86ac92bbe4d60f4669e0781 1 parent ef1e5af
Colin Jones authored
2  project.clj
@@ -3,7 +3,7 @@
3 3 (defproject reply "0.1.10-SNAPSHOT"
4 4 :description "REPL-y: A fitter, happier, more productive REPL for Clojure."
5 5 :dependencies [[org.clojure/clojure "1.4.0"]
6   - [jline/jline "2.8"]
  6 + [jline/jline "2.10"]
7 7 [org.thnetos/cd-client "0.3.6"]
8 8 [clj-stacktrace "0.2.4"]
9 9 [org.clojure/tools.nrepl "0.2.1"]
26 src/clj/reply/eval_modes/nrepl.clj
@@ -38,6 +38,11 @@
38 38 TimeUnit/MILLISECONDS)
39 39 (session-responses session))))
40 40
  41 +(defn safe-read-line [input-stream]
  42 + (try (.readLine input-stream)
  43 + (catch jline.console.UserInterruptException e
  44 + :interrupted)))
  45 +
41 46 (defn execute-with-client [client options form]
42 47 (let [command-id (nrepl.misc/uuid)
43 48 session (or (:session options) @current-session)
@@ -50,10 +55,11 @@
50 55 (some #{"done" "interrupted" "error"} (:status %))))
51 56 (filter identity (session-responses session)))]
52 57 (when (some #{"need-input"} (:status res))
53   - (let [input-result (.readLine *in*)]
54   - (session-sender
55   - {:op "stdin" :stdin (str input-result "\n")
56   - :id (nrepl.misc/uuid)})))
  58 + (let [input-result (safe-read-line *in*)]
  59 + (when-not (= :interrupted input-result)
  60 + (session-sender
  61 + {:op "stdin" :stdin (str input-result "\n")
  62 + :id (nrepl.misc/uuid)}))))
57 63 (when value ((:value options print) value))
58 64 (flush)
59 65 (when (and ns (not (:session options)))
@@ -65,12 +71,14 @@
65 71 (defn parsed-forms
66 72 ([request-exit] (parsed-forms request-exit nil))
67 73 ([request-exit text-so-far]
68   - (if-let [next-text (.readLine *in*)]
69   - (let [concatted-text (if text-so-far
  74 + (if-let [next-text (safe-read-line *in*)]
  75 + (let [interrupted? (= :interrupted next-text)
  76 + parse-tree (when-not interrupted?
  77 + (sjacket.parser/parser
  78 + (if text-so-far
70 79 (str text-so-far \newline next-text)
71   - next-text)
72   - parse-tree (sjacket.parser/parser concatted-text)]
73   - (if (empty? (:content parse-tree))
  80 + next-text)))]
  81 + (if (or interrupted? (empty? (:content parse-tree)))
74 82 (list "")
75 83 (let [completed? (fn [node]
76 84 (or (not= :net.cgrand.parsley/unfinished (:tag node))
1  src/clj/reply/reader/jline.clj
@@ -34,6 +34,7 @@
34 34 history (FileHistory. (make-history-file (:history-file options)))
35 35 completer (jline.completion/make-completer reply.initialization/eval-in-user-ns #())]
36 36 (.setBlinkMatchingParen (.getKeys reader) true)
  37 + (.setHandleUserInterrupt reader true)
37 38 (doto reader
38 39 (.setHistory history)
39 40 (.setExpandEvents false)

0 comments on commit b75f5f1

Please sign in to comment.
Something went wrong with that request. Please try again.