@@ -2048,6 +2048,77 @@ 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 (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
+
2051
2122
(defvar clojure-ts-refactor-map
2052
2123
(let ((map (make-sparse-keymap )))
2053
2124
(keymap-set map " C-t" #'clojure-ts-thread )
@@ -2060,6 +2131,16 @@ value is `clojure-ts-thread-all-but-last'."
2060
2131
(keymap-set map " l" #'clojure-ts-thread-last-all )
2061
2132
(keymap-set map " C-p" #'clojure-ts-cycle-privacy )
2062
2133
(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 )
2063
2144
map)
2064
2145
" Keymap for `clojure-ts-mode' refactoring commands." )
2065
2146
@@ -2074,6 +2155,12 @@ value is `clojure-ts-thread-all-but-last'."
2074
2155
[" Toggle between string & keyword" clojure-ts-cycle-keyword-string]
2075
2156
[" Align expression" clojure-ts-align]
2076
2157
[" 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])
2077
2164
(" Refactor -> and ->>"
2078
2165
[" Thread once more" clojure-ts-thread]
2079
2166
[" Fully thread a form with ->" clojure-ts-thread-first-all]
0 commit comments