@@ -205,6 +205,20 @@ Out-of-the box clojure-mode understands lein, boot and gradle."
205205 (define-key map (kbd " C-c C-r l" ) #'clojure-thread-last-all )
206206 (define-key map (kbd " C-c C-r C-a" ) #'clojure-unwind-all )
207207 (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-(" ) #'clojure-convert-collection-to-list )
211+ (define-key map (kbd " C-c C-r (" ) #'clojure-convert-collection-to-list )
212+ (define-key map (kbd " C-c C-r C-'" ) #'clojure-convert-collection-to-quoted-list )
213+ (define-key map (kbd " C-c C-r '" ) #'clojure-convert-collection-to-quoted-list )
214+ (define-key map (kbd " C-c C-r C-{" ) #'clojure-convert-collection-to-map )
215+ (define-key map (kbd " C-c C-r {" ) #'clojure-convert-collection-to-map )
216+ (define-key map (kbd " C-c C-r C-[" ) #'clojure-convert-collection-to-vector )
217+ (define-key map (kbd " C-c C-r [" ) #'clojure-convert-collection-to-vector )
218+ (define-key map (kbd " C-c C-r C-#" ) #'clojure-convert-collection-to-set )
219+ (define-key map (kbd " C-c C-r #" ) #'clojure-convert-collection-to-set )
220+ (define-key map (kbd " C-c C-r C-i" ) #'clojure-cycle-if )
221+ (define-key map (kbd " C-c C-r i" ) #'clojure-cycle-if )
208222 (define-key map (kbd " C-c C-r n i" ) #'clojure-insert-ns-form )
209223 (define-key map (kbd " C-c C-r n h" ) #'clojure-insert-ns-form-at-point )
210224 (define-key map (kbd " C-c C-r n u" ) #'clojure-update-ns )
@@ -213,11 +227,19 @@ Out-of-the box clojure-mode understands lein, boot and gradle."
213227 '(" Clojure"
214228 [" Toggle between string & keyword" clojure-toggle-keyword-string]
215229 [" Align expression" clojure-align]
230+ [" Cycle privacy" clojure-cycle-privacy]
231+ [" Cycle if, if-not" clojure-cycle-if]
216232 (" ns forms"
217233 [" Insert ns form at the top" clojure-insert-ns-form]
218234 [" Insert ns form here" clojure-insert-ns-form-at-point]
219235 [" Update ns form" clojure-update-ns]
220236 [" Sort ns form" clojure-sort-ns])
237+ (" Convert collection"
238+ [" Convert to list" clojure-convert-collection-to-list]
239+ [" Convert to quoted list" clojure-convert-collection-to-quoted-list]
240+ [" Convert to map" clojure-convert-collection-to-map]
241+ [" Convert to vector" clojure-convert-collection-to-vector]
242+ [" Convert to set" clojure-convert-collection-to-set])
221243 (" Refactor -> and ->>"
222244 [" Thread once more" clojure-thread]
223245 [" Fully thread a form with ->" clojure-thread-first-all]
@@ -1629,6 +1651,8 @@ This will skip over sexps that don't represent objects, so that ^hints and
16291651; ; Refactoring support
16301652; ;
16311653; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1654+
1655+ ; ;; Threading macros related
16321656(defcustom clojure-thread-all-but-last nil
16331657 " Non-nil means do not thread the last expression.
16341658This means that `clojure-thread-first-all' and
@@ -1824,6 +1848,106 @@ When BUT-LAST is passed the last expression is not threaded."
18241848 (interactive " P" )
18251849 (clojure--thread-all " ->> " but-last))
18261850
1851+ ; ;; Cycling stuff
1852+
1853+ (defcustom clojure-use-metadata-for-privacy nil
1854+ " If nil, `clojure-cycle-privacy' will use (defn- f []).
1855+ If t, it will use (defn ^:private f [])."
1856+ :package-version '(clojure-mode . " 5.5.0" )
1857+ :safe #'booleanp
1858+ :type 'boolean )
1859+
1860+ ;;;### autoload
1861+ (defun clojure-cycle-privacy ()
1862+ " Make public the current private def, or vice-versa.
1863+ See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-privacy"
1864+ (interactive )
1865+ (save-excursion
1866+ (ignore-errors (forward-char 7 ))
1867+ (search-backward-regexp " (defn?\\ (-\\ | ^:private\\ )?\\ _>" )
1868+ (if (match-string 1 )
1869+ (replace-match " " nil nil nil 1 )
1870+ (goto-char (match-end 0 ))
1871+ (insert (if (or clojure-use-metadata-for-privacy
1872+ (equal (match-string 0 ) " (def" ))
1873+ " ^:private"
1874+ " -" )))))
1875+
1876+ (defun clojure--convert-collection (coll-open coll-close )
1877+ " Convert the collection at (point) by unwrapping it an wrapping it between COLL-OPEN and COLL-CLOSE."
1878+ (save-excursion
1879+ (while (and
1880+ (not (bobp ))
1881+ (not (looking-at " (\\ |{\\ |\\ [" )))
1882+ (backward-char ))
1883+ (when (or (eq ?\# (char-before ))
1884+ (eq ?\' (char-before )))
1885+ (delete-char -1 ))
1886+ (when (and (bobp )
1887+ (not (memq (char-after ) '(?\{ ?\( ?\[ ))))
1888+ (user-error " Beginning of file reached, collection is not found" ))
1889+ (insert coll-open (substring (clojure-delete-and-extract-sexp) 1 -1 ) coll-close)))
1890+
1891+ ;;;### autoload
1892+ (defun clojure-convert-collection-to-list ()
1893+ " Convert collection at (point) to list."
1894+ (interactive )
1895+ (clojure--convert-collection " (" " )" ))
1896+
1897+ ;;;### autoload
1898+ (defun clojure-convert-collection-to-quoted-list ()
1899+ " Convert collection at (point) to quoted list."
1900+ (interactive )
1901+ (clojure--convert-collection " '(" " )" ))
1902+
1903+ ;;;### autoload
1904+ (defun clojure-convert-collection-to-map ()
1905+ " Convert collection at (point) to map."
1906+ (interactive )
1907+ (clojure--convert-collection " {" " }" ))
1908+
1909+ ;;;### autoload
1910+ (defun clojure-convert-collection-to-vector ()
1911+ " Convert collection at (point) to vector."
1912+ (interactive )
1913+ (clojure--convert-collection " [" " ]" ))
1914+
1915+ ;;;### autoload
1916+ (defun clojure-convert-collection-to-set ()
1917+ " Convert collection at (point) to set."
1918+ (interactive )
1919+ (clojure--convert-collection " #{" " }" ))
1920+
1921+ (defun clojure--goto-if ()
1922+ (when (in-string-p )
1923+ (while (or (not (looking-at " (" ))
1924+ (in-string-p ))
1925+ (backward-char )))
1926+ (while (not (looking-at " \\ ((if \\ )\\ |\\ ((if-not \\ )" ))
1927+ (condition-case nil
1928+ (backward-up-list )
1929+ (scan-error (user-error " No if or if-not found" )))))
1930+
1931+ ;;;### autoload
1932+ (defun clojure-cycle-if ()
1933+ " Change a surrounding if to if-not, or vice-versa.
1934+
1935+ See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-if"
1936+ (interactive )
1937+ (save-excursion
1938+ (clojure--goto-if)
1939+ (cond
1940+ ((looking-at " (if-not" )
1941+ (forward-char 3 )
1942+ (delete-char 4 )
1943+ (forward-sexp 2 )
1944+ (transpose-sexps 1 ))
1945+ ((looking-at " (if" )
1946+ (forward-char 3 )
1947+ (insert " -not" )
1948+ (forward-sexp 2 )
1949+ (transpose-sexps 1 )))))
1950+
18271951
18281952; ;; ClojureScript
18291953(defconst clojurescript-font-lock-keywords
0 commit comments