[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
New comment-sexp command and key bind
From: |
Artur Malabarba |
Subject: |
New comment-sexp command and key bind |
Date: |
Fri, 21 Aug 2015 12:11:12 +0100 |
I'd like to add the following command that comments and uncomments
sexps. I'm attacking a gif to show its behavior, but it is pretty much
the same as our current comment-line, except it acts on sexps.
Furthermore, I'd like to bind it to `C-M-;' since C-M- is a relatively
common modifier for sexp-stuff.
-----
(defun uncomment-sexp (&optional n)
"Uncomment a sexp around point."
(interactive "P")
(let* ((initial-point (point-marker))
(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 (= 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)
(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 (= 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 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:]")
(comment-region l r)
(skip-chars-forward "\r\n[:blank:]"))))
(defun 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))))
(uncomment-sexp n)
(dotimes (_ (or n 1))
(comment-sexp--raw))))
comment-or-uncomment-sexp.gif
Description: GIF image
- New comment-sexp command and key bind,
Artur Malabarba <=