Skip to content

Commit f300bb7

Browse files
anthonygaleabbatsov
authored andcommitted
[Fix #410] Add refactoring: add an arity to a function.
1 parent f515f21 commit f300bb7

5 files changed

+204
-0
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
* [#496](https://github.com/clojure-emacs/clojure-mode/issues/496): Highlight `[[wikilinks]]` in comments.
88
* [#366](https://github.com/clojure-emacs/clj-refactor.el/issues/366): Add support for renaming ns aliases (`clojure-rename-ns-alias`).
9+
* [#410](https://github.com/clojure-emacs/clojure-mode/issues/410): Add support for adding an arity to a function (`clojure-add-arity`).
910

1011
### Bugs fixed
1112

Diff for: README.md

+10
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ specific `clojure-mode` release.**
3434
- [Cycling things](#cycling-things)
3535
- [Convert collection](#convert-collection)
3636
- [Let expression](#let-expression)
37+
- [Rename ns alias](#rename-ns-alias)
38+
- [Add arity to a function](#add-arity-to-a-function)
3739
- [Related packages](#related-packages)
3840
- [REPL Interaction](#repl-interaction)
3941
- [Basic REPL](#basic-repl)
@@ -319,6 +321,14 @@ a prefix argument slurp the previous n forms.
319321

320322
`paredit-convolute-sexp` is advised to replace occurrences of bound forms with their bound names when convolute is used on a let form.
321323

324+
### Rename ns alias
325+
326+
Rename an alias inside a namespace declaration.
327+
328+
### Add arity to a function
329+
330+
Add a new arity to an existing single-arity or multi-arity function.
331+
322332
## Related packages
323333

324334
* [clojure-mode-extra-font-locking][] provides additional font-locking

Diff for: clojure-mode.el

+32
Original file line numberDiff line numberDiff line change
@@ -2729,6 +2729,38 @@ With a numeric prefix argument the let is introduced N lists up."
27292729
(clojure--rename-ns-alias-internal current-alias new-alias))
27302730
(message "Cannot find namespace alias: '%s'" current-alias))))))
27312731

2732+
;;;###autoload
2733+
(defun clojure-add-arity ()
2734+
"Add an arity to a function."
2735+
(interactive)
2736+
(let ((end (save-excursion (end-of-defun)
2737+
(point)))
2738+
(beg (progn (beginning-of-defun)
2739+
(point))))
2740+
(down-list 2)
2741+
(when (looking-back "{" 1) ;; skip metadata if present
2742+
(up-list)
2743+
(down-list))
2744+
(cond
2745+
((looking-back "(" 1) ;; multi-arity defn
2746+
(insert "[")
2747+
(save-excursion (insert "])\n("))
2748+
(indent-region beg end))
2749+
((looking-back "\\[" 1) ;; single-arity defn
2750+
(let* ((bol (save-excursion (beginning-of-line) (point)))
2751+
(same-line (save-excursion (re-search-backward "defn" bol t)))
2752+
(new-arity-text (concat (when same-line "\n") "([])\n[")))
2753+
(re-search-backward " +\\[")
2754+
(replace-match new-arity-text)
2755+
(save-excursion
2756+
(end-of-defun)
2757+
(re-search-backward ")")
2758+
(insert ")"))
2759+
(left-char)
2760+
(insert "(")
2761+
(indent-region beg end)
2762+
(left-char 6))))))
2763+
27322764

27332765
;;; ClojureScript
27342766
(defconst clojurescript-font-lock-keywords

Diff for: test/clojure-mode-refactor-add-arity-test.el

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
;;; clojure-mode-refactor-add-arity.el --- Clojure Mode: refactor add arity -*- lexical-binding: t; -*-
2+
3+
;; This file is not part of GNU Emacs.
4+
5+
;; This program is free software; you can redistribute it and/or modify
6+
;; it under the terms of the GNU General Public License as published by
7+
;; the Free Software Foundation, either version 3 of the License, or
8+
;; (at your option) any later version.
9+
10+
;; This program is distributed in the hope that it will be useful,
11+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
;; GNU General Public License for more details.
14+
15+
;; You should have received a copy of the GNU General Public License
16+
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
19+
;;; Commentary:
20+
21+
;; Tests for clojure-add-arity
22+
23+
;;; Code:
24+
25+
(require 'clojure-mode)
26+
(require 'buttercup)
27+
28+
(defmacro when-refactoring-with-point-it (description before after &rest body)
29+
"Return a buttercup spec.
30+
31+
Like when-refactor-it but also checks whether point is moved to the expected
32+
position.
33+
34+
BEFORE is the buffer string before refactoring, where a pipe (|) represents
35+
point.
36+
37+
AFTER is the expected buffer string after refactoring, where a pipe (|)
38+
represents the expected position of point.
39+
40+
DESCRIPTION is a string with the description of the spec."
41+
`(it ,description
42+
(let* ((after ,after)
43+
(expected-cursor-pos (1+ (s-index-of "|" after)))
44+
(expected-state (delete ?| after)))
45+
(with-clojure-buffer ,before
46+
(goto-char (point-min))
47+
(search-forward "|")
48+
(delete-char -1)
49+
,@body
50+
(expect (buffer-string) :to-equal expected-state)
51+
(expect (point) :to-equal expected-cursor-pos)))))
52+
53+
(describe "clojure-add-arity"
54+
55+
(when-refactoring-with-point-it "should add an arity to a single-arity defn with args on same line"
56+
"(defn foo [arg]
57+
body|)"
58+
59+
"(defn foo
60+
([|])
61+
([arg]
62+
body))"
63+
64+
(clojure-add-arity))
65+
66+
(when-refactoring-with-point-it "should add an arity to a single-arity defn with args on next line"
67+
"(defn foo
68+
[arg]
69+
bo|dy)"
70+
71+
"(defn foo
72+
([|])
73+
([arg]
74+
body))"
75+
76+
(clojure-add-arity))
77+
78+
(when-refactoring-with-point-it "should handle a single-arity defn with a docstring"
79+
"(defn foo
80+
\"some docst|ring\"
81+
[arg]
82+
body)"
83+
84+
"(defn foo
85+
\"some docstring\"
86+
([|])
87+
([arg]
88+
body))"
89+
90+
(clojure-add-arity))
91+
92+
(when-refactoring-with-point-it "should handle a single-arity defn with metadata"
93+
"(defn fo|o
94+
^{:bla \"meta\"}
95+
[arg]
96+
body)"
97+
98+
"(defn foo
99+
^{:bla \"meta\"}
100+
([|])
101+
([arg]
102+
body))"
103+
104+
(clojure-add-arity))
105+
106+
(when-refactoring-with-point-it "should add an arity to a multi-arity defn"
107+
"(defn foo
108+
([arg1])
109+
([ar|g1 arg2]
110+
body))"
111+
112+
"(defn foo
113+
([|])
114+
([arg1])
115+
([arg1 arg2]
116+
body))"
117+
118+
(clojure-add-arity))
119+
120+
(when-refactoring-with-point-it "should handle a multi-arity defn with a docstring"
121+
"(defn foo
122+
\"some docstring\"
123+
([])
124+
([arg|]
125+
body))"
126+
127+
"(defn foo
128+
\"some docstring\"
129+
([|])
130+
([])
131+
([arg]
132+
body))"
133+
134+
(clojure-add-arity))
135+
136+
(when-refactoring-with-point-it "should handle a multi-arity defn with metadata"
137+
"(defn foo
138+
\"some docstring\"
139+
^{:bla \"meta\"}
140+
([])
141+
|([arg]
142+
body))"
143+
144+
"(defn foo
145+
\"some docstring\"
146+
^{:bla \"meta\"}
147+
([|])
148+
([])
149+
([arg]
150+
body))"
151+
152+
(clojure-add-arity)))
153+
154+
(provide 'clojure-mode-refactor-add-arity-test)
155+
156+
;;; clojure-mode-refactor-add-arity-test.el ends here

Diff for: test/clojure-mode-refactor-rename-ns-alias-test.el

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
;; You should have received a copy of the GNU General Public License
1616
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
1717

18+
19+
;;; Commentary:
20+
21+
;; Tests for clojure-rename-ns-alias
22+
1823
;;; Code:
1924

2025
(require 'clojure-mode)

0 commit comments

Comments
 (0)