Skip to content

Commit b6d834b

Browse files
committed
Fix cider-find-keyword for clojure-ts-mode
1 parent 531c91e commit b6d834b

File tree

5 files changed

+143
-1
lines changed

5 files changed

+143
-1
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
- [#3777](https://github.com/clojure-emacs/cider/issues/3777): Inspector no longer displays parsed Javadoc for Java classes and members.
88

9+
### Bugs fixed
10+
11+
- `cider-find-keyword` doesn't work with `clojure-ts-mode`.
12+
913
## 1.17.1 (2025-02-25)
1014

1115
### Changes

cider-find.el

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ are disregarded."
206206
(current-point (point)))
207207
(while continue
208208
(setq found (and (search-forward-regexp kw nil 'noerror)
209-
(member 'clojure-keyword-face (text-properties-at (1- (point))))))
209+
(cider-keyword-at-point-p (1- (point)))))
210210
(setq continue (and (not found)
211211
;; if we haven't moved, there's nothing left to search:
212212
(not (equal current-point (point)))))

cider-util.el

+16
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ Setting this to nil removes the fontification restriction."
6969
"Return non-nil if current buffer is managed by a ClojureC major mode."
7070
(derived-mode-p 'clojurec-mode 'clojure-ts-clojurec-mode))
7171

72+
(defun cider-clojure-ts-mode-p ()
73+
"Return non-nil if current buffer is managed by a Clojure[TS] major mode."
74+
(derived-mode-p 'clojure-ts-mode))
75+
7276
(defun cider-util--clojure-buffers ()
7377
"Return a list of all existing `clojure-mode' buffers."
7478
(seq-filter
@@ -107,6 +111,18 @@ If BUFFER is provided act on that buffer instead."
107111
(with-current-buffer (or buffer (current-buffer))
108112
(or (cider-clojurec-major-mode-p))))
109113

114+
(defun cider-keyword-at-point-p (&optional point)
115+
"Return non-nil if POINT is in a Clojure keyword.
116+
117+
Take into consideration current major mode."
118+
(let ((pos (or point (point))))
119+
(if (and (cider-clojure-ts-mode-p)
120+
(fboundp 'clojure-ts--keyword-node-p)
121+
(fboundp 'treesit-node-parent)
122+
(fboundp 'treesit-node-at))
123+
(clojure-ts--keyword-node-p (treesit-node-parent (treesit-node-at pos)))
124+
(member 'clojure-keyword-face (text-properties-at pos)))))
125+
110126

111127
;;; Thing at point
112128

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
;;; cider-find-ts-tests.el --- -*- lexical-binding: t; -*-
2+
3+
;; Copyright (C) 2025 Roman Rudakov
4+
5+
;; Author: Roman Rudakov <[email protected]>
6+
7+
;; This program is free software; you can redistribute it and/or modify
8+
;; it under the terms of the GNU General Public License as published by
9+
;; the Free Software Foundation, either version 3 of the License, or
10+
;; (at your option) any later version.
11+
12+
;; This program is distributed in the hope that it will be useful,
13+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
;; GNU General Public License for more details.
16+
17+
;; You should have received a copy of the GNU General Public License
18+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
20+
;;; Commentary:
21+
22+
;; This is part of CIDER
23+
24+
;;; Code:
25+
26+
(require 'buttercup)
27+
(require 'cider-find)
28+
29+
(describe "cider--find-keyword-loc (TreeSitter)"
30+
(it "finds the given keyword, discarding false positives"
31+
(with-clojure-ts-buffer "(ns some.ns)
32+
;; ::foo
33+
\"::foo\"
34+
#_::foo
35+
::foobar
36+
\"
37+
::foo
38+
\"
39+
::foo
40+
more
41+
stuff"
42+
(let* ((sample-buffer (current-buffer)))
43+
(spy-on 'cider-ensure-connected :and-return-value t)
44+
(spy-on 'cider-sync-request:ns-path :and-call-fake (lambda (kw-ns _)
45+
kw-ns))
46+
(spy-on 'cider-resolve-alias :and-call-fake (lambda (_ns ns-qualifier)
47+
ns-qualifier))
48+
(spy-on 'cider-find-file :and-call-fake (lambda (kw-ns)
49+
(when (equal kw-ns "some.ns")
50+
sample-buffer)))
51+
52+
(nrepl-dbind-response (cider--find-keyword-loc "::some.ns/foo") (dest dest-point)
53+
(expect dest-point :to-equal 63)
54+
(with-current-buffer dest
55+
(goto-char dest-point)
56+
;; important - ensure that we're looking at ::foo and not ::foobar:
57+
(expect (cider-symbol-at-point 'look-back) :to-equal "::foo")))
58+
59+
(nrepl-dbind-response (cider--find-keyword-loc "::foo") (dest dest-point)
60+
(expect dest-point :to-equal 63)
61+
(with-current-buffer dest
62+
(goto-char dest-point)
63+
;; important - ensure that we're looking at ::foo and not ::foobar:
64+
(expect (cider-symbol-at-point 'look-back) :to-equal "::foo")))
65+
66+
(nrepl-dbind-response (cider--find-keyword-loc ":some.ns/foo") (dest dest-point)
67+
(expect dest-point :to-equal 63)
68+
(with-current-buffer dest
69+
(goto-char dest-point)
70+
;; important - ensure that we're looking at ::foo and not ::foobar:
71+
(expect (cider-symbol-at-point 'look-back) :to-equal "::foo")))
72+
73+
(nrepl-dbind-response (cider--find-keyword-loc "::some.ns/bar") (dest dest-point)
74+
(expect dest-point :to-equal nil))
75+
76+
(nrepl-dbind-response (cider--find-keyword-loc ":some.ns/bar") (dest dest-point)
77+
(expect dest-point :to-equal nil))
78+
79+
(expect (cider--find-keyword-loc ":foo") :to-throw 'user-error)
80+
81+
(nrepl-dbind-response (cider--find-keyword-loc ":unrelated/foo") (dest dest-point)
82+
(expect dest-point :to-equal nil))
83+
84+
(nrepl-dbind-response (cider--find-keyword-loc "::unrelated/foo") (dest dest-point)
85+
(expect dest-point :to-equal nil))))))
86+
87+
(provide 'cider-find-ts-tests)
88+
;;; cider-find-ts-tests.el ends here

test/clojure-ts-mode/cider-util-ts-tests.el

+34
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@
3232
(require 'clojure-ts-mode)
3333
(require 'cider-util)
3434

35+
(defun with-clojure-ts-buffer--go-to-point ()
36+
(when (search-forward "|" nil 'noerror)
37+
(delete-char -1)))
38+
39+
(defmacro with-clojure-ts-buffer (contents &rest body)
40+
"Execute BODY in a clojure-ts-mode buffer with CONTENTS
41+
42+
CONTENTS is a string containing an optional character `|' indicating the
43+
cursor position. If not present, the cursor is placed at the end of the
44+
buffer."
45+
(declare (indent 1))
46+
`(with-temp-buffer
47+
(delay-mode-hooks (clojure-ts-mode))
48+
(insert ,contents)
49+
(goto-char (point-min))
50+
(with-clojure-ts-buffer--go-to-point)
51+
,@body))
52+
3553
(describe "clojure-ts-mode activation"
3654
(it "test suite installs the tree-sitter-clojure grammar"
3755
(with-temp-buffer
@@ -56,4 +74,20 @@
5674
(expect (cider-clojurescript-major-mode-p) :not :to-be-truthy)
5775
(expect (cider-clojurec-major-mode-p) :to-be-truthy))))
5876

77+
(describe "cider-keyword-at-p"
78+
(it "returns `t' if in keyword"
79+
(with-clojure-ts-buffer ":he|llo"
80+
(expect (cider-keyword-at-point-p) :to-be-truthy)
81+
(expect (cider-keyword-at-point-p (point)) :to-be-truthy))
82+
(with-clojure-ts-buffer "::he|llo"
83+
(expect (cider-keyword-at-point-p) :to-be-truthy)
84+
(expect (cider-keyword-at-point-p (point)) :to-be-truthy))
85+
(with-clojure-ts-buffer ":some.names|pace/hello"
86+
(expect (cider-keyword-at-point-p) :to-be-truthy)
87+
(expect (cider-keyword-at-point-p (point)) :to-be-truthy)))
88+
(it "returns `nil' if not in keyword"
89+
(with-clojure-ts-buffer ":hello \"|World\""
90+
(expect (cider-keyword-at-point-p) :not :to-be-truthy)
91+
(expect (cider-keyword-at-point-p (point)) :not :to-be-truthy))))
92+
5993
(provide 'cider-ts-util-tests)

0 commit comments

Comments
 (0)