-
Notifications
You must be signed in to change notification settings - Fork 0
/
cider.el
219 lines (186 loc) · 8.84 KB
/
cider.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
;;
;; Clojure Data visualisation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (defun rebl-interactive-eval (s bounds)
;; (let* ((reblized (concat "(cognitect.rebl/inspect " s ")")))
;; (cider-interactive-eval reblized nil bounds (cider--nrepl-pr-request-map))))
;; (defun rebl-eval-cider-loc (f)
;; (rebl-interactive-eval (funcall f) (funcall f 'bounds)))
;; (defun rebl-eval-last-sexp ()
;; (interactive)
;; (rebl-eval-cider-loc 'cider-last-sexp))
;; (defun rebl-eval-defun-at-point ()
;; (interactive)
;; (rebl-eval-cider-loc 'cider-defun-at-point))
;; (defun rebl-eval-list-at-point ()
;; (interactive)
;; (rebl-eval-cider-loc 'cider-list-at-point))
;; (defun rebl-eval-sexp-at-point ()
;; (interactive)
;; (rebl-eval-cider-loc 'cider-sexp-at-point))
;; (defun rebl-eval-region (start end)
;; (interactive "r")
;; (rebl-interactive-eval (buffer-substring start end) (list start end)))
;; Use LSP completions instead when at the REPL
(add-hook 'cider-mode-hook
(lambda ()
(remove-hook 'completion-at-point-functions #'cider-complete-at-point)))
(defvar me-hijack-cider-eval-wrap-form nil)
(defun cider-interactive-eval (formin &optional callback bounds additional-params)
"Evaluate FORM and dispatch the response to CALLBACK.
If the code to be evaluated comes from a buffer, it is preferred to use a
nil FORM, and specify the code via the BOUNDS argument instead.
This function is the main entry point in CIDER's interactive evaluation
API. Most other interactive eval functions should rely on this function.
If CALLBACK is nil use `cider-interactive-eval-handler'.
BOUNDS, if non-nil, is a list of two numbers marking the start and end
positions of FORM in its buffer.
ADDITIONAL-PARAMS is a map to be merged into the request message.
If `cider-interactive-eval-override' is a function, call it with the same
arguments and only proceed with evaluation if it returns nil."
(let* ((form (or formin (apply #'buffer-substring-no-properties bounds)))
(form (if me-hijack-cider-eval-wrap-form
(funcall me-hijack-cider-eval-wrap-form form)
form))
(start (car-safe bounds))
(end (car-safe (cdr-safe bounds))))
(when (and start end)
(remove-overlays start end 'cider-temporary t))
(unless (and cider-interactive-eval-override
(functionp cider-interactive-eval-override)
(funcall cider-interactive-eval-override form callback bounds))
(cider-map-repls :auto
(lambda (connection)
(cider--prep-interactive-eval form connection)
(cider-nrepl-request:eval
form
(or callback (cider-interactive-eval-handler nil bounds))
;; always eval ns forms in the user namespace
;; otherwise trying to eval ns form for the first time will produce an error
(if (cider-ns-form-p form) "user" (cider-current-ns))
(when start (line-number-at-pos start))
(when start (cider-column-number-at-pos start))
(seq-mapcat #'identity additional-params)
connection))))))
(defvar rebl-hijack-cider-eval nil)
(defvar rebl-enable-hijack-cider-eval nil)
(defun rebl-toggle-hijack-cider-eval ()
(interactive)
(let ((r (not rebl-enable-hijack-cider-eval)))
(message (format "Set REBL status: %s" r))
(setq rebl-enable-hijack-cider-eval r)))
(defvar rebl-cider-hide-eval-output nil)
(defvar rebl-cider-tap-to-portal nil)
(defvar rebl-cider-tap-to-reveal nil)
(defun rebl-hijack-cider-eval-wrap-form (form)
(let* ((form (if rebl-hijack-cider-eval (concat "(cognitect.rebl/inspect " form ")") form))
(form (if rebl-cider-tap-to-portal (concat "(let[result " form "](when-some[submit(resolve 'portal.api/submit)](submit result))result)") form))
(form (if rebl-cider-tap-to-reveal (concat "(let[result " form "](when-some[reveal(resolve 'dev/reveal)](reveal result))result)") form))
(form (if rebl-cider-hide-eval-output (concat "(do " form " :cider/hidden)") form)))
form))
(defun rebl-wrap-eval-main (cmd)
(let ((me-hijack-cider-eval-wrap-form 'rebl-hijack-cider-eval-wrap-form)
(rebl-hijack-cider-eval rebl-enable-hijack-cider-eval))
(funcall cmd)))
(defun rebl-wrap-eval-alt (cmd)
(let ((me-hijack-cider-eval-wrap-form 'rebl-hijack-cider-eval-wrap-form)
(rebl-cider-tap-to-reveal t)
(rebl-cider-tap-to-portal nil))
(funcall cmd)))
(defun rebl-eval-sexp-end-of-line ()
(interactive)
(rebl-wrap-eval-main 'spacemacs/cider-eval-sexp-end-of-line))
(defun rebl-open ()
(interactive)
(setq rebl-enable-hijack-cider-eval t)
(cider-nrepl-sync-request:eval
"((requiring-resolve 'cognitect.rebl/ui))"))
(defun vlaaad.reveal/open ()
(interactive)
(cider-nrepl-sync-request:eval
"(create-ns 'dev)(intern 'dev 'reveal((requiring-resolve 'vlaaad.reveal/ui) :title \"Emacs General\" :close-difficulty :normal))"))
(defun vlaaad.reveal/clear ()
(interactive)
(cider-nrepl-sync-request:eval
"(when (resolve 'dev/reveal) (dev/reveal {:vlaaad.reveal/command '(clear-output)}))"))
(defun vlaaad.reveal/open-tap-log ()
(interactive)
(cider-nrepl-sync-request:eval "(vlaaad.reveal/tap-log)"))
(defun vlaaad.reveal/open-ui-tap-log ()
(interactive)
(cider-nrepl-sync-request:eval "(add-tap (vlaaad.reveal/ui :title \"Taps\" :close-difficulty :normal))"))
(defun portal.api/open ()
(interactive)
(setq rebl-cider-tap-to-portal t)
(cider-nrepl-sync-request:eval
"(require 'portal.api) (add-tap #'portal.api/submit) (portal.api/open)"))
;; (defun portal.api/clear ()
;; (interactive)
;; (cider-nrepl-sync-request:eval "(portal.api/clear)"))
;; (defun portal.api/close ()
;; (interactive)
;; (cider-nrepl-sync-request:eval "(portal.api/close)"))
(defmacro rebl-make-cider-eval-fun (group quoted-cmd)
(let* ((cmd-sym (second quoted-cmd))
(rebl-sym (intern (concat "rebl-" group "-"
(substring (symbol-name cmd-sym) 5))))
(rebl-eval-sym (intern (concat "rebl-wrap-eval-" group))))
(list 'progn
(list 'defun rebl-sym '()
(list 'interactive)
(list rebl-eval-sym quoted-cmd))
(list 'quote rebl-sym))))
(spacemacs|forall-clojure-modes m
(spacemacs/set-leader-keys-for-major-mode m
"dp" 'portal.api/open
"dr" 'vlaaad.reveal/open
"dtr" 'vlaaad.reveal/open-ui-tap-log
"dtR" 'vlaaad.reveal/open-tap-log
"dcr" 'vlaaad.reveal/clear
"eF" 'cider-eval-defun-up-to-point
": o" 'rebl-toggle-hijack-cider-eval
"SPC e" (rebl-make-cider-eval-fun "main" 'cider-eval-last-sexp)
"SPC f" (rebl-make-cider-eval-fun "main" 'cider-eval-defun-at-point)
"SPC x" (rebl-make-cider-eval-fun "main" 'cider-eval-defun-up-to-point)
"SPC v" (rebl-make-cider-eval-fun "main" 'cider-eval-sexp-at-point)
"SPC (" (rebl-make-cider-eval-fun "main" 'cider-eval-list-at-point)
"SPC r" (rebl-make-cider-eval-fun "main" 'cider-eval-region)
"SPC V" (rebl-make-cider-eval-fun "main" 'cider-eval-sexp-up-to-point)
"v e" (rebl-make-cider-eval-fun "alt" 'cider-eval-last-sexp)
"v f" (rebl-make-cider-eval-fun "alt" 'cider-eval-defun-at-point)
"v x" (rebl-make-cider-eval-fun "alt" 'cider-eval-defun-up-to-point)
"v v" (rebl-make-cider-eval-fun "alt" 'cider-eval-sexp-at-point)
"v (" (rebl-make-cider-eval-fun "alt" 'cider-eval-list-at-point)
"v r" (rebl-make-cider-eval-fun "alt" 'cider-eval-region)
"v V" (rebl-make-cider-eval-fun "alt" 'cider-eval-sexp-up-to-point)
"SPC l" 'rebl-eval-sexp-end-of-line
"do" 'rebl-open))
(defun me-cider-wrap-eval-add-libs (form)
(concat "(require '[clojure.tools.deps.alpha.repl])"
"(clojure.tools.deps.alpha.repl/add-libs (quote " form "))"))
(defun me-cider-eval-list-add-libs ()
(interactive)
(let ((me-hijack-cider-eval-wrap-form 'me-cider-wrap-eval-add-libs))
(cider-eval-list-at-point)))
(spacemacs|forall-clojure-modes m
(spacemacs/set-leader-keys-for-major-mode m
"end" 'me-cider-eval-list-add-libs))
;;
;; CIDER NREPL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; make repl more dynamic - download cider specific deps on connection to nrepl
;; see https://lambdaisland.com/blog/2021-11-24-making-nrepl-cider-more-dynamic-2
;; remove the previous one if necessary
;; (pop 'cider-connected-hook)
(add-hook 'cider-connected-hook
(lambda ()
(cider-sync-tooling-eval
(parseedn-print-str
`(.addURL (loop
[loader (.getContextClassLoader (Thread/currentThread))]
(let [parent (.getParent loader)]
(if (instance? clojure.lang.DynamicClassLoader parent)
(recur parent)
loader)))
(java.net.URL. ,(concat "file:" (cider-jar-find-or-fetch "cider" "cider-nrepl" cider-injected-nrepl-version))))))
(cider-add-cider-nrepl-middlewares)))