|
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
|
@@ -220,6 +222,21 @@ whichever process buffer you want to use.")
|
220 | 222 |
|
221 | 223 | (put 'inf-clojure-mode 'mode-class 'special)
|
222 | 224 |
|
| 225 | +(defcustom inf-clojure-repl-flavor 'clojure |
| 226 | + "Symbol to define your REPL flavor. |
| 227 | +The default flavor is 'clojure, 'lumo is the other supported |
| 228 | +one." |
| 229 | + :type 'symbol |
| 230 | + :options '(clojure lumo) |
| 231 | + :group 'inf-clojure) |
| 232 | + |
| 233 | +(defun inf-clojure--flavor-setup () |
| 234 | + "Setup inf-clojure defcustoms depending on the choose flavor." |
| 235 | + (pcase inf-clojure-repl-flavor |
| 236 | + (lumo (progn (message "[inf-clojure] will switch to the Lumo flavor") |
| 237 | + (inf-clojure--flavor-lumo-setup))) |
| 238 | + (_ (message "[inf-clojure] will default to the Clojure flavor")))) |
| 239 | + |
223 | 240 | (define-derived-mode inf-clojure-mode comint-mode "Inferior Clojure"
|
224 | 241 | "Major mode for interacting with an inferior Clojure process.
|
225 | 242 | Runs a Clojure interpreter as a subprocess of Emacs, with Clojure I/O through an
|
@@ -571,6 +588,21 @@ The value is nil if it can't find one."
|
571 | 588 | "Return the name of the symbol at point, otherwise nil."
|
572 | 589 | (or (thing-at-point 'symbol) ""))
|
573 | 590 |
|
| 591 | +(defun inf-clojure--read-classpath (classpath-option) |
| 592 | + "Read the classpath from the input CLASSPATH-OPTION." |
| 593 | + (let ((classpath-file-path (concat (inf-clojure-project-root) classpath-option))) |
| 594 | + (cond |
| 595 | + ((and (file-exists-p classpath-file-path) (file-readable-p classpath-file-path)) |
| 596 | + (f-read classpath-file-path)) |
| 597 | + ;; TODO launch a command that returns the classpath string? |
| 598 | + ((message (concat "Option \"" classpath-option "\" was not a (readable) file, the classpath will be empty.")) |
| 599 | + "")))) |
| 600 | + |
| 601 | +(defun inf-clojure--maybe-set-program (program) |
| 602 | + "Set inf-clojure-program iff it is not a cons cell." |
| 603 | + (when (nlistp inf-clojure-program) |
| 604 | + (setq inf-clojure-program program))) |
| 605 | + |
574 | 606 | ;;; Documentation functions: var doc and arglist.
|
575 | 607 | ;;; ======================================================================
|
576 | 608 |
|
@@ -787,6 +819,64 @@ Return the number of nested sexp the point was over or after."
|
787 | 819 | (interactive)
|
788 | 820 | (message "inf-clojure (version %s)" inf-clojure-version))
|
789 | 821 |
|
790 |
| -(provide 'inf-clojure) |
| 822 | +;;;; Lumo |
| 823 | +;;;; ==== |
| 824 | + |
| 825 | +(defgroup lumo nil |
| 826 | + "Run an external Lumo process (REPL) in an Emacs buffer." |
| 827 | + :group 'inf-clojure) |
791 | 828 |
|
| 829 | +(defcustom inf-clojure-lumo-command "lumo" |
| 830 | + "The command used to launch lumo." |
| 831 | + :type 'string |
| 832 | + :group 'lumo) |
| 833 | + |
| 834 | +(defcustom inf-clojure-lumo-args "-d" |
| 835 | + "The command arguments used to launch lumo." |
| 836 | + :type 'string |
| 837 | + :group 'lumo) |
| 838 | + |
| 839 | +;; AR - TODO Alternatively you can specify a command string that will be called, |
| 840 | +;; which should return a string. |
| 841 | +(defcustom inf-clojure-lumo-classpath-generator "cp" |
| 842 | + "The file used to create the classpath string. |
| 843 | +The classpath string has to be a \":\" separated list of dir and |
| 844 | +files." |
| 845 | + :type 'string |
| 846 | + :group 'lumo) |
| 847 | + |
| 848 | +;; AR - not used but left here because it is a possible sanity check |
| 849 | +(defun inf-clojure--lumo-mode-p () |
| 850 | + "Return true if the lumo is the target REPL." |
| 851 | + (comint-send-string (inf-clojure-proc) "(js/global.hasOwnProperty \"$$LUMO_GLOBALS\")")) |
| 852 | + |
| 853 | +(defun inf-clojure--lumo-repl-command () |
| 854 | + "Return inf-clojure-program for lumo." |
| 855 | + (concat inf-clojure-lumo-command |
| 856 | + " " |
| 857 | + (when (not (string-empty-p inf-clojure-lumo-classpath-generator)) |
| 858 | + (concat inf-clojure-lumo-args " ")) |
| 859 | + "-c " (inf-clojure--read-classpath inf-clojure-lumo-classpath-generator))) |
| 860 | + |
| 861 | +(defun inf-clojure--flavor-lumo-setup () |
| 862 | + "Setup defcustoms for the Lumo flavor." |
| 863 | + ;; The defcustoms for the following are already ok: |
| 864 | + ;; * inf-clojure-set-ns-command |
| 865 | + ;; * inf-clojure-macroexpand-command |
| 866 | + ;; * inf-clojure-macroexpand-1-command |
| 867 | + ;; |
| 868 | + ;; https://github.com/anmonteiro/lumo/issues/84 |
| 869 | + ;; (setq inf-clojure-var-source-command "(lumo.repl/source %s)") |
| 870 | + ;; https://github.com/anmonteiro/lumo/issues/87 |
| 871 | + ;; (setq inf-clojure-ns-vars-command "(lumo.repl/dir %s)") |
| 872 | + ;; https://github.com/anmonteiro/lumo/issues/86 |
| 873 | + ;; (setq inf-clojure-var-apropos-command "(lumo.repl/apropos %s)") |
| 874 | + |
| 875 | + ;; Uncomment after https://github.com/anmonteiro/lumo/pull/88 |
| 876 | + ;; (setq inf-clojure-arglist-command "(lumo.repl/get-arglists \"%s\")") |
| 877 | + (setq inf-clojure-var-doc-command "(lumo.repl/doc %s)") |
| 878 | + (setq inf-clojure-completion-command "(or (doall (map str (lumo.repl/get-completions \"%s\")) '())") |
| 879 | + (inf-clojure--maybe-set-program (inf-clojure--lumo-repl-command))) |
| 880 | + |
| 881 | +(provide 'inf-clojure) |
792 | 882 | ;;; inf-clojure.el ends here
|
0 commit comments