@@ -2048,6 +2048,76 @@ value is `clojure-ts-thread-all-but-last'."
2048
2048
(user-error " No string or keyword at point" )))
2049
2049
(goto-char pos)))
2050
2050
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 (coll-open coll-close &optional prefix )
2078
+ " Convert collection at point to another collection type.
2079
+
2080
+ The original collection is being unwrapped and wrapped between COLL-OPEN
2081
+ and COLL-CLOSE. If PREFIX is non-nil it's inserted before COLL-OPEN."
2082
+ (if-let* ((coll-node (clojure-ts--collection-node-at-point)))
2083
+ (save-excursion
2084
+ (goto-char (treesit-node-start coll-node))
2085
+ (when (string-match-p (rx (or " set_lit" " quoting_lit" ))
2086
+ (treesit-node-type coll-node))
2087
+ (delete-char 1 ))
2088
+ (let ((parens-require-spaces nil )
2089
+ (delete-pair-blink-delay 0 ))
2090
+ (when prefix
2091
+ (insert-char prefix))
2092
+ (insert-pair 1 coll-open coll-close)
2093
+ (delete-pair 1 )))
2094
+ (user-error " No collection at point to convert" )))
2095
+
2096
+ (defun clojure-ts-convert-collection-to-list ()
2097
+ " Convert collection at point to list."
2098
+ (interactive )
2099
+ (clojure-ts--convert-collection ?\( ?\) ))
2100
+
2101
+ (defun clojure-ts-convert-collection-to-quoted-list ()
2102
+ " Convert collection at point to quoted list."
2103
+ (interactive )
2104
+ (clojure-ts--convert-collection ?\( ?\) ?' ))
2105
+
2106
+ (defun clojure-ts-convert-collection-to-map ()
2107
+ " Convert collection at point to map."
2108
+ (interactive )
2109
+ (clojure-ts--convert-collection ?{ ?} ))
2110
+
2111
+ (defun clojure-ts-convert-collection-to-vector ()
2112
+ " Convert collection at point to vector."
2113
+ (interactive )
2114
+ (clojure-ts--convert-collection ?\[ ?\] ))
2115
+
2116
+ (defun clojure-ts-convert-collection-to-set ()
2117
+ " Convert collection at point to set."
2118
+ (interactive )
2119
+ (clojure-ts--convert-collection ?{ ?} ?# ))
2120
+
2051
2121
(defvar clojure-ts-refactor-map
2052
2122
(let ((map (make-sparse-keymap )))
2053
2123
(keymap-set map " C-t" #'clojure-ts-thread )
@@ -2060,6 +2130,16 @@ value is `clojure-ts-thread-all-but-last'."
2060
2130
(keymap-set map " l" #'clojure-ts-thread-last-all )
2061
2131
(keymap-set map " C-p" #'clojure-ts-cycle-privacy )
2062
2132
(keymap-set map " p" #'clojure-ts-cycle-privacy )
2133
+ (keymap-set map " C-(" #'clojure-ts-convert-collection-to-list )
2134
+ (keymap-set map " (" #'clojure-ts-convert-collection-to-list )
2135
+ (keymap-set map " C-'" #'clojure-ts-convert-collection-to-quoted-list )
2136
+ (keymap-set map " '" #'clojure-ts-convert-collection-to-quoted-list )
2137
+ (keymap-set map " C-{" #'clojure-ts-convert-collection-to-map )
2138
+ (keymap-set map " {" #'clojure-ts-convert-collection-to-map )
2139
+ (keymap-set map " C-[" #'clojure-ts-convert-collection-to-vector )
2140
+ (keymap-set map " [" #'clojure-ts-convert-collection-to-vector )
2141
+ (keymap-set map " C-#" #'clojure-ts-convert-collection-to-set )
2142
+ (keymap-set map " #" #'clojure-ts-convert-collection-to-set )
2063
2143
map)
2064
2144
" Keymap for `clojure-ts-mode' refactoring commands." )
2065
2145
@@ -2074,6 +2154,12 @@ value is `clojure-ts-thread-all-but-last'."
2074
2154
[" Toggle between string & keyword" clojure-ts-cycle-keyword-string]
2075
2155
[" Align expression" clojure-ts-align]
2076
2156
[" Cycle privacy" clojure-ts-cycle-privacy]
2157
+ (" Convert collection"
2158
+ [" Convert to list" clojure-ts-convert-collection-to-list]
2159
+ [" Convert to quoted list" clojure-ts-convert-collection-to-quoted-list]
2160
+ [" Convert to map" clojure-ts-convert-collection-to-map]
2161
+ [" Convert to vector" clojure-ts-convert-collection-to-vector]
2162
+ [" Convert to set" clojure-ts-convert-collection-to-set])
2077
2163
(" Refactor -> and ->>"
2078
2164
[" Thread once more" clojure-ts-thread]
2079
2165
[" Fully thread a form with ->" clojure-ts-thread-first-all]
0 commit comments