@@ -205,6 +205,12 @@ Out-of-the box clojure-mode understands lein, boot and gradle."
205
205
(define-key map (kbd " C-c C-r l" ) #'clojure-thread-last-all )
206
206
(define-key map (kbd " C-c C-r C-a" ) #'clojure-unwind-all )
207
207
(define-key map (kbd " C-c C-r a" ) #'clojure-unwind-all )
208
+ (define-key map (kbd " C-c C-r C-p" ) #'clojure-cycle-privacy )
209
+ (define-key map (kbd " C-c C-r p" ) #'clojure-cycle-privacy )
210
+ (define-key map (kbd " C-c C-r C-c" ) #'clojure-cycle-collection )
211
+ (define-key map (kbd " C-c C-r c" ) #'clojure-cycle-collection )
212
+ (define-key map (kbd " C-c C-r C-i" ) #'clojure-cycle-if )
213
+ (define-key map (kbd " C-c C-r i" ) #'clojure-cycle-if )
208
214
(define-key map (kbd " C-c C-r n i" ) #'clojure-insert-ns-form )
209
215
(define-key map (kbd " C-c C-r n h" ) #'clojure-insert-ns-form-at-point )
210
216
(define-key map (kbd " C-c C-r n u" ) #'clojure-update-ns )
@@ -225,6 +231,10 @@ Out-of-the box clojure-mode understands lein, boot and gradle."
225
231
" --"
226
232
[" Unwind once" clojure-unwind]
227
233
[" Fully unwind a threading macro" clojure-unwind-all])
234
+ (" Cycle things"
235
+ [" Cycle privacy" clojure-cycle-privacy]
236
+ [" Cycle collection type" clojure-cycle-collection]
237
+ [" Cycle if, if-not" clojure-cycle-if])
228
238
" --"
229
239
[" Clojure-mode version" clojure-mode-display-version]))
230
240
map)
@@ -1629,6 +1639,8 @@ This will skip over sexps that don't represent objects, so that ^hints and
1629
1639
; ; Refactoring support
1630
1640
; ;
1631
1641
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1642
+
1643
+ ; ;; Threading macros related
1632
1644
(defcustom clojure-thread-all-but-last nil
1633
1645
" Non-nil means do not thread the last expression.
1634
1646
This means that `clojure-thread-first-all' and
@@ -1824,6 +1836,114 @@ When BUT-LAST is passed the last expression is not threaded."
1824
1836
(interactive " P" )
1825
1837
(clojure--thread-all " ->> " but-last))
1826
1838
1839
+ ; ;; Cycling stuff
1840
+
1841
+ (defcustom clojure-use-metadata-for-privacy nil
1842
+ " If nil, `clojure-cycle-privacy' will use (defn- f []).
1843
+ If t, it will use (defn ^:private f [])."
1844
+ :package-version '(clojure-mode . " 5.5.0" )
1845
+ :safe #'booleanp
1846
+ :type 'boolean )
1847
+
1848
+ ;;;### autoload
1849
+ (defun clojure-cycle-privacy ()
1850
+ " Make public the current private def, or vice-versa.
1851
+
1852
+ See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-privacy"
1853
+ (interactive )
1854
+ (save-excursion
1855
+ (ignore-errors (forward-char 7 ))
1856
+ (search-backward-regexp " \\ ((defn-? \\ )\\ |\\ ((def \\ )" )
1857
+ (cond
1858
+ ((and clojure-use-metadata-for-privacy
1859
+ (looking-at " (defn ^:private" ))
1860
+ (forward-char 5 )
1861
+ (delete-char 10 ))
1862
+ ((and (not clojure-use-metadata-for-privacy)
1863
+ (looking-at " (defn-" ))
1864
+ (forward-char 5 )
1865
+ (delete-char 1 ))
1866
+ ((and clojure-use-metadata-for-privacy
1867
+ (looking-at " (defn" ))
1868
+ (forward-char 5 )
1869
+ (insert " ^:private" ))
1870
+ ((and (not clojure-use-metadata-for-privacy)
1871
+ (looking-at " (defn" ))
1872
+ (forward-char 5 )
1873
+ (insert " -" ))
1874
+ ((looking-at " (def ^:private" )
1875
+ (forward-char 5 )
1876
+ (delete-char 10 ))
1877
+ ((looking-at " (def " )
1878
+ (forward-char 5 )
1879
+ (insert " ^:private " )))))
1880
+
1881
+ ;;;### autoload
1882
+ (defun clojure-cycle-collection ()
1883
+ " Convert the coll at (point) from (x) -> {x} -> [x] -> -> #{x} -> (x) recur.
1884
+
1885
+ See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-coll"
1886
+ (interactive )
1887
+ (save-excursion
1888
+ (while (and
1889
+ (> (point ) 1 )
1890
+ (not (eq (string-to-char " (" ) (char-after )))
1891
+ (not (string= " #{" (buffer-substring (point ) (+ 2 (point )))))
1892
+ (not (eq (string-to-char " {" ) (char-after )))
1893
+ (not (eq (string-to-char " [" ) (char-after ))))
1894
+ (backward-char ))
1895
+
1896
+ (cond
1897
+ ((eq (string-to-char " (" ) (char-after ))
1898
+ (insert " {" (substring (clojure-delete-and-extract-sexp) 1 -1 ) " }" ))
1899
+
1900
+ ((eq (string-to-char " #" ) (char-after ))
1901
+ (delete-char 1 )
1902
+ (insert " (" (substring (clojure-delete-and-extract-sexp) 1 -1 ) " )" ))
1903
+
1904
+ ((eq (string-to-char " {" ) (char-after ))
1905
+ (if (not (equal (string-to-char " #" ) (char-before )))
1906
+ (insert " [" (substring (clojure-delete-and-extract-sexp) 1 -1 ) " ]" )
1907
+ (backward-char )
1908
+ (delete-char 1 )
1909
+ (insert " (" (substring (clojure-delete-and-extract-sexp) 1 -1 ) " )" )))
1910
+
1911
+ ((eq (string-to-char " [" ) (char-after ))
1912
+ (insert " #{" (substring (clojure-delete-and-extract-sexp) 1 -1 ) " }" ))
1913
+
1914
+ ((equal 1 (point ))
1915
+ (user-error " Beginning of file reached, collection is not found" )))))
1916
+
1917
+ (defun clojure--goto-if ()
1918
+ (when (in-string-p )
1919
+ (while (or (not (looking-at " (" ))
1920
+ (in-string-p ))
1921
+ (backward-char )))
1922
+ (while (not (looking-at " \\ ((if \\ )\\ |\\ ((if-not \\ )" ))
1923
+ (condition-case nil
1924
+ (backward-up-list )
1925
+ (scan-error (user-error " No if or if-not found" )))))
1926
+
1927
+ ;;;### autoload
1928
+ (defun clojure-cycle-if ()
1929
+ " Change a surrounding if to if-not, or vice-versa.
1930
+
1931
+ See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-if"
1932
+ (interactive )
1933
+ (save-excursion
1934
+ (clojure--goto-if)
1935
+ (cond
1936
+ ((looking-at " (if-not" )
1937
+ (forward-char 3 )
1938
+ (delete-char 4 )
1939
+ (forward-sexp 2 )
1940
+ (transpose-sexps 1 ))
1941
+ ((looking-at " (if" )
1942
+ (forward-char 3 )
1943
+ (insert " -not" )
1944
+ (forward-sexp 2 )
1945
+ (transpose-sexps 1 )))))
1946
+
1827
1947
1828
1948
; ;; ClojureScript
1829
1949
(defconst clojurescript-font-lock-keywords
0 commit comments