clojure-ts-mode 
- Description
- Major mode for Clojure code
- Latest
- clojure-ts-mode-0.2.4snapshot0.20250326.192250.tar (.sig), 2025-Mar-26, 250 KiB
- Maintainer
- Danny Freeman <danny@dfreeman.email>
- Website
- http://github.com/clojure-emacs/clojure-ts-mode
- Browse ELPA's repository
- CGit or Gitweb
- Badge
To install this package from Emacs, use package-install
or list-packages
.
Full description
Clojure Tree-Sitter Mode
clojure-ts-mode
is an Emacs major mode that provides font-lock (syntax
highlighting), indentation, and navigation support for the
Clojure(Script) programming language, powered by the
tree-sitter-clojure
tree-sitter grammar.
Rationale
clojure-mode has served us well
for a very long time, but it suffers from a few long-standing
problems, related to
Emacs limitations baked into its design. The introduction of built-in support
for Tree-sitter in Emacs 29 presents a natural opportunity to address many of
them. Enter clojure-ts-mode
, which makes use of TreeSitter to provide:
- fast, accurate and more granular font-locking
- fast indentation
- common Emacs functionality like structured navigation,
imenu
(an outline of a source buffer), current form inference (used internally by various Emacs modes and utilities), etc
Working with TreeSitter is significantly easier than the legacy Emacs APIs for font-locking and
indentation, which makes it easier to contribute to clojure-ts-mode
, and to improve it in general.
Keep in mind that the transition to clojure-ts-mode
won't happen overnight for several reasons:
- getting to feature parity with
clojure-mode
will take some time - tools that depend on
clojure-mode
will need to be updated to work withclojure-ts-mode
- we still need to support users of older Emacs versions that don't support Tree-sitter
That's why clojure-ts-mode
is being developed independently of clojure-mode
and will one day replace it when the time is right. (e.g. 3 major Emacs version
down the road, so circa Emacs 32)
You can read more about the vision for clojure-ts-mode
here.
Current Status
[!WARNING]
This library is still under active development. Breaking changes should be expected.
The currently provided functionality should cover the needs of most Clojure programmers, but you can expect to encounter some bugs and missing functionality here and there.
Those will be addressed over the time, as more and more people use clojure-ts-mode
.
Installation
Requirements
For clojure-ts-mode
to work, you need Emacs 30+ built with TreeSitter support.
To check if your Emacs supports tree sitter run the following (e.g. by using M-:
):
(treesit-available-p)
Additionally, you'll need to have Git and some C compiler (cc
) installed and available
in your $PATH
(or Emacs's exec-path
), for clojure-ts-mode
to be able to install the required
TreeSitter grammars automatically.
[!TIP]
As the TreeSitter support in Emacs is still fairly new and under active development itself, for optimal results you should use the latest stable Emacs release or even the development version of Emacs. See the "Caveats" section for more on the subject.
Install clojure-ts-mode
[!NOTE]
That's the recommended way to install
clojure-ts-mode
.
If you have git
and a C compiler (cc
) available on your system's PATH
,
clojure-ts-mode
will install the
grammars
clojure-ts-mode is available on MElPA and NonGNU ELPA. It can be installed with
(package-install 'clojure-ts-mode)
package-vc
Emacs 29 also includes package-vc-install
, so you can run
(package-vc-install "https://github.com/clojure-emacs/clojure-ts-mode")
to install this package from source.
Manual installation
You can install it by cloning the repository and adding it to your load path.
git clone https://github.com/clojure-emacs/clojure-ts-mode.git
(add-to-list 'load-path "~/path/to/clojure-ts-mode/")
Once installed, evaluate clojure-ts-mode.el and you should be ready to go.
Install tree-sitter grammars
[!NOTE]
clojure-ts-mode
install the required grammars automatically, so for most people no manual actions will be required.
clojure-ts-mode
makes use of two TreeSitter grammars to work properly:
- The Clojure grammar, mentioned earlier
- markdown_inline, which
will be used for docstrings if available and if
clojure-ts-use-markdown-inline
is enabled.
If you have git
and a C compiler (cc
) available on your system's PATH
,
clojure-ts-mode
will install the
grammars when you first open a Clojure file and clojure-ts-ensure-grammars
is
set to t
(the default).
If clojure-ts-mode
fails to automatically install the grammar, you have the
option to install it manually, Please, refer to the installation instructions of
each required grammar and make sure you're install the versions expected. (see
clojure-ts-grammar-recipes
for details)
Configuration
To see a list of available configuration options do M-x customize-group <RET> clojure-ts
.
Most configuration changes will require reverting any active clojure-ts-mode
buffers.
Remapping of clojure-mode
buffers
By default, clojure-ts-mode
assumes command over all buffers and file extensions previously associated with clojure-mode
(and derived major modes like clojurescript-mode
). To disable this remapping, set
(setopt clojure-ts-auto-remap nil)
You can also use the commands clojure-ts-activate
/ clojure-ts-deactivate
to interactively change this behavior.
Indentation
clojure-ts-mode
currently supports 2 different indentation strategies:
semantic
, the default, which tries to match the indentation ofclojure-mode
andcljfmt
fixed
, a simple indentation strategy outlined by Tonsky in a blog post
Set the var clojure-ts-indent-style
to change it.
(setq clojure-ts-indent-style 'fixed)
[!TIP]
You can find this article comparing semantic and fixed indentation useful.
Customizing semantic indentation
The indentation of special forms and macros with bodies is controlled via
clojure-ts-semantic-indent-rules
. Nearly all special forms and built-in macros
with bodies have special indentation settings in clojure-ts-mode, which are
aligned with cljfmt indent rules. You can add/alter the indentation settings in
your personal config. Let's assume you want to indent ->>
and ->
like this:
(->> something
ala
bala
portokala)
You can do so by putting the following in your config:
(setopt clojure-ts-semantic-indent-rules '(("->" . (:block 1))
("->>" . (:block 1))))
This means that the body of the ->
/->>
is after the first argument.
The default set of rules is defined as
clojure-ts--semantic-indent-rules-defaults
, any rule can be overridden using
customization option.
There are 2 types of rules supported: :block
and :inner
, similarly to
cljfmt. If rule is defined as :block n
, n
means a number of arguments after
which begins the body. If rule is defined as :inner n
, each form in the body
is indented with 2 spaces regardless of n
value (currently all default rules
has 0 value).
For example:
- do
has a rule :block 0
.
- when
has a rule :block 1
.
- defn
and fn
have a rule :inner 0
.
Font Locking
To highlight entire rich comment
expression with the comment font face, set
(setq clojure-ts-comment-macro-font-lock-body t)
By default this is nil
, so that anything within a comment
expression is
highlighted like regular clojure code.
[!TIP]
You can customize the exact level of font-locking via the variables
treesit-font-lock-level
(the default value is 3) andtreesit-font-lock-features-list
. Check this section of the Emacs manual for more details.
Highlight markdown syntax in docstrings
By default markdown syntax is highlighted in the docstrings using
markdown_inline
grammar. To disable this feature set
(setopt clojure-ts-use-markdown-inline nil)
Navigation and Evaluation
To make forms inside of (comment ...)
forms appear as top-level forms for evaluation and navigation, set
(setq clojure-ts-toplevel-inside-comment-form t)
Fill paragraph
To change the maximal line length used by M-x prog-fill-reindent-defun
(also
bound to M-q
by default) to reformat docstrings and comments it's possible to
customize clojure-ts-fill-paragraph
variable (by default set to the value of
Emacs' fill-paragraph
value).
Every new line in the docstrings is indented by
clojure-ts-docstring-fill-prefix-width
number of spaces (set to 2 by default
which matches the clojure-mode
settings).
Migrating to clojure-ts-mode
If you are migrating to clojure-ts-mode
note that clojure-mode
is still required for cider and clj-refactor packages to work properly.
After installing the package do the following.
- Check the value of
clojure-mode-hook
and copy all relevant hooks toclojure-ts-mode-hook
.
(add-hook 'clojure-ts-mode-hook #'cider-mode)
(add-hook 'clojure-ts-mode-hook #'enable-paredit-mode)
(add-hook 'clojure-ts-mode-hook #'rainbow-delimiters-mode)
(add-hook 'clojure-ts-mode-hook #'clj-refactor-mode)
- Update
.dir-locals.el
in all of your Clojure projects to activate directory local variables inclojure-ts-mode
.
((clojure-mode
(cider-clojure-cli-aliases . ":test:repl"))
(clojure-ts-mode
(cider-clojure-cli-aliases . ":test:repl")))
Caveats
As the TreeSitter Emacs APIs are new and keep evolving there are some
differences in the behavior of clojure-ts-mode
on different Emacs versions.
Here are some notable examples:
- On Emacs 29 the parent mode is
prog-mode
, but on Emacs 30+ it's bothprog-mode
andclojure-mode
(this is very helpful when dealing withderived-mode-p
checks) - Navigation by sexp/lists might work differently on Emacs versions lower than 31. Starting with version 31, Emacs uses TreeSitter 'things' settings, if available, to rebind some commands.
Frequently Asked Questions
What clojure-mode
features are currently missing?
As of version 0.2.x, the most obvious missing feature are the various
refactoring commands in clojure-mode
.
Does clojure-ts-mode
work with CIDER?
Yes! Preliminary support for clojure-ts-mode
was released in CIDER
1.14. Make sure to
grab the latest CIDER from MELPA/GitHub. Note that clojure-mode
is still
needed for some APIs that haven't yet been ported to clojure-ts-mode
.
For now, when you take care of the keybindings for the CIDER commands you use
and ensure cider-mode
is enabled for clojure-ts-mode
buffers in your config,
most functionality should already work:
(add-hook 'clojure-ts-mode-hook #'cider-mode)
Check out this article for more details.
Does clojure-ts-mode
work with inf-clojure
?
Currently, there is an open PR adding support for inf-clojure.
License
Copyright © 2022-2025 Danny Freeman and contributors.
Distributed under the GNU General Public License; type C-h C-c to view it.
Old versions
clojure-ts-mode-0.2.4snapshot0.20250325.70315.tar.lz | 2025-Mar-25 | 44.2 KiB |
clojure-ts-mode-0.2.4snapshot0.20250310.123844.tar.lz | 2025-Mar-10 | 44.0 KiB |
clojure-ts-mode-0.2.3.0.20250308.183559.tar.lz | 2025-Mar-08 | 43.9 KiB |
clojure-ts-mode-0.2.3.0.20250304.134254.tar.lz | 2025-Mar-04 | 43.4 KiB |
clojure-ts-mode-0.2.2.0.20250303.205551.tar.lz | 2025-Mar-03 | 43.4 KiB |
clojure-ts-mode-0.2.2.0.20250216.85255.tar.lz | 2025-Feb-16 | 43.3 KiB |
clojure-ts-mode-0.2.0.0.20240215.54347.tar.lz | 2024-Feb-15 | 25.6 KiB |
clojure-ts-mode-0.2.0.0.20230924.232019.tar.lz | 2023-Sep-25 | 24.6 KiB |
clojure-ts-mode-0.1.5.0.20230924.94650.tar.lz | 2023-Sep-24 | 24.3 KiB |
clojure-ts-mode-0.1.4.0.20230829.171042.tar.lz | 2023-Aug-30 | 20.4 KiB |
News
Changelog
main (unreleased)
- #62: Define
list
"thing" to improve navigation in Emacs 31. - [#64]: Add defcustom
clojure-ts-auto-remap
to control remapping ofclojure-mode
buffers. - Improve syntax highlighting:
- Highlight metadata with single keyword with
clojure-ts-keyword-face
. - Only highlight built-ins from
clojure.core
namespace. - Highlight named lambda functions properly.
- Fix syntax highlighting for functions and vars with metadata on the previous line.
- Highlight metadata with single keyword with
- Improve semantic indentation rules to be more consistent with cljfmt.
- Introduce
clojure-ts-semantic-indent-rules
customization option.
0.2.3 (2025-03-04)
- [#38]: Add support for
in-ns
forms inclojure-ts-find-ns
. - [#46]: Fix missing
comment-add
variable inclojure-ts-mode-variables
mentioned in [#26] - Add imenu support for
deftest
definitions. - [#53]: Let
clojure-ts-mode
derive fromclojure-mode
for Emacs 30+. - [#42]: Fix imenu support for definitions with metadata.
- [#42]: Fix font locking of definitions with metadata.
- [#42]: Fix indentation of definitions with metadata.
- [#49]: Fix semantic indentation of quoted functions.
- [#58]: Add custom
fill-paragraph-function
which respects docstrings similar toclojure-mode
. - [#59]: Add customization option to disable markdown syntax highlighting in the docstrings.
0.2.2 (2024-02-16)
- [#37]: Fix derived modes broken with [#36].
0.2.1 (2024-02-14)
- [#36]: Rename all derived mode vars to match the package prefix.
clojurescript-ts-mode
->clojure-ts-clojurescript-mode
clojurec-ts-mode
->clojure-ts-clojurec-mode
clojure-dart-ts-mode
->clojure-ts-clojuredart-mode
clojure-jank-ts-mode
->clojure-ts-jank-mode
- [#30]: Add custom option
clojure-ts-toplevel-inside-comment-form
as an equivalent toclojure-toplevel-inside-comment-form
inclojure-mode
. - [#32]: Change behavior of
beginning-of-defun
andend-of-defun
to consider all Clojure sexps as defuns.
0.2.0
- Pin grammar revision in treesit-language-source-alist
- Make font lock feature list more conforming with recommendations
- (See treesit-font-lock-level documentation for more information.)
- 2225190ee57ef667d69f2cd740e0137810bc38e7
- Highlight docstrings in interface, protocol, and variable definitions
- Add support for semantic indentation (now the default)
- Highlight "`quoted-symbols` in docs strings like this."
- This feature uses a nested markdown parser. If the parser is not available this feature should be silently disabled.
- 9af0a6b35c708309acdfeb4c0c79061b0fd4eb44
- Highlight methods for
deftype
,defrecord
,defprotocol
,reify
anddefinterface
forms (#20).