Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### Changes

* [#705](https://github.com/clojure-emacs/clojure-mode/pull/705): Rename the `#_` toggle commands to `clojure-toggle-discard`, `clojure-toggle-discard-surrounding-form` and `clojure-toggle-discard-defun`, matching Clojure's "discard" terminology (the old `clojure-toggle-ignore*` names remain as obsolete aliases).

## 5.23.0 (2026-03-25)

### New features
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,8 +485,8 @@ Here's a summary of the keybindings available in `clojure-mode`:
| `C-c C-r i` | `clojure-cycle-if` |
| `C-c C-r w` | `clojure-cycle-when` |
| `C-c C-r o` | `clojure-cycle-not` |
| `C-c C-r -` | `clojure-toggle-ignore` |
| `C-c C-r _` | `clojure-toggle-ignore-surrounding-form` |
| `C-c C-r -` | `clojure-toggle-discard` |
| `C-c C-r _` | `clojure-toggle-discard-surrounding-form` |
| `C-c C-r P` | `clojure-promote-fn-literal` |
| `C-c C-r a` | `clojure-add-arity` |
| `C-c C-r (` | `clojure-convert-collection-to-list` |
Expand Down Expand Up @@ -561,17 +561,17 @@ the same as before.

<img width="512" src="/doc/clojure-cycle-if.gif">

### Toggle ignore forms
### Toggle discard forms

`clojure-toggle-ignore`: Toggle `#_` on the form at point, commenting it out for
the reader. With a numeric prefix argument, toggle N `#_` forms at the same
point (e.g. `#_#_` to ignore two forms).
`clojure-toggle-discard`: Toggle `#_` on the form at point, discarding it at the
reader. With a numeric prefix argument, toggle N `#_` forms at the same point
(e.g. `#_#_` to discard two forms).

`clojure-toggle-ignore-surrounding-form`: Toggle `#_` on the surrounding form.
`clojure-toggle-discard-surrounding-form`: Toggle `#_` on the surrounding form.
With a numeric prefix argument, go up N levels first. With `C-u`, act on the
top-level form.

`clojure-toggle-ignore-defun`: Toggle `#_` on the top-level form at point.
`clojure-toggle-discard-defun`: Toggle `#_` on the top-level form at point.

### Promote function literal

Expand Down
53 changes: 30 additions & 23 deletions clojure-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,10 @@ containing that specific file."
(define-key map (kbd "s b") #'clojure-let-backward-slurp-sexp)
(define-key map (kbd "C-a") #'clojure-add-arity)
(define-key map (kbd "a") #'clojure-add-arity)
(define-key map (kbd "-") #'clojure-toggle-ignore)
(define-key map (kbd "C--") #'clojure-toggle-ignore)
(define-key map (kbd "_") #'clojure-toggle-ignore-surrounding-form)
(define-key map (kbd "C-_") #'clojure-toggle-ignore-surrounding-form)
(define-key map (kbd "-") #'clojure-toggle-discard)
(define-key map (kbd "C--") #'clojure-toggle-discard)
(define-key map (kbd "_") #'clojure-toggle-discard-surrounding-form)
(define-key map (kbd "C-_") #'clojure-toggle-discard-surrounding-form)
(define-key map (kbd "P") #'clojure-promote-fn-literal)
(define-key map (kbd "C-P") #'clojure-promote-fn-literal)
map)
Expand All @@ -360,8 +360,8 @@ containing that specific file."
["Cycle if, if-not" clojure-cycle-if]
["Cycle when, when-not" clojure-cycle-when]
["Cycle not" clojure-cycle-not]
["Toggle #_ ignore form" clojure-toggle-ignore]
["Toggle #_ ignore of surrounding form" clojure-toggle-ignore-surrounding-form]
["Toggle #_ discard form" clojure-toggle-discard]
["Toggle #_ discard of surrounding form" clojure-toggle-discard-surrounding-form]
["Add function arity" clojure-add-arity]
["Promote #() fn literal" clojure-promote-fn-literal]
("ns forms"
Expand Down Expand Up @@ -3586,10 +3586,10 @@ Assumes cursor is at beginning of function."
(indent-region beg end-marker))))


;;; Toggle Ignore forms
;;; Toggle Discard forms

(defun clojure--toggle-ignore-next-sexp (&optional n)
"Insert or delete N `#_' ignore macros at the current point.
(defun clojure--toggle-discard-next-sexp (&optional n)
"Insert or delete N `#_' discard reader macros at the current point.
Point must be directly before a sexp or the #_ characters.
When acting on a top level form, insert #_ on a new line
preceding the form to prevent indentation changes."
Expand All @@ -3603,8 +3603,8 @@ preceding the form to prevent indentation changes."
(when (zerop (car (syntax-ppss)))
(insert-before-markers "\n")))))

(defun clojure-toggle-ignore (&optional n)
"Toggle the #_ ignore reader form for the sexp at point.
(defun clojure-toggle-discard (&optional n)
"Toggle the #_ discard reader form for the sexp at point.
With numeric argument, toggle N number of #_ forms at the same point.

e.g. with N = 2:
Expand All @@ -3614,27 +3614,34 @@ With numeric argument, toggle N number of #_ forms at the same point.
(ignore-errors
(goto-char (or (nth 8 (syntax-ppss)) ;; beginning of string
(beginning-of-thing 'sexp))))
(clojure--toggle-ignore-next-sexp n)))
(clojure--toggle-discard-next-sexp n)))

(defun clojure-toggle-ignore-surrounding-form (&optional arg)
"Toggle the #_ ignore reader form for the surrounding form at point.
(defun clojure-toggle-discard-surrounding-form (&optional arg)
"Toggle the #_ discard reader form for the surrounding form at point.
With optional ARG, move up by ARG surrounding forms first.
With universal argument \\[universal-argument], act on the \"top-level\" form."
(interactive "P")
(save-excursion
(if (consp arg)
(clojure-toggle-ignore-defun)
(clojure-toggle-discard-defun)
(condition-case nil
(backward-up-list arg t t)
(scan-error nil)))
(clojure--toggle-ignore-next-sexp)))
(clojure--toggle-discard-next-sexp)))

(defun clojure-toggle-ignore-defun ()
"Toggle the #_ ignore reader form for the \"top-level\" form at point."
(defun clojure-toggle-discard-defun ()
"Toggle the #_ discard reader form for the \"top-level\" form at point."
(interactive)
(save-excursion
(beginning-of-defun-raw)
(clojure--toggle-ignore-next-sexp)))
(clojure--toggle-discard-next-sexp)))

(define-obsolete-function-alias 'clojure-toggle-ignore
'clojure-toggle-discard "5.24.0")
(define-obsolete-function-alias 'clojure-toggle-ignore-surrounding-form
'clojure-toggle-discard-surrounding-form "5.24.0")
(define-obsolete-function-alias 'clojure-toggle-ignore-defun
'clojure-toggle-discard-defun "5.24.0")


;;; ClojureScript
Expand Down Expand Up @@ -3697,10 +3704,10 @@ With universal argument \\[universal-argument], act on the \"top-level\" form."
(define-key prefix (kbd "[") #'clojure-convert-collection-to-vector)
(define-key prefix (kbd "C-#") #'clojure-convert-collection-to-set)
(define-key prefix (kbd "#") #'clojure-convert-collection-to-set)
(define-key prefix (kbd "-") #'clojure-toggle-ignore)
(define-key prefix (kbd "C--") #'clojure-toggle-ignore)
(define-key prefix (kbd "_") #'clojure-toggle-ignore-surrounding-form)
(define-key prefix (kbd "C-_") #'clojure-toggle-ignore-surrounding-form)
(define-key prefix (kbd "-") #'clojure-toggle-discard)
(define-key prefix (kbd "C--") #'clojure-toggle-discard)
(define-key prefix (kbd "_") #'clojure-toggle-discard-surrounding-form)
(define-key prefix (kbd "C-_") #'clojure-toggle-discard-surrounding-form)
(define-key map clojure-refactor-map-prefix prefix)
map)
"Keymap for EDN mode.
Expand Down
57 changes: 33 additions & 24 deletions test/clojure-mode-util-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -300,90 +300,99 @@
[methodTwo [] String]]
:init init))"))))

(describe "clojure-toggle-ignore"
(describe "clojure-toggle-discard"
(when-refactoring-with-point-it "should add #_ to literals"
"[1 |2 3]" "[1 #_|2 3]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should work with point in middle of symbol"
"[foo b|ar baz]" "[foo #_b|ar baz]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should remove #_ after cursor"
"[1 |#_2 3]" "[1 |2 3]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should remove #_ before cursor"
"[#_:fo|o :bar :baz]" "[:fo|o :bar :baz]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should insert multiple #_"
"{:foo| 1 :bar 2 :baz 3}"
"{#_#_#_#_:foo| 1 :bar 2 :baz 3}"
(clojure-toggle-ignore 4))
(clojure-toggle-discard 4))
(when-refactoring-with-point-it "should remove multiple #_"
"{#_#_#_#_:foo| 1 :bar 2 :baz 3}"
"{#_#_:foo| 1 :bar 2 :baz 3}"
(clojure-toggle-ignore 2))
(clojure-toggle-discard 2))
(when-refactoring-with-point-it "should handle spaces and newlines"
"[foo #_ \n #_ \r\n b|ar baz]" "[foo b|ar baz]"
(clojure-toggle-ignore 2))
(clojure-toggle-discard 2))
(when-refactoring-with-point-it "should toggle entire string"
"[:div \"lorem ips|um text\"]"
"[:div #_\"lorem ips|um text\"]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should toggle regexps"
"[|#\".*\"]"
"[#_|#\".*\"]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should toggle collections"
"[foo |[bar baz]]"
"[foo #_|[bar baz]]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should toggle hash sets"
"[foo #|{bar baz}]"
"[foo #_#|{bar baz}]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should work on last-sexp"
"[foo '(bar baz)| quux]"
"[foo #_'(bar baz)| quux]"
(clojure-toggle-ignore))
(clojure-toggle-discard))
(when-refactoring-with-point-it "should insert newline before top-level form"
"|[foo bar baz]"
"#_
|[foo bar baz]"
(clojure-toggle-ignore)))
(clojure-toggle-discard)))

(describe "clojure-toggle-ignore-surrounding-form"
(describe "clojure-toggle-discard-surrounding-form"
(when-refactoring-with-point-it "should toggle lists"
"(li|st [vector {map #{set}}])"
"#_\n(li|st [vector {map #{set}}])"
(clojure-toggle-ignore-surrounding-form))
(clojure-toggle-discard-surrounding-form))
(when-refactoring-with-point-it "should toggle vectors"
"(list #_[vector| {map #{set}}])"
"(list [vector| {map #{set}}])"
(clojure-toggle-ignore-surrounding-form))
(clojure-toggle-discard-surrounding-form))
(when-refactoring-with-point-it "should toggle maps"
"(list [vector #_ \n {map #{set}|}])"
"(list [vector {map #{set}|}])"
(clojure-toggle-ignore-surrounding-form))
(clojure-toggle-discard-surrounding-form))
(when-refactoring-with-point-it "should toggle sets"
"(list [vector {map #{set|}}])"
"(list [vector {map #_#{set|}}])"
(clojure-toggle-ignore-surrounding-form))
(clojure-toggle-discard-surrounding-form))
(when-refactoring-with-point-it "should work with numeric arg"
"(four (three (two (on|e)))"
"(four (three #_(two (on|e)))"
(clojure-toggle-ignore-surrounding-form 2))
(clojure-toggle-discard-surrounding-form 2))
(when-refactoring-with-point-it "should remove #_ with numeric arg"
"(four #_(three (two (on|e)))"
"(four (three (two (on|e)))"
(clojure-toggle-ignore-surrounding-form 3)))
(clojure-toggle-discard-surrounding-form 3)))

(describe "clojure-toggle-ignore-defun"
(when-refactoring-with-point-it "should ignore defun with newline"
(describe "clojure-toggle-discard-defun"
(when-refactoring-with-point-it "should discard defun with newline"
"(defn foo [x]
{:nested (in|c x)})"
"#_
(defn foo [x]
{:nested (in|c x)})"
(clojure-toggle-ignore-defun)))
(clojure-toggle-discard-defun)))

(describe "clojure-toggle-ignore obsolete aliases"
(it "keeps the old command names working"
(expect (indirect-function 'clojure-toggle-ignore)
:to-equal (indirect-function 'clojure-toggle-discard))
(expect (indirect-function 'clojure-toggle-ignore-surrounding-form)
:to-equal (indirect-function 'clojure-toggle-discard-surrounding-form))
(expect (indirect-function 'clojure-toggle-ignore-defun)
:to-equal (indirect-function 'clojure-toggle-discard-defun))))

(describe "clojure-find-def"
(it "should recognize def and defn"
Expand Down
Loading