¿Cuál es una forma rápida de comentar / descomentar líneas en Vim?

1172

Tengo un archivo de código Ruby abierto en vi, hay líneas comentadas con #:

class Search < ActiveRecord::Migration
  def self.up
    # create_table :searches do |t|
    #   t.integer :user_id
    #   t.string :name
    #   t.string :all_of
    #   t.string :any_of
    #   t.string :none_of
    #   t.string :exact_phrase
    # 
    #   t.timestamps
    # end
  end

  def self.down
    # drop_table :searches
  end
end

Digamos que quiero descomentar todas las líneas en la primera def ... endsección. ¿Cuál es una manera eficiente de hacer eso en Vim?

En general, estoy buscando una manera fácil y fluida de comentar y descomentar líneas. Aquí estoy tratando con el código Ruby, pero podría ser JavaScript ( //) o Haml ( -#).

Ethan
fuente
20
La respuesta aceptada debe cambiarse a una de las respuestas que tiene instrucciones detalladas sobre cómo realizar bloques de comentarios / comentarios sin usar un complemento. La respuesta actual aceptada es básicamente solo un enlace a un complemento de terceros.
faintsignal
La respuesta mejor calificada no menciona ningún complemento, @rationalis su comentario es engañoso, ¿podría corregirlo o eliminarlo? Gracias.
bonobo

Respuestas:

181

Yo uso el script NERD Commenter . Le permite comentar, descomentar o alternar fácilmente los comentarios en su código.

Como se menciona en los comentarios :

para cualquiera que esté confundido por el uso, el líder predeterminado es "\", por lo que 10 \ cc comentará diez líneas y 10 \ cu descomentará esas diez líneas

Manuel Ceron
fuente
¡Interesante! Leí el Doc y descubrí que hay un "comentario sexy", solo use "\ cs". Para Ruby, usará =beginy =endpara comentar varias líneas en lugar de etiquetas hash.
Hegwin
Creo que no es la forma más rápida de hacerlo con vim, ya que requiere instalar un complemento. Además, la mejor respuesta ya ha recibido más votos, pero no se ha marcado como solución.
whirmill
138
No te detengas aquí. Las respuestas más votadas están a continuación sin el requisito de ningún complemento. stackoverflow.com/a/15588798/2117868 y stackoverflow.com/a/1676690/2117868
kuttumiah
@whirmill Creo que "mejor" realmente depende del caso de uso. El modo de bloqueo visual es más rápido si quiero alternar comentarios una vez en mi vida. Pero si no me importa instalar un complemento y quiero hacer la menor cantidad de pulsaciones posible para alternar comentarios y no tener que diferenciar la operación entre agregar o eliminar comentarios, entonces esta podría ser la "mejor respuesta".
Carolus el
@Carolus Hubiera estado de acuerdo contigo si la pregunta hubiera comenzado con "cuál es la mejor manera" en lugar de "qué es una manera rápida".
whirmill
2546

Para esas tareas que uso la mayor parte del tiempo selección del bloque de .

Coloque el cursor sobre el primer #carácter, presione CtrlV(o CtrlQpara gVim), baje hasta la última línea comentada y presionex , que eliminará todos los #caracteres verticalmente.

Para comentar un bloque de texto es casi lo mismo:

  1. Primero, vaya a la primera línea que desea comentar, presione CtrlV . Esto pondrá al editor en el VISUAL BLOCKmodo.
  2. Luego, usando la tecla de flecha y seleccione hasta la última línea
  3. Ahora presione ShiftI, lo que pondrá el editor en INSERTmodo y luego presione# . Esto agregará un hash a la primera línea.
  4. Luego presione Esc(dele un segundo) e insertará un #carácter en todas las demás líneas seleccionadas.

Para la versión simplificada de vim que se entrega con debian / ubuntu de forma predeterminada, escriba : s/^/#el tercer paso en su lugar (cualquier resaltado restante del primer carácter de cada línea se puede eliminar con :nohl).

Aquí hay dos pequeñas grabaciones de pantalla para referencia visual.

Comentario: Comentario

Comentario: Descomentar

CMS
fuente
87
Por defecto es CTRL + V. La versión de Windows de gvim usa Ctrl + Q porque Ctrl + V ya se usa para pegar.
R. Martinho Fernandes el
8
@amindfv Ctrl + V, n(donde n es num líneas - 1), j, n(donde n num número de longitud de la secuencia de caracteres de comentario - 1), l, x.
michael.bartnett
28
¿Cómo harías esto con '//'?
AustinT
74
Puede hacer clic en Esc dos veces para no esperar ese segundo;)
Ahmed Hegazy
45
Esto no funcionó para mí. Shift-Entré en modo de inserción simple.
Geremia
829

Para comentar bloques en vim:

  • presione Esc(para salir de la edición u otro modo)
  • hit ctrl+ v(modo de bloqueo visual)
  • use las teclas de flecha / para seleccionar las líneas que desee (no resaltará todo, ¡está bien!
  • Shift+ i(capital I)
  • inserte el texto que desee, por ejemplo %
  • prensa EscEsc

Para descomentar bloques en vim:

  • presione Esc(para salir de la edición u otro modo)
  • hit ctrl+ v(modo de bloqueo visual)
  • use las teclas de flecha / para seleccionar las líneas para descomentar.

    Si desea seleccionar varios caracteres, use uno o combine estos métodos:

    • use las teclas de flecha izquierda / derecha para seleccionar más texto
    • para seleccionar fragmentos de texto use la tecla shift+ / flecha
    • puede presionar repetidamente las teclas de eliminación a continuación, como un botón de eliminación normal

  • presione do xpara borrar caracteres, repetidamente si es necesario
amelia
fuente
35
@amelia: el atajo de comentario no funciona para mí. Shift + i me lleva al modo de inserción. ¿Depende de la versión vim?
user3527975
77
¿Por qué toma un segundo?
Conor Patrick
24
El único problema que tengo con esta respuesta es que te dice que uses las teclas de flecha .
cosyconemotel
66
Pulsa Esc dos veces en su lugar. :)
Aaron Alphonsus
22
Al principio, habilitar los comentarios no funcionó para mí, pero después de leerlo, una vez más funcionó bien: 1. asegúrese de usar Ctrl-V, no V para la selección 2. al insertarlo aparecerá ya que está modificando solo una línea 3. todas las inserciones ocurren cuando golpeas Esc al final
timurb
336

A veces me envuelven en una caja remota donde mis complementos y .vimrc no pueden ayudarme, o a veces NerdCommenter se equivoca (por ejemplo, JavaScript incrustado en HTML).

En estos casos, una alternativa de baja tecnología es el normcomando incorporado , que solo ejecuta cualquier comando vim arbitrario en cada línea en su rango especificado. Por ejemplo:

Comentando con # :

1. visually select the text rows (using V as usual)
2. :norm i#

Esto inserta "#" al comienzo de cada línea. Tenga en cuenta que cuando escribe: el rango se completará, por lo que realmente se verá como:'<,'>norm i#

Sin comentarios # :

1. visually select the text as before (or type gv to re-select the previous selection)
2. :norm x

Esto elimina el primer carácter de cada línea. Si hubiera usado un comentario de 2 caracteres como // entonces simplemente lo haría:norm xx para eliminar ambos caracteres.

Si los comentarios están sangrados como en la pregunta del OP, puede anclar su eliminación de esta manera:

:norm ^x

lo que significa "ir al primer carácter que no sea espacio, luego eliminar un carácter". Tenga en cuenta que, a diferencia de la selección de bloque, esta técnica funciona incluso si los comentarios tienen sangría desigual.

Nota : desdenorm que literalmente solo se ejecutan comandos vim regulares, no está limitado a comentarios, también puede realizar algunas modificaciones complejas en cada línea. Si necesita el carácter de escape como parte de su secuencia de comandos, escriba ctrl-v y luego presione la tecla de escape (o incluso más fácil, simplemente grabe una macro rápida y luego use la norma para ejecutar esa macro en cada línea).

Nota 2 : Por supuesto, también puede agregar una asignación si se encuentra usando normmucho. Por ejemplo, poner la siguiente línea en ~ / .vimrc le permite escribir en ctrl-nlugar de :normdespués de hacer su selección visual

vnoremap <C-n> :norm

Nota 3 : Vim Bare-bones a veces no tiene el normcomando compilado, así que asegúrese de usar la versión reforzada, es decir, típicamente / usr / bin / vim, no / bin / vi

(Gracias a @Manbroski y @rakslice por las mejoras incorporadas en esta respuesta)

Magnus
fuente
Pensé que este era el camino a seguir hasta que me desplacé para leer esta respuesta stackoverflow.com/a/1676690/850996 La selección de bloque usando CTRL + V (en oposición a la selección de línea con SHIFT + V) da un control mucho más agradable sobre dónde está el comentario Se lleva a cabo la inserción de caracteres.
Shyam Habarakada
2
@Shyam La técnica ctrl-v combinada con comandos especiales de selección de bloque solamente es lo que recomiendan la mayoría de las otras respuestas; sin embargo, personalmente considero que la técnica de "norma" que he descrito es más fácil porque no introduce ninguna sintaxis nueva además del comando de norma en sí, por lo que puedo reutilizar lo que ya sé sobre vim.
Magnus
2
Para descomentar un bloque sangrado, es útil decirlo :norm ^x. Este método en general tiene la ventaja de trabajar con selecciones de región (por ejemplo vi{, seleccionará dentro de llaves). Tales selectores de objetos de texto no funcionan con Visual Block.
ivan-k
1
Ah, acabo de descubrirlo: en centos 6 /bin/vies vim 7.2, pero es una construcción diferente /usr/bin/vimy tiene características como esta desactivadas.
rakslice
44
Esta es, de lejos, la mejor respuesta. Especialmente cuando se combina con vippara seleccionar un párrafo completo.
meh
122

Tengo lo siguiente en mi .vimrc:

" Commenting blocks of code.
autocmd FileType c,cpp,java,scala let b:comment_leader = '// '
autocmd FileType sh,ruby,python   let b:comment_leader = '# '
autocmd FileType conf,fstab       let b:comment_leader = '# '
autocmd FileType tex              let b:comment_leader = '% '
autocmd FileType mail             let b:comment_leader = '> '
autocmd FileType vim              let b:comment_leader = '" '
noremap <silent> ,cc :<C-B>silent <C-E>s/^/<C-R>=escape(b:comment_leader,'\/')<CR>/<CR>:nohlsearch<CR>
noremap <silent> ,cu :<C-B>silent <C-E>s/^\V<C-R>=escape(b:comment_leader,'\/')<CR>//e<CR>:nohlsearch<CR>

Ahora puede escribir ,ccpara comentar una línea y,cu descomentar una línea (funciona tanto en modo normal como visual).

(Lo robé de algún sitio web hace muchos años, así que ya no puedo explicar completamente cómo funciona :). Hay un comentario donde se explica).

jqno
fuente
¿Cuál es el atajo que debo usar? ¡No puedo asegurarme del código vim mismo!
Gideon
en modo normal o visual, use ", cc" (secuencia de 3 caracteres) para comentar la línea actual y ", cu" para descomentar la línea actual.
Dan
8
me gusta :)! ¡Gracias! En una nota al margen, no me resulta difícil de explicar. a) reasigna un comando (no de forma recursiva [vea esto] ( stackoverflow.com/questions/3776117/… ) así que ahora cuando presiona, cc se ejecuta: ... la cosa se ejecuta. b) ahora esto es básicamente un sed (s El comando / what / towhat / where) cambia ^ (inicio de línea) al carácter de comentario establecido correctamente en función del tipo de archivo que ha abierto c) en cuanto a las cosas silenciosas que simplemente suprimen la salida de los comandos. d): nohlsearch le impide resaltar la búsqueda sed
ramrunner
14
Tenga en cuenta que esta no es la forma correcta de cargar comandos automáticos. Deben estar dentro de un grupo o de lo contrario se agregarán a vim varias veces y causarán una gran desaceleración. Ver: learnvimscriptthehardway.stevelosh.com/chapters/14.html . He agregado mi respuesta a esta pregunta.
Agradable. Esta es una respuesta real a la pregunta que tenía sobre cómo (des) comentar mientras tiene una selección de bloque.
Erwin Rooijakkers
120

Especifique qué líneas comentar en vim:

Revelar los números de línea:

:set number

entonces

:5,17s/^/#/     this will comment out line 5-17

o esto:

:%s/^/#/        will comment out all lines in file
Carlos
fuente
11
Como solo está cambiando el primer carácter de cada línea, no necesita la "g" al final
Magnus,
1
Algunos VIMS en cajas incrustados (como OpenWRT) no tienen modo visual .. Así que esto es freaking impresionante :)
kim0
¿Puede explicar por qué :%s/^/#/gcomentará todas las líneas? Me preguntaba el signo de porcentaje%
Bin
18
Y para descomentar estas líneas puede escribir: 5,17s / ^ # /
Iraklis Moutidis
¡Excelente! Realmente funciona muy bien con la selección de bloques como: va{o con varruby.
Artur Małecki
58

Así es como lo hago:

  1. Vaya al primer carácter en la primera línea que desea comentar.

  2. Hit Ctrl+ qen gVim o Ctrl+ ven VIM, y luego ir hacia abajo para seleccionar el primer carácter en las líneas a comentar.

  3. Luego presione cy agregue el carácter de comentario.

Descomentar funciona de la misma manera, simplemente escriba un espacio en lugar del carácter de comentario.

Marcin
fuente
44
ctambién elimina el primer personaje. La respuesta de CMS es correcta, es decir, presionar y Iluego escribir los caracteres de comentario y luego Esc(esto está en Windows vim)
Samaursa
66
Esto funciona, excepto que 'r' debe presionarse en el paso tres, no 'c'.
David Baucum
alternativamente, puede presionar ESCdos veces después de presionar cy eso debería hacer el truco
nihiser
Todas estas opciones son destructivas para el primer personaje en la línea.
Josiah
36

Se me ocurrió una simple adición a mi archivo .vimrc que funciona bastante bien y se puede extender fácilmente. Simplemente agregue un nuevo tipo de archivo al comment_map y su líder de comentarios.

Agregué un mapeo a los modos normal y visual, pero puedes reasignarlo a lo que quieras. Prefiero solo tener una función de estilo 'alternar'. Uno lleva múltiples mapeos, etc.

let s:comment_map = { 
    \   "c": '\/\/',
    \   "cpp": '\/\/',
    \   "go": '\/\/',
    \   "java": '\/\/',
    \   "javascript": '\/\/',
    \   "lua": '--',
    \   "scala": '\/\/',
    \   "php": '\/\/',
    \   "python": '#',
    \   "ruby": '#',
    \   "rust": '\/\/',
    \   "sh": '#',
    \   "desktop": '#',
    \   "fstab": '#',
    \   "conf": '#',
    \   "profile": '#',
    \   "bashrc": '#',
    \   "bash_profile": '#',
    \   "mail": '>',
    \   "eml": '>',
    \   "bat": 'REM',
    \   "ahk": ';',
    \   "vim": '"',
    \   "tex": '%',
    \ }

function! ToggleComment()
    if has_key(s:comment_map, &filetype)
        let comment_leader = s:comment_map[&filetype]
        if getline('.') =~ "^\\s*" . comment_leader . " " 
            " Uncomment the line
            execute "silent s/^\\(\\s*\\)" . comment_leader . " /\\1/"
        else 
            if getline('.') =~ "^\\s*" . comment_leader
                " Uncomment the line
                execute "silent s/^\\(\\s*\\)" . comment_leader . "/\\1/"
            else
                " Comment the line
                execute "silent s/^\\(\\s*\\)/\\1" . comment_leader . " /"
            end
        end
    else
        echo "No comment leader found for filetype"
    end
endfunction


nnoremap <leader><Space> :call ToggleComment()<cr>
vnoremap <leader><Space> :call ToggleComment()<cr>

Nota:

No utilizo devoluciones de llamada ni enlaces en los tipos / carga de archivos, porque encuentro que ralentizan el inicio de Vim más que la .vimrcfunción / mapa estático, pero esa es solo mi preferencia. También he tratado de mantenerlo simple y eficiente. Si utiliza los comandos automáticos, debe asegurarse de colocarlos en un grupo de comandos automáticos o, de lo contrario, las devoluciones de llamada se agregarán al tipo de archivo varias veces por archivo cargado y causarán una gran degradación del rendimiento.

ideasman42
fuente
1
Soy completamente nuevo en vim, ¿qué botón debo presionar para alternar la función asignada? ¿Cuál es esa <leader><Space>declaración en la parte inferior?
Jens Kohl
2
Puede reemplazar <leader> con una tecla como <,>. Luego presiona, ESPACIO y alternará el estado de comentario de la línea. El líder es cualquiera que sea tu líder, el <leader> predeterminado de Vim es \, pero puedes configurarlo como "let mapleader = ','"
Gran respuesta, sin embargo, una molestia, comentar bloques que ya tienen algunos comentarios, cambiará comentarios por líneas no comentadas. QtCreator, por ejemplo, solo elimina comentarios si todas las líneas no vacías tienen comentarios iniciales, de lo contrario, agregue un comentario principal.
ideasman42
1
Hice una versión ligeramente diferente usando \zsy \zetruco regex, el código se hizo un poco más pequeño. puedes verlo aquí
SergioAraujo
33

Cambiar comentarios

Si todo lo que necesita es alternar comentarios , prefiero ir con commentary.vim por tpope .

ingrese la descripción de la imagen aquí

Instalación

Patógeno:

cd ~/.vim/bundle
git clone git://github.com/tpope/vim-commentary.git

vim-plug:

Plug 'tpope/vim-commentary'

Paquete:

Plugin 'tpope/vim-commentary'

Personalización adicional

Agregue esto a su archivo .vimrc: noremap <leader>/ :Commentary<cr>

Ahora puede alternar comentarios presionando Leader+ /, al igual que Sublime y Atom.

Flavio Wuensche
fuente
¡Gracias! ¿Va a soportar comentarios CSS dentro de un HTML en algún momento en el futuro?
Dan Oak
25

Use Control-V para seleccionar rectángulos de texto: vaya al primer #carácter, escriba Ctrl+ V, muévase a la derecha una vez y luego hacia abajo, hasta el final de los comentarios. Ahora escriba x: está eliminando todos los #caracteres seguidos de un espacio.

Arthur Reutenauer
fuente
18

Aquí hay una sección de mi .vimrc:

"insert and remove comments in visual and normal mode
vmap ,ic :s/^/#/g<CR>:let @/ = ""<CR>
map  ,ic :s/^/#/g<CR>:let @/ = ""<CR>
vmap ,rc :s/^#//g<CR>:let @/ = ""<CR>
map  ,rc :s/^#//g<CR>:let @/ = ""<CR>

En modo normal y visual, esto me permite presionar ,icpara insertar comentarios y ,rceliminar comentarios.

innaM
fuente
Esto es muy útil para un principiante sobre cómo aprender a escribir por su cuenta .vimrc.
refrescante
3
mapcubre los modos normales y visuales, por lo que no necesita las vmaplíneas
dobleDown
Mejor lugar está adentro after/ftplugin/ruby.vim.
Santosh Kumar
también use <leader>icy<leader>rc
Hans Kristian
15

Yo uso vim 7.4 y esto funciona para mí.
Asumiendo que estamos comentando / descomentando 3 líneas.

Comentar:

si la línea no tiene tabulación / espacio al principio:
ctrl + Ventonces, jjjluego, shift + I (cappital i)luego //, esc esc
si la línea tiene tabulación / espacio al principio, aún puede hacer lo anterior o cambiar por c:
ctrl + Vluego jjj, cluego, //entonces esc esc

Para descomentar:

si las líneas no tienen tabulación / espacio al principio:
ctrl + Ventonces jjj, ll (lower cap L)luegoc

si las líneas tienen pestaña / espacio al principio, luego un espacio de una y esc
ctrl + Vluego jjja continuación, ll (lower cap L)a continuación, ca continuación, spacea continuación,esc

Andy
fuente
9

Con 30 respuestas por delante, intentaré dar una solución aún más fácil: inserte un #al principio de la línea. Luego baja una línea y presiona dot ( .). Para repetir, no j, ., j, ., etc ... Para uncomment, quita un #(usted puede golpear xsobre el #), y hacer el uso de reversa k, .etc ...

imaginador
fuente
1
Es una respuesta muy simple que incluso los principiantes pueden entender y usar. Sin embargo, funciona bastante lentamente en grandes cantidades de líneas para comentar. Para evitar esto, puede escribir I#<Esc>jen el búfer, por ejemplo, cy luego hacer 10@c, o cualquier número de líneas que le convenga.
Daerdemandt
9

Cómo descomentar las siguientes tres líneas en vi:

#code code
#code
#code code code

Coloque el cursor sobre el #símbolo superior izquierdo y presione CtrlV. Esto te pone en modo de bloqueo visual. Presione la flecha hacia abajo o Jtres veces para seleccionar las tres líneas. Luego presione D. Todos los comentarios desaparecen. Para deshacer, presione U.

Cómo comentar las siguientes tres líneas en vi:

code code
code
code code code

Coloque el cursor sobre el carácter superior izquierdo, presione CtrlV. Esto te pone en modo de bloqueo visual. Presione o Jtres veces para seleccionar las tres líneas. Entonces presione:

I//Esc

Esa es una mayúscula I, // y Escape.

Cuando presiona ESC, todas las líneas seleccionadas obtendrán el símbolo de comentario que especificó.

Ivor Scott
fuente
1
Si omite el hash "superior izquierdo", puede presionar o para mover el cursor al "otro lado" en modo visual.
dylnmc
Creo que es mejor usarlo. No necesita ningún tercero, solo use vim nativo
Ardi Nusawan
mejor respuesta, simple y sin ningún tercero
aze
8

Sí, ya hay 33 respuestas (en su mayoría repetitivas) a esta pregunta.

Aquí hay otro enfoque sobre cómo comentar líneas en Vim: movimientos . La idea básica es comentar o descomentar líneas usando el mismo método que tirar de un párrafo escribiendo yipo eliminando 2 líneas escribiendo dj.

Este enfoque te permitirá hacer cosas como:

  • ccjcomentar las siguientes 2 líneas y cukdescomentarlas;

  • cci{comentar un bloqueo y cui{descomentarlo;

  • ccipcomentar un párrafo completo y cuipdescomentarlo.

  • ccGcomentar todo hasta la última línea y cuggdescomentar todo hasta la primera línea.

Todo lo que necesita son 2 funciones que operan sobre movimientos y 2 asignaciones para cada función. Primero, las asignaciones:

nnoremap <silent> cc  :set opfunc=CommentOut<cr>g@
vnoremap <silent> cc  :<c-u>call  CommentOut(visualmode(), 1)<cr>
nnoremap <silent> cu  :set opfunc=Uncomment<cr>g@
vnoremap <silent> cu  :<c-u>call  Uncomment(visualmode(), 1)<cr>

(Consulte el manual sobre el g@operador y eloperatorfunc variable).

Y ahora las funciones:

function! CommentOut(type, ...)
  if a:0
    silent exe "normal!  :'<,'>s/^/#/\<cr>`<"
  else
    silent exe "normal!  :'[,']s/^/#/\<cr>'["
  endif
endfunction

function! Uncomment(type, ...)
  if a:0
    silent exe "normal!  :'<,'>s/^\\(\\s*\\)#/\\1/\<cr>`<"
  else
    silent exe "normal!  :'[,']s/^\\(\\s*\\)#/\\1/\<cr>`["
  endif
endfunction

Modifique las expresiones regulares anteriores para adaptarse a su gusto en cuanto a dónde #debería estar:

nr
fuente
"movimientos [...] completamente nuevos" parece un poco exagerado: los complementos t_comment y vim-commentary, que son anteriores a esta respuesta, le permiten comentar usando movimientos.
Rico
¡Buen material! Votado (También creo que podría comenzar a usar este enfoque en lugar del complemento que estaba usando anteriormente, ¡así que gracias por escribirlo!)
Rich
7

Si ya conoce los números de línea, entonces n,ms/# //funcionaría.

uckelman
fuente
Realmente eso probablemente debería ser: n, ms / ^ \ s. # // Debido a que podría tener un espacio en blanco inicial y no seguir el hash con uno
Skip Huffman
7

Marco la primera y la última línea (ma y mb), y luego hago: 'a', bs / ^ # //

SDGator
fuente
6

Yo uso EnhancedCommentify . Comenta todo lo que necesitaba (lenguajes de programación, scripts, archivos de configuración). Lo uso con enlaces de modo visual. Simplemente seleccione el texto que desea comentar y presione co / cc / cd.

vmap co :call EnhancedCommentify('','guess')<CR>
vmap cc :call EnhancedCommentify('','comment')<CR>
vmap cd :call EnhancedCommentify('','decomment')<CR> 
qba
fuente
5

Combiné la respuesta de Phil y jqno e hice comentarios alternos con espacios:

autocmd FileType c,cpp,java,scala let b:comment_leader = '//'
autocmd FileType sh,ruby,python   let b:comment_leader = '#'
autocmd FileType conf,fstab       let b:comment_leader = '#'
autocmd FileType tex              let b:comment_leader = '%'
autocmd FileType mail             let b:comment_leader = '>'
autocmd FileType vim              let b:comment_leader = '"'
function! CommentToggle()
    execute ':silent! s/\([^ ]\)/' . b:comment_leader . ' \1/'
    execute ':silent! s/^\( *\)' . b:comment_leader . ' \?' . b:comment_leader . ' \?/\1/'
endfunction
map <F7> :call CommentToggle()<CR>
mathewguest
fuente
5

Existe este complemento que cambia la vida tpopellamadovim-commentary

https://github.com/tpope/vim-commentary

Este complemento proporciona :

  • Cordura
  • Comentarios correctamente sangrados
  • No comenta líneas vacías / innecesarias

Uso :

  • Instalar a través de Vundle (o patógeno, supongo).
  • Resalta tu texto y presiona :que aparecerá como:<,'>
  • Escriba Comentario aquí :<,'>Commentaryy presione Enter.
  • Auge. Tu amigo hecho.
Weston Ganger
fuente
vim-commentary(como todos los complementos de tpope) tiene la ventaja de ser idiota vim. gc= "ir a comentar", gcap= "ir a comentar un párrafo", etc.
goldenratio
¿Podría haber sido solo una edición de la respuesta de Tim Pope de Jim Stewart?
jdk1.0
5

Esta respuesta es más útil si no puede instalar complementos pero aún desea que sus caracteres de comentario sigan los niveles de sangría existentes.

Esta respuesta está aquí a 1) muestra el código correcto para pegar en una .vimrcde conseguir vim 7.4+hacer el bloque de comentar / descomentar manteniendo nivel de sangría con 1 acceso directo en el modo visual y 2) para explicarlo. Aquí está el código:

let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.[ch]    let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.cpp    let b:commentChar='//'
autocmd BufNewFile,BufReadPost *.py    let b:commentChar='#'
autocmd BufNewFile,BufReadPost *.*sh    let b:commentChar='#'
function! Docomment ()
  "make comments on all the lines we've grabbed
  execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'
endfunction
function! Uncomment ()
  "uncomment on all our lines
  execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'
endfunction
function! Comment ()
  "does the first line begin with a comment?
  let l:line=getpos("'<")[1]
  "if there's a match
  if match(getline(l:line), '^\s*'.b:commentChar)>-1
    call Uncomment()
  else
    call Docomment()
  endif
endfunction
vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>

Cómo funciona:

  • let b:commentChar='//': Esto crea una variable en vim. el baquí se refiere al alcance, que en este caso está contenido en el búfer, es decir, el archivo abierto actualmente. Sus caracteres de comentario son cadenas y deben estar entre comillas, las comillas no son parte de lo que se sustituirá al alternar comentarios.

  • autocmd BufNewFile,BufReadPost *...: Los comandos automáticos se disparan en diferentes cosas, en este caso, se disparan cuando un nuevo archivo o el archivo de lectura termina con una cierta extensión. Una vez activado, ejecute el siguiente comando, que nos permite cambiar el tipo commentCharde archivo dependiendo. Hay otras formas de hacer esto, pero son más confusas para los novatos (como yo).

  • function! Docomment(): Las funciones se declaran comenzando functiony terminando con endfunction. Las funciones deben comenzar con una capital. los !asegura que esta función sobrescribe los anteriores funciones definidas como Docomment()con esta versión de Docomment(). Sin el !, tuve errores, pero eso podría deberse a que estaba definiendo nuevas funciones a través de la línea de comando vim.

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e': Ejecutar llama a un comando. En este caso, estamos ejecutando substitute, que puede tomar un rango (por defecto, esta es la línea actual), como %para todo el búfer o '<,'>para la sección resaltada. ^\s*es regex para que coincida con el inicio de una línea seguida de cualquier cantidad de espacio en blanco, que luego se agrega a (debido a &). El .que aquí se utiliza para la concatenación de cadenas, ya que escape()no se puede ajustar entre comillas. escape()le permite escapar de caracteres commentCharque coinciden con los argumentos (en este caso, \y /) al anteponerlos con un \. Después de esto, nos concatenamos nuevamente con el final de nuestrosubstitute cadena, que tiene elebandera. Esta bandera nos permite fallar en silencio, lo que significa que si no encontramos una coincidencia en una línea determinada, no gritaremos al respecto. En general, esta línea nos permite poner un carácter de comentario seguido de un espacio justo antes del primer texto, lo que significa que mantenemos nuestro nivel de sangría.

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e': Esto es similar a nuestro último gran comando largo. Único a este, tenemos \v, lo que asegura que no tenemos que escapar de nuestro (), y 1, que se refiere al grupo que hicimos con nuestro (). Básicamente, estamos haciendo coincidir una línea que comienza con cualquier cantidad de espacio en blanco y luego nuestro carácter de comentario seguido de cualquier cantidad de espacio en blanco, y solo mantenemos el primer conjunto de espacios en blanco. Nuevamente, edejemos de fallar en silencio si no tenemos un carácter de comentario en esa línea.

  • let l:line=getpos("'<")[1]: establece una variable muy similar a lo que hicimos con nuestro carácter de comentario, pero se lrefiere al ámbito local (local para esta función). getpos()obtiene la posición de, en este caso, el inicio de nuestro resaltado, y [1]significa que solo nos importa el número de línea, no otras cosas como el número de columna.

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1: ya sabes cómo iffunciona. match()verifica si lo primero contiene lo segundo, por lo que tomamos la línea en la que comenzamos a resaltar y verificamos si comienza con un espacio en blanco seguido de nuestro carácter de comentario. match()devuelve el índice donde esto es cierto, y -1si no se encontraron coincidencias. Como ifevalúa todos los números distintos de cero para que sean verdaderos, tenemos que comparar nuestra salida para ver si es mayor que -1. La comparación en vimdevuelve 0 si es falso y 1 si es verdadero, que es lo que ifquiere ver para evaluar correctamente.

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>: vnoremapsignifica asignar el siguiente comando en modo visual, pero no asignarlo de forma recursiva (es decir, no cambiar ningún otro comando que pueda usarse de otras maneras). Básicamente, si eres un novato vim, siempre úsalo noremappara asegurarte de no romper cosas. <silent>significa "No quiero tus palabras, solo tus acciones" y le dice que no imprima nada en la línea de comando. <C-r>es lo que estamos asignando, que es ctrl + r en este caso (tenga en cuenta que todavía puede usar Cr normalmente para "rehacer" en modo normal con esta asignación). C-ues un poco confuso, pero básicamente se asegura de que no pierdas el rastro de tu resaltado visual (según esta respuesta , tu comando comienza con '<,'>lo que queremos).call aquí solo le dice a vim que ejecute la función que nombramos, y<cr> refiere a enterpresionar el botón.call function() en la línea de comando, y tenemos que presionarlo nuevamente para que nuestros sustitutos pasen por todo el camino (no estoy seguro de por qué, pero lo que sea).

De todos modos, espero que esto ayude. Esto tomará todo lo resaltado con v, Vo C-v, verifique si la primera línea está comentada, en caso afirmativo, intente descomentar todas las líneas resaltadas, y si no, agregue una capa adicional de caracteres de comentario a cada línea. Este es mi comportamiento deseado; No solo quería que cambiara si cada línea en el bloque estaba comentada o no, por lo que funciona perfectamente para mí después de hacer múltiples preguntas sobre el tema.

jeremysprofile
fuente
3

Puede usar vim-commentary de tpope ( https://github.com/tpope/vim-commentary ) puede usarlo de la siguiente manera:

Ingrese al modo visual presionando

'v'

Entonces presione

'j' repeatedly or e.g 4j to select 4 row

Ahora todo lo que tiene que hacer con la selección es ingresar teclas:

'gc'

Esto comentará toda la selección, para descomentar las teclas de repetición:

'gc'
Kingsley Ijomah
fuente
3

Aquí hay una línea básica basada en lo C-vseguido porI método descrito anteriormente.

Este comando ( :Comment) agrega una cadena elegida al comienzo de cualquier línea seleccionada.

command! -range -nargs=1 Comment :execute "'<,'>normal! <C-v>0I" . <f-args> . "<Esc><Esc>"

Agregue esta línea a su .vimrcpara crear un comando que acepte un solo argumento y coloque el argumento al comienzo de cada línea en la selección actual.

Por ejemplo, si se selecciona el siguiente texto:

1
2

y ejecutas esto: :Comment //el resultado será:

//1
//2
bgran
fuente
3

Comenzando con las ideas en las respuestas aquí, comencé mi propia función de comentarios. Activa y desactiva los comentarios. Puede manejar cosas como //print('blue'); //this thing is bluey solo alterna el primer comentario. Además, agrega comentarios y un solo espacio justo donde está el primer espacio no en blanco y no al comienzo de la línea. Además, no copia innecesariamente los espacios en blanco, sino que usa los zooms (: h \ zs para obtener ayuda) para evitar este trabajo adicional, al comentar y la línea sangrada. Espero que ayude a algunos minimalistas. Las sugerencias son bienvenidas.

" these lines are needed for ToggleComment()
autocmd FileType c,cpp,java      let b:comment_leader = '//'
autocmd FileType arduino         let b:comment_leader = '//'
autocmd FileType sh,ruby,python  let b:comment_leader = '#'
autocmd FileType zsh             let b:comment_leader = '#'
autocmd FileType conf,fstab      let b:comment_leader = '#'
autocmd FileType matlab,tex      let b:comment_leader = '%'
autocmd FileType vim             let b:comment_leader = '"'

" l:pos   --> cursor position
" l:space --> how many spaces we will use b:comment_leader + ' '

function! ToggleComment()
    if exists('b:comment_leader')
        let l:pos = col('.')
        let l:space = ( &ft =~ '\v(c|cpp|java|arduino)' ? '3' : '2' )
        if getline('.') =~ '\v(\s*|\t*)' .b:comment_leader
            let l:space -= ( getline('.') =~ '\v.*\zs' . b:comment_leader . '(\s+|\t+)@!' ?  1 : 0 )
            execute 'silent s,\v^(\s*|\t*)\zs' .b:comment_leader.'[ ]?,,g'
            let l:pos -= l:space
        else
            exec 'normal! 0i' .b:comment_leader .' '
            let l:pos += l:space
        endif
        call cursor(line("."), l:pos)
    else
        echo 'no comment leader found for filetype'
    end
endfunction

nnoremap <Leader>t :call ToggleComment()<CR>
inoremap <Leader>t <C-o>:call ToggleComment()<CR>
xnoremap <Leader>t :'<,'>call ToggleComment()<CR>
Miguel
fuente
1
He creado una versión ligeramente diferente de su solución que también restaura la posición del cursor, me gustaría conocer su opinión al respecto. en github
SergioAraujo
Frio. ¡Puedes editar mi publicación y agregar tu solución (debido a la similitud)!
Mike
Se ha cambiado para evitar la reducción inversa de c, cpp, java y el uso de otro separador en sustituciones para evitar E488. También el espacio cambia para java, cpp porque los comentarios tienen tres caracteres, // más espacio, esto lo hace l: espacio.
SergioAraujo
3

Yo uso comments.vim de Jasmeet Singh Anand (encontrado en vim.org),

Funciona con C, C ++, Java, PHP [2345], proc, CSS, HTML, htm, XML, XHTML, vim, vimrc, SQL, sh, ksh, csh, Perl, tex, fortran, ml, caml, ocaml, vhdl, haskel y archivos normales

Comenta y descomenta líneas en diferentes archivos fuente tanto en modo normal como visual

Uso:

  • CtrlCa comentar una sola línea
  • CtrlXpara descomentar una sola línea
  • ShiftVy seleccione varias líneas, luego CtrlCcomente las múltiples líneas seleccionadas
  • ShiftVy seleccione varias líneas, luego CtrlXdescomente las múltiples líneas seleccionadas
Ronan
fuente
3

El método más rápido e intuitivo de todos es reasignar )para comentarios de líneas, y luego( para hacer comentarios sin comentarios. Pruébalo y no volverás.

En Ruby o Bash , con sangría de 2 espacios:

map ) I# <Esc>j
map ( k^2x

En C / C ++ o PHP , con sangrías de 4 espacios:

map ) I//  <Esc>j
map ( k^4x

Lo malo es que pierdes (y )mueves las oraciones (pero daspuedes completarlas), y ocasionalmente recurres a seleccionar y reemplazar oCtrlV para manejar secciones largas. Pero eso es bastante raro.

Y para el estilo C, los comentarios largos se manejan mejor con:

set cindent
set formatoptions=tcqr

... Que combina bien con el uso V[move]gqpara rehacer el ajuste de palabras.

eukras
fuente
2

Este fragmento simple es de mi .vimrc:

function! CommentToggle()
    execute ':silent! s/\([^ ]\)/\/\/ \1/'
    execute ':silent! s/^\( *\)\/\/ \/\/ /\1/'
endfunction

map <F7> :call CommentToggle()<CR>

Es para // - Comentarios, pero puedes adaptarlo fácilmente para otros personajes. Puede usar autocmd para establecer un líder como sugirió jqno.

Esta es una forma muy simple y eficiente de trabajar con rangos y modo visual de forma natural.

Phil
fuente
2

Me gusta /* ... */(comentarios de C ansi), así que aquí está mi truco para ti. Puede adaptarlo para usarlo en diferentes casos, por supuesto.


Comenta con / * ... * /

Seleccione el texto (vaya al comienzo, comience el bloque visual, salte con }):

<c-V>}

Escriba el comando que se aplicará en la selección.

:norm i/* <c-v><esc>$a */

El comando se verá así: :'<,'>norm i /* ^[$a */

Ver (i *) para más detalles.


Descomenta el / * ... * /

Seleccione el texto (como antes, u otra forma que desee):

<c-V>}

Escriba el comando que se aplicará en la selección.

:norm :s-\s*/\*\s*-<c-v><enter>$bbld$

El comando se verá así: :'<,'>norm :s-\s*/\*\s*-^M$bbld$

Ver (ii *) para más detalles.


Resultado

El efecto es comentarios línea por línea:

Comment block
Comment block
Comment block

Se convierte (y viceversa):

/* Comment block */
/* Comment block */
/* Comment block */

Es mejor guardarlo como algo mapo @regen tu .vimrc, porque es mucho para escribir. Si prefiere una sola /*y */que todo el bloque, utilice:

Comenta con un solo / * * / todo el bloque

Guárdelo en un registro grabando con, digamos qc, luego, al comienzo de un párrafo para comentar:

v}di/*  */<esc>hhhp

y no te olvides de qnuevo, para terminar el disco.

Ver (iii *) para más detalles.


Descomentar un solo / * * / de un bloque

Guardar en el registro, por ejemplo, @u. Coloque el cursor en cualquier lugar dentro del bloque y:

?/\*<enter>xx/\*/<enter>xx

Guarde el registro terminando q comando.

Ver (iv *) para más detalles.


Resultado

El efecto es un solo comentario para varias líneas:

Comment block
Comment block
Comment block

Se convierte (y viceversa):

/* Comment block
Comment block
Comment block */

Explicaciones

(i *) Funciona mediante el uso normque aplica el mismo comando repetidamente en cada línea seleccionada. El comando simplemente inserta un /*, encuentra el final de esa línea y termina insertando un*/

:norm i/* <c-v><esc>$a */

(ii *) También se utiliza normpara repetir la búsqueda / reemplazo en cada línea. Buscar spaces /* spacesy reemplazar por nada. Después de eso, encuentra el final de la línea, retrocede dos palabras, escribe una letra, borra hasta el final.

:norm :s-\s*/\*\s*-<c-v><enter>$bbld$

(iii *) Selecciona el párrafo por v}, elimínelo, inserte un comentario abierto y cercano, muévalo a la mitad y pegue el bloque eliminado.

v}di/*  */<esc>hhhp

(iv *) En cualquier lugar en el medio, encuentra hacia atrás a /*, lo elimina; encuentra hacia adelante a */, lo elimina.

?/\*<enter>xx/\*/<enter>xx
Dr. Beco
fuente