Tree-sitter users, I've been experiencing some odd editing-behavior the last month or so (when I switched to using tree-sitter), which I think is a result of conflicting indentation/formatting mechanisms/configs, and I'm having trouble tracking it down. (I am using DOOM personally, but I haven't been able to prove/disprove explicit relation) My only clojure-related config is as follows:
;; CIDER Configs ;;
(setq clojure-ts-toplevel-inside-comment-form t)
(setq clojure-ts-indent-style 'fixed) ; 'tonsky style'
;; HACK: fix keybindings for new clojure tree-sitter mode (possibly no longer necessary? my localleader and other binds were disappearing without this)
(after! cider
(set-keymap-parent clojure-ts-mode-map clojure-mode-map)
(set-keymap-parent clojure-ts-clojurescript-mode-map clojurescript-mode-map)
(set-keymap-parent clojure-ts-clojurec-mode-map clojurec-mode-map))
An example of the behavior I'm experiencing is below, where $ is my cursor, and I hit to begin writing a form on new line.
I would expect for my cursor to be placed in line with the other elements of the list, but its instead indented an extra space:
;; INITIAL FORM
(ns my-ns
(:require
[clojure.string :as str]
[malli.core :as m]$
[malli.transform :as mt]))
;; ---
;; AFTER
(ns my-ns
(:require
[clojure.string :as str]
[malli.core :as m
$]
[malli.transform :as mt]))
So it seems like my editor is fighting between "semantic" indents (which would indent 2 spaces from the first element in thelist) and https://tonsky.me/blog/clojurefmt/ indents (which would indent in-line with the first element, because it isn't a symbol) (the moved square-bracket is my parinfer doing its best), but I'm not sure what other config I could add/alter to assure that my editor uses tonsky-style indents.
(I've disabled electric-indent-mode to no discernible effect, and I've confirmed that clojure-ts-mode is active, and clojure-mode is not)
I do see a var called lisp-body-indent which has a value of 2, but I can't tell if that's being used by any active mode or not (`lisp-mode` is not an active minor mode).The only one well tested indentation style is semantic. Other styles might be broken due to switching to a modified grammar. I would suggest to report the issue on GitHub.
lisp-body-indent shouldn't have any effect in clojure-ts-mode.
Although, I've just quickly tested your scenario and I cannot reproduce it. I noticed that in your snippet vectors in the (:require list have wrong indentation (1 space instead of 2), so when I end up with the following results:
(ns my-ns
(:require
[clojure.string :as str]
[malli.core :as m]
|
[malli.transform :as mt]))
if the initial indentation is correct, then everything works as expected:
(ns my-ns
(:require
[clojure.string :as str]
[malli.core :as m]
|
[malli.transform :as mt]))For fixed (tonsky-style) indentation, the 1-space indentation is 'correct', according to the (entirety of the) rules below > • Multi-line lists that start with a symbol are always indented with two spaces, > • Other multi-line lists, vectors, maps and sets are aligned with the first element (1 or 2 spaces).
Maybe 🙂 But that's not how it's defined in clojure-ts-mode. Fixed style just indents everything with 2 spaces
mm, actually not exactly. If the first item is a symbol or a keyword, then children are indented with 2 spaces
(defvar clojure-ts--fixed-indent-rules
;; This is in contrast to semantic
;; fixed-indent-rules come from
`((clojure
((parent-is "source") parent-bol 0)
;; ((query "(list_lit . [(sym_lit) (kwd_lit)] _* @node)") parent 2)
;; Using the above `query' rule here doesn't always work because sometimes `node' is nil.
;; `query' requires `node' to be matched.
;; We really only care about the parent node being a function-call like list.
;; with it's first named child being a symbol
((lambda (node parent _)
(and (clojure-ts--list-node-p parent)
;; Should we also check for keyword first child, as in (:k map) calls?
(let ((first-child (treesit-node-child parent 0 t)))
(or (clojure-ts--symbol-node-p first-child)
(clojure-ts--keyword-node-p first-child)))))
parent 2)
((parent-is "vec_lit") parent 1)
((parent-is "map_lit") parent 1)
((parent-is "list_lit") parent 1)
((parent-is "set_lit") parent 2))))ok good i thought my dementia had progressed further than i originally thought
it can be easily fixed if this is wrong
I don't see any explanation regarding keywords in the git history
so maybe it was just a wrong assumption
I guess if the first element is a keyword it is also can be considered as a function call
Ah, yea I think, according to the rules-as-written, it shouldn't be indented for keyword-lead-lists, but I guess it would only come up for stuff like :require forms, and "`(:k map)`" calls as mentioned in the comment.
I apologize though, as I may have then picked a bad example to illustrate my experiences, as my behavior is not limited to this name-space-indentation-fight (I was just hoping it was the same root cause).
Another example, indicating some possible conflict between indentation/alignment systems:
$ is once again my cursor
;; INITIAL FORM
(defn kill-file [path]
(io/delete-file (io/file path))$)
When I hit enter (to add some other form below), this is what my emacs deems to be a suitable update/placement (all added whitespace appears to be real, and is not merely a display issue)
;; AFTER ``
(defn kill-file [path]
(io/delete-file (io/file path))
$ )
And when I type (, to write the new form, it auto-indents reasonably for that form, but its no longer aligned with the one above
;; AFTER `(`
(defn kill-file [path]
(io/delete-file (io/file path))
($))Is it also happening with fixed style?
indeed
I cannot reproduce it
probably some other package causes it
mm, I do suspect I have some config hidden somewhere, I've been searching variables to track it down but nothing particularly suspicious has come up
To track it down, you can try to start with emacs -q and just enable clojure-ts-mode without any other packages
You can evaluate the following in the *scratch* buffer:
(require 'package)
(package-initialize)
(require 'clojure-ts-mode)
(setopt clojure-ts-indent-style 'fixed)and then open any .clj file and try to reproduce your problems
you can also try enabling your extra packages one by one
ah this might be an artifact of using straight.el for managing my packages perhaps, as I get a No such file or directory, clojure-ts-mode error, i will need to... experiment.
I will at least file an issue regarding the keyword-lead-list indentation (where the final verdict can be decided on wrt if its desired or not)
Sounds good. I can't help with straight.el unfortunately. If you know where the clojure-ts-mode.el is located, you can just add this directory to the load-path as I have done on the screenshot.
(got it working, turning things off and on again, much appreciate the guidance @rrudakov)
Happy to help. If you find any bugs in clojure-ts-mode, please report it on GH, so they won't get lost.
(I've been DMing mr tonsky himself to confirm, before I make an uneducated PR)
I think I've pinned down the cause to something inside the lispy-mode package, which unfortunately seems to bundle quite a bit of functionality/other minor modes, but making headway thanks to you