Vim: auto-comentario en nueva línea


9

Vim inserta automáticamente un comentario cuando comienzo una nueva línea desde una línea comentada, porque lo he configurado formatoptions=tcroql. Por ejemplo (el cursor es *):

// this is a comment*

y después de presionar <Enter>(modo de inserción) o o(modo normal) me queda:

// this is a comment
// *

Esta característica es muy útil al escribir comentarios largos de varias líneas, pero a menudo solo quiero un comentario de una sola línea. Ahora, si quiero finalizar la serie de comentarios, tengo varias opciones:

  • golpear <Esc>S
  • golpear <BS>tres veces

Ambos ofrecen tres pulsaciones de teclas, junto con <Enter>esto significa cuatro pulsaciones de teclas para una nueva línea, lo que creo que es demasiado. Idealmente, me gustaría golpear <Enter>una segunda vez para quedarme con:

// this is a comment
*

Es importante que la solución también funcione con diferentes niveles de sangría, es decir

int main(void) {
    // this is a comment*
}

golpear <Enter>

int main(void) {
    // this is a comment
    // *
}

golpear <Enter>

int main(void) {
    // this is a comment
    *
}

Creo que he visto esta característica en algún editor de texto hace unos años, pero no recuerdo cuál era. ¿Alguien sabe de una solución que haga esto por mí en Vim? Los punteros en la dirección correcta sobre cómo lanzar mi propia solución también son muy bienvenidos.


3
Puede usar ctrl-u en modo de inserción para eliminar los marcadores de comentarios insertados automáticamente en un acorde de tecla.
Etan Reisner

1
@EtanReisner eso es realmente mejor, pero aún así una pulsación de tecla demasiado para mí, ya que es un caso de uso tan común :)
Patrick Oscity

¿Sugeriste que querías poder presionar enter nuevamente para obtener el comportamiento que querías pero ctrl-u es demasiado? Puede intentar asignar <enter> <enter> en modo de inserción para realizar automáticamente el ctrl-u por usted, pero eso introduciría un retraso si alguna vez presiona <enter> solo una vez (sin presionar nada más).
Etan Reisner

Bueno, además, solo debería activarse si la línea comentada está vacía. Un retraso notable al presionar <Enter> también es inaceptable.
Patrick Oscity el

Creo que solo se retrasará si no presionas ninguna otra tecla, ya que vim tendrá que esperar para asegurarte de que todavía no planeas presionar otra tecla. También podría usar una función para realizar esa verificación, aunque podría no ser particularmente fácil de hacer.
Etan Reisner el

Respuestas:


4

Prueba esto:

function! EnterEnter()
  if getline(".") =~ '^\s*\(//\|#\|"\)\s*$'
    return "\<C-u>"
  else
    return "\<CR>"
  endif
endfunction

imap <expr> <CR> EnterEnter()

Gracias se ve genial! Lo intentaré cuando llegue a casa. ¿Conoces una forma de extender la expresión regular para que coincida con el lenguaje de los marcadores de comentarios de forma independiente? La información debe estar allí en los archivos de sintaxis o algo así. Tal vez pueda aprovechar la función de sintaxis para esto ...
Patrick Oscity

Quiero decir que en C debe coincidir con // y / * y * (comentarios multilínea) y en ruby ​​# y así sucesivamente
Patrick Oscity el

Obviamente, esta función no es genérica en absoluto. Ver :h 'comment'y :h format-comment'.
romainl

Función modificada para trabajar con el #ruby y el "vimscript además del clásico //. Realmente no tiene sentido hacer nada por los *comentarios multilínea de estilo C porque debe terminar con el de */todos modos.
romainl

Hmm, tal vez <CR><CR>podría usarse para terminar el comentario multilínea ...
romainl

3

Extendí la respuesta de @ romainl para trabajar con lenguajes arbitrarios generando la expresión regular de Vim &commentstring:

function! s:IsOnlyComment(getlineArg)
  let commentRegex='^\s*'.substitute(&commentstring,'%s','\\s*','').'$'
  return strlen(matchstr(getline(a:getlineArg), commentRegex)) > 0
endfunction

function! SmartEnter()
  if s:IsOnlyComment('.')
    return "\<Esc>S"
  else
    return "\<CR>"
  endif
endfunction

inoremap <expr> <CR> SmartEnter()

Sin embargo, parece que no puedo reasignar <CR>en absoluto, esto simplemente no funcionará. Por ahora, lo uso <CR><CR>hasta que se resuelva este problema.


1
¿Por qué <Esc>S? <C-u>hace lo mismo sin salir del modo de inserción. De todos modos, tenía una función personalizada que hacía un montón de cosas <CR>y la renombré SmartEnter()solo ayer después de publicar mi respuesta ;-). Tampoco estoy seguro de que &commentstringsea ​​la opción correcta, ya que generalmente solo contiene un formulario y puede ser "en línea" o "en bloque" ( /*%s*/en C, //%sen Javascript, etc.).
romainl

2

Eliminar r de 'formatoptions. Eso es lo que hace esa opción. Desactivarlo significará que nunca tendrás vim haciendo eso por ti, lo que significa que tendrás que agregar los marcadores de comentarios principales cuando realmente los quieras, pero eso es una compensación.


2
De hecho, quiero que Vim agregue los marcadores de comentarios para mí, me encanta esto. Pero también quiero una forma rápida de salir del comentario. Gracias por tu respuesta sin embargo.
Patrick Oscity el

Para el comando 'o' en modo normal, uno debe eliminar 'r' deformatoptions
eleg
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.