21

Some code editors such as eclipse automatically form neat blocks when you start typing a multi-line comment:

enter image description here

Is there some package or another way to do this in emacs too?

Edit: To clarify: I do not want a key-combination that inserts a comment block. I want a comment block to be automatically created when I press RET after /*.

7
  • Did you check this similar question? stackoverflow.com/a/6578421/4780877
    – Emacs User
    Aug 7, 2015 at 17:34
  • @EmacsUser: Yeah. But that's not what I want. I don't want just a snippet or the feature to comment an already written region.
    – Geier
    Aug 7, 2015 at 17:44
  • See the manual for Multiple Lines of Comments.
    – Dan
    Aug 7, 2015 at 18:04
  • @Dan: That's pretty close, but it does not automatically insert the closing */
    – Geier
    Aug 7, 2015 at 18:45
  • 2
    @Name The * signs are not strictly required, but nice to have.
    – Geier
    Aug 7, 2015 at 21:18

1 Answer 1

9

The below code works fine from my brief testing in a c-mode buffer:

  • After typing /*, hit M-j, the default binding for indent-new-comment-line (and the default binding for c-indent-new-comment-line in c-mode). If it is the first comment line the closing closing characters */ will be auto-inserted.
  • Hitting M-j more times with insert more comment lines with the * prefix. This is the in-built behavior of c-indent-new-comment-line/indent-new-comment-line functions. Check out the Multiple lines of comments documentation.
  • An extra nugget in the below code ensures that there is at least one space between the * on each comment line and the comment.
(defun my-prettify-c-block-comment (orig-fun &rest args)
  (let* ((first-comment-line (looking-back "/\\*\\s-*.*"))
         (star-col-num (when first-comment-line
                         (save-excursion
                           (re-search-backward "/\\*")
                           (1+ (current-column))))))
    (apply orig-fun args)
    (when first-comment-line
      (save-excursion
        (newline)
        (dotimes (cnt star-col-num)
          (insert " "))
        (move-to-column star-col-num)
        (insert "*/"))
      (move-to-column star-col-num) ; comment this line if using bsd style
      (insert "*") ; comment this line if using bsd style
     ))
  ;; Ensure one space between the asterisk and the comment
  (when (not (looking-back " "))
    (insert " ")))
(advice-add 'c-indent-new-comment-line :around #'my-prettify-c-block-comment)
;; (advice-remove 'c-indent-new-comment-line #'my-prettify-c-block-comment)

For instance, after evaluating the above code, I get the below on typing: /* M-j First comment line M-j Second comment line. The ▮ indicates the cursor location at the end of typing.

/*
 * First comment line
 * Second comment line▮
 */ 

Testing offset comment block ..

With cursor after the semicolon, typing: /* M-j Test offset comment gives the below. The ▮ indicates the cursor location at the end of typing.

#include<stdio.h>
main() {
  printf("Hello World"); /*
                          * Test offset comment▮  
                          */                                 
}
3
  • Thanks! That works, but if I have (setq c-default-style "bsd" c-basic-offset 4) in my init.el, this happens: i.imgur.com/KMLx6Ll.gif Any idea?
    – Geier
    Aug 10, 2015 at 17:27
  • 1
    Removing (move-to-column star-col-num) (insert "*") from the above solution will fix that for you. I don't code in C, so I haven't investigated what variables are set by "bsd" style. Aug 10, 2015 at 18:06
  • Using this code with Dafny mode from github.com/boogie-org/boogie-friends, I get ` /*` for each newline rather than ` *`.
    – JAB
    May 22, 2017 at 22:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.