blob: 22450f70f94e72749187897512979b7a67beeab3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
;;; +lisp.el -*- lexical-binding: t -*-
;;; Comment-or-uncomment-sexp
;; from https://endlessparentheses.com/a-comment-or-uncomment-sexp-command.html
(defun +lisp-uncomment-sexp (&optional n)
"Uncomment N sexps around point."
(interactive "P")
(let* ((initial-point (point-marker))
(inhibit-field-text-motion t)
(p)
(end (save-excursion
(when (elt (syntax-ppss) 4)
(re-search-backward comment-start-skip
(line-beginning-position)
t))
(setq p (point-marker))
(comment-forward (point-max))
(point-marker)))
(beg (save-excursion
(forward-line 0)
(while (and (not (bobp))
(= end (save-excursion
(comment-forward (point-max))
(point))))
(forward-line -1))
(goto-char (line-end-position))
(re-search-backward comment-start-skip
(line-beginning-position)
t)
(ignore-errors
(while (looking-at-p comment-start-skip)
(forward-char -1)))
(point-marker))))
(unless (= beg end)
(uncomment-region beg end)
(goto-char p)
;; Indentify the "top-level" sexp inside the comment.
(while (and (ignore-errors (backward-up-list) t)
(>= (point) beg))
(skip-chars-backward (rx (syntax expression-prefix)))
(setq p (point-marker)))
;; Re-comment everything before it.
(ignore-errors
(comment-region beg p))
;; And everything after it.
(goto-char p)
(forward-sexp (or n 1))
(skip-chars-forward "\r\n[:blank:]")
(if (< (point) end)
(ignore-errors
(comment-region (point) end))
;; If this is a closing delimiter, pull it up.
(goto-char end)
(skip-chars-forward "\r\n[:blank:]")
(when (eq 5 (car (syntax-after (point))))
(delete-indentation))))
;; Without a prefix, it's more useful to leave point where
;; it was.
(unless n
(goto-char initial-point))))
(defun +lisp-comment-sexp--raw ()
"Comment the sexp at point or ahead of point."
(pcase (or (bounds-of-thing-at-point 'sexp)
(save-excursion
(skip-chars-forward "\r\n[:blank:]")
(bounds-of-thing-at-point 'sexp)))
(`(,l . ,r)
(goto-char r)
(skip-chars-forward "\r\n[:blank:]")
(save-excursion
(comment-region l r))
(skip-chars-forward "\r\n[:blank:]"))))
(defun +lisp-comment-or-uncomment-sexp (&optional n)
"Comment the sexp at point and move past it.
If already inside (or before) a comment, uncomment instead.
With a prefix argument N, (un)comment that many sexps."
(interactive "P")
(if (or (elt (syntax-ppss) 4)
(< (save-excursion
(skip-chars-forward "\r\n[:blank:]")
(point))
(save-excursion
(comment-forward 1)
(point))))
(+lisp-uncomment-sexp n)
(dotimes (_ (or n 1))
(+lisp-comment-sexp--raw))))
(provide '+lisp)
;;; +lisp.el ends here
|