I am working on this little function that pulls up the next line to the current line. I want to add a functionality so that if the current line is a line comment and the next line is also a line comment, then the comment characters are removed after the "pull-up" action.
Example:
Before
;; comment 1▮
;; comment 2
Calling M-x modi/pull-up-line
After
;; comment 1▮comment 2
Note that the ;;
characters are removed that were before comment 2
.
(defun modi/pull-up-line ()
"Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.
If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
(interactive)
(join-line -1)
;; If the current line is a comment
(when (nth 4 (syntax-ppss))
;; Remove the comment prefix chars from the pulled-up line if present
(save-excursion
(forward-char)
(while (looking-at "/\\|;\\|#")
(delete-forward-char 1))
(when (looking-at "\\s-")
(delete-forward-char 1)))))
The above function works but for now, regardless of the major-mode, it will consider /
or ;
or #
as a comment character: (looking-at "/\\|;\\|#")
.
I'd like to make this line more intelligent; major-mode specific.
Solution
Thanks to @ericstokes' solution, I believe that the below now covers all my use cases :)
(defun modi/pull-up-line ()
"Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.
If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
(interactive)
(join-line -1)
;; If the current line is a comment
(when (nth 4 (syntax-ppss))
;; Remove the comment prefix chars from the pulled-up line if present
(save-excursion
(forward-char)
;; Delete all comment-start or space characters
(while (looking-at (concat "\\s<" ; comment-start char as per syntax table
"\\|" (substring comment-start 0 1) ; first char of `comment-start'
"\\|" "\\s-")) ; extra spaces
(delete-forward-char 1)))))
/* ... */
)?comment-start
andcomment-end
strings that are set to "/*" and "*/" inc-mode
(but notc++-mode
). And there'sc-comment-start-regexp
that matches both styles. You deleting the end characters then the beginning after joining. But I think my solution would be touncomment-region
,join-line
thecomment-region
and let Emacs worry about what comment character is what.