Skip to content

Add preliminary support for clojure-ts-mode #3461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,8 @@ jobs:
cd dev; ../clojure.sh clojure -M:gen; cd -
wc -l test/File.edn
eldev -p -dtTC test --test-type enrich || eldev -p -dtTC test --test-type enrich


- name: Test clojure-ts-mode
if: startsWith (matrix.emacs_version, '29')
run: |
eldev -p -dtTC test --test-type clojure-ts-mode || eldev -p -dtTC test --test-type clojure-ts-mode
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
- [#3352](https://github.com/clojure-emacs/cider/pull/3496): Introduce [`cider-eval-dwim`](https://docs.cider.mx/cider/usage/cider_mode.html#key-reference).
- Add new customization variable [`cider-clojurec-eval-destination`](https://docs.cider.mx/cider/cljs/up_and_running.html#working-with-cljc-files) to allow specifying which REPL .cljc evals are sent to.
- [#3354](https://github.com/clojure-emacs/cider/issues/3354): Add new customization variable [`cider-reuse-dead-repls`](https://docs.cider.mx/cider/usage/managing_connections.html#reusing-dead-repls) to control how dead REPL buffers are reused on new connections.
- Basic support for using CIDER from [clojure-ts-mode](https://github.com/clojure-emacs/clojure-ts-mode)
- [#3461](https://github.com/clojure-emacs/cider/pull/3461) Basic support for using CIDER from [clojure-ts-mode](https://github.com/clojure-emacs/clojure-ts-mode)
- [#3461](https://github.com/clojure-emacs/cider/pull/3461) Basic support for using CIDER with [clojure-ts-mode](https://github.com/clojure-emacs/clojure-ts-mode)
- The clojure-mode dependency is still required for CIDER to function
- some features like `cider-dynamic-indentation` and `cider-font-lock-dynamically` do not work with clojure-ts-mode (yet).

### Bugs fixed

Expand Down
22 changes: 16 additions & 6 deletions Eldev
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

(eldev-add-loading-roots 'test "test/utils")
(eldev-add-extra-dependencies 'runtime '(:package logview :optional t))
(eldev-add-extra-dependencies 'runtime '(:package clojure-ts-mode :optional t))

;; slightly increase the maximum (applies to checkdoc and the byte compiler alike)
(setq byte-compile-docstring-max-column 100)
Expand All @@ -21,25 +22,34 @@
(setf eldev-standard-excludes `(:or ,eldev-standard-excludes
;; Avoid including files in test "projects".
(eldev-pcase-exhaustive cider-test-type
(`main "./test/*/")
(`integration '("./test/" "!./test/integration"))
(`enrich '("./test/" "!./test/enrich"))
(`all '("./test/*/" "!./test/integration")))
(`main "./test/*/")
(`integration '("./test/" "!./test/integration"))
(`enrich '("./test/" "!./test/enrich"))
(`clojure-ts-mode '("./test/*/" "!./test/clojure-ts-mode"))
(`all '("./test/*/" "!./test/integration")))
"test/integration/projects"
;; This file is _supposed_ to be excluded
;; from automated testing.
"test/cider-tests--no-auto.el"))

(eldev-defoption cider-test-selection (type)
"Select tests to run; type can be `main', `integration', `enrich' or `all'"
"Select tests to run; type can be `main', `integration', `enrich', `clojure-ts-mode' or `all'"
:options (-T --test-type)
:for-command test
:value TYPE
:default-value cider-test-type
(unless (memq (intern type) '(main integration enrich all))
(unless (memq (intern type) '(main integration enrich clojure-ts-mode all))
(signal 'eldev-wrong-option-usage `("unknown test type `%s'" ,type)))
(setf cider-test-type (intern type)))

(add-hook 'eldev-load-dependencies-hook
(lambda (type additional-sets)
(when (and (eq cider-test-type 'clojure-ts-mode)
(member 'runtime additional-sets))
(message "Installing tree-sitter grammars")
(require 'clojure-ts-mode)
(clojure-ts--ensure-grammars))))

(add-hook 'eldev-test-hook
(lambda ()
(eldev-verbose "Using cider tests of type `%s'" cider-test-type)))
Expand Down
3 changes: 2 additions & 1 deletion cider-clojuredocs.el
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
(require 'cider-common)
(require 'subr-x)
(require 'cider-popup)
(require 'cider-util)

(require 'nrepl-dict)

Expand Down Expand Up @@ -160,7 +161,7 @@ Prompts for the symbol to use, or uses the symbol at point, depending on
the value of `cider-prompt-for-symbol'. With prefix arg ARG, does the
opposite of what that option dictates."
(interactive "P")
(when (derived-mode-p 'clojurescript-mode)
(when (cider-clojurescript-major-mode-p)
(user-error "`cider-clojuredocs' doesn't support ClojureScript"))
(funcall (cider-prompt-for-symbol-function arg)
"ClojureDocs doc for"
Expand Down
7 changes: 4 additions & 3 deletions cider-connection.el
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ message in the REPL area."
See command `cider-mode'."
(interactive)
(add-hook 'clojure-mode-hook #'cider-mode)
(add-hook 'clojure-ts-mode-hook #'cider-mode)
(dolist (buffer (cider-util--clojure-buffers))
(with-current-buffer buffer
(unless cider-mode
Expand Down Expand Up @@ -800,9 +801,9 @@ multi. This function infers connection type based on the major mode.
For the REPL type use the function `cider-repl-type'."
(with-current-buffer (or buffer (current-buffer))
(cond
((derived-mode-p 'clojurescript-mode) 'cljs)
((derived-mode-p 'clojurec-mode) cider-clojurec-eval-destination)
((derived-mode-p 'clojure-mode) 'clj)
((cider-clojurescript-major-mode-p) 'cljs)
((cider-clojurec-major-mode-p) cider-clojurec-eval-destination)
((cider-clojure-major-mode-p) 'clj)
(cider-repl-type))))

(defun cider-set-repl-type (&optional type)
Expand Down
2 changes: 1 addition & 1 deletion cider-eval.el
Original file line number Diff line number Diff line change
Expand Up @@ -1421,7 +1421,7 @@ command `cider-debug-defun-at-point'."
(interactive "P")
(let ((inline-debug (eq 16 (car-safe debug-it))))
(when debug-it
(when (derived-mode-p 'clojurescript-mode)
(when (cider-clojurescript-major-mode-p)
(when (y-or-n-p (concat "The debugger doesn't support ClojureScript yet, and we need help with that."
" \nWould you like to read the Feature Request?"))
(browse-url "https://github.com/clojure-emacs/cider/issues/1416"))
Expand Down
24 changes: 18 additions & 6 deletions cider-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -549,14 +549,16 @@ higher precedence."
(cider--menu-add-help-strings (symbol-value variable))))
map))

;; This menu works as an easy entry-point into CIDER. Even if cider.el isn't
;; loaded yet, this will be shown in Clojure buffers next to the "Clojure"
;; menu.
;;;###autoload
(with-eval-after-load 'clojure-mode
(easy-menu-define cider-clojure-mode-menu-open clojure-mode-map
(defun cider--setup-menu-for-clojure-major-mode (mode-map)
"Setup a Cider menu for a Clojure major mode's MODE-MAP.

This menu works as an easy entry-point into CIDER. Even if cider.el isn't
loaded yet, this will be shown in Clojure buffers next to the Clojure menu."
(easy-menu-define cider-clojure-mode-menu-open mode-map
"Menu for Clojure mode.
This is displayed in `clojure-mode' buffers, if `cider-mode' is not active."
This is displayed in `clojure-mode' and `clojure-ts-mode' buffers,
if `cider-mode' is not active."
`("CIDER" :visible (not cider-mode)
["Start a Clojure REPL" cider-jack-in-clj
:help "Starts an nREPL server and connects a Clojure REPL to it."]
Expand All @@ -571,6 +573,16 @@ higher precedence."
"--"
["View user manual" cider-view-manual])))

;;;###autoload
(with-eval-after-load 'clojure-mode
(cider--setup-menu-for-clojure-major-mode clojure-mode-map))

;;;###autoload
(with-eval-after-load 'clojure-ts-mode
(cider--setup-menu-for-clojure-major-mode
(with-suppressed-warnings ((free-vars clojure-ts-mode-map))
clojure-ts-mode-map)))

;;; Dynamic indentation
(defcustom cider-dynamic-indentation t
"Whether CIDER should aid Clojure(Script) indentation.
Expand Down
2 changes: 1 addition & 1 deletion cider-ns.el
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ If t, save the files without confirmation."
:group 'cider
:package-version '(cider . "0.15.0"))

(defcustom cider-ns-save-files-on-refresh-modes '(clojure-mode)
(defcustom cider-ns-save-files-on-refresh-modes '(clojure-mode clojure-ts-mode)
"Controls which files might be saved before refreshing.
If a list of modes, any buffers visiting files on the classpath whose major
mode is derived from any of the modes might be saved.
Expand Down
15 changes: 9 additions & 6 deletions cider-selector.el
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,26 @@ DESCRIPTION is a one-line description of what the key selects.")
Not meant to be set by users. It's used internally
by `cider-selector'.")

(defun cider-selector--recently-visited-buffer (mode &optional consider-visible-p)
"Return the most recently visited buffer, deriving its `major-mode' from MODE.
(defun cider-selector--recently-visited-buffer (modes &optional consider-visible-p)
"Return the most recently visited buffer, deriving its `major-mode' from MODES.
MODES may be a symbol for a single mode, or a list of mode symbols.
CONSIDER-VISIBLE-P will allow handling of visible windows as well.
First pass only considers buffers that are not already visible.
Second pass will attempt one of visible ones for scenarios where the window
is visible, but not focused."
(cl-loop for buffer in (buffer-list)
when (and (with-current-buffer buffer
(derived-mode-p mode))
(apply #'derived-mode-p (if (listp modes)
modes
(list modes))))
;; names starting with space are considered hidden by Emacs
(not (string-match-p "^ " (buffer-name buffer)))
(or consider-visible-p
(null (get-buffer-window buffer 'visible))))
return buffer
finally (if consider-visible-p
(error "Can't find unshown buffer in %S" mode)
(cider-selector--recently-visited-buffer mode t))))
(error "Can't find unshown buffer in %S" modes)
(cider-selector--recently-visited-buffer modes t))))

;;;###autoload
(defun cider-selector (&optional other-window)
Expand Down Expand Up @@ -134,7 +137,7 @@ is chosen. The returned buffer is selected with

(def-cider-selector-method ?c
"Most recently visited clojure-mode buffer."
(cider-selector--recently-visited-buffer 'clojure-mode))
(cider-selector--recently-visited-buffer '(clojure-mode clojure-ts-mode)))

(def-cider-selector-method ?e
"Most recently visited emacs-lisp-mode buffer."
Expand Down
18 changes: 16 additions & 2 deletions cider-util.el
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,24 @@ Setting this to nil removes the fontification restriction."
(maphash (lambda (k _v) (setq keys (cons k keys))) hashtable)
keys))

(defun cider-clojure-major-mode-p ()
"Return non-nil if current buffer is managed by a Clojure major mode."
(derived-mode-p 'clojure-mode 'clojure-ts-mode))

(defun cider-clojurescript-major-mode-p ()
"Return non-nil if current buffer is managed by a ClojureScript major mode."
(derived-mode-p 'clojurescript-mode 'clojurescript-ts-mode))

(defun cider-clojurec-major-mode-p ()
"Return non-nil if current buffer is managed by a ClojureC major mode."
(derived-mode-p 'clojurec-mode 'clojurec-ts-mode))

(defun cider-util--clojure-buffers ()
"Return a list of all existing `clojure-mode' buffers."
(seq-filter
(lambda (buffer) (with-current-buffer buffer (derived-mode-p 'clojure-mode)))
(lambda (buffer)
(with-current-buffer buffer
(cider-clojure-major-mode-p)))
(buffer-list)))

(defun cider-current-dir ()
Expand Down Expand Up @@ -91,7 +105,7 @@ which nREPL uses for temporary evaluation file names."

If BUFFER is provided act on that buffer instead."
(with-current-buffer (or buffer (current-buffer))
(or (derived-mode-p 'clojurec-mode))))
(or (cider-clojurec-major-mode-p))))


;;; Thing at point
Expand Down
32 changes: 22 additions & 10 deletions cider.el
Original file line number Diff line number Diff line change
Expand Up @@ -2121,17 +2121,29 @@ alternative to the default is `cider-random-tip'."
(add-hook 'cider-connected-hook #'cider--maybe-inspire-on-connect)

;;;###autoload
(with-eval-after-load 'clojure-mode
(define-key clojure-mode-map (kbd "C-c M-x") #'cider)
(define-key clojure-mode-map (kbd "C-c M-j") #'cider-jack-in-clj)
(define-key clojure-mode-map (kbd "C-c M-J") #'cider-jack-in-cljs)
(define-key clojure-mode-map (kbd "C-c M-c") #'cider-connect-clj)
(define-key clojure-mode-map (kbd "C-c M-C") #'cider-connect-cljs)
(define-key clojure-mode-map (kbd "C-c C-x") 'cider-start-map)
(define-key clojure-mode-map (kbd "C-c C-s") 'sesman-map)
(defun cider--setup-clojure-major-mode (mode-map mode-hook)
"Setup Cider key bindings on a Clojure mode's MODE-MAP and hooks in MODE-HOOK."
(define-key mode-map (kbd "C-c M-x") #'cider)
(define-key mode-map (kbd "C-c M-j") #'cider-jack-in-clj)
(define-key mode-map (kbd "C-c M-J") #'cider-jack-in-cljs)
(define-key mode-map (kbd "C-c M-c") #'cider-connect-clj)
(define-key mode-map (kbd "C-c M-C") #'cider-connect-cljs)
(define-key mode-map (kbd "C-c C-x") 'cider-start-map)
(define-key mode-map (kbd "C-c C-s") 'sesman-map)
(require 'sesman)
(sesman-install-menu clojure-mode-map)
(add-hook 'clojure-mode-hook (lambda () (setq-local sesman-system 'CIDER))))
(sesman-install-menu mode-map)
(add-hook mode-hook (lambda () (setq-local sesman-system 'CIDER))))

;;;###autoload
(with-eval-after-load 'clojure-mode
(cider--setup-clojure-major-mode clojure-mode-map 'clojure-mode-hook))

;;;###autoload
(with-eval-after-load 'clojure-ts-mode
(cider--setup-clojure-major-mode
(with-suppressed-warnings ((free-vars clojure-ts-mode-map))
clojure-ts-mode-map)
'clojure-ts-mode-hook))

(provide 'cider)

Expand Down
2 changes: 1 addition & 1 deletion doc/modules/ROOT/pages/additional_packages.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

There are many additional Emacs packages that can enhance your Clojure programming
experience. The majority of the minor modes listed here should be enabled for both
`cider-repl-mode` and `clojure-mode` for optimal effects.
`cider-repl-mode`, `clojure-mode`, and `clojure-ts-mode` for optimal effects.

The packages listed here belong to three categories:

Expand Down
14 changes: 14 additions & 0 deletions doc/modules/ROOT/pages/caveats.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,17 @@ provide the dependencies by editing your `~/.lein/profiles.clj` as described in
the xref:basics/middleware_setup.adoc#setting-up-a-standalone-repl[standalone REPL] section.
* Adjust the value of `cider-injected-nrepl-version` to the same nREPL version as the
one that's bundled with Leiningen.

== Clojure-ts-mode integration

Cider has basic support for working with
https://github.com/clojure-emacs/clojure-ts-mode[clojure-ts-mode] buffers, but it still depends on
https://github.com/clojure-emacs/clojure-mode[clojure-mode] for certain functionality, like
extracting information about clojure code out of the buffer. We hope to make clojure-ts-mode capable
of providing cider with all the functionality it needs to interact with clojure buffers, but that
will take some time.

Additionally, some features like
xref:config/indentation.adoc#dynamic-indentation[`cider-dynamic-indentation`]
and xref:config/syntax_highlighting.adoc#dynamic-syntax-highlighting[`cider-font-lock-dynamically`]
are not supported by clojure-ts-mode.
7 changes: 3 additions & 4 deletions doc/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ that **R**ocks!

CIDER extends Emacs with support for xref:usage/interactive_programming.adoc[interactive programming] in Clojure. The
features are centered around xref:usage/cider_mode.adoc[cider-mode], an Emacs minor-mode that complements
https://github.com/clojure-emacs/clojure-mode[clojure-mode]. While `clojure-mode` supports editing Clojure source files,
`cider-mode` adds support for interacting with a running Clojure process for
compilation, debugging, definition and documentation lookup, running tests and
so on.
https://github.com/clojure-emacs/clojure-mode[clojure-mode] and https://github.com/clojure-emacs/clojure-ts-mode[clojure-ts-mode].
While `clojure-mode` supports editing Clojure source files, `cider-mode` adds support for interacting with a running Clojure process for
compilation, debugging, definition and documentation lookup, running tests and so on.

.Inspired by SLIME
****
Expand Down
9 changes: 8 additions & 1 deletion doc/modules/ROOT/pages/usage/cider_mode.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ it, so you can be productive.
(add-hook 'clojure-mode-hook #'cider-mode)
----

NOTE: There's no need to enable it explicitly for modes derived from `clojure-mode` like `clojurescript-mode`.
or if you are using `clojure-ts-mode`:

[source,lisp]
----
(add-hook 'clojure-ts-mode-hook #'cider-mode)
----

NOTE: There's no need to enable it explicitly for modes derived from `clojure-mode` or `clojure-ts-mode` like `clojurescript-mode` and `clojurescript-ts-mode`.

== Disabling cider-mode

Expand Down
3 changes: 2 additions & 1 deletion nrepl-client.el
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
(require 'sesman)
(require 'tramp)

(require 'cider-util)

;;; Custom

Expand Down Expand Up @@ -853,7 +854,7 @@ the corresponding type of response."
value ns out err status id)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(when (and ns (not (derived-mode-p 'clojure-mode)))
(when (and ns (not (cider-clojure-major-mode-p)))
(cider-set-buffer-ns ns))))
(cond ((and content-type content-type-handler)
(funcall content-type-handler buffer
Expand Down
Loading