Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
- [#172](https://github.com/clojure-emacs/clojure-ts-mode/pull/172): Fix `clojure-ts-outline-variant` and `clojure-ts-completion-enabled` being ignored in `.dir-locals.el`.
- [#172](https://github.com/clojure-emacs/clojure-ts-mode/pull/172): Stop marking `clojure-ts-ensure-grammars`, `clojure-ts-auto-remap` and the options that turn the embedded parsers on and off as safe in `.dir-locals.el`, where they have no effect.
- [#169](https://github.com/clojure-emacs/clojure-ts-mode/pull/169): Add `clojure-ts-remove-unused-keys` (`C-c C-r k`), which removes the names the top-level form at point destructures from maps but never uses, along with their `:or` defaults.
- [#164](https://github.com/clojure-emacs/clojure-ts-mode/pull/164): Support `setopt-local` for `clojure-ts-indent-style`, `clojure-ts-extra-def-forms` and `clojure-ts-comment-macro-font-lock-body`, which Emacs 31 refused to set locally and Emacs 32 warned about in `.dir-locals.el`.

## 0.6.0 (2025-12-02)

Expand Down
46 changes: 19 additions & 27 deletions clojure-ts-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -834,17 +834,16 @@ OVERRIDE, START and END are passed to `treesit-fontify-with-override'."
marker: "@" @font-lock-punctuation-face))))

(defun clojure-ts--set-font-lock-option (symbol value &optional scope)
"Set the default value of SYMBOL to VALUE and refontify Clojure buffers.

When SCOPE is `buffer-local' (Emacs's `setopt-local' / dir-locals path),
set VALUE buffer-locally and recompute the cache for the current buffer
only. Otherwise set the global SYMBOL value and recompute the cache in
every `clojure-ts-mode' buffer from that buffer's own effective value,
so a buffer carrying a local override is left untouched.
"Set SYMBOL to VALUE and refontify Clojure buffers.
When SCOPE is `buffer-local', as with `setopt-local', set VALUE in the
current buffer and refontify only that one.

NOTE: This function is not meant to be called directly."
(if (eq scope 'buffer-local)
(set (make-local-variable symbol) value)
(progn
(set (make-local-variable symbol) value)
(when (derived-mode-p 'clojure-ts-mode)
(font-lock-flush)))
(set-default-toplevel-value symbol value)
(dolist (buf (match-buffers '(derived-mode . clojure-ts-mode)))
(with-current-buffer buf
Expand Down Expand Up @@ -1202,18 +1201,18 @@ See `clojure-ts--standard-definition-node-name' for the implementation used.")
(- (match-end 1) (match-beginning 1))))

(defun clojure-ts--set-indent-style (symbol value &optional scope)
"Set the default value of SYMBOL to VALUE and reconfigure Clojure buffers.
A buffer with its own indentation style keeps it.

When SCOPE is `buffer-local' (Emacs's `setopt-local' / dir-locals path),
set VALUE buffer-locally and recompute the cache for the current buffer
only. Otherwise set the global SYMBOL value and recompute the cache in
every `clojure-ts-mode' buffer from that buffer's own effective value,
so a buffer carrying a local override is left untouched.
"Set SYMBOL to VALUE and reconfigure Clojure buffers.
A buffer with its own indentation style keeps it. When SCOPE is
`buffer-local', as with `setopt-local', set VALUE in the current buffer
and reconfigure only that one.

NOTE: This function is not meant to be called directly."
(if (eq scope 'buffer-local)
(set (make-local-variable symbol) value)
(progn
(set (make-local-variable symbol) value)
(when (derived-mode-p 'clojure-ts-mode)
(setq-local treesit-simple-indent-rules
(clojure-ts--configured-indent-rules))))
(set-default-toplevel-value symbol value)
(dolist (buf (match-buffers '(derived-mode . clojure-ts-mode)))
(with-current-buffer buf
Expand Down Expand Up @@ -1836,12 +1835,6 @@ children of the rich comment form are also considered as top-level."
parent-source-p))
parent-source-p)))

(defconst clojure-ts--markdown-inline-sexp-nodes
'("inline_link" "full_reference_link" "collapsed_reference_link"
"uri_autolink" "email_autolink" "shortcut_link" "image"
"code_span")
"Nodes representing s-expressions in the `markdown-inline' parser.")

(defun clojure-ts--default-sexp-node-p (node)
"Return non-nil if point is after the # marker of set or function literal NODE."
(and (eq (char-before) ?\#)
Expand Down Expand Up @@ -3921,8 +3914,6 @@ REGEX-AVAILABLE."
(defun clojure-ts--apply-local-variables ()
"Redo the parts of the setup that depend on file or directory-local variables.
Those are set after the major mode."
(when (local-variable-p 'clojure-ts-align-forms-automatically)
(setq-local indent-region-function #'clojure-ts-indent-region))
(when (local-variable-p 'clojure-ts-indent-style)
(setq-local treesit-simple-indent-rules (clojure-ts--configured-indent-rules)))
(when (local-variable-p 'clojure-ts-outline-variant)
Expand All @@ -3935,8 +3926,9 @@ Those are set after the major mode."
The modes that embed another language run the setup again once they've
added its parser, so this is used for every run."
(treesit-major-mode-setup)
(when clojure-ts-align-forms-automatically
(setq-local indent-region-function #'clojure-ts-indent-region))
;; It checks `clojure-ts-align-forms-automatically' when it runs, so that
;; turning the option on later, or in .dir-locals.el, works.
(setq-local indent-region-function #'clojure-ts-indent-region)
;; Workaround for treesit-transpose-sexps not correctly working with
;; treesit-thing-settings on Emacs 30.
;; Once treesit-transpose-sexps is working again this can be removed
Expand Down
28 changes: 28 additions & 0 deletions test/clojure-ts-mode-config-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,34 @@ y)
clojure-ts-comment-macro-font-lock-body nil
clojure-ts-indent-style 'semantic))))))

(describe "options set with setopt-local"
(it "should apply to the current buffer, and only to that one"
(assume (fboundp 'setopt-local) "setopt-local needs Emacs 31")
(with-clojure-ts-buffer clojure-ts-test--options-source
(with-clojure-ts-buffer clojure-ts-test--options-source
(font-lock-ensure)
(spy-on 'font-lock-flush :and-call-through)
(setopt-local clojure-ts-extra-def-forms '("defelem")
clojure-ts-comment-macro-font-lock-body t
clojure-ts-indent-style 'fixed)
;; `font-lock-ensure' refontifies everything in batch mode, so it
;; can't tell whether the old faces would have stayed on screen.
(expect 'font-lock-flush :to-have-been-called)
(font-lock-ensure)
(expect (clojure-ts-test--face-at "defelem")
:to-equal 'font-lock-keyword-face)
(expect (clojure-ts-test--face-at "(foo)")
:to-equal 'font-lock-comment-face)
(indent-region (point-min) (point-max))
(expect (buffer-string) :to-match "(foo\n bar)"))
(font-lock-ensure)
(expect (clojure-ts-test--face-at "defelem")
:not :to-equal 'font-lock-keyword-face)
(expect (clojure-ts-test--face-at "(foo)")
:not :to-equal 'font-lock-comment-face)
(indent-region (point-min) (point-max))
(expect (buffer-string) :to-match "(foo\n bar)"))))

(describe "clojure-ts-semantic-indent-rules"
(it "should apply however it's set"
(with-clojure-ts-buffer "(my-block x\ny)"
Expand Down
6 changes: 6 additions & 0 deletions test/clojure-ts-mode-indentation-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,12 @@ c)
:a 1
:bbbbb 2)"))))

(it "should align when the option is turned on after the mode starts"
(with-clojure-ts-buffer "{:a 1\n:bbb 2}"
(setq-local clojure-ts-align-forms-automatically t)
(indent-region (point-min) (point-max))
(expect (buffer-string) :to-equal "{:a 1\n :bbb 2}")))

(when-aligning-it "should handle trailing commas"
"
{:a {:a :a,
Expand Down
Loading