|
42 | 42 | (require 'clojure-mode)
|
43 | 43 | (require 'eldoc)
|
44 | 44 | (require 'thingatpt)
|
| 45 | +(require 'subr-x) |
45 | 46 |
|
46 | 47 |
|
47 | 48 | (defgroup inf-clojure nil
|
@@ -138,6 +139,7 @@ The following commands are available:
|
138 | 139 |
|
139 | 140 | \\{inf-clojure-minor-mode-map}"
|
140 | 141 | :lighter "" :keymap inf-clojure-minor-mode-map
|
| 142 | + (inf-clojure--flavor-setup) |
141 | 143 | (inf-clojure-eldoc-setup)
|
142 | 144 | (make-local-variable 'completion-at-point-functions)
|
143 | 145 | (add-to-list 'completion-at-point-functions
|
@@ -226,6 +228,21 @@ whichever process buffer you want to use.")
|
226 | 228 |
|
227 | 229 | (put 'inf-clojure-mode 'mode-class 'special)
|
228 | 230 |
|
| 231 | +(defcustom inf-clojure-repl-flavor 'clojure |
| 232 | + "Symbol to define your REPL flavor. |
| 233 | +The default flavor is 'clojure, 'lumo is the other supported |
| 234 | +one." |
| 235 | + :type 'symbol |
| 236 | + :options '(clojure lumo) |
| 237 | + :group 'inf-clojure) |
| 238 | + |
| 239 | +(defun inf-clojure--flavor-setup () |
| 240 | + "Setup inf-clojure defcustoms depending on the choose flavor." |
| 241 | + (pcase inf-clojure-repl-flavor |
| 242 | + (lumo (progn (message "[inf-clojure] will switch to the Lumo flavor") |
| 243 | + (inf-clojure--flavor-lumo-setup))) |
| 244 | + (_ (message "[inf-clojure] will default to the Clojure flavor")))) |
| 245 | + |
229 | 246 | (define-derived-mode inf-clojure-mode comint-mode "Inferior Clojure"
|
230 | 247 | "Major mode for interacting with an inferior Clojure process.
|
231 | 248 | Runs a Clojure interpreter as a subprocess of Emacs, with Clojure I/O through an
|
@@ -577,6 +594,21 @@ The value is nil if it can't find one."
|
577 | 594 | "Return the name of the symbol at point, otherwise nil."
|
578 | 595 | (or (thing-at-point 'symbol) ""))
|
579 | 596 |
|
| 597 | +(defun inf-clojure--read-classpath (classpath-option) |
| 598 | + "Read the classpath from the input CLASSPATH-OPTION." |
| 599 | + (let ((classpath-file-path (concat (inf-clojure-project-root) classpath-option))) |
| 600 | + (cond |
| 601 | + ((and (file-exists-p classpath-file-path) (file-readable-p classpath-file-path)) |
| 602 | + (f-read classpath-file-path)) |
| 603 | + ;; TODO launch a command that returns the classpath string? |
| 604 | + ((message (concat "Option \"" classpath-option "\" was not a (readable) file, the classpath will be empty.")) |
| 605 | + "")))) |
| 606 | + |
| 607 | +(defun inf-clojure--maybe-set-program (program) |
| 608 | + "Set inf-clojure-program iff it is not a cons cell." |
| 609 | + (when (nlistp inf-clojure-program) |
| 610 | + (setq inf-clojure-program program))) |
| 611 | + |
580 | 612 | ;;; Documentation functions: var doc and arglist.
|
581 | 613 | ;;; ======================================================================
|
582 | 614 |
|
@@ -798,6 +830,64 @@ Return the number of nested sexp the point was over or after."
|
798 | 830 | (interactive)
|
799 | 831 | (message "inf-clojure (version %s)" inf-clojure-version))
|
800 | 832 |
|
801 |
| -(provide 'inf-clojure) |
| 833 | +;;;; Lumo |
| 834 | +;;;; ==== |
| 835 | + |
| 836 | +(defgroup lumo nil |
| 837 | + "Run an external Lumo process (REPL) in an Emacs buffer." |
| 838 | + :group 'inf-clojure) |
802 | 839 |
|
| 840 | +(defcustom inf-clojure-lumo-command "lumo" |
| 841 | + "The command used to launch lumo." |
| 842 | + :type 'string |
| 843 | + :group 'lumo) |
| 844 | + |
| 845 | +(defcustom inf-clojure-lumo-args "-d" |
| 846 | + "The command arguments used to launch lumo." |
| 847 | + :type 'string |
| 848 | + :group 'lumo) |
| 849 | + |
| 850 | +;; AR - TODO Alternatively you can specify a command string that will be called, |
| 851 | +;; which should return a string. |
| 852 | +(defcustom inf-clojure-lumo-classpath-generator "cp" |
| 853 | + "The file used to create the classpath string. |
| 854 | +The classpath string has to be a \":\" separated list of dir and |
| 855 | +files." |
| 856 | + :type 'string |
| 857 | + :group 'lumo) |
| 858 | + |
| 859 | +;; AR - not used but left here because it is a possible sanity check |
| 860 | +(defun inf-clojure--lumo-mode-p () |
| 861 | + "Return true if the lumo is the target REPL." |
| 862 | + (comint-send-string (inf-clojure-proc) "(js/global.hasOwnProperty \"$$LUMO_GLOBALS\")")) |
| 863 | + |
| 864 | +(defun inf-clojure--lumo-repl-command () |
| 865 | + "Return inf-clojure-program for lumo." |
| 866 | + (concat inf-clojure-lumo-command |
| 867 | + " " |
| 868 | + (when (not (string-empty-p inf-clojure-lumo-classpath-generator)) |
| 869 | + (concat inf-clojure-lumo-args " ")) |
| 870 | + "-c " (inf-clojure--read-classpath inf-clojure-lumo-classpath-generator))) |
| 871 | + |
| 872 | +(defun inf-clojure--flavor-lumo-setup () |
| 873 | + "Setup defcustoms for the Lumo flavor." |
| 874 | + ;; The defcustoms for the following are already ok: |
| 875 | + ;; * inf-clojure-set-ns-command |
| 876 | + ;; * inf-clojure-macroexpand-command |
| 877 | + ;; * inf-clojure-macroexpand-1-command |
| 878 | + ;; |
| 879 | + ;; https://github.com/anmonteiro/lumo/issues/84 |
| 880 | + ;; (setq inf-clojure-var-source-command "(lumo.repl/source %s)") |
| 881 | + ;; https://github.com/anmonteiro/lumo/issues/87 |
| 882 | + ;; (setq inf-clojure-ns-vars-command "(lumo.repl/dir %s)") |
| 883 | + ;; https://github.com/anmonteiro/lumo/issues/86 |
| 884 | + ;; (setq inf-clojure-var-apropos-command "(lumo.repl/apropos %s)") |
| 885 | + |
| 886 | + ;; Uncomment after https://github.com/anmonteiro/lumo/pull/88 |
| 887 | + ;; (setq inf-clojure-arglist-command "(lumo.repl/get-arglists \"%s\")") |
| 888 | + (setq inf-clojure-var-doc-command "(lumo.repl/doc %s)") |
| 889 | + (setq inf-clojure-completion-command "(or (doall (map str (lumo.repl/get-completions \"%s\")) '())") |
| 890 | + (inf-clojure--maybe-set-program (inf-clojure--lumo-repl-command))) |
| 891 | + |
| 892 | +(provide 'inf-clojure) |
803 | 893 | ;;; inf-clojure.el ends here
|
0 commit comments