Skip to content

Commit f164a80

Browse files
committed
Support REPL flavors and Lumo
This patch adds the `inf-clojure-repl-flavor` defcustom in order to support different kind of configurations based on the selected flavor. The default flavor is `'clojure`, and the other supported one is `'lumo`. It also adds other vars to further customize hostname, port and classpath used in the Lumo flavor.
1 parent d04c36c commit f164a80

File tree

1 file changed

+66
-6
lines changed

1 file changed

+66
-6
lines changed

inf-clojure.el

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
(require 'thingatpt)
4545
(require 'ansi-color)
4646
(require 'cl-lib)
47+
(require 'subr-x)
4748

4849

4950
(defgroup inf-clojure nil
@@ -148,6 +149,7 @@ The following commands are available:
148149
149150
\\{inf-clojure-minor-mode-map}"
150151
:lighter "" :keymap inf-clojure-minor-mode-map
152+
(setq comint-input-sender 'inf-clojure--send-string)
151153
(inf-clojure-eldoc-setup)
152154
(make-local-variable 'completion-at-point-functions)
153155
(add-to-list 'completion-at-point-functions
@@ -183,6 +185,30 @@ often connecting to a remote REPL process."
183185
:type '(choice (string)
184186
(cons string integer)))
185187

188+
(defvar-local inf-clojure-repl-flavor nil
189+
"Symbol to define your REPL flavor.
190+
Its root binding is nil and it can be further customized using
191+
either `setq-local` or an entry in `.dir-locals.el`." )
192+
193+
(defun inf-clojure--probe-flavor (proc)
194+
"Identifies the current REPL flavor for PROC."
195+
(cond
196+
((inf-clojure--lumo-p proc) 'lumo)
197+
(t 'clojure)))
198+
199+
(defun inf-clojure--set-flavor (proc)
200+
"Set the flavor if has not already been set."
201+
(when (not inf-clojure-repl-flavor)
202+
(setq inf-clojure-repl-flavor (inf-clojure--probe-flavor proc))))
203+
204+
(defun inf-clojure--send-string (proc string)
205+
"A custom `comint-input-sender` / `comint-send-string`.
206+
Perform the required side effects on every send for PROC and
207+
STRING (for example set the buffer local REPL flavor). It should
208+
be used instead of `comint-send-string`."
209+
(inf-clojure--set-flavor proc)
210+
(comint-simple-send proc string))
211+
186212
(defcustom inf-clojure-load-command "(clojure.core/load-file \"%s\")\n"
187213
"Format-string for building a Clojure expression to load a file.
188214
This format string should use `%s' to substitute a file name
@@ -296,6 +322,7 @@ If `comint-use-prompt-regexp' is nil (the default), \\[comint-insert-input] on o
296322
Paragraphs are separated only by blank lines. Semicolons start comments.
297323
If you accidentally suspend your process, use \\[comint-continue-subjob]
298324
to continue it."
325+
(setq comint-input-sender 'inf-clojure--send-string)
299326
(setq comint-prompt-regexp inf-clojure-comint-prompt-regexp)
300327
(setq mode-line-process '(":%s"))
301328
(clojure-mode-variables)
@@ -408,12 +435,12 @@ Prefix argument AND-GO means switch to the Clojure buffer afterwards."
408435
(let ((str (replace-regexp-in-string
409436
"[\n]*\\'" "\n"
410437
(buffer-substring-no-properties start end))))
411-
(comint-send-string (inf-clojure-proc) str))
438+
(inf-clojure--send-string (inf-clojure-proc) str))
412439
(if and-go (inf-clojure-switch-to-repl t)))
413440

414441
(defun inf-clojure-eval-string (code)
415442
"Send the string CODE to the inferior Clojure process to be executed."
416-
(comint-send-string (inf-clojure-proc) (concat code "\n")))
443+
(inf-clojure--send-string (inf-clojure-proc) (concat code "\n")))
417444

418445
(defun inf-clojure-eval-defun (&optional and-go)
419446
"Send the current defun to the inferior Clojure process.
@@ -504,8 +531,8 @@ The prefix argument SWITCH-TO-REPL controls whether to switch to REPL after the
504531
(comint-check-source file-name) ; Check to see if buffer needs saved.
505532
(setq inf-clojure-prev-l/c-dir/file (cons (file-name-directory file-name)
506533
(file-name-nondirectory file-name)))
507-
(comint-send-string (inf-clojure-proc)
508-
(format inf-clojure-load-command file-name))
534+
(inf-clojure--send-string (inf-clojure-proc)
535+
(format inf-clojure-load-command file-name))
509536
(when switch-to-repl
510537
(inf-clojure-switch-to-repl t))))
511538

@@ -683,7 +710,7 @@ See variable `inf-clojure-macroexpand-command'.
683710
With a prefix arg MACRO-1 uses `inf-clojure-macroexpand-1-command'."
684711
(interactive "P")
685712
(let ((last-sexp (buffer-substring-no-properties (save-excursion (backward-sexp) (point)) (point))))
686-
(comint-send-string
713+
(inf-clojure--send-string
687714
(inf-clojure-proc)
688715
(format (if macro-1
689716
inf-clojure-macroexpand-1-command
@@ -876,6 +903,39 @@ to suppress the usage of the target buffer discovery logic."
876903
(inf-clojure (inf-clojure-cmd (inf-clojure-project-type)))
877904
(rename-buffer target-buffer-name)))
878905

879-
(provide 'inf-clojure)
906+
(defun inf-clojure--response-match-p (form match-p proc)
907+
"Return MATCH-P on the result of sending FORM to PROC.
908+
Note that this function will add a \n to the end of the string
909+
for evaluation, therefore FORM should not include it."
910+
(let* ((kept "")
911+
(is-matching nil)
912+
(prev-filter (process-filter proc)))
913+
(set-process-filter proc (lambda (_ string) (setq kept (concat kept string))))
914+
(unwind-protect
915+
;; use the real comind-send-string in order to avoid stack overflows
916+
(comint-send-string proc (concat form "\n"))
917+
;; yey, loads of procedural code again
918+
(while (and (not is-matching)
919+
(not (string-match inf-clojure-prompt kept))
920+
(accept-process-output proc 2))
921+
(setq is-matching (funcall match-p kept)))
922+
(set-process-filter proc prev-filter))
923+
is-matching))
924+
925+
;;;; Lumo
926+
;;;; ====
927+
928+
(defcustom inf-clojure--lumo-repl-form
929+
"(js/global.hasOwnProperty \"$$LUMO_GLOBALS\")"
930+
"Form to invoke in order to verify that we launched a Lumo REPL."
931+
:type 'string)
880932

933+
(defalias 'inf-clojure--lumo-p
934+
(apply-partially 'inf-clojure--response-match-p
935+
inf-clojure--lumo-repl-form
936+
(lambda (string)
937+
(string-match-p (concat inf-clojure--lumo-repl-form "\\Ca*true\\Ca*") string)))
938+
"Ascertain that PROC is a Lumo REPL.")
939+
940+
(provide 'inf-clojure)
881941
;;; inf-clojure.el ends here

0 commit comments

Comments
 (0)