17

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 /*.

  • Did you check this similar question? stackoverflow.com/a/6578421/4780877 – Emacs User Aug 7 '15 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 '15 at 17:44
  • See the manual for Multiple Lines of Comments. – Dan Aug 7 '15 at 18:04
  • @Dan: That's pretty close, but it does not automatically insert the closing */ – Geier Aug 7 '15 at 18:45
  • 2
    @Name The * signs are not strictly required, but nice to have. – Geier Aug 7 '15 at 21:18
7

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▮  
                          */                                 
}
  • 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 '15 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. – Kaushal Modi Aug 10 '15 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 '17 at 22:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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