Skip to content

Commit 8f0c99e

Browse files
committed
Enhance add arity refactoring.
Support reader conditionals, letfn, defprotocol, reify and proxy in addition to defn.
1 parent 721287c commit 8f0c99e

File tree

3 files changed

+181
-23
lines changed

3 files changed

+181
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## master (unreleased)
44

5+
### Bugs fixed
6+
7+
* Enhance add arity refactoring to support reader conditionals, letfn, defprotocol, reify and proxy.
8+
59
## 5.11.0 (2019-07-16)
610

711
### New features

clojure-mode.el

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2736,37 +2736,76 @@ With a numeric prefix argument the let is introduced N lists up."
27362736
(clojure--rename-ns-alias-internal current-alias new-alias))
27372737
(message "Cannot find namespace alias: '%s'" current-alias))))))
27382738

2739-
;;;###autoload
2740-
(defun clojure-add-arity ()
2741-
"Add an arity to a function."
2742-
(interactive)
2743-
(let ((end (save-excursion (end-of-defun)
2744-
(point)))
2745-
(beg (progn (beginning-of-defun)
2746-
(point))))
2739+
(defun clojure-add-arity-defprotocol-internal ()
2740+
"Add an arity to a signature inside a defprotocol.
2741+
2742+
Assumes cursor is at beginning of signature."
2743+
(re-search-forward "\\[")
2744+
(save-excursion (insert "] [")))
2745+
2746+
(defun clojure-add-arity-reify-internal ()
2747+
"Add an arity to a function inside a reify.
2748+
2749+
Assumes cursor is at beginning of function."
2750+
(re-search-forward "\\(\\w+ \\)")
2751+
(insert "[")
2752+
(save-excursion (insert "])\n(" (match-string 0))))
2753+
2754+
(defun clojure-add-arity-internal ()
2755+
"Add an arity to a function.
2756+
2757+
Assumes cursor is at beginning of function."
2758+
(let ((beg-line (what-line))
2759+
(end (save-excursion (forward-sexp)
2760+
(point))))
27472761
(down-list 2)
27482762
(when (looking-back "{" 1) ;; skip metadata if present
27492763
(up-list)
27502764
(down-list))
27512765
(cond
2752-
((looking-back "(" 1) ;; multi-arity defn
2766+
((looking-back "(" 1) ;; multi-arity fn
27532767
(insert "[")
2754-
(save-excursion (insert "])\n("))
2755-
(indent-region beg end))
2756-
((looking-back "\\[" 1) ;; single-arity defn
2757-
(let* ((bol (save-excursion (beginning-of-line) (point)))
2758-
(same-line (save-excursion (re-search-backward "defn" bol t)))
2759-
(new-arity-text (concat (when same-line "\n") "([])\n[")))
2760-
(re-search-backward " +\\[")
2761-
(replace-match new-arity-text)
2768+
(save-excursion (insert "])\n(")))
2769+
((looking-back "\\[" 1) ;; single-arity fn
2770+
(let* ((same-line (string= beg-line (what-line)))
2771+
(new-arity-text (concat (when same-line "\n") "([")))
27622772
(save-excursion
2763-
(end-of-defun)
2764-
(re-search-backward ")")
2773+
(goto-char end)
27652774
(insert ")"))
2766-
(left-char)
2767-
(insert "(")
2768-
(indent-region beg end)
2769-
(left-char 6))))))
2775+
2776+
(re-search-backward " +\\[")
2777+
(replace-match new-arity-text)
2778+
(save-excursion (insert "])\n([")))))))
2779+
2780+
;;;###autoload
2781+
(defun clojure-add-arity ()
2782+
"Add an arity to a function."
2783+
(interactive)
2784+
(let ((original-pos (point))
2785+
(n 0))
2786+
(while (not (looking-at-p "(\\(defn\\|letfn\\|defprotocol\\|reify\\|proxy\\)"))
2787+
(setq n (1+ n))
2788+
(backward-up-list 1 t))
2789+
(let ((beg (point))
2790+
(end-marker (make-marker))
2791+
(end (save-excursion (forward-sexp)
2792+
(point))))
2793+
(set-marker end-marker end)
2794+
(cond
2795+
((looking-at-p "(defn") (clojure-add-arity-internal))
2796+
((looking-at-p "(letfn") (progn (goto-char original-pos)
2797+
(backward-up-list (- n 2) t)
2798+
(clojure-add-arity-internal)))
2799+
((looking-at-p "(proxy") (progn (goto-char original-pos)
2800+
(backward-up-list (- n 1) t)
2801+
(clojure-add-arity-internal)))
2802+
((looking-at-p "(defprotocol") (progn (goto-char original-pos)
2803+
(backward-up-list (- n 1) t)
2804+
(clojure-add-arity-defprotocol-internal)))
2805+
((looking-at-p "(reify") (progn (goto-char original-pos)
2806+
(backward-up-list (- n 1) t)
2807+
(clojure-add-arity-reify-internal))))
2808+
(indent-region beg end-marker))))
27702809

27712810

27722811
;;; ClojureScript

test/clojure-mode-refactor-add-arity-test.el

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,121 @@ DESCRIPTION is a string with the description of the spec."
149149
([arg]
150150
body))"
151151

152+
(clojure-add-arity))
153+
154+
(when-refactoring-with-point-it "should handle a defn inside a reader conditional"
155+
"#?(:clj
156+
(defn foo
157+
\"some docstring\"
158+
^{:bla \"meta\"}
159+
|([arg]
160+
body)))"
161+
162+
"#?(:clj
163+
(defn foo
164+
\"some docstring\"
165+
^{:bla \"meta\"}
166+
([|])
167+
([arg]
168+
body)))"
169+
170+
(clojure-add-arity))
171+
172+
(when-refactoring-with-point-it "should handle a defn inside a reader conditional with 2 platform tags"
173+
"#?(:clj
174+
(defn foo
175+
\"some docstring\"
176+
^{:bla \"meta\"}
177+
|([arg]
178+
body))
179+
:cljs
180+
(defn foo
181+
\"some docstring\"
182+
^{:bla \"meta\"}
183+
([arg]
184+
body)))"
185+
186+
"#?(:clj
187+
(defn foo
188+
\"some docstring\"
189+
^{:bla \"meta\"}
190+
([|])
191+
([arg]
192+
body))
193+
:cljs
194+
(defn foo
195+
\"some docstring\"
196+
^{:bla \"meta\"}
197+
([arg]
198+
body)))"
199+
200+
(clojure-add-arity))
201+
202+
(when-refactoring-with-point-it "should handle a single-arity fn inside a letfn"
203+
"(letfn [(foo [x]
204+
bo|dy)]
205+
(foo 3))"
206+
207+
"(letfn [(foo
208+
([|])
209+
([x]
210+
body))]
211+
(foo 3))"
212+
213+
(clojure-add-arity))
214+
215+
(when-refactoring-with-point-it "should handle a multi-arity fn inside a letfn"
216+
"(letfn [(foo
217+
([x]
218+
body)
219+
|([x y]
220+
body))]
221+
(foo 3))"
222+
223+
"(letfn [(foo
224+
([|])
225+
([x]
226+
body)
227+
([x y]
228+
body))]
229+
(foo 3))"
230+
231+
(clojure-add-arity))
232+
233+
(when-refactoring-with-point-it "should handle a proxy"
234+
"(proxy [Foo] []
235+
(bar [arg]
236+
body|))"
237+
238+
"(proxy [Foo] []
239+
(bar
240+
([|])
241+
([arg]
242+
body)))"
243+
244+
(clojure-add-arity))
245+
246+
(when-refactoring-with-point-it "should handle a defprotocol"
247+
"(defprotocol Foo
248+
\"some docstring\"
249+
(bar [arg] [x |y] \"some docstring\"))"
250+
251+
"(defprotocol Foo
252+
\"some docstring\"
253+
(bar [|] [arg] [x y] \"some docstring\"))"
254+
255+
(clojure-add-arity))
256+
257+
(when-refactoring-with-point-it "should handle a reify"
258+
"(reify Foo
259+
(bar [arg] body)
260+
(blahs [arg]| body))"
261+
262+
"(reify Foo
263+
(bar [arg] body)
264+
(blahs [|])
265+
(blahs [arg] body))"
266+
152267
(clojure-add-arity)))
153268

154269
(provide 'clojure-mode-refactor-add-arity-test)

0 commit comments

Comments
 (0)