@@ -2048,6 +2048,77 @@ value is `clojure-ts-thread-all-but-last'."
20482048 (user-error " No string or keyword at point" )))
20492049 (goto-char pos)))
20502050
2051+ (defun clojure-ts--collection-node-at-point ()
2052+ " Return node at point that represent a collection."
2053+ (when-let* ((node (thread-first (point )
2054+ (treesit-node-at 'clojure )
2055+ (treesit-parent-until (rx bol
2056+ (or " map_lit"
2057+ " vec_lit"
2058+ " set_lit"
2059+ " list_lit"
2060+ " quoting_lit" )
2061+ eol)))))
2062+ (cond
2063+ ; ; If node is a list, check if it's quoted.
2064+ ((string= (treesit-node-type node) " list_lit" )
2065+ (if-let* ((parent (treesit-node-parent node))
2066+ ((string= (treesit-node-type parent) " quoting_lit" )))
2067+ parent
2068+ node))
2069+ ; ; If the point is at the quote character, check if the child node is a
2070+ ; ; list.
2071+ ((string= (treesit-node-type node) " quoting_lit" )
2072+ (when-let* ((first-child (clojure-ts--node-child-skip-metadata node 0 ))
2073+ ((string= (treesit-node-type first-child) " list_lit" )))
2074+ node))
2075+ (t node))))
2076+
2077+ (defun clojure-ts--convert-collection (delim-open &optional prefix )
2078+ " Convert collection at point to another collection type.
2079+
2080+ The original collection is being unwrapped and wrapped between
2081+ DELIM-OPEN and its matching paren. If PREFIX is non-nil it's inserted
2082+ before DELIM-OPEN."
2083+ (if-let* ((coll-node (clojure-ts--collection-node-at-point)))
2084+ (save-excursion
2085+ (goto-char (treesit-node-start coll-node))
2086+ (when (string-match-p (rx (or " set_lit" " quoting_lit" ))
2087+ (treesit-node-type coll-node))
2088+ (delete-char 1 ))
2089+ (let ((parens-require-spaces nil )
2090+ (delete-pair-blink-delay 0 ))
2091+ (when prefix
2092+ (insert-char prefix))
2093+ (insert-pair 1 delim-open (matching-paren delim-open))
2094+ (delete-pair 1 )))
2095+ (user-error " No collection at point to convert" )))
2096+
2097+ (defun clojure-ts-convert-collection-to-list ()
2098+ " Convert collection at point to list."
2099+ (interactive )
2100+ (clojure-ts--convert-collection ?\( ))
2101+
2102+ (defun clojure-ts-convert-collection-to-quoted-list ()
2103+ " Convert collection at point to quoted list."
2104+ (interactive )
2105+ (clojure-ts--convert-collection ?\( ?' ))
2106+
2107+ (defun clojure-ts-convert-collection-to-map ()
2108+ " Convert collection at point to map."
2109+ (interactive )
2110+ (clojure-ts--convert-collection ?{ ))
2111+
2112+ (defun clojure-ts-convert-collection-to-vector ()
2113+ " Convert collection at point to vector."
2114+ (interactive )
2115+ (clojure-ts--convert-collection ?\[ ))
2116+
2117+ (defun clojure-ts-convert-collection-to-set ()
2118+ " Convert collection at point to set."
2119+ (interactive )
2120+ (clojure-ts--convert-collection ?{ ?# ))
2121+
20512122(defvar clojure-ts-refactor-map
20522123 (let ((map (make-sparse-keymap )))
20532124 (keymap-set map " C-t" #'clojure-ts-thread )
@@ -2060,6 +2131,16 @@ value is `clojure-ts-thread-all-but-last'."
20602131 (keymap-set map " l" #'clojure-ts-thread-last-all )
20612132 (keymap-set map " C-p" #'clojure-ts-cycle-privacy )
20622133 (keymap-set map " p" #'clojure-ts-cycle-privacy )
2134+ (keymap-set map " C-(" #'clojure-ts-convert-collection-to-list )
2135+ (keymap-set map " (" #'clojure-ts-convert-collection-to-list )
2136+ (keymap-set map " C-'" #'clojure-ts-convert-collection-to-quoted-list )
2137+ (keymap-set map " '" #'clojure-ts-convert-collection-to-quoted-list )
2138+ (keymap-set map " C-{" #'clojure-ts-convert-collection-to-map )
2139+ (keymap-set map " {" #'clojure-ts-convert-collection-to-map )
2140+ (keymap-set map " C-[" #'clojure-ts-convert-collection-to-vector )
2141+ (keymap-set map " [" #'clojure-ts-convert-collection-to-vector )
2142+ (keymap-set map " C-#" #'clojure-ts-convert-collection-to-set )
2143+ (keymap-set map " #" #'clojure-ts-convert-collection-to-set )
20632144 map)
20642145 " Keymap for `clojure-ts-mode' refactoring commands." )
20652146
@@ -2074,6 +2155,12 @@ value is `clojure-ts-thread-all-but-last'."
20742155 [" Toggle between string & keyword" clojure-ts-cycle-keyword-string]
20752156 [" Align expression" clojure-ts-align]
20762157 [" Cycle privacy" clojure-ts-cycle-privacy]
2158+ (" Convert collection"
2159+ [" Convert to list" clojure-ts-convert-collection-to-list]
2160+ [" Convert to quoted list" clojure-ts-convert-collection-to-quoted-list]
2161+ [" Convert to map" clojure-ts-convert-collection-to-map]
2162+ [" Convert to vector" clojure-ts-convert-collection-to-vector]
2163+ [" Convert to set" clojure-ts-convert-collection-to-set])
20772164 (" Refactor -> and ->>"
20782165 [" Thread once more" clojure-ts-thread]
20792166 [" Fully thread a form with ->" clojure-ts-thread-first-all]
0 commit comments