Skip to content

Commit 23b7b05

Browse files
committed
3.2.1 Socket: Report number of reflection warnings in status bar
1 parent 5c76a7b commit 23b7b05

File tree

6 files changed

+87
-33
lines changed

6 files changed

+87
-33
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 3.2.1 - Sep 10, 2023
2+
3+
- Socket: Report number of reflection warnings in status bar
4+
15
### 3.2.0 - Sep 10, 2023
26

37
- Socket REPL: handle exceptions in lookup

cs_conn.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import os, re, sublime, sublime_plugin
2-
from . import cs_common, cs_eval, cs_eval_status, cs_parser
2+
from . import cs_common, cs_eval, cs_eval_status, cs_parser, cs_warn
33

44
# Global connection instance
55
conn = None
@@ -114,6 +114,7 @@ def disconnect(self):
114114
conn = None
115115
cs_common.set_status(status_key, None)
116116
cs_eval.erase_evals()
117+
cs_warn.reset_warnings()
117118

118119
def set_status(self, phase, message, *args):
119120
status = phases[phase] + ' ' + message.format(*args)

cs_conn_socket_repl.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json, os, re, sublime, sublime_plugin, threading
2-
from . import cs_common, cs_conn, cs_eval, cs_eval_status, cs_parser
2+
from . import cs_common, cs_conn, cs_eval, cs_eval_status, cs_parser, cs_warn
33

44
def lines(socket):
55
buffer = b''
@@ -82,6 +82,7 @@ def eval_impl(self, form):
8282
self.send(msg)
8383

8484
def eval(self, view, sel):
85+
cs_warn.reset_warnings()
8586
for region in sel:
8687
# find regions to eval
8788
if region.empty():
@@ -113,6 +114,7 @@ def eval(self, view, sel):
113114
self.eval_impl(form)
114115

115116
def eval_status(self, code, ns):
117+
cs_warn.reset_warnings()
116118
batch_id = cs_eval.Eval.next_id()
117119
eval = cs_eval_status.StatusEval(code, id = f'{batch_id}.0', batch_id = batch_id)
118120
form = cs_common.Form(id = batch_id, code = code, ns = ns)
@@ -164,12 +166,19 @@ def handle_lookup(self, msg):
164166
cs_eval.on_lookup(id, val)
165167
return True
166168

169+
def handle_err(self, msg):
170+
if 'err' == msg['tag']:
171+
if msg['val'].startswith("Reflection warning"):
172+
cs_warn.add_warning()
173+
return True
174+
167175
def handle_msg(self, msg):
168176
# cs_common.debug('MSG {}', msg)
169177
self.handle_value(msg) \
170178
or self.handle_exception(msg) \
171179
or self.handle_done(msg) \
172-
or self.handle_lookup(msg)
180+
or self.handle_lookup(msg) \
181+
or self.handle_err(msg)
173182

174183
class ClojureSublimedConnectSocketReplCommand(sublime_plugin.ApplicationCommand):
175184
def run(self, address):

cs_warn.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import sublime, sublime_plugin
2+
from . import cs_common
3+
4+
status_key = 'clojure-sublimed-warn-status'
5+
warnings = 0
6+
7+
def add_warning():
8+
global warnings
9+
warnings += 1
10+
suffix = 's' if warnings > 0 else ''
11+
cs_common.set_status(status_key, f'⚠️ {warnings} warning{suffix}')
12+
13+
def reset_warnings():
14+
global warnings
15+
warnings = 0
16+
cs_common.set_status(status_key, None)

src_clojure/clojure_sublimed/core.clj

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[clojure.string :as str])
55
(:import
66
[clojure.lang Compiler Compiler$CompilerException ExceptionInfo LispReader$ReaderException]
7-
[java.io Writer]))
7+
[java.io BufferedWriter OutputStream OutputStreamWriter PrintWriter Writer]))
88

99
(def ^:dynamic *print-quota*
1010
1024)
@@ -33,7 +33,7 @@
3333
([x off len]
3434
(locking total
3535
(let [cbuf (to-char-array x)
36-
rem (- quota @total)]
36+
rem (- quota @total)]
3737
(vswap! total + len)
3838
(.write writer cbuf ^int off ^int (min len rem))
3939
(when (neg? (- rem len))
@@ -54,6 +54,28 @@
5454
(str writer "...")
5555
(throw e))))))
5656

57+
(defn duplicate-writer ^Writer [^Writer writer tag out-fn]
58+
(let [sb (StringBuffer.)
59+
proxy (proxy [Writer] []
60+
(flush []
61+
(.flush writer)
62+
(let [len (.length sb)]
63+
(when (pos? len)
64+
(out-fn {"tag" tag, "val" (str sb)})
65+
(.delete sb 0 len))))
66+
(close []
67+
(.close writer))
68+
(write
69+
([x]
70+
(let [cbuf (to-char-array x)]
71+
(.write writer cbuf)
72+
(.append sb cbuf)))
73+
([x off len]
74+
(let [cbuf (to-char-array x)]
75+
(.write writer cbuf ^int off ^int len)
76+
(.append sb cbuf ^int off ^int len)))))]
77+
(PrintWriter. proxy true)))
78+
5779
;; CompilerException has location info, but its cause RuntimeException has the message ¯\_(ツ)_/¯
5880
(defn root-cause [^Throwable t]
5981
(loop [t t

src_clojure/clojure_sublimed/socket_repl.clj

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[clojure.string :as str]
44
[clojure-sublimed.core :as core])
55
(:import
6-
[java.io Reader StringReader]
6+
[java.io FilterWriter Reader StringReader Writer]
77
[java.lang.reflect Field]
88
[clojure.lang Compiler Compiler$CompilerException LineNumberingPushbackReader LispReader LispReader$ReaderException RT]))
99

@@ -197,33 +197,35 @@
197197
(defn out-fn [out]
198198
(let [lock (Object.)]
199199
#(locking lock
200-
(binding [*out* out]
200+
(binding [*out* out
201+
*print-readably* true]
201202
(prn (merge (some-> *context* deref) %))))))
202203

203204
(defn repl []
204-
(binding [*out-fn* (out-fn *out*)
205-
*out* (.getRawRoot #'*out*)
206-
*err* (.getRawRoot #'*err*)
207-
core/*changed-vars (atom {})]
208-
(*out-fn* {"tag" "started"})
209-
(loop []
210-
(when
211-
(binding [*context* (volatile! {})]
212-
(try
213-
(let [form (read-command *in*)]
214-
(core/set-changed-vars!)
215-
(when-some [id (form "id")]
216-
(vswap! *context* assoc "id" id))
217-
(case (get form "op")
218-
"eval" (fork-eval form)
219-
"interrupt" (interrupt form)
220-
"lookup" (lookup-symbol form)
221-
(throw (Exception. (str "Unknown op: " (get form "op")))))
222-
true)
223-
(catch Throwable t
224-
(when-not (-> t ex-data ::stop)
225-
(report-throwable t)
226-
true))))
227-
(recur)))
228-
(doseq [[id f] @*evals]
229-
(future-cancel f))))
205+
(let [out-fn (out-fn *out*)]
206+
(binding [*out-fn* out-fn
207+
*out* (core/duplicate-writer (.getRawRoot #'*out*) "out" out-fn)
208+
*err* (core/duplicate-writer (.getRawRoot #'*err*) "err" out-fn)
209+
core/*changed-vars (atom {})]
210+
(out-fn {"tag" "started"})
211+
(loop []
212+
(when
213+
(binding [*context* (volatile! {})]
214+
(try
215+
(let [form (read-command *in*)]
216+
(core/set-changed-vars!)
217+
(when-some [id (form "id")]
218+
(vswap! *context* assoc "id" id))
219+
(case (get form "op")
220+
"eval" (fork-eval form)
221+
"interrupt" (interrupt form)
222+
"lookup" (lookup-symbol form)
223+
(throw (Exception. (str "Unknown op: " (get form "op")))))
224+
true)
225+
(catch Throwable t
226+
(when-not (-> t ex-data ::stop)
227+
(report-throwable t)
228+
true))))
229+
(recur)))
230+
(doseq [[id f] @*evals]
231+
(future-cancel f)))))

0 commit comments

Comments
 (0)