clojure-emacs / clojure-ts-mode Goto Github PK
View Code? Open in Web Editor NEWThe next generation Clojure major mode for Emacs, powered by TreeSitter
License: GNU General Public License v3.0
The next generation Clojure major mode for Emacs, powered by TreeSitter
License: GNU General Public License v3.0
If you are in a recent enough emacs 29, then I think you can use package-vc-install
(package-vc-install "https://github.com/clojure-emacs/clojure-ts-mode")
This is what I have left to do before this is ready for general use:
This issue is for me to keep track of what needs to be done, not for gathering feedback. Anyone should feel free to open a separate issue if they have a question, bug, request, etc.
This package should be listed in the Non-GNU ELPA package repository. This will make the package easier to install for users who do not have MELPA configured.
indent-region
respects clojure-align-forms-automatically
.
indent-region
does not seem to take clojure-align-forms-automatically
set to t
into account.
/tmp/test-project
) with the following files:.dir-locals.el
((nil . ((clojure-align-forms-automatically . t))))
test.clj
(ns test)
{:a 1
:ab 2
:abc 3}
test.clj
M-x clojure-ts-mode
(unless you set major-mode-remap-alist
already to prefer it over clojure-mode
)test.clj
(I use mark-sexp
, bound to C-M-SPC
)indent-region
(either via M-x
or with C-M-\
)clojure-align-forms-automatically
clojure-mode
this works as expected, meaning I get the following:{:a 1
:ab 2
:abc 3}
clojure-ts-mode-0.1.5.0.20230915.3529
v0.0.12
GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, cairo version 1.16.0) of 2023-09-19
Commit: 7be5c8f47c9df01a5accdbf954d952b9bbe5b5f0
Ubuntu 22.04.3
Hopefully someone can reproduce this easily, if not, just close this issue . My emacs config is pretty complex, so it could be easily something else.
copy and paste this at the top of a large clojure file without any other backticks , and you see syntax color mess up
(defmacro satisfies? [c]
{:pre [(symbol? c)
(contains? (eval c) :on)]}
`[:fn {:error/message (str "should satisfy protocol " (:on ~c))}
#(clojure.core/satisfies? ~c %)])
Include here the version string displayed by M-x clojure-ts-mode-display-version
. Here's an example:
i'm on a fork... maybe that's why. but its very recent.
clojure-ts-mode (version 0.1.5)
E.g. v0.0.12
should be the latest, its rarely updated.
Please make sure you are using compatible tree-sitter grammars.
See the variable clojure-ts-grammar-recipes for the current recommend versions.
They should be installed automatically if not found.
However, some linux distributions package these same grammars and Emacs will use them if found.
If you are not sure what version you are using, try running
M-x treesit-install-language-grammar clojure y, and use the values
https://github.com/sogaiu/tree-sitter-clojure.git for the URL,
v0.0.12 for the TAG and default values for the remaining options.
Then see if the problem still persists.
29.1
using the emacs-mac build from https://github.com/railwaycat/homebrew-emacsmacport
mac
clojure-mode has done this but creating derived modes from the base clojure-mode.
There could be others for
See commit 177ac05
Bascically, as you type and hit treesit indent functionality tries to unindent everything back to 2 spaces, so it's hard to add nicer indentation inside docstrings.
(defn foo
"My docstring
I like to be indented like this
If I come out to hear, treesit indent stuff pulls me back
to this position"
...)
comment-add
is 1
in clojure-mode
1, whereas clojure-ts-mode
does not set it in clojure-ts-mode-variables
. This affects how many ;
are added when using comment-region
(see the full explanation below).
I guess it would make sense to simply reproduce clojure-mode
settings.
I can open a PR for that, if it's the case.
What do you think?
Thanks!
comment-add is a variable defined in ‘newcomment.el’.
Its value is 1
Local in buffer clojure-mode.el; global value is 0
How many more comment chars should be inserted by ‘comment-region’.
This determines the default value of the numeric argument of ‘comment-region’.
The ‘plain’ comment style doubles this value.
Method definitions in forms like defprotocol
, definterface
, deftype
, reify
, etc should have nice font locking on the method names.
I've already done some work to make docstrings and semantic indentation work properly in these forms. Taking inspiration from that prior art, it should be fairly trivial to capture these nodes in the :definition
font-lock feature.
I noticed a lot of the tree sitter repos have a dedicated queries folder,
e.g. https://github.com/helix-editor/helix/tree/master/runtime/queries/julia
Just a thought... makes it a bit more modular, and also is a possible avenue for extensions maybe, if you load them from a variety of locations found on the path.
I saw the following bit in the emacs-devel archives:
some files may consist of several parts requiring different tree-sitter
grammars. For example, a JavaScript file may have its documentation
written with jsdoc: JavaScript and jsdoc have a tree-sitter grammar
each.Is there a way to use a tree-sitter grammar in parts of the file and
another one in other parts? There could be a main grammar and secondary
grammars would be activated on some kinds of nodes of the main one.Yes, it should be possible, AFAIU. See the node "Multiple Languages"
in the ELisp manual, I believe it explains how to do what you want.
As an idea for "somewhere down the line", perhaps it would be interesting to consider the following...
Since tree-sitter-clojure can recognize regex literals, may be one could apply an appropriate regular expression grammar to highlight the portions within the double quotes.
I don't know how close this grammar is to Clojure's flavor of regex, but may be it or some appropriate modification to it (or something that inherits from it) might be used for the task.
For reference, the part of the manual being referred to in the quote above can be see in .texi
form here. I didn't manage to find an HTML version. If you've got a recent enough Emacs from the emacs-29 branch, the info may be viewable from within emacs. Worked for me anyway...
Ah sorry. May be I should have made this in the Discussions area?
As discussed in clojure-emacs/cider#3461, the https://github.com/clojure-emacs/clojure-mode/tree/master/test tests could be copied here, and then run in a CI matrix.
Note that although clojure-mode uses circleci, I'd recommend GHA more, these days.
Please use an Emacs and OS matrix similar to CIDER's.
Do feel free to disable tests that don't make sense here, or that can be left for later.
I'd suggest using the Eldev file to disable such tests, rather than deletion or commenting out. (That way one may be able to even git-clone clojure-test at a fixed tag, and run test/
verbatim).
Cheers - V
Given this code (|
being the cursor)
(comment
(+ 1 1)|)
Have an option equivalent to clojure-toplevel-inside-comment-form
so running cider-eval-defun-at-point
evals to 2
, as there is for clojure-mode
.
running cider-eval-defun-at-point
with clojure-ts-mode
evals to nil
as clojure-ts-mode
as doesn't seem to have an equivalent option to clojure-toplevel-inside-comment-form
clojure-ts-mode (version 0.2.0)
User can install clojure-ts-mode
from MELPA on emacs-29
Package cannot be installed with the error:
package-compute-transaction: This package requires Emacs version 29.1
Run M-x package-install
- clojure-ts-mode
clojure-ts-mode (version 0.1.0)
GNU Emacs 29.0.91 (build 1, aarch64-apple-darwin22.5.0, NS
Mac OS
package-vc-install
without any issues.Libraries like https://github.com/gnl/ghostwheel have a macro >defn
for defining functions, in one of my codebases i define >defn
myself, but it's implemented with malli.experimental/defn
There's no way to adjust clojure-ts-mode syntax highlighting without forking the repo, e.g.
(defconst clojure-ts--definition-keyword-regexp
(rx
line-start
(or (group (or "ns" "fn"))
(group ">def"
(+ (or alnum
;; What are valid characters for symbols? is a negative match better?
"-" "_" "!" "@" "#" "$" "%" "^" "&" "*" "|" "?" "<" ">" "+" "=" ":")))
(group "def"
(+ (or alnum
;; What are valid characters for symbols? is a negative match better?
"-" "_" "!" "@" "#" "$" "%" "^" "&" "*" "|" "?" "<" ">" "+" "=" ":"))))
line-end))
(defvar clojure-ts--function-type-regexp
(rx string-start (or ">defn" "defn" "defmethod") string-end))
There should be a general extension mechanism.
One random idea is we parse PROJECT/.clj-kondo/** edn files for :lint-as, e.g.
:lint-as {
mynamespace/>defn schema.core/defn
richelieu.core/defadvice clojure.core/defn
}
Although doing this the proper way would probably add too much complexity.
I get No comment syntax is defined. Use:
in the minibuffer when invoking comment-region
.
I don't know if the treesit stuff will somehow make this all work via some clever means (or if there's already a way), but for the moment the traditional method of:
(setq-local comment-start ";")
in an appropriate location within the define-derived-mode
form seems to work.
Plumatic style function syntax :-
can be found in a few libraries
https://github.com/plumatic/schema#beyond-type-hints
https://github.com/metosin/malli/blob/master/docs/function-schemas.md#function-schema-metadata
https://github.com/gnl/ghostwheel
is there any desire to support this out-of-the-box? it might be challenging to add an user configuration mechanism for it , and there's not a lot of downside to understanding the optional syntax. This is a qualitatively distinct problem than supporting different function definition aliases 'defn', which is more amenable to user config.
:-
appears both to denote function return type, as well as function parameter(s) type, the only place where support needs to be added is the function return type as far as I can tell.
it's a trivial change in clojure-ts--docstring-query , I'm using this rough code right now, but probably needs a :match expression the literal :-
(defn foobar :- long?
"comment string"
[a :- long?]
:do-something)
0.2.0
30.x
Create an interactive function, called something like clojure-ts-grammar-doctor
that checks the available clojure and markdown grammars for compatibility with the current queries we issue.
This can be done by calling treesit-query-capture
and checking for errors, or perhaps treesit-query-validate
with a series of diagnostic queries that can help us narrow down what version of the grammar is loaded, and other info to see where the grammar was loaded from the file system.
These diagnostic queries should check for nodes and tree structures we depend on that may not exist in older versions of the grammars.
If the doctor function finds no issues, a nice message should be displayed in the echo area.
If the doctor does find issues, perhaps a special buffer *clojure-ts-doctor*
can be shown with details about the issues found.
A query like this
(kwd_lit (kwd_name) @capture)
Would only work on versions of tree-sitter-clojure greater than v0.0.10 and later. If a user has an older grammar clojure-ts-mode will break. If that happens the user can run clojure-ts-grammar-doctor
to get a "diagnosis" about the grammar they do have and recommendations for remedying the problem.
Given a .clj
file with the following content:
{:a :b}
With point between :a
and :b
:
{:a| :b}
If I hit C-M-t, I get:
{:b :a}
Just like clojure-mode
behaves.
Given the previous scenario, when I hit C-M-t, I get the message:
transpose-subr-1: Don’t have two things to transpose
Provided clojure-ts-mode
is installed (I installed via NonGNU ELPA):
emacs -Q
{:a :b}
:a
and :b
0.1.4
GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, cairo version 1.16.0) of 2023-08-29
Ubuntu 22.04.3
Clojure-ts-mode currently only uses a simple fixed indentation style made up of two basic rules taken from Tonsky's blog post on Clojure indentation [0].
This was a great way to get clojure-ts-mode off the ground. However, most Clojure developers are adjusted to formatting rules similar to those outlined in the Clojure Style Guide [1].
This ticket is for a feature to allow users to choose between the simple fixed indentation rules that exist now, and semantic indentation rules that match (as closely as possible) those laid out in the Clojure Style Guide.
Please, remove all of the placeholder text (the one in italics) in your final report!
emacs playground.clj
Execute the above command to open a clojure file without any problem, but got the following error:
Saying the lm-version
is a void function
Debugger entered--Lisp error: (error "Eager macro-expansion failure: (void-function lm-v...")
signal(error ("Eager macro-expansion failure: (void-function lm-v..."))
error("Eager macro-expansion failure: %S" (void-function lm-version))
internal-macroexpand-for-load((defconst clojure-ts-mode-version (eval-when-compile (lm-version (or load-file-name buf$
eval-buffer(#<buffer *load*> nil "/home/noel/.emacs.d/straight/build/clojure-ts-mode..." nil t) ; Reading at buffer$
load-with-code-conversion("/home/noel/.emacs.d/straight/build/clojure-ts-mode..." "/home/noel/.emacs.d/straight/build$
clojure-ts-mode()
I installed the mode via straight:
(straight-use-package '(clojure-ts-mode :type git :host github :repo "clojure-emacs/clojure-ts-mode"))
And use git log
to list the REV installed:
commit 2fe33b8fc2873fdad34367a2086d3d02388bc0a0 (grafted, HEAD -> main, origin/main, origin/HEAD)
clojure-ts-mode (version 0.0.1)
GNU Emacs 29.0.90 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.37, cairo version 1.17.8) of 2023-04-20
Arch Linux
As a response to my article https://metaredux.com/posts/2023/03/12/clojure-mode-meets-tree-sitter.html someone asked if it'd be possible/easy to modify the tree-sitter grammar used by clojure-ts-mode
. (e.g. teach the mode about some macros) I know that obviously they fork the grammar and build custom binaries, but I'm wondering if there's a simpler way to make some changes. I guess we should document this somewhere.
As pointed out in #27, some paths for the "Compile From Source" instructions are off for both Linux and macOS.
For example, for Linux I currently see:
mkdir -p dist
cc -c -I./src src/parser.c -o "parser.o"
cc -fPIC -shared src/parser.o -o "dist/libtree-sitter-clojure.so"
The second cc
invocation refers to a .o
that's not likely to exist from just following the instructions. Likely to lead to a better result might be:
mkdir -p dist
cc -c -I./src src/parser.c -o "src/parser.o"
cc -fPIC -shared src/parser.o -o "dist/libtree-sitter-clojure.so"
That is, have the first cc
invocation put the .o
file in the src
subdirectory.
A similar situation holds for the current macOS instructions.
One way to amend those might be:
mkdir -p dist
cc -c -I./src src/parser.c -o "src/parser.o"
cc -fPIC -shared src/parser.o -o "dist/libtree-sitter-clojure.dylib"
(setq clojure-align-forms-automatically t)
in clojure-mode.el
'indents'
{:a 1
:bbbb 2}
to
{:a 1
:bbbb 2}
We should consider having a way to support the Jank dialect of Clojure
Some interest is expressed here: jank-lang/jank#24
I would propose a new derivative mode, something like clojure-jank-ts-mode
.
Jank supports some embedded code (c++). We could work to include a nested parser for this language. Good support for this may not land until Emacs 30. Currently nested parsers have a tendency to break out of their regions.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.