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