¿Cómo crear automáticamente bloques de comentarios C limpios mientras escribes?

17

Algunos editores de código, como eclipse, forman automáticamente bloques limpios cuando comienza a escribir un comentario de varias líneas:

ingrese la descripción de la imagen aquí

¿Hay algún paquete u otra forma de hacer esto en emacs también?

Editar: Para aclarar: no quiero una combinación de teclas que inserte un bloque de comentarios. Quiero que se cree automáticamente un bloque de comentarios cuando presiono RETdespués /*.

Geier
fuente
¿Revisaste esta pregunta similar? stackoverflow.com/a/6578421/4780877
Usuario de Emacs el
@EmacsUser: Sí. Pero eso no es lo que quiero. No quiero solo un fragmento o la función para comentar una región ya escrita.
Geier
Consulte el manual de Múltiples líneas de comentarios .
Dan
@Dan: Eso está bastante cerca, pero no inserta automáticamente el cierre*/
Geier
2
@Name Los *signos no son estrictamente necesarios, pero es bueno tenerlos .
Geier

Respuestas:

7

El siguiente código funciona bien desde mi breve prueba en un c-modebúfer:

  • Después de escribir /*, presione M-j, el enlace predeterminado para indent-new-comment-line(y el enlace predeterminado para c-indent-new-comment-linein c-mode). Si es la primera línea de comentario, los caracteres de cierre de cierre */se insertarán automáticamente.
  • Golpear M-jmás veces con insertar más líneas de comentario con el *prefijo. Este es el comportamiento incorporado de c-indent-new-comment-line/ indent-new-comment-linefunciones. Consulte la documentación de Múltiples líneas de comentarios .
  • Un nugget adicional en el siguiente código asegura que haya al menos un espacio entre *cada línea de comentario y el comentario.
(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)

Por ejemplo, después de evaluar el código anterior, me sale el siguiente en la tipificación: /* M-j First comment line M-j Second comment line. La ▮ indica la ubicación del cursor al final de la escritura.

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

Prueba del bloque de comentarios de compensación ...

Con el cursor después del punto y coma, escribiendo: /* M-j Test offset commentda lo siguiente. La ▮ indica la ubicación del cursor al final de la escritura.

#include<stdio.h>
main() {
  printf("Hello World"); /*
                          * Test offset comment▮  
                          */                                 
}
Kaushal Modi
fuente
¡Gracias! Eso funciona, pero si tengo (setq c-default-style "bsd" c-basic-offset 4)en mi init.el, esto sucede: i.imgur.com/KMLx6Ll.gif ¿ Alguna idea?
Geier
1
Eliminarlo (move-to-column star-col-num) (insert "*")de la solución anterior lo solucionará por usted. No codifico en C, así que no he investigado qué variables están establecidas por "bsd"estilo.
Kaushal Modi
Al usar este código con el modo Dafny de github.com/boogie-org/boogie-friends , obtengo `/ *` para cada nueva línea en lugar de `*`.
JAB