6565
6666(require 'comint )
6767(require 'clojure-mode )
68+ (require 'clojure-ts-mode nil :no-error )
6869(require 'eldoc )
6970(require 'thingatpt )
7071(require 'ansi-color )
7172(require 'cl-lib )
7273(require 'subr-x )
74+ (require 'project )
7375
7476(defvar inf-clojure-startup-forms '((lein . " lein repl" )
7577 (boot . " boot repl" )
@@ -193,10 +195,10 @@ either `setq-local` or an entry in `.dir-locals.el`." )
193195MULTIPLE PROCESS SUPPORT
194196===========================================================================
195197To run multiple Clojure processes, you start the first up
196- with \\ [inf-clojure]. It will be in a buffer named ` *inf-clojure*' .
198+ with \\ [inf-clojure]. It will be in a buffer named *inf-clojure*.
197199Rename this buffer with \\ [rename-buffer]. You may now start up a new
198200process with another \\ [inf-clojure]. It will be in a new buffer,
199- named ` *inf-clojure*' . You can switch between the different process
201+ named *inf-clojure*. You can switch between the different process
200202buffers with \\ [switch-to-buffer].
201203
202204Commands that send text from source buffers to Clojure processes --
@@ -205,7 +207,7 @@ process to send to, when you have more than one Clojure process around. This
205207is determined by the global variable `inf-clojure-buffer' . Suppose you
206208have three inferior Clojures running:
207209 Buffer Process
208- foo inf-clojure
210+ foo ` inf-clojure'
209211 bar inf-clojure<2>
210212 *inf-clojure* inf-clojure<3>
211213If you do a \\ [inf-clojure-eval-defun] command on some Clojure source code,
@@ -269,7 +271,7 @@ has been found. See also variable `inf-clojure-buffer'."
269271 (error " No Clojure subprocess; see variable `inf-clojure-buffer' " ))))
270272
271273(defun inf-clojure-repl-p (&optional buf )
272- " Indicates if BUF is an inf-clojure REPL.
274+ " Indicates if BUF is an ` inf-clojure' REPL.
273275If BUF is nil then defaults to the current buffer.
274276Checks the mode and that there is a live process."
275277 (let ((buf (or buf (current-buffer ))))
@@ -278,35 +280,35 @@ Checks the mode and that there is a live process."
278280 (process-live-p (get-buffer-process buf)))))
279281
280282(defun inf-clojure-repls ()
281- " Return a list of all inf-clojure REPL buffers."
283+ " Return a list of all ` inf-clojure' REPL buffers."
282284 (let (repl-buffers)
283285 (dolist (b (buffer-list ))
284286 (when (inf-clojure-repl-p b)
285287 (push (buffer-name b) repl-buffers)))
286288 repl-buffers))
287289
288290(defun inf-clojure--prompt-repl-buffer (prompt )
289- " Prompt the user to select an inf-clojure repl buffer.
291+ " Prompt the user to select an ` inf-clojure' repl buffer.
290292PROMPT is a string to prompt the user.
291293Returns nil when no buffer is selected."
292294 (let ((repl-buffers (inf-clojure-repls)))
293295 (if (> (length repl-buffers) 0 )
294- (when-let ((repl-buffer (completing-read prompt repl-buffers nil t )))
296+ (when-let* ((repl-buffer (completing-read prompt repl-buffers nil t )))
295297 (get-buffer repl-buffer))
296298 (user-error " No buffers have an inf-clojure process" ))))
297299
298300(defun inf-clojure-set-repl (always-ask )
299- " Set an inf-clojure buffer as the active (default) REPL.
301+ " Set an ` inf-clojure' buffer as the active (default) REPL.
300302If in a REPL buffer already, use that unless a prefix is used (or
301- ALWAYS-ASK). Otherwise get a list of all active inf-clojure
303+ ALWAYS-ASK). Otherwise get a list of all active ` inf-clojure'
302304REPLS and offer a choice. It's recommended to rename REPL
303305buffers after they are created with `rename-buffer' ."
304306 (interactive " P" )
305- (when-let ((new-repl-buffer
306- (if (or always-ask
307- (not (inf-clojure-repl-p)))
308- (inf-clojure--prompt-repl-buffer " Select default REPL: " )
309- (current-buffer ))))
307+ (when-let* ((new-repl-buffer
308+ (if (or always-ask
309+ (not (inf-clojure-repl-p)))
310+ (inf-clojure--prompt-repl-buffer " Select default REPL: " )
311+ (current-buffer ))))
310312 (setq inf-clojure-buffer new-repl-buffer)
311313 (message " Current inf-clojure REPL set to %s " new-repl-buffer)))
312314
@@ -349,6 +351,14 @@ mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword
349351\( as in :a, :c, etc.)"
350352 :type 'regexp )
351353
354+ (defcustom inf-clojure-source-modes '(clojure-ts-mode clojure-mode)
355+ " Used to determine if a buffer contains Clojure source code.
356+
357+ Any buffer with one of these major modes, it's considered a Clojure
358+ source file by all `inf-clojure' commands."
359+ :type '(repeat symbol)
360+ :safe #'symbolp )
361+
352362(defun inf-clojure--modeline-info ()
353363 " Return modeline info for `inf-clojure-minor-mode' .
354364Either \" no process\" or \" buffer-name(repl-type)\" "
@@ -453,7 +463,7 @@ The value of this variable is a mode line template as in
453463`mode-line-format' . See Info Node `(elisp)Mode Line Format' for details
454464about mode line templates.
455465
456- Customize this variable to change how inf-clojure-minor-mode
466+ Customize this variable to change how ` inf-clojure-minor-mode'
457467displays its status in the mode line. The default value displays
458468the current REPL. Set this variable to nil to disable the
459469mode line entirely."
@@ -609,24 +619,35 @@ This should usually be a combination of `inf-clojure-prompt' and
609619 :package-version '(inf-clojure . " 2.0.0" ))
610620
611621(defcustom inf-clojure-auto-mode t
612- " Automatically enable inf-clojure-minor-mode.
622+ " Automatically enable ` inf-clojure-minor-mode' .
613623All buffers in `clojure-mode' will automatically be in
614624`inf-clojure-minor-mode' unless set to nil."
615625 :type 'boolean
616626 :safe #'booleanp
617627 :package-version '(inf-clojure . " 3.1.0" ))
618628
629+ (defun inf-clojure--get-preferred-major-modes ()
630+ " Return list of preferred major modes that are actually available."
631+ (cl-remove-if-not (lambda (mode ) (featurep mode))
632+ inf-clojure-source-modes))
633+
634+ (defun inf-clojure--clojure-buffer-p ()
635+ " Return TRUE if the current buffer is a Clojure buffer."
636+ (derived-mode-p (inf-clojure--get-preferred-major-modes)))
637+
619638(defun inf-clojure--clojure-buffers ()
620639 " Return a list of all existing `clojure-mode' buffers."
621- (cl-remove-if-not
622- (lambda (buffer ) (with-current-buffer buffer (derived-mode-p 'clojure-mode )))
623- (buffer-list )))
640+ (cl-remove-if-not (lambda (buffer )
641+ (with-current-buffer buffer
642+ (inf-clojure--clojure-buffer-p)))
643+ (buffer-list )))
624644
625645(defun inf-clojure-enable-on-existing-clojure-buffers ()
626646 " Enable inf-clojure's minor mode on existing Clojure buffers.
627647See command `inf-clojure-minor-mode' ."
628648 (interactive )
629- (add-hook 'clojure-mode-hook #'inf-clojure-minor-mode )
649+ (dolist (mode (inf-clojure--get-preferred-major-modes))
650+ (add-hook (derived-mode-hook-name mode) #'inf-clojure-minor-mode ))
630651 (dolist (buffer (inf-clojure--clojure-buffers))
631652 (with-current-buffer buffer
632653 (inf-clojure-minor-mode +1 ))))
@@ -688,6 +709,8 @@ If `comint-use-prompt-regexp' is nil (the default), \\[comint-insert-input] on
688709 (setq comint-input-sender 'inf-clojure--send-string )
689710 (setq comint-prompt-regexp inf-clojure-comint-prompt-regexp)
690711 (setq mode-line-process '(" :%s" ))
712+ ; ; NOTE: Using Tree-sitter based syntax highlighting in comint
713+ ; ; buffer is currently not possible.
691714 (clojure-mode-variables)
692715 (clojure-font-lock-setup)
693716 (when inf-clojure-enable-eldoc
@@ -799,10 +822,24 @@ to suppress the usage of the target buffer discovery logic."
799822The name is simply the final segment of the path."
800823 (file-name-nondirectory (directory-file-name dir)))
801824
825+ (defun inf-clojure--project-dir ()
826+ " Return current Clojure project root."
827+ (let ((project-vc-extra-root-markers '(" project.clj" ; Leiningen
828+ " build.boot" ; Boot
829+ " build.gradle" ; Gradle
830+ " build.gradle.kts" ; Gradle
831+ " deps.edn" ; Clojure CLI (a.k.a. tools.deps)
832+ " shadow-cljs.edn" ; shadow-cljs
833+ " bb.edn" ; babashka
834+ " nbb.edn" ; nbb
835+ " basilisp.edn" ; Basilisp (Python)
836+ )))
837+ (project-root (project-current ))))
838+
802839;;;### autoload
803840(defun inf-clojure (cmd &optional suppress-message )
804- " Run an inferior Clojure process, input and output via buffer ` *inf-clojure*' .
805- If there is a process already running in ` *inf-clojure*' , just
841+ " Run an inferior Clojure process, input and output via buffer *inf-clojure*.
842+ If there is a process already running in *inf-clojure*, just
806843switch to that buffer.
807844
808845CMD is a string which serves as the startup command or a cons of
@@ -826,7 +863,7 @@ process buffer for a list of commands.)"
826863 (mapcar #'cdr inf-clojure-startup-forms)
827864 nil
828865 'confirm-after-completion ))))
829- (let* ((project-dir (clojure-project-dir))
866+ (let* ((project-dir (inf- clojure- -project-dir))
830867 (process-buffer-name (or
831868 inf-clojure-custom-repl-name
832869 (if project-dir
@@ -850,7 +887,9 @@ process buffer for a list of commands.)"
850887 (with-current-buffer (apply #'make-comint
851888 process-buffer-name (car cmdlist) nil (cdr cmdlist))
852889 (inf-clojure-mode)
853- (set-syntax-table clojure-mode-syntax-table)
890+ (set-syntax-table (pcase (car (inf-clojure--get-preferred-major-modes))
891+ ('clojure-ts-mode clojure-ts-mode-syntax-table)
892+ (_ clojure-mode-syntax-table)))
854893 (setq-local inf-clojure-repl-type repl-type)
855894 (hack-dir-local-variables-non-file-buffer ))))
856895 ; ; update the default comint buffer and switch to it
@@ -940,7 +979,7 @@ defaults provided in `inf-clojure-socket-repl-startup-forms'."
940979 'confirm-after-completion ))))
941980 (let* ((host " localhost" )
942981 (port (or inf-clojure-socket-repl-port (+ 5500 (random 500 ))))
943- (project-dir (clojure-project-dir))
982+ (project-dir (inf- clojure- -project-dir))
944983 (repl-type (or (unless prefix-arg
945984 inf-clojure-custom-repl-type)
946985 (car (rassoc cmd inf-clojure-socket-repl-startup-forms))
@@ -978,16 +1017,19 @@ of forms."
9781017 (condition-case nil
9791018 (with-temp-buffer
9801019 (progn
981- (clojurec-mode)
1020+ ; ; Activate preferred major mode.
1021+ (funcall (car (inf-clojure--get-preferred-major-modes)))
9821022 (insert str)
9831023 (whitespace-cleanup )
9841024 (goto-char (point-min ))
9851025 (while (not (eobp ))
9861026 (while (looking-at " \n " )
9871027 (delete-char 1 ))
9881028 (unless (eobp )
989- (clojure-forward-logical-sexp))
990- (unless (eobp )
1029+ ; ; NOTE: There is no special API for that in
1030+ ; ; `clojure-ts-mode' , so probably for now lets keep this
1031+ ; ; `clojure-mode' function.
1032+ (clojure-forward-logical-sexp)
9911033 (forward-char )))
9921034 (buffer-substring-no-properties (point-min ) (point-max ))))
9931035 (scan-error str)))
@@ -1105,13 +1147,6 @@ START and END are the beginning and end positions in the buffer to send."
11051147This holds a cons cell of the form `(DIRECTORY . FILE)'
11061148describing the last `inf-clojure-load-file' command." )
11071149
1108- (defcustom inf-clojure-source-modes '(clojure-mode)
1109- " Used to determine if a buffer contains Clojure source code.
1110- If it's loaded into a buffer that is in one of these major modes, it's
1111- considered a Clojure source file by `inf-clojure-load-file' .
1112- Used by this command to determine defaults."
1113- :type '(repeat symbol))
1114-
11151150(defun inf-clojure-load-file (&optional switch-to-repl file-name )
11161151 " Load a Clojure file into the inferior Clojure process.
11171152
@@ -1123,7 +1158,7 @@ is present it will be used instead of the current file."
11231158 (file-name (or file-name
11241159 (car (comint-get-source " Load Clojure file: " inf-clojure-prev-l/c-dir/file
11251160 ; ; nil because doesn't need an exact name
1126- inf-clojure-source- modes nil ))))
1161+ ( inf-clojure--get-preferred-major- modes) nil ))))
11271162 (load-form (inf-clojure-get-feature proc 'load )))
11281163 (comint-check-source file-name) ; Check to see if buffer needs saved.
11291164 (setq inf-clojure-prev-l/c-dir/file (cons (file-name-directory file-name)
@@ -1132,23 +1167,32 @@ is present it will be used instead of the current file."
11321167 (when switch-to-repl
11331168 (inf-clojure-switch-to-repl t ))))
11341169
1170+ (defun inf-clojure--find-ns ()
1171+ " Return the namespace of the current Clojure buffer.
1172+
1173+ This function delegates its job to an appropritate function, considering
1174+ `inf-clojure-source-modes' ."
1175+ (pcase (car (inf-clojure--get-preferred-major-modes))
1176+ ('clojure-ts-mode (clojure-ts-find-ns))
1177+ (_ (clojure-find-ns))))
1178+
11351179(defun inf-clojure-reload (arg )
11361180 " Send a query to the inferior Clojure for reloading the namespace.
1137- See variable `inf-clojure-reload-form' and
1181+ See variable `inf-clojure-reload-form' and variable
11381182`inf-clojure-reload-all-form' .
11391183
11401184The prefix argument ARG can change the behavior of the command:
11411185
1142- - C-u M-x ` inf-clojure-reload' : prompts for a namespace name.
1143- - M-- M-x ` inf-clojure-reload' : executes (require ... :reload-all).
1144- - M-- C-u M-x ` inf-clojure-reload' : reloads all AND prompts."
1186+ - \\ ` C-u' \\ [ inf-clojure-reload] : prompts for a namespace name.
1187+ - \\ ` M--' \\ [ inf-clojure-reload] : executes (require ... :reload-all).
1188+ - \\ ` M--' \\ ` C-u' \\ [ inf-clojure-reload] : reloads all AND prompts."
11451189 (interactive " P" )
11461190 (let* ((proc (inf-clojure-proc))
11471191 (reload-all-p (or (equal arg '- ) (equal arg '(-4 ))))
11481192 (prompt-p (or (equal arg '(4 )) (equal arg '(-4 ))))
11491193 (ns (if prompt-p
1150- (car (inf-clojure-symprompt " Namespace" (clojure-find-ns)))
1151- (clojure-find-ns)))
1194+ (car (inf-clojure-symprompt " Namespace" (inf- clojure- -find-ns)))
1195+ (inf- clojure- -find-ns)))
11521196 (form (if (not reload-all-p)
11531197 (inf-clojure-reload-form proc)
11541198 (inf-clojure-reload-all-form proc))))
@@ -1249,7 +1293,7 @@ STRING if present."
12491293 (prin1-to-string (substring-no-properties string))))
12501294 nil
12511295 (expand-file-name inf-clojure--log-file-name
1252- (clojure-project-dir))
1296+ (inf- clojure- -project-dir))
12531297 'append
12541298 'no-annoying-write-file-in-minibuffer )))
12551299
@@ -1357,11 +1401,11 @@ for evaluation, therefore FORM should not include it."
13571401(defun inf-clojure-arglists (fn )
13581402 " Send a query to the inferior Clojure for the arglists for function FN.
13591403See variable `inf-clojure-arglists-form' ."
1360- (when-let ((proc (inf-clojure-proc 'no-error ) ))
1361- ( when-let ( (arglists-form (inf-clojure-get-feature proc 'arglists )))
1362- (thread-first (format arglists-form fn)
1363- (inf-clojure--process-response proc " (" " )" )
1364- (inf-clojure--some) ))))
1404+ (when-let* ((proc (inf-clojure-proc 'no-error ))
1405+ (arglists-form (inf-clojure-get-feature proc 'arglists )))
1406+ (thread-first (format arglists-form fn)
1407+ (inf-clojure--process-response proc " (" " )" )
1408+ (inf-clojure--some))))
13651409
13661410(defun inf-clojure-show-arglists (prompt-for-symbol )
13671411 " Show the arglists for function FN in the mini-buffer.
@@ -1383,8 +1427,8 @@ prefix argument PROMPT-FOR-NS, it prompts for a namespace name."
13831427 (interactive " P" )
13841428 (let* ((proc (inf-clojure-proc))
13851429 (ns (if prompt-for-ns
1386- (car (inf-clojure-symprompt " Ns vars" (clojure-find-ns)))
1387- (clojure-find-ns)))
1430+ (car (inf-clojure-symprompt " Ns vars" (inf- clojure- -find-ns)))
1431+ (inf- clojure- -find-ns)))
13881432 (ns-vars-form (inf-clojure-get-feature proc 'ns-vars )))
13891433 (inf-clojure--send-string proc (format ns-vars-form ns))))
13901434
@@ -1396,8 +1440,8 @@ PROMPT-FOR-NS, it prompts for a namespace name."
13961440 (interactive " P" )
13971441 (let* ((proc (inf-clojure-proc))
13981442 (ns (if prompt-for-ns
1399- (car (inf-clojure-symprompt " Set ns to" (clojure-find-ns)))
1400- (clojure-find-ns)))
1443+ (car (inf-clojure-symprompt " Set ns to" (inf- clojure- -find-ns)))
1444+ (inf- clojure- -find-ns)))
14011445 (set-ns-form (inf-clojure-get-feature proc 'set-ns )))
14021446 (when (or (not ns) (equal ns " " ))
14031447 (user-error " No namespace selected" ))
0 commit comments