Skip to content

Commit 3a69e45

Browse files
committed
New command: clojure-sort-ns
1 parent ca17c57 commit 3a69e45

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* When aligning forms with `clojure-align` (or with the automatic align feature), blank lines will divide alignment regions.
88
* [#378](https://github.com/clojure-emacs/clojure-mode/issues/378): Font-lock escape characters in strings.
99
* Port threading macros related features from clj-refactor.el. Available refactorings: thread, unwind, thread first all, thread last all, unwind all.
10+
* New command: `clojure-sort-ns`.
1011

1112
## 5.3.0 (2016-04-04)
1213

clojure-mode.el

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,68 @@ Useful if a file has been renamed."
14521452
(replace-match nsname nil nil nil 4)
14531453
(error "Namespace not found")))))))
14541454

1455+
(defun clojure--sort-following-sexps ()
1456+
"Sort sexps between point and end of current sexp.
1457+
Comments at the start of a line are considered part of the
1458+
following sexp. Comments at the end of a line (after some other
1459+
content) are considered part of the preceding sexp."
1460+
;; Here we're after the :require/:import symbol.
1461+
(save-restriction
1462+
(narrow-to-region (point) (save-excursion
1463+
(up-list)
1464+
(1- (point))))
1465+
(skip-chars-forward "\r\n[:blank:]")
1466+
(sort-subr nil
1467+
(lambda () (skip-chars-forward "\r\n[:blank:]"))
1468+
;; Move to end of current top-level thing.
1469+
(lambda ()
1470+
(condition-case nil
1471+
(while t (up-list))
1472+
(scan-error nil))
1473+
;; We could be inside a symbol instead of a sexp.
1474+
(unless (looking-at "\\s-\\|$")
1475+
(clojure-forward-logical-sexp))
1476+
;; move past comments at the end of the line.
1477+
(search-forward-regexp "$"))
1478+
;; Move to start of ns name.
1479+
(lambda ()
1480+
(comment-forward)
1481+
(skip-chars-forward "[(")
1482+
(clojure-forward-logical-sexp)
1483+
(forward-sexp -1)
1484+
nil)
1485+
;; Move to end of ns name.
1486+
(lambda ()
1487+
(clojure-forward-logical-sexp)))))
1488+
1489+
(defun clojure-sort-ns ()
1490+
"Internally sort each sexp inside the ns form."
1491+
(interactive)
1492+
(comment-normalize-vars)
1493+
(if (clojure-find-ns)
1494+
(save-excursion
1495+
(goto-char (match-beginning 0))
1496+
(redisplay)
1497+
(let ((beg (point))
1498+
(ns))
1499+
(forward-sexp 1)
1500+
(setq ns (buffer-substring beg (point)))
1501+
(forward-char -1)
1502+
(while (progn (forward-sexp -1)
1503+
(looking-at "(:[a-z]"))
1504+
(save-excursion
1505+
(forward-char 1)
1506+
(forward-sexp 1)
1507+
(clojure--sort-following-sexps)))
1508+
(goto-char beg)
1509+
(if (looking-at (regexp-quote ns))
1510+
(message "ns form is already sorted")
1511+
(sleep-for 0.1)
1512+
(redisplay)
1513+
(message "ns form has been sorted")
1514+
(sleep-for 0.1))))
1515+
(user-error "Namespace not found")))
1516+
14551517
(defconst clojure-namespace-name-regex
14561518
(rx line-start
14571519
"("

0 commit comments

Comments
 (0)