Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 82df151

Browse filesBrowse files
committed
Define sexp-default thing to improve navigation in Emacs 31
1 parent 3522b57 commit 82df151
Copy full SHA for 82df151

File tree

4 files changed

+119
-3
lines changed
Filter options

4 files changed

+119
-3
lines changed

‎CHANGELOG.md

Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [#96](https://github.com/clojure-emacs/clojure-ts-mode/pull/96): Highlight function name properly in `extend-protocol` form.
66
- [#96](https://github.com/clojure-emacs/clojure-ts-mode/pull/96): Add support for extend-protocol forms to `clojure-ts-add-arity` refactoring
77
command.
8+
- Slightly improved navigation by s-expressions for Emacs 31.
89

910
## 0.4.0 (2025-05-15)
1011

‎clojure-ts-mode.el

Copy file name to clipboardExpand all lines: clojure-ts-mode.el
+23-2Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,8 @@ literals with regex grammar."
788788

789789
(defun clojure-ts--metadata-node-p (node)
790790
"Return non-nil if NODE is a Clojure metadata node."
791-
(string-equal "meta_lit" (treesit-node-type node)))
791+
(or (string-equal "meta_lit" (treesit-node-type node))
792+
(string-equal "old_meta_lit" (treesit-node-type node))))
792793

793794
(defun clojure-ts--var-node-p (node)
794795
"Return non-nil if NODE is a var (eg. #\\'foo)."
@@ -1545,10 +1546,23 @@ function literal."
15451546
"code_span")
15461547
"Nodes representing s-expressions in the `markdown-inline' parser.")
15471548

1549+
(defun clojure-ts--default-sexp-node-p (node)
1550+
"Return TRUE if point is NODE is either function literal or set or has metadata."
1551+
(or
1552+
;; Opening paren of set or function literal.
1553+
(and (eq (char-before (point)) ?\#)
1554+
(string-match-p (rx bol (or "anon_fn_lit" "set_lit") eol)
1555+
(treesit-node-type (treesit-node-parent node))))
1556+
;; Node with metadata.
1557+
(clojure-ts--metadata-node-p (treesit-node-prev-sibling node))))
1558+
15481559
(defconst clojure-ts--thing-settings
15491560
`((clojure
15501561
(sexp ,(regexp-opt clojure-ts--sexp-nodes))
15511562
(list ,(regexp-opt clojure-ts--list-nodes))
1563+
(sexp-default
1564+
;; For `C-M-f' in "#|(a)" or "#|{1 2 3}"
1565+
(,(rx (or "(" "{" "[")) . ,#'clojure-ts--default-sexp-node-p))
15521566
(text ,(regexp-opt '("comment")))
15531567
(defun ,#'clojure-ts--defun-node-p))
15541568
(when clojure-ts-use-markdown-inline
@@ -2130,7 +2144,7 @@ type, etc. See `treesit-thing-settings' for more details."
21302144
(newline-and-indent))
21312145
(when single-arity-p
21322146
(insert-pair 2 ?\( ?\))
2133-
(backward-up-list))
2147+
(forward-char -1))
21342148
(insert "([])\n")
21352149
;; Put the point between square brackets.
21362150
(down-list -2)))
@@ -2601,6 +2615,13 @@ REGEX-AVAILABLE."
26012615
0
26022616
t)
26032617

2618+
;; Improve navigation by matching parenthesis for Emacs 31+
2619+
(when (>= emacs-major-version 31)
2620+
(setq-local up-list-function
2621+
(lambda (&optional arg escape-strings no-syntax-crossing)
2622+
(let ((treesit-sexp-type-regexp 'sexp))
2623+
(treesit-up-list arg escape-strings no-syntax-crossing)))))
2624+
26042625
;; Workaround for treesit-transpose-sexps not correctly working with
26052626
;; treesit-thing-settings on Emacs 30.
26062627
;; Once treesit-transpose-sexps it working again this can be removed
+89Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
;;; clojure-ts-mode-navigation-test.el --- Clojure[TS] Mode: code navigation test suite -*- lexical-binding: t; -*-
2+
3+
;; Copyright (C) 2025 Roman Rudakov
4+
5+
;; Author: Roman Rudakov <rrudakov@fastmail.com>
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+
;; Verify that Emacs' built-in navigation commands work as expected.
23+
24+
;;; Code:
25+
26+
(require 'clojure-ts-mode)
27+
(require 'buttercup)
28+
(require 'test-helper "test/test-helper")
29+
30+
(describe "function literals"
31+
(describe "forward-sexp"
32+
(when-refactoring-with-point-it "should navigate to a closing paren if point is before an opening paren"
33+
"#|(-> (.-value (.-target %)))"
34+
"#(-> (.-value (.-target %)))|"
35+
(forward-sexp))
36+
(when-refactoring-with-point-it "should navigate to a closing paren if point is before a # character"
37+
"|#(-> (.-value (.-target %)))"
38+
"#(-> (.-value (.-target %)))|"
39+
(forward-sexp)))
40+
41+
(describe "backward-up-list"
42+
(when-refactoring-with-point-it "should navigate to the beginning of a parent expression"
43+
"#(-> |(.-value (.-target %)))"
44+
"|#(-> (.-value (.-target %)))"
45+
(backward-up-list)))
46+
47+
(describe "raise-sexp"
48+
(when-refactoring-with-point-it "should keep balanced parenthesis"
49+
"#(-> |(.-value (.-target %)))"
50+
"|(.-value (.-target %))"
51+
(raise-sexp))))
52+
53+
(describe "sets"
54+
(describe "forward-sexp"
55+
(when-refactoring-with-point-it "should navigate to a closing paren if point is before an opening paren"
56+
"#|{1 2 3}"
57+
"#{1 2 3}|"
58+
(forward-sexp))
59+
(when-refactoring-with-point-it "should navigate to a closing paren if point is before a # character"
60+
"|#{1 2 3}"
61+
"#{1 2 3}|"
62+
(forward-sexp)))
63+
64+
(describe "backward-up-list"
65+
(when-refactoring-with-point-it "should navigate to the beginning of a parent expression"
66+
"#{1 |2 3}"
67+
"|#{1 2 3}"
68+
(backward-up-list)))
69+
70+
(describe "raise-sexp"
71+
(when-refactoring-with-point-it "should not keep unwanted characters"
72+
"#{1 |2 3}"
73+
"|2"
74+
(raise-sexp))))
75+
76+
(describe "nodes with metadata"
77+
(describe "forward-sexp"
78+
(when-refactoring-with-point-it "should navigate to a closing paren if point is before an opening paren"
79+
"^String |[arg]"
80+
"^String [arg]|"
81+
(forward-sexp))
82+
;; This is not perfect, but with the current grammar we cannot handle it better.
83+
(when-refactoring-with-point-it "should naigate to a closing paren if point is before metadata"
84+
"|^String [arg]"
85+
"^String [arg]|"
86+
(forward-sexp))))
87+
88+
(provide 'clojure-ts-mode-navigation-test)
89+
;;; clojure-ts-mode-navigation-test.el ends here

‎test/samples/refactoring.clj

Copy file name to clipboardExpand all lines: test/samples/refactoring.clj
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,14 @@
7676
(def my-name "Roma")
7777

7878
(defn say-hello
79-
[]
79+
^String []
8080
(println "Hello" my-name))
8181

82+
(defn foo
83+
^{:bla "meta"}
84+
[arg]
85+
body)
86+
8287
(definline bad-sqr [x] `(* ~x ~x))
8388

8489
(defmulti service-charge (juxt account-level :tag))

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.