Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 97bde83

Browse files
committedApr 29, 2025··
Add unwind refactoring commands
1 parent ff3969c commit 97bde83

8 files changed

+461
-40
lines changed
 

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- Syntax highlighting of built-in keywords.
1111
- Consistent indentation with regular forms.
1212
- Support for automatic aligning forms.
13+
- [#88](https://github.com/clojure-emacs/clojure-ts-mode/pull/88): Introduce `clojure-ts-unwind` and `clojure-ts-unwind-all`.
1314

1415
## 0.3.0 (2025-04-15)
1516

‎README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,28 @@ following customization:
372372
(setopt clojure-ts-outline-variant 'imenu)
373373
```
374374

375+
## Refactoring support
376+
377+
### Threading macros related features
378+
379+
`clojure-unwind`: Unwind a threaded expression. Supports both `->>`/`some->>`
380+
and `->`/`some->`.
381+
382+
`clojure-unwind-all`: Fully unwind a threaded expression removing the threading
383+
macro.
384+
385+
### Default keybindings
386+
387+
| Keybinding | Command |
388+
|:------------|:--------------------|
389+
| `C-c SPC` | `clojure-ts-align` |
390+
| `C-c C-r u` | `clojure-ts-unwind` |
391+
392+
### Customize refactoring commands prefix
393+
394+
By default prefix for all refactoring commands is `C-c C-r`. It can be changed
395+
by customizing `clojure-ts-refactor-map-prefix` variable.
396+
375397
## Migrating to clojure-ts-mode
376398

377399
If you are migrating to `clojure-ts-mode` note that `clojure-mode` is still

‎clojure-ts-mode.el

Lines changed: 195 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757

5858
(require 'treesit)
5959
(require 'align)
60+
(require 'subr-x)
6061

6162
(declare-function treesit-parser-create "treesit.c")
6263
(declare-function treesit-node-eq "treesit.c")
@@ -144,6 +145,11 @@ three or more semicolons will be treated as outline headings. If set to
144145
(const :tag "Use imenu" imenu))
145146
:package-version '(clojure-ts-mode . "0.4"))
146147

148+
(defcustom clojure-ts-refactor-map-prefix "C-c C-r"
149+
"Clojure refactor keymap prefix."
150+
:type 'string
151+
:package-version '(clojure-ts-mode . "0.4"))
152+
147153
(defcustom clojure-ts-align-reader-conditionals nil
148154
"Whether to align reader conditionals, as if they were maps."
149155
:package-version '(clojure-ts-mode . "0.4")
@@ -1691,11 +1697,199 @@ Forms between BEG and END are aligned according to
16911697
(when clojure-ts-align-forms-automatically
16921698
(clojure-ts-align beg end))))
16931699

1700+
;;; Refactoring
1701+
1702+
(defun clojure-ts--threading-sexp-node ()
1703+
"Return list node at point which is a threading expression."
1704+
(when-let* ((node-at-point (treesit-node-at (point) 'clojure t)))
1705+
;; We don't want to match `cond->' and `cond->>', so we should define a very
1706+
;; specific regexp.
1707+
(let ((sym-regex (rx bol (* "some") "->" (* ">") eol)))
1708+
(treesit-parent-until node-at-point
1709+
(lambda (node)
1710+
(and (or (clojure-ts--list-node-p node)
1711+
(clojure-ts--anon-fn-node-p node))
1712+
(let ((first-child (treesit-node-child node 0 t)))
1713+
(clojure-ts--symbol-matches-p sym-regex first-child))))
1714+
t))))
1715+
1716+
(defun clojure-ts--delete-and-extract-sexp ()
1717+
"Delete the surrounding sexp and return it."
1718+
(let* ((sexp-node (treesit-thing-at-point 'sexp 'nested))
1719+
(result (treesit-node-text sexp-node)))
1720+
(delete-region (treesit-node-start sexp-node)
1721+
(treesit-node-end sexp-node))
1722+
result))
1723+
1724+
(defun clojure-ts--ensure-parens-around-function-name ()
1725+
"Insert parens around function name if necessary."
1726+
(unless (string= (treesit-node-text (treesit-node-at (point))) "(")
1727+
(insert-parentheses 1)
1728+
(backward-up-list)))
1729+
1730+
(defun clojure-ts--multiline-sexp-p ()
1731+
"Return TRUE if s-expression at point is multiline."
1732+
(let ((sexp (treesit-thing-at-point 'sexp 'nested)))
1733+
(not (= (line-number-at-pos (treesit-node-start sexp))
1734+
(line-number-at-pos (treesit-node-end sexp))))))
1735+
1736+
(defun clojure-ts--unwind-thread-first ()
1737+
"Unwind a thread first macro once."
1738+
(let* ((threading-sexp (clojure-ts--threading-sexp-node))
1739+
(first-child-start (thread-first threading-sexp
1740+
(treesit-node-child 0 t)
1741+
(treesit-node-start)
1742+
(copy-marker))))
1743+
(save-excursion
1744+
(goto-char first-child-start)
1745+
(treesit-beginning-of-thing 'sexp -1)
1746+
(let ((contents (clojure-ts--delete-and-extract-sexp)))
1747+
(when (looking-at " *\n")
1748+
(join-line 'following))
1749+
(just-one-space)
1750+
(goto-char first-child-start)
1751+
(treesit-beginning-of-thing 'sexp -1)
1752+
(let ((multiline-p (clojure-ts--multiline-sexp-p)))
1753+
(clojure-ts--ensure-parens-around-function-name)
1754+
(down-list)
1755+
(forward-sexp)
1756+
(insert " " contents)
1757+
(when multiline-p
1758+
(insert "\n")))))))
1759+
1760+
(defun clojure-ts--unwind-thread-last ()
1761+
"Unwind a thread last macro once."
1762+
(let* ((threading-sexp (clojure-ts--threading-sexp-node))
1763+
(first-child-start (thread-first threading-sexp
1764+
(treesit-node-child 0 t)
1765+
(treesit-node-start)
1766+
(copy-marker))))
1767+
(save-excursion
1768+
(goto-char first-child-start)
1769+
(treesit-beginning-of-thing 'sexp -1)
1770+
(let ((contents (clojure-ts--delete-and-extract-sexp)))
1771+
(when (looking-at " *\n")
1772+
(join-line 'following))
1773+
(just-one-space)
1774+
(goto-char first-child-start)
1775+
(treesit-beginning-of-thing 'sexp -1)
1776+
(let ((multiline-p (clojure-ts--multiline-sexp-p)))
1777+
(clojure-ts--ensure-parens-around-function-name)
1778+
(forward-list)
1779+
(down-list -1)
1780+
(when multiline-p
1781+
(insert "\n"))
1782+
(insert " " contents))))))
1783+
1784+
(defun clojure-ts--node-threading-p (node)
1785+
"Return non-nil if NODE is a threading macro s-expression."
1786+
(and (or (clojure-ts--list-node-p node)
1787+
(clojure-ts--anon-fn-node-p node))
1788+
(let ((first-child (treesit-node-child node 0 t)))
1789+
(clojure-ts--symbol-matches-p clojure-ts--threading-macro first-child))))
1790+
1791+
(defun clojure-ts--skip-first-child (parent)
1792+
"Move point to the beginning of the first child of the PARENT node."
1793+
(thread-first parent
1794+
(treesit-node-child 1 t)
1795+
(treesit-node-start)
1796+
(goto-char)))
1797+
1798+
(defun clojure-ts--nothing-more-to-unwind ()
1799+
"Return TRUE if threading expression at point has only one argument."
1800+
(let ((threading-sexp (clojure-ts--threading-sexp-node)))
1801+
(save-excursion
1802+
(clojure-ts--skip-first-child threading-sexp)
1803+
(not (treesit-end-of-thing 'sexp 2 'restricted)))))
1804+
1805+
(defun clojure-ts--pop-out-of-threading ()
1806+
"Raise a sexp up a level to unwind a threading form."
1807+
(let ((threading-sexp (clojure-ts--threading-sexp-node)))
1808+
(save-excursion
1809+
(clojure-ts--skip-first-child threading-sexp)
1810+
(raise-sexp))))
1811+
1812+
(defun clojure-ts--fix-sexp-whitespace ()
1813+
"Fix whitespace after unwinding a threading form."
1814+
(save-excursion
1815+
(let ((beg (point)))
1816+
(treesit-end-of-thing 'sexp)
1817+
(indent-region beg (point))
1818+
(delete-trailing-whitespace beg (point)))))
1819+
1820+
(defun clojure-ts--unwind-sexps-counter ()
1821+
"Return total number of s-expressions of a threading form at point."
1822+
(if-let* ((threading-sexp (clojure-ts--threading-sexp-node)))
1823+
(save-excursion
1824+
(clojure-ts--skip-first-child threading-sexp)
1825+
(let ((n 0))
1826+
(while (treesit-end-of-thing 'sexp 1 'restricted)
1827+
(setq n (1+ n)))
1828+
n))
1829+
(user-error "No threading form to unwind at point")))
1830+
1831+
(defun clojure-ts-unwind (&optional n)
1832+
"Unwind thread at point or above point by N levels.
1833+
1834+
With universal argument \\[universal-argument], fully unwinds thread."
1835+
(interactive "P")
1836+
(setq n (cond
1837+
((equal n '(4)) (clojure-ts--unwind-sexps-counter))
1838+
(n)
1839+
(1)))
1840+
(if-let* ((threading-sexp (clojure-ts--threading-sexp-node))
1841+
(sym (thread-first threading-sexp
1842+
(treesit-node-child 0 t)
1843+
(clojure-ts--named-node-text))))
1844+
(save-excursion
1845+
(let ((beg (thread-first threading-sexp
1846+
(treesit-node-start)
1847+
(copy-marker)))
1848+
(end (thread-first threading-sexp
1849+
(treesit-node-end)
1850+
(copy-marker))))
1851+
(while (> n 0)
1852+
(cond
1853+
((string-match-p (rx bol (* "some") "->" eol) sym)
1854+
(clojure-ts--unwind-thread-first))
1855+
((string-match-p (rx bol (* "some") "->>" eol) sym)
1856+
(clojure-ts--unwind-thread-last)))
1857+
(setq n (1- n))
1858+
;; After unwinding we check if it is the last expression and maybe
1859+
;; splice it.
1860+
(when (clojure-ts--nothing-more-to-unwind)
1861+
(clojure-ts--pop-out-of-threading)
1862+
(clojure-ts--fix-sexp-whitespace)
1863+
(setq n 0)))
1864+
(indent-region beg end)
1865+
(delete-trailing-whitespace beg end)))
1866+
(user-error "No threading form to unwind at point")))
1867+
1868+
(defun clojure-ts-unwind-all ()
1869+
"Fully unwind thread at point or above point."
1870+
(interactive)
1871+
(clojure-ts-unwind '(4)))
1872+
1873+
(defvar clojure-ts-refactor-map
1874+
(let ((map (make-sparse-keymap)))
1875+
(keymap-set map "C-u" #'clojure-ts-unwind)
1876+
(keymap-set map "u" #'clojure-ts-unwind)
1877+
map)
1878+
"Keymap for `clojure-ts-mode' refactoring commands.")
1879+
16941880
(defvar clojure-ts-mode-map
16951881
(let ((map (make-sparse-keymap)))
16961882
;;(set-keymap-parent map clojure-mode-map)
16971883
(keymap-set map "C-c SPC" #'clojure-ts-align)
1698-
map))
1884+
(keymap-set map clojure-ts-refactor-map-prefix clojure-ts-refactor-map)
1885+
(easy-menu-define clojure-ts-mode-menu map "Clojure[TS] Mode Menu"
1886+
'("Clojure"
1887+
["Align expression" clojure-ts-align]
1888+
("Refactor -> and ->>"
1889+
["Unwind once" clojure-ts-unwind]
1890+
["Fully unwind a threading macro" clojure-ts-unwind-all])))
1891+
map)
1892+
"Keymap for `clojure-ts-mode'.")
16991893

17001894
(defvar clojure-ts-clojurescript-mode-map
17011895
(let ((map (make-sparse-keymap)))

‎test/clojure-ts-mode-font-lock-test.el

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434
(declare (debug t)
3535
(indent 1))
3636
`(with-clojure-ts-buffer ,content
37-
(font-lock-ensure)
38-
(goto-char (point-min))
39-
,@body))
37+
(font-lock-ensure)
38+
(goto-char (point-min))
39+
,@body))
4040

4141
(defun clojure-ts-get-face-at (start end content)
4242
"Get the face between START and END in CONTENT."
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
;;; clojure-ts-mode-refactor-threading-test.el --- clojure-ts-mode: refactor threading tests -*- lexical-binding: t; -*-
2+
3+
;; Copyright (C) 2025 Roman Rudakov
4+
5+
;; Author: Roman Rudakov <rrudakov@fastmail.com>
6+
;; Keywords:
7+
8+
;; This program is free software; you can redistribute it and/or modify
9+
;; it under the terms of the GNU General Public License as published by
10+
;; the Free Software Foundation, either version 3 of the License, or
11+
;; (at your option) any later version.
12+
13+
;; This program is distributed in the hope that it will be useful,
14+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
;; GNU General Public License for more details.
17+
18+
;; You should have received a copy of the GNU General Public License
19+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
21+
;;; Commentary:
22+
23+
;; The threading refactoring code is adapted from clojure-mode.el.
24+
25+
;;; Code:
26+
27+
(require 'clojure-ts-mode)
28+
(require 'buttercup)
29+
(require 'test-helper "test/test-helper")
30+
31+
(describe "clojure-unwind"
32+
33+
(when-refactoring-it "should unwind -> one step"
34+
"(-> {}
35+
(assoc :key \"value\")
36+
(dissoc :lock))"
37+
38+
"(-> (assoc {} :key \"value\")
39+
(dissoc :lock))"
40+
41+
(clojure-ts-unwind))
42+
43+
(when-refactoring-it "should unwind -> completely"
44+
"(-> {}
45+
(assoc :key \"value\")
46+
(dissoc :lock))"
47+
48+
"(dissoc (assoc {} :key \"value\") :lock)"
49+
50+
(clojure-ts-unwind)
51+
(clojure-ts-unwind))
52+
53+
(when-refactoring-it "should unwind ->> one step"
54+
"(->> [1 2 3 4 5]
55+
(filter even?)
56+
(map square))"
57+
58+
"(->> (filter even? [1 2 3 4 5])
59+
(map square))"
60+
61+
(clojure-ts-unwind))
62+
63+
(when-refactoring-it "should unwind ->> completely"
64+
"(->> [1 2 3 4 5]
65+
(filter even?)
66+
(map square))"
67+
68+
"(map square (filter even? [1 2 3 4 5]))"
69+
70+
(clojure-ts-unwind)
71+
(clojure-ts-unwind))
72+
73+
(when-refactoring-it "should unwind N steps with numeric prefix arg"
74+
"(->> [1 2 3 4 5]
75+
(filter even?)
76+
(map square)
77+
sum)"
78+
79+
"(->> (map square (filter even? [1 2 3 4 5]))
80+
sum)"
81+
82+
(clojure-ts-unwind 2))
83+
84+
(when-refactoring-it "should unwind completely with universal prefix arg"
85+
"(->> [1 2 3 4 5]
86+
(filter even?)
87+
(map square)
88+
sum)"
89+
90+
"(sum (map square (filter even? [1 2 3 4 5])))"
91+
92+
(clojure-ts-unwind '(4)))
93+
94+
(when-refactoring-it "should unwind correctly when multiple ->> are present on same line"
95+
"(->> 1 inc) (->> [1 2 3 4 5]
96+
(filter even?)
97+
(map square))"
98+
99+
"(->> 1 inc) (map square (filter even? [1 2 3 4 5]))"
100+
101+
(clojure-ts-unwind)
102+
(clojure-ts-unwind))
103+
104+
(when-refactoring-it "should unwind with function name"
105+
"(->> [1 2 3 4 5]
106+
sum
107+
square)"
108+
109+
"(->> (sum [1 2 3 4 5])
110+
square)"
111+
112+
(clojure-ts-unwind))
113+
114+
(when-refactoring-it "should unwind with function name twice"
115+
"(-> [1 2 3 4 5]
116+
sum
117+
square)"
118+
119+
"(square (sum [1 2 3 4 5]))"
120+
121+
(clojure-ts-unwind)
122+
(clojure-ts-unwind))
123+
124+
(when-refactoring-it "should thread-issue-6-1"
125+
"(defn plus [a b]
126+
(-> a (+ b)))"
127+
128+
"(defn plus [a b]
129+
(+ a b))"
130+
131+
(clojure-ts-unwind))
132+
133+
(when-refactoring-it "should thread-issue-6-2"
134+
"(defn plus [a b]
135+
(->> a (+ b)))"
136+
137+
"(defn plus [a b]
138+
(+ b a))"
139+
140+
(clojure-ts-unwind))
141+
142+
(when-refactoring-it "should unwind some->"
143+
"(some-> {:a 1}
144+
(find :b)
145+
val
146+
(+ 5))"
147+
148+
"(some-> (val (find {:a 1} :b))
149+
(+ 5))"
150+
151+
(clojure-ts-unwind)
152+
(clojure-ts-unwind))
153+
154+
(when-refactoring-it "should unwind some->>"
155+
"(some->> :b
156+
(find {:a 1}) val
157+
(+ 5))"
158+
159+
"(some->> (val (find {:a 1} :b))
160+
(+ 5))"
161+
162+
(clojure-ts-unwind)
163+
(clojure-ts-unwind)))
164+
165+
(provide 'clojure-ts-mode-refactor-threading-test)
166+
;;; clojure-ts-mode-refactor-threading-test.el ends here

‎test/clojure-ts-mode-util-test.el

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -31,101 +31,101 @@
3131
(describe "clojure-ts-find-ns"
3232
(it "should find common namespace declarations"
3333
(with-clojure-ts-buffer "(ns foo)"
34-
(expect (clojure-ts-find-ns) :to-equal "foo"))
34+
(expect (clojure-ts-find-ns) :to-equal "foo"))
3535
(with-clojure-ts-buffer "(ns
3636
foo)"
37-
(expect (clojure-ts-find-ns) :to-equal "foo"))
37+
(expect (clojure-ts-find-ns) :to-equal "foo"))
3838
(with-clojure-ts-buffer "(ns foo.baz)"
39-
(expect (clojure-ts-find-ns) :to-equal "foo.baz"))
39+
(expect (clojure-ts-find-ns) :to-equal "foo.baz"))
4040
(with-clojure-ts-buffer "(ns ^:bar foo)"
41-
(expect (clojure-ts-find-ns) :to-equal "foo"))
41+
(expect (clojure-ts-find-ns) :to-equal "foo"))
4242
(with-clojure-ts-buffer "(ns ^:bar ^:baz foo)"
43-
(expect (clojure-ts-find-ns) :to-equal "foo")))
43+
(expect (clojure-ts-find-ns) :to-equal "foo")))
4444

4545
(it "should find namespaces with spaces before ns form"
4646
(with-clojure-ts-buffer " (ns foo)"
47-
(expect (clojure-ts-find-ns) :to-equal "foo")))
47+
(expect (clojure-ts-find-ns) :to-equal "foo")))
4848

4949
(it "should skip namespaces within any comment forms"
5050
(with-clojure-ts-buffer "(comment
5151
(ns foo))"
52-
(expect (clojure-ts-find-ns) :to-equal nil))
52+
(expect (clojure-ts-find-ns) :to-equal nil))
5353
(with-clojure-ts-buffer " (ns foo)
5454
(comment
5555
(ns bar))"
56-
(expect (clojure-ts-find-ns) :to-equal "foo"))
56+
(expect (clojure-ts-find-ns) :to-equal "foo"))
5757
(with-clojure-ts-buffer " (comment
5858
(ns foo))
5959
(ns bar)
6060
(comment
6161
(ns baz))"
62-
(expect (clojure-ts-find-ns) :to-equal "bar")))
62+
(expect (clojure-ts-find-ns) :to-equal "bar")))
6363

6464
(it "should find namespace declarations with nested metadata and docstrings"
6565
(with-clojure-ts-buffer "(ns ^{:bar true} foo)"
66-
(expect (clojure-ts-find-ns) :to-equal "foo"))
66+
(expect (clojure-ts-find-ns) :to-equal "foo"))
6767
(with-clojure-ts-buffer "(ns #^{:bar true} foo)"
68-
(expect (clojure-ts-find-ns) :to-equal "foo"))
68+
(expect (clojure-ts-find-ns) :to-equal "foo"))
6969
(with-clojure-ts-buffer "(ns #^{:fail {}} foo)"
70-
(expect (clojure-ts-find-ns) :to-equal "foo"))
70+
(expect (clojure-ts-find-ns) :to-equal "foo"))
7171
(with-clojure-ts-buffer "(ns ^{:fail2 {}} foo.baz)"
72-
(expect (clojure-ts-find-ns) :to-equal "foo.baz"))
72+
(expect (clojure-ts-find-ns) :to-equal "foo.baz"))
7373
(with-clojure-ts-buffer "(ns ^{} foo)"
74-
(expect (clojure-ts-find-ns) :to-equal "foo"))
74+
(expect (clojure-ts-find-ns) :to-equal "foo"))
7575
(with-clojure-ts-buffer "(ns ^{:skip-wiki true}
7676
aleph.netty)"
77-
(expect (clojure-ts-find-ns) :to-equal "aleph.netty"))
77+
(expect (clojure-ts-find-ns) :to-equal "aleph.netty"))
7878
(with-clojure-ts-buffer "(ns ^{:foo {:bar :baz} :fake (ns in.meta)} foo
7979
\"docstring
8080
(ns misleading)\")"
81-
(expect (clojure-ts-find-ns) :to-equal "foo")))
81+
(expect (clojure-ts-find-ns) :to-equal "foo")))
8282

8383
(it "should support non-alphanumeric characters"
8484
(with-clojure-ts-buffer "(ns foo+)"
85-
(expect (clojure-ts-find-ns) :to-equal "foo+"))
85+
(expect (clojure-ts-find-ns) :to-equal "foo+"))
8686
(with-clojure-ts-buffer "(ns bar**baz$-_quux)"
87-
(expect (clojure-ts-find-ns) :to-equal "bar**baz$-_quux"))
87+
(expect (clojure-ts-find-ns) :to-equal "bar**baz$-_quux"))
8888
(with-clojure-ts-buffer "(ns aoc-2019.puzzles.day14)"
89-
(expect (clojure-ts-find-ns) :to-equal "aoc-2019.puzzles.day14")))
89+
(expect (clojure-ts-find-ns) :to-equal "aoc-2019.puzzles.day14")))
9090

9191
(it "should support in-ns forms"
9292
(with-clojure-ts-buffer "(in-ns 'bar.baz)"
93-
(expect (clojure-ts-find-ns) :to-equal "bar.baz")))
93+
(expect (clojure-ts-find-ns) :to-equal "bar.baz")))
9494

9595
(it "should take the first ns instead of closest unlike clojure-mode"
9696
(with-clojure-ts-buffer " (ns foo1)
9797
9898
(ns foo2)"
99-
(expect (clojure-ts-find-ns) :to-equal "foo1"))
99+
(expect (clojure-ts-find-ns) :to-equal "foo1"))
100100
(with-clojure-ts-buffer-point " (in-ns foo1)
101101
(ns 'foo2)
102102
(in-ns 'foo3)
103103
|
104104
(ns foo4)"
105-
(expect (clojure-ts-find-ns) :to-equal "foo3"))
105+
(expect (clojure-ts-find-ns) :to-equal "foo3"))
106106
(with-clojure-ts-buffer "(ns foo)
107107
(ns-unmap *ns* 'map)
108108
(ns.misleading 1 2 3)"
109-
(expect (clojure-ts-find-ns) :to-equal "foo")))
109+
(expect (clojure-ts-find-ns) :to-equal "foo")))
110110

111111
(it "should skip leading garbage"
112112
(with-clojure-ts-buffer " (ns foo)"
113-
(expect (clojure-ts-find-ns) :to-equal "foo"))
113+
(expect (clojure-ts-find-ns) :to-equal "foo"))
114114
(with-clojure-ts-buffer "1(ns foo)"
115-
(expect (clojure-ts-find-ns) :to-equal "foo"))
115+
(expect (clojure-ts-find-ns) :to-equal "foo"))
116116
(with-clojure-ts-buffer "1 (ns foo)"
117-
(expect (clojure-ts-find-ns) :to-equal "foo"))
117+
(expect (clojure-ts-find-ns) :to-equal "foo"))
118118
(with-clojure-ts-buffer "1
119119
(ns foo)"
120-
(expect (clojure-ts-find-ns) :to-equal "foo"))
120+
(expect (clojure-ts-find-ns) :to-equal "foo"))
121121
(with-clojure-ts-buffer "[1]
122122
(ns foo)"
123-
(expect (clojure-ts-find-ns) :to-equal "foo"))
123+
(expect (clojure-ts-find-ns) :to-equal "foo"))
124124
(with-clojure-ts-buffer "[1] (ns foo)"
125-
(expect (clojure-ts-find-ns) :to-equal "foo"))
125+
(expect (clojure-ts-find-ns) :to-equal "foo"))
126126
(with-clojure-ts-buffer "[1](ns foo)"
127-
(expect (clojure-ts-find-ns) :to-equal "foo"))
127+
(expect (clojure-ts-find-ns) :to-equal "foo"))
128128
(with-clojure-ts-buffer "(ns)(ns foo)"
129-
(expect (clojure-ts-find-ns) :to-equal "foo"))
129+
(expect (clojure-ts-find-ns) :to-equal "foo"))
130130
(with-clojure-ts-buffer "(ns 'foo)(ns bar)"
131-
(expect (clojure-ts-find-ns) :to-equal "bar"))))
131+
(expect (clojure-ts-find-ns) :to-equal "bar"))))

‎test/samples/refactoring.clj

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
(ns refactoring)
2+
3+
;;; Threading
4+
5+
(-> ;; This is comment
6+
(foo)
7+
;; Another comment
8+
(bar true
9+
;; Hello
10+
false)
11+
(baz))
12+
13+
14+
(let [some (->> yeah
15+
(world foo
16+
false)
17+
hello)])
18+
19+
(->> coll
20+
(filter identity)
21+
(map :id)
22+
(map :name))
23+
24+
(some->> coll
25+
(filter identity)
26+
(map :id)
27+
(map :name))
28+
29+
(defn plus [a b]
30+
(-> a (+ b)))
31+
32+
(some->> :b
33+
(find {:a 1}) val
34+
(+ 5))
35+
36+
(some->> (val (find {:a 1} :b))
37+
(+ 5))

‎test/test-helper.el

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ and point left there."
4242
(declare (indent 2))
4343
`(progn
4444
(with-clojure-ts-buffer ,text
45-
(goto-char (point-min))
46-
(re-search-forward "|")
47-
(delete-char -1)
48-
,@body)))
45+
(goto-char (point-min))
46+
(re-search-forward "|")
47+
(delete-char -1)
48+
,@body)))
4949

5050
(defun clojure-ts--s-index-of (needle s &optional ignore-case)
5151
"Returns first index of NEEDLE in S, or nil.
@@ -108,4 +108,5 @@ Removes the temp directory at the end of evaluation."
108108
,@body)
109109
(delete-directory ,temp-dir t))))
110110

111+
(provide 'test-helper)
111112
;;; test-helper.el ends here

0 commit comments

Comments
 (0)
Please sign in to comment.