Skip to content

Commit c7a3555

Browse files
rrudakovbbatsov
authored andcommitted
Introduce clojure-ts-toggle-keyword-string
1 parent ea1c134 commit c7a3555

File tree

4 files changed

+62
-8
lines changed

4 files changed

+62
-8
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- [#89](https://github.com/clojure-emacs/clojure-ts-mode/pull/89): Introduce `clojure-ts-thread`, `clojure-ts-thread-first-all` and
1515
`clojure-ts-thread-last-all`.
1616
- [#90](https://github.com/clojure-emacs/clojure-ts-mode/pull/90): Introduce `clojure-ts-cycle-privacy`.
17+
- [#91](https://github.com/clojure-emacs/clojure-ts-mode/pull/91): Introduce `clojure-ts-cycle-keyword-string`.
1718

1819
## 0.3.0 (2025-04-15)
1920

README.md

+12-8
Original file line numberDiff line numberDiff line change
@@ -393,20 +393,24 @@ threading macro.
393393

394394
### Cycling things
395395

396+
`clojure-ts-cycle-keyword-string`: Convert the string at point to a keyword and
397+
vice versa.
398+
396399
`clojure-ts-cycle-privacy`: Cycle privacy of `def`s or `defn`s. Use metadata
397400
explicitly with setting `clojure-ts-use-metadata-for-defn-privacy` to `t` for
398401
`defn`s too.
399402

400403
### Default keybindings
401404

402-
| Keybinding | Command |
403-
|:----------------------------|:------------------------------|
404-
| `C-c SPC` | `clojure-ts-align` |
405-
| `C-c C-r t` / `C-c C-r C-t` | `clojure-ts-thread` |
406-
| `C-c C-r u` / `C-c C-r C-u` | `clojure-ts-unwind` |
407-
| `C-c C-r f` / `C-c C-r C-f` | `clojure-ts-thread-first-all` |
408-
| `C-c C-r l` / `C-c C-r C-l` | `clojure-ts-thread-last-all` |
409-
| `C-c C-r p` / `C-c C-r C-p` | `clojure-ts-cycle-privacy` |
405+
| Keybinding | Command |
406+
|:----------------------------|:----------------------------------|
407+
| `C-:` | `clojure-ts-cycle-keyword-string` |
408+
| `C-c SPC` | `clojure-ts-align` |
409+
| `C-c C-r t` / `C-c C-r C-t` | `clojure-ts-thread` |
410+
| `C-c C-r u` / `C-c C-r C-u` | `clojure-ts-unwind` |
411+
| `C-c C-r f` / `C-c C-r C-f` | `clojure-ts-thread-first-all` |
412+
| `C-c C-r l` / `C-c C-r C-l` | `clojure-ts-thread-last-all` |
413+
| `C-c C-r p` / `C-c C-r C-p` | `clojure-ts-cycle-privacy` |
410414

411415
### Customize refactoring commands prefix
412416

clojure-ts-mode.el

+18
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,22 @@ value is `clojure-ts-thread-all-but-last'."
20322032
"-"))))
20332033
(user-error "No defun at point")))
20342034

2035+
(defun clojure-ts-cycle-keyword-string ()
2036+
"Convert the string at point to a keyword, or vice versa."
2037+
(interactive)
2038+
(let ((node (treesit-thing-at-point 'sexp 'nested))
2039+
(pos (point)))
2040+
(cond
2041+
((clojure-ts--string-node-p node)
2042+
(if (string-match-p " " (treesit-node-text node t))
2043+
(user-error "Cannot convert a string containing spaces to keyword")
2044+
(insert ?: (substring (clojure-ts--delete-and-extract-sexp) 1 -1))))
2045+
((clojure-ts--keyword-node-p node)
2046+
(insert ?\" (substring (clojure-ts--delete-and-extract-sexp) 1) ?\"))
2047+
(t
2048+
(user-error "No string or keyword at point")))
2049+
(goto-char pos)))
2050+
20352051
(defvar clojure-ts-refactor-map
20362052
(let ((map (make-sparse-keymap)))
20372053
(keymap-set map "C-t" #'clojure-ts-thread)
@@ -2050,10 +2066,12 @@ value is `clojure-ts-thread-all-but-last'."
20502066
(defvar clojure-ts-mode-map
20512067
(let ((map (make-sparse-keymap)))
20522068
;;(set-keymap-parent map clojure-mode-map)
2069+
(keymap-set map "C-:" #'clojure-ts-cycle-keyword-string)
20532070
(keymap-set map "C-c SPC" #'clojure-ts-align)
20542071
(keymap-set map clojure-ts-refactor-map-prefix clojure-ts-refactor-map)
20552072
(easy-menu-define clojure-ts-mode-menu map "Clojure[TS] Mode Menu"
20562073
'("Clojure"
2074+
["Toggle between string & keyword" clojure-ts-cycle-keyword-string]
20572075
["Align expression" clojure-ts-align]
20582076
["Cycle privacy" clojure-ts-cycle-privacy]
20592077
("Refactor -> and ->>"

test/clojure-ts-mode-cycling-test.el

+31
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,37 @@
2727
(require 'buttercup)
2828
(require 'test-helper "test/test-helper")
2929

30+
(describe "clojure-ts-cycle-keyword-string"
31+
(when-refactoring-with-point-it "should convert string to keyword"
32+
"\"hel|lo\""
33+
34+
":hel|lo"
35+
36+
(clojure-ts-cycle-keyword-string))
37+
38+
(when-refactoring-with-point-it "should convert keyword to string"
39+
":|hello"
40+
41+
"\"|hello\""
42+
43+
(clojure-ts-cycle-keyword-string))
44+
45+
(it "should signal a user error when there is nothing to convert at point"
46+
(with-clojure-ts-buffer "[true false]"
47+
(goto-char 2)
48+
(expect (clojure-ts-cycle-keyword-string)
49+
:to-throw
50+
'user-error
51+
'("No string or keyword at point"))))
52+
53+
(it "should signal a user error when string at point contains spaces"
54+
(with-clojure-ts-buffer "\"Hello world\""
55+
(goto-char 2)
56+
(expect (clojure-ts-cycle-keyword-string)
57+
:to-throw
58+
'user-error
59+
'("Cannot convert a string containing spaces to keyword")))))
60+
3061
(describe "clojure-ts-cycle-privacy"
3162

3263
(when-refactoring-it "should turn a public defn into a private defn"

0 commit comments

Comments
 (0)