O que é uma maneira rápida de comentar / descomentar linhas no Vim?

1172

Eu tenho um arquivo de código Ruby aberto no vi, existem linhas comentadas com #:

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 eu queira descomentar todas as linhas da primeira def ... endseção. Qual é uma maneira eficiente de fazer isso no Vim?

Em geral, estou procurando uma maneira fácil e fluida de comentar e comentar comentários. Aqui estou lidando com o código Ruby, mas pode ser JavaScript ( //) ou Haml ( -#).

Ethan
fonte
20
A resposta aceita deve ser alterada para uma das respostas que possui instruções detalhadas sobre como realizar blocos de comentários / comentários sem usar um plug-in. A resposta atual aceita é basicamente apenas um link para um plug-in de terceiros.
Faintsignal
A resposta melhor classificada não menciona nenhum plug-in, @racional é seu comentário enganador, você pode corrigi-lo ou removê-lo, obrigado.
bonobo

Respostas:

181

Eu uso o script NERD Commenter . Permite comentar, descomentar ou alternar comentários com facilidade no seu código.

Como mencionado nos comentários :

para quem está confuso com o uso, o líder padrão é "\", então 10 \ cc comentará dez linhas e 10 \ cu descomentará essas dez linhas

Manuel Ceron
fonte
Interessante! Eu li o Doc e descobri que há um "comentário sexy" - basta usar "\ cs". Para Ruby, ele usa =begine =endcomenta várias linhas em vez de tags de hash.
Hegwin
Eu acho que não é a maneira mais rápida de fazer isso com o vim, pois requer a instalação de um plugin. Além disso, a melhor resposta já recebeu mais votos, mas não foi marcada como solução.
whirmill
138
Não pare por aqui. As respostas mais votadas estão abaixo sem a necessidade de plugins. stackoverflow.com/a/15588798/2117868 e stackoverflow.com/a/1676690/2117868
kuttumiah
@ whirmill Eu acho que "melhor" realmente depende do caso de uso. O modo de bloqueio visual é mais rápido se eu quiser alternar os comentários uma vez na vida. Mas se eu não me importo em instalar um plug-in e quero fazer o menor número possível de teclas para alternar os comentários e não precisar diferenciar a operação entre adicionar ou remover comentários - então esta aqui pode ser a "melhor resposta".
Carolus
@Carolus Eu teria concordado com você se a pergunta tivesse começado com "qual é a melhor maneira" em vez de "qual é uma maneira rápida".
amigos estão dizendo sobre whirmill
2544

Para essas tarefas, uso a maior parte da seleção de blocos de tempo .

Coloque o cursor no primeiro #caractere, pressione CtrlV(ou CtrlQpara gVim) e desça até a última linha comentada e pressione x, que excluirá todos os #caracteres na vertical.

Para comentar um bloco de texto é quase o mesmo:

  1. Primeiro, vá para a primeira linha que deseja comentar, pressione CtrlV. Isso colocará o editor no VISUAL BLOCKmodo.
  2. Em seguida, use a tecla de seta e selecione até a última linha
  3. Agora pressione ShiftI, o que colocará o editor no INSERTmodo e depois pressione# . Isso adicionará um hash à primeira linha.
  4. Em seguida, pressione Esc(aguarde um segundo) e ele inserirá um #caractere em todas as outras linhas selecionadas.

Para a versão simplificada do vim enviada com o debian / ubuntu por padrão, digite : s/^/#a terceira etapa (qualquer destaque restante do primeiro caractere de cada linha pode ser removido com:nohl ).

Aqui estão duas pequenas gravações de tela para referência visual.

Comente: Comment

Descomentar: Uncomment

CMS
fonte
87
Por padrão, é CTRL + V. A versão do gvim para Windows usa Ctrl + Q porque Ctrl + V já é usado para colar.
R. Martinho Fernandes
8
@amindfv Ctrl + V, n(onde n é um número de linhas - 1), j, n(onde n num número de comprimento da sequência de caracteres do comentário - 1), l, x.
michael.bartnett
28
Como você faria isso com '//'?
AustinT
74
Você pode clicar em Esc duas vezes para não esperar esse segundo;)
Ahmed Hegazy
45
Isso não funcionou para mim. Shift-eu entrei no modo de inserção simples.
Geremia 14/02
828

Para comentar os blocos no vim:

  • pressione Esc(para sair da edição ou outro modo)
  • pressione ctrl+ v(modo de bloqueio visual)
  • use as teclas de seta / para selecionar as linhas que você deseja (não destacará tudo - tudo bem!)
  • Shift+ i(capital I)
  • insira o texto desejado, por exemplo %
  • pressione EscEsc

Para remover o comentário de blocos no vim:

  • pressione Esc(para sair da edição ou outro modo)
  • pressione ctrl+ v(modo de bloqueio visual)
  • use as teclas de seta / para selecionar as linhas a serem descomentadas.

    Se você deseja selecionar vários caracteres, use um ou combine estes métodos:

    • use as teclas de seta esquerda / direita para selecionar mais texto
    • para selecionar partes do texto, use a tecla shift+ / seta
    • você pode pressionar repetidamente as teclas de exclusão abaixo, como um botão de exclusão comum

  • pressione dou xpara excluir caracteres, repetidamente se necessário
amelia
fonte
34
@amelia: O atalho para comentários não funciona para mim. Shift + i leva-me ao modo de inserção. Depende da versão vim?
user3527975
7
Por que demora um segundo?
Conor Patrick
24
O único problema que tenho com esta resposta é que ela diz para você usar as teclas de seta .
Cozyconemotel
6
Pressione Esc duas vezes. :)
Aaron Alphonsus
22
A princípio, permitir comentários não funcionou para mim, mas depois de ler isso funcionou bem novamente: 1. certifique-se de usar Ctrl-V, não V para a seleção 2. ao inseri-lo, aparecerá porque você está modificando apenas uma única linha 3. todas as inserções acontecem quando você pressiona Esc no final
timurb
335

Às vezes, estou dentro de uma caixa remota onde meus plugins e .vimrc não podem me ajudar, ou às vezes o NerdCommenter erra (por exemplo, JavaScript incorporado no HTML).

Nesses casos, uma alternativa de baixa tecnologia é o normcomando interno, que apenas executa qualquer comando arbitrário do vim em cada linha no intervalo especificado. Por exemplo:

Comentando com # :

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

Isso insere "#" no início de cada linha. Observe que, quando você digita: o intervalo será preenchido, então parecerá realmente:'<,'>norm i#

Sem comentários # :

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

Isso exclui o primeiro caractere de cada linha. Se eu tivesse usado um comentário de 2 caracteres, como //, simplesmente faria :norm xxpara excluir os dois caracteres.

Se os comentários forem recuados como na pergunta do OP, você poderá ancorar sua exclusão desta forma:

:norm ^x

o que significa "vá para o primeiro caractere não espacial e exclua um caractere". Observe que, diferentemente da seleção de blocos, essa técnica funciona mesmo que os comentários tenham recuo desigual!

Nota : Como normliteralmente está apenas executando comandos regulares do vim, você não se limita a comentários, também pode fazer algumas edições complexas em cada linha. Se você precisar do caractere de escape como parte de sua sequência de comandos, digite ctrl-v e pressione a tecla Escape (ou mais fácil, basta gravar uma macro rápida e usar a norma para executar essa macro em cada linha).

Nota 2 : Obviamente, você também pode adicionar um mapeamento se estiver usando normmuito. Por exemplo, colocar a seguinte linha em ~ / .vimrc permite digitar em ctrl-nvez de :normdepois de fazer sua seleção visual

vnoremap <C-n> :norm

Nota 3 : Às vezes, o bare-vim vim não possui onorm comando compilado, portanto, certifique-se de usar a versão atualizada, ou seja, normalmente / usr / bin / vim, não / bin / vi

(Obrigado a @Manbroski e @rakslice pelas melhorias incorporadas a esta resposta)

Magnus
fonte
Eu pensei que este era o caminho a percorrer até que eu rolada para ler esta resposta stackoverflow.com/a/1676690/850996 A seleção de bloco usando CTRL + V (em oposição a seleção de linha com SHIFT + V) dá muito controle mais agradável sobre o lugar onde o comentário inserção de caracteres ocorre.
Shyam Habarakada
2
@Shyam A técnica ctrl-v combinada com comandos especiais somente de seleção de bloco é o que a maioria das outras respostas recomenda; no entanto, eu pessoalmente acho a técnica "norma" que descrevi mais fácil, porque ela não introduz nenhuma nova sintaxe além do próprio comando norm, para que eu possa reutilizar o que já sei sobre o vim.
Magnus
2
Para descomentar um bloco recuado, é útil dizer :norm ^x. Este método em geral tem a vantagem de trabalhar com seleções de região (por exemplo vi{, selecionará dentro de chaves). Esses seletores de objeto de texto não funcionam Visual Block.
ivan-k
1
Ah, eu acabei de descobrir - no centos 6 o /bin/viis vim 7.2, mas é uma compilação diferente /usr/bin/vime possui recursos como este desativados.
rakslice
4
Esta é de longe a melhor resposta. Especialmente quando combinado com vippara selecionar um parágrafo inteiro.
meh
122

Eu tenho o seguinte no meu .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>

Agora você pode digitar ,ccpara comentar uma linha e ,curemover o comentário de uma linha (funciona no modo normal e visual).

(Eu o roubei de algum site há muitos anos, então não posso mais explicar completamente como ele funciona :). Há um comentário onde é explicado.)

jqno
fonte
qual é o atalho que devo usar? Eu não posso ter certeza do próprio código vim!
Gideon
no modo normal ou visual, use ", cc" (sequência de 3 caracteres) para comentar a linha atual e ", cu" para descomentar a linha atual.
Dan
8
eu gosto disso :)! obrigado! Em uma nota lateral, não acho difícil de explicar. a) remapeia um comando (não recursivamente [veja isso] ( stackoverflow.com/questions/3776117/… ); agora, quando você pressiona, cc, a coisa: ... é executada. b) agora isso é basicamente um sed (s) / what / towhat / where) comando alterando ^ (início da linha) para o caractere de comentário definido corretamente com base no tipo de arquivo que você abriu c) quanto aos itens silenciosos, eles simplesmente suprimem a saída dos comandos. d): nohlsearch impede de destacar a busca sed
ramrunner
14
Observe que essa não é a maneira correta de carregar comandos automáticos. Eles devem estar dentro de um augroup ou então serão adicionados ao vim várias vezes e causarão muito mais lentidão. Consulte: learnvimscriptthehardway.stevelosh.com/chapters/14.html . Eu adicionei minha resposta a esta pergunta.
Agradável. Esta é uma resposta real à pergunta que eu tive sobre como (des) comentar enquanto você tem uma seleção de blocos.
Erwin Rooijakkers
120

Especifique quais linhas comentar no vim:

Revele os números das linhas:

:set number

então

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

ou isto:

:%s/^/#/        will comment out all lines in file
Carlos
fonte
11
Desde que você está apenas mudando o 1º caractere de cada linha, você não precisa do "g" no final
Magnus
1
Alguns VIMS em caixas embutidas (como openwrt) não têm modo visual .. Então isso é freaking incrível :)
kim0
você pode explicar por :%s/^/#/gque comentará todas as linhas? Eu queria saber o sinal de porcentagem%
Bin
18
E para descomentar essas linhas, você pode escrever: 5,17s / ^ # /
Iraklis Moutidis
Ótimo! Realmente funciona bem com a seleção de blocos como: va{ou com varpara ruby.
Artur Małecki 29/11
58

Aqui está como eu faço isso:

  1. Vá para o primeiro caractere na primeira linha que deseja comentar.

  2. Pressione Ctrl+ qno GVIM ou Ctrl+ vno VIM e desça para selecionar o primeiro caractere nas linhas a comentar.

  3. Em seguida c, pressione e adicione o caractere de comentário.

A remoção de comentários funciona da mesma maneira, basta digitar um espaço em vez do caractere de comentário.

Marcin
fonte
44
cexclui o primeiro caractere também. A resposta de CMS tem direito ou seja, pressionando Iem seguida, digitando o caractere de comentário (s) e depois Esc(isto é em janelas VIM)
Samaursa
6
Isso funciona, exceto que 'r' precisa ser pressionado na etapa três, não 'c'.
David Baucum
Alternativamente, você pode pressionar ESCduas vezes depois de pressionar ce que deve fazer o truque
nihiser
Todas essas opções são destrutivas do primeiro caractere na linha.
1937 Josiah
36

Eu vim com uma adição simples ao meu arquivo .vimrc, que funciona muito bem e pode ser estendido facilmente. Você simplesmente adiciona um novo tipo de arquivo ao comment_map e seu líder de comentários.

Adicionei um mapeamento aos modos normal e visual, mas você pode remapear para o que quiser. Prefiro apenas ter uma função de estilo 'alternar'. Um suporta ter vários mapeamentos 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:

Eu não uso nenhum retorno de chamada ou gancho nos tipos de arquivo / carregamento, porque acho que eles atrasam a inicialização do Vim mais do que a .vimrcfunção / mapa estático, mas essa é apenas a minha preferência. Eu também tentei mantê-lo simples e com bom desempenho. Se você usa comandos automáticos, é necessário colocá-los em um grupo de comandos automáticos, caso contrário, os retornos de chamada serão adicionados ao tipo de arquivo várias vezes por arquivo carregado e causam muita degradação no desempenho.

ideasman42
fonte
1
Sou completamente novo no vim, qual botão devo pressionar para alternar a função mapeada? O que é essa <leader><Space>declaração na parte inferior?
Jens Kohl
2
Você pode substituir <líder> por uma chave como <,>. Então você pressiona, ESPAÇO e alterna o estado do comentário da linha. Líder é o que o seu líder é, padrão do Vim <líder> é \, mas você pode definir o seu próprio como "vamos mapleader = ''"
Ótima resposta, porém, um aborrecimento, ao comentar blocos que já têm alguns comentários, trocará comentários por linhas não comentadas. O QtCreator for, por exemplo, apenas remove comentários se todas as linhas não vazias tiverem comentários iniciais, caso contrário, adicione um comentário inicial.
precisa saber é o seguinte
1
Eu fiz uma versão ligeiramente diferente usando \zse \zetruque regex, o código tornou-se um pouco menor. você pode vê-lo aqui
SergioAraujo 4/18
33

Alternar comentários

Se tudo o que você precisa é alternar os comentários , prefiro ir com commentary.vim pelo tpope .

insira a descrição da imagem aqui

Instalação

Patógeno:

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

vim-plug:

Plug 'tpope/vim-commentary'

Vundle:

Plugin 'tpope/vim-commentary'

Personalização adicional

Adicione isso ao seu arquivo .vimrc: noremap <leader>/ :Commentary<cr>

Agora você pode alternar os comentários pressionando Leader+ /, como Sublime e Atom.

Flavio Wuensche
fonte
obrigado! ele vai suportar comentários de css dentro de um html em algum momento no futuro?
Dan Oak
25

Use Control-V para selecionar retângulos de texto: vá para o primeiro #caractere, digite Ctrl+ V, mova para a direita uma vez e depois para baixo, até o final dos comentários. Agora digite x: você está excluindo todos os #caracteres seguidos por um espaço.

Arthur Reutenauer
fonte
18

Aqui está uma seção do meu .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>

No modo normal e no visual, isso permite que eu pressione ,icpara inserir e ,rcremover comentários.

innaM
fonte
Isso é muito útil para um iniciante, como aprender a escrever .vimrc.
Coolesting 6/10/11
3
maptampas normais e modos visuais, então você não precisa as vmaplinhas
DoubleDown
Melhor lugar é no after/ftplugin/ruby.vim.
22813 Santosh Kumar
use também <leader>ice<leader>rc
Hans Kristian
15

Eu uso o vim 7.4 e isso funciona para mim.
Supondo que estamos comentando / descomentando 3 linhas.

Comentar:

Se a linha não tem guia / espaço no início:
ctrl + Vem seguida, jjjem seguida, shift + I (cappital i)em seguida, //em seguida, esc esc
se a linha tem guia / espaço no início você ainda pode fazer o acima ou permuta por c:
ctrl + Vem seguida, jjjem seguida, cem seguida, //em seguida, esc esc

para remover o comentário:

se as linhas não têm nenhum guia / espaço no início:
ctrl + Vem seguida, jjjem seguida, ll (lower cap L)em seguida,c

se as linhas têm guia / espaço no início, então você um espaço de mais e esc
ctrl + V, em seguida, jjjem seguida, ll (lower cap L)em seguida, cem seguida, spaceem seguida,esc

Andy
fonte
9

Com 30 respostas à minha frente, tentarei fornecer uma solução ainda mais fácil: insira um #no início da linha. Em seguida, desça uma linha e pressione ponto ( .). Para repetir, não j, ., j, ., etc ... para remover o comentário, remover um #(você pode bater xsobre a #), e fazer o uso reverso k, .etc ...

imagineerThat
fonte
1
É uma resposta muito simples que mesmo os iniciantes podem entender e usar. No entanto, ele funciona bem devagar em grandes quantidades de linhas para comentar. Para contornar isso, você pode escrever I#<Esc>jno buffer - digamos c- - e, em seguida 10@c, executar , ou qualquer número de linhas que mais lhe convier.
Daerdemandt
9

Como descomentar as três linhas a seguir no vi:

#code code
#code
#code code code

Coloque o cursor sobre o #símbolo superior esquerdo e pressione CtrlV. Isso coloca você no modo de bloqueio visual. Pressione a seta para baixo ou Jtrês vezes para selecionar as três linhas. Então pressione D. Todos os comentários desaparecem. Para desfazer, pressione U.

Como comentar as seguintes três linhas no vi:

code code
code
code code code

Coloque o cursor sobre o caractere superior esquerdo, pressione CtrlV. Isso coloca você no modo de bloqueio visual. Pressione ou Jtrês vezes para selecionar as três linhas. Então aperte:

I//Esc

Isso é um capital I, // e Escape.

Ao pressionar ESC, todas as linhas selecionadas receberão o símbolo de comentário especificado.

Ivor Scott
fonte
1
se você errar o hash "superior esquerdo", pressione o para mover o cursor para o "outro lado" no modo visual.
dylnmc
Eu acho que isso é melhor usar. Não há necessidade quaisquer terceiros, basta usar vim nativa
Ardi Nusawan
melhor resposta, simples e sem terceiros #
aze
8

Sim, já existem 33 respostas (principalmente repetitivas) para esta pergunta.

Aqui está outra abordagem de como comentar linhas no Vim: movimentos . A idéia básica é comentar ou remover o comentário de linhas usando o mesmo método que puxar um parágrafo digitando yipou excluindo 2 linhas digitandodj .

Essa abordagem permitirá que você faça coisas como:

  • ccjcomentar as próximas 2 linhas e cukdescomentá-las;

  • cci{comentar um bloco e cui{descomentá-lo;

  • ccipcomentar um parágrafo inteiro e cuipremovê-lo do comentário.

  • ccGcomentar tudo até a última linha e cuggdescomentar tudo até a primeira linha.

Tudo o que você precisa são 2 funções que operam sobre movimentos e 2 mapeamentos para cada função. Primeiro, os mapeamentos:

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>

(Veja o manual sobre o g@operador e a operatorfuncvariável.)

E agora as funções:

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 as expressões regulares acima para se adequar ao seu gosto e onde #deve estar:

nr
fonte
"movimentos completamente [...] novos" parece um pouco exagerado: os plugins t_comment e vim-commentary, ambos anteriores à resposta, permitem comentar usando movimentos.
Rico
Coisa boa! Votado. (Eu também acho que eu poderia começar a usar essa abordagem em vez do plugin eu estava usando anteriormente, por isso obrigado por escrever isso!)
Rico
7

Se você já conhece os números das linhas, n,ms/# //funcionaria.

uckelman
fonte
realmente isso provavelmente deve ser: n, ms / ^ \ s. # // Porque você pode ter um espaço em branco à esquerda e não seguir o hash com um
Skip Huffman
7

Marquei a primeira e a última linha (ma e mb) e depois faço: 'a,' bs / ^ # //

SDGator
fonte
6

Eu uso EnhancedCommentify . Ele comenta tudo o que eu precisava (linguagens de programação, scripts, arquivos de configuração). Eu o uso com ligações de modo visual. Basta selecionar o texto que deseja comentar e pressionar co / cc / cd.

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

Combinei a resposta de Phil e jqno e fiz comentários descompactados com espaços:

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
fonte
5

Existe esse plugin de mudança de vida tpopechamadovim-commentary

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

Este plugin fornece :

  • Sanidade
  • Comentários devidamente recuados
  • Não comenta linhas vazias / desnecessárias

Uso :

  • Instale via Vundle (ou Pathogen, eu acho).
  • Destaque seu texto e pressione, :que será exibido como:<,'>
  • Digite Comentário aqui :<,'>Commentarye pressione Enter.
  • Estrondo. Seu broto feito.
Weston Ganger
fonte
vim-commentary(como todos os plugins do tpope) tem o bônus de ser vim idiomático. gc= "vá comentar", gcap= "vá comentar um parágrafo", etc.
goldenratio
Isso poderia ter sido apenas uma edição da resposta de Tim Pope por Jim Stewart?
jdk1.0
5

Essa resposta é mais útil se você não conseguir instalar plug-ins, mas ainda deseja que seus caracteres de comentário sigam os níveis de recuo existentes.

Esta resposta está aqui para 1) mostram o código correto para colar em uma .vimrcpara conseguir vim 7.4+fazer bloco comentando / descomentando mantendo nível de recuo com um atalho no modo visual e 2) para explicá-lo. Aqui está o 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>

Como funciona:

  • let b:commentChar='//': Isso cria uma variável no vim. o baqui refere-se ao âmbito de aplicação, que neste caso está contido no tampão, o que significa que o ficheiro que está aberto. Os caracteres do seu comentário são cadeias de caracteres e precisam ser agrupados entre aspas; as aspas não fazem parte do que será substituído ao alternar os comentários.

  • autocmd BufNewFile,BufReadPost *...: Os comandos automáticos são acionados em diferentes coisas; nesse caso, são acionadas quando um novo arquivo ou o arquivo lido termina com uma certa extensão. Uma vez acionado, execute o seguinte comando, o que nos permite alterar o commentChartipo de arquivo dependendo. Existem outras maneiras de fazer isso, mas elas são mais confusas para iniciantes (como eu).

  • function! Docomment(): As funções são declaradas iniciando functione terminando com endfunction. As funções devem começar com uma capital. os !garante que esta função substitui qualquer funções anteriores como definidos Docomment()com esta versão Docomment(). Sem o !, tive erros, mas isso pode ser porque eu estava definindo novas funções através da linha de comando do vim.

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e': Executar chama um comando. Nesse caso, estamos executando substitute, o que pode assumir um intervalo (por padrão, esta é a linha atual), como %para todo o buffer ou '<,'>para a seção destacada. ^\s*é regex para corresponder ao início de uma linha seguida por qualquer quantidade de espaço em branco, que é então anexado a (devido a &). O .aqui é usado para concatenação de cadeias, pois escape()não pode ser colocado entre aspas. escape()permite que você escape um caractere commentCharque corresponda aos argumentos (nesse caso, \e /), acrescentando-os com a \. Depois disso, concatenamos novamente com o final de nossasubstitute string, que tem oebandeira. Essa bandeira nos deixa falhar silenciosamente, o que significa que, se não encontrarmos uma correspondência em uma determinada linha, não gritaremos sobre isso. Como um todo, essa linha nos permite colocar um caractere de comentário seguido por um espaço antes do primeiro texto, o que significa que mantemos nosso nível de indentação.

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e': Isso é semelhante ao nosso último grande e longo comando. Exclusivo para este, temos \v, o que garante que não temos que escapar do nosso (), e 1, que se refere ao grupo que fizemos com o nosso (). Basicamente, estamos combinando uma linha que começa com qualquer quantidade de espaço em branco e, em seguida, nosso caractere de comentário seguido por qualquer quantidade de espaço em branco, e estamos mantendo apenas o primeiro conjunto de espaços em branco. Novamente, evamos falhar silenciosamente se não tivermos um caractere de comentário nessa linha.

  • let l:line=getpos("'<")[1]: define uma variável como fizemos com o nosso caractere de comentário, mas lrefere-se ao escopo local (local para esta função). getpos()obtém a posição de, nesse caso, o início de nosso destaque e os [1]meios que nos importam apenas com o número da linha, e não com outras coisas, como o número da coluna.

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1: você sabe como iffunciona. match()verifica se a primeira coisa contém a segunda, então pegamos a linha na qual começamos o destaque e verificamos se ela começa com espaço em branco seguido pelo caractere de comentário. match()retorna o índice onde isso é verdade e -1se nenhuma correspondência foi encontrada. Como ifavalia todos os números diferentes de zero como verdadeiros, precisamos comparar nossa saída para ver se é maior que -1. Comparação nos vimretornos 0 se falso e 1 se verdadeiro, que é o que ifdeseja ver para avaliar corretamente.

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>: vnoremapsignifica mapear o seguinte comando no modo visual, mas não o mapeie recursivamente (ou seja, não altere nenhum outro comando que possa ser usado de outras maneiras). Basicamente, se você é um novato em vim, sempre use noremappara se certificar de não quebrar as coisas. <silent>significa "Não quero suas palavras, apenas suas ações" e diz para não imprimir nada na linha de comando. <C-r>é o que estamos mapeando, que é ctrl + r nesse caso (observe que você ainda pode usar Cr normalmente para "refazer" no modo normal com esse mapeamento). C-ué meio confuso, mas basicamente garante que você não perca o destaque visual (de acordo com esta resposta, ele inicia seu comando aqui, apenas informa ao vim para executar a função que chamamos, e'<,'> o que queremos).call<cr> clique no enterbotão).call function() na linha de comando, e precisamos pressioná-lo novamente para que nossos substitutos passem por todo o caminho (não sei ao certo por que, mas tanto faz).

Enfim, espero que isso ajude. Isso vai levar nada destacou com v, Vou C-v, cheque se a primeira linha é comentada, se sim, tentar tire todas as linhas destacadas, e se não, adicionar uma camada extra de caracteres de comentário para cada linha. Este é o meu comportamento desejado; Eu não queria apenas alternar se cada linha do bloco era comentada ou não, por isso funciona perfeitamente para mim depois de fazer várias perguntas sobre o assunto.

jeremysprofile
fonte
3

Você pode usar o vim-commentary por tpope ( https://github.com/tpope/vim-commentary ), você pode usá-lo da seguinte maneira:

Entre no modo visual pressionando

'v'

Então aperte

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

Agora tudo o que você tem a ver com a seleção é inserir teclas:

'gc'

Isso irá comentar toda a seleção, para descomentar as teclas de repetição:

'gc'
Kingsley Ijomah
fonte
3

A seguir, um one-liner básico com base no método C-vseguido Idescrito acima.

Este comando ( :Comment) adiciona uma sequência escolhida ao início de qualquer linha selecionada.

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

Inclua essa linha no seu .vimrcpara criar um comando que aceite um único argumento e coloque o argumento no início de cada linha na seleção atual.

Por exemplo, se o seguinte texto for selecionado:

1
2

e você executa isso:, :Comment //o resultado será:

//1
//2
bgran
fonte
3

Começando com as idéias nas respostas aqui, iniciei minha própria função de comentário. Ativa e desativa comentários. Ele pode lidar com coisas como //print('blue'); //this thing is bluee apenas alterna o primeiro comentário. Além disso, ele adiciona comentários e um único espaço exatamente onde está o primeiro espaço em branco e não no início da linha. Além disso, ele não copia desnecessariamente os espaços em branco, mas usa os zooms (: h \ zs para obter ajuda) para evitar esse trabalho extra ao comentar e recuar linhas. Espero que ajude alguns minimalistas por aí. Sugestões são bem vindas.

" 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>
Mike
fonte
1
Fiz uma versão ligeiramente diferente da sua solução que também restaura a posição do cursor. Gostaria de ter sua opinião sobre isso. no github
SergioAraujo 23/03
Legal. Você pode editar minha postagem e adicionar sua solução (por causa da semelhança)!
mike
Foi alterado para evitar a barra invertida c, cpp, java e o uso de outro separador em substituições para evitar o E488. Também o espaçamento muda para java, cpp porque os comentários têm três caracteres, // mais espaço, isso é feito por l: space.
SergioAraujo 24/03
3

Eu uso comments.vim de Jasmeet Singh Anand (encontrado em vim.org),

Funciona com C, C ++, Java, PHP [2345], proc, CSS, HTML, HTML, HTML, XHTML, vim, vimrc, SQL, sh, ksh, csh, Perl, tex, fortran, ml, caml, ocaml, arquivos vhdl, haskel e normais

Ele comenta e remove comentários de linhas em diferentes arquivos de origem, tanto no modo normal quanto no visual

Uso:

  • CtrlCpara comentar uma única linha
  • CtrlXpara un-comentar uma única linha
  • ShiftVe selecione várias linhas, CtrlCpara comentar as várias linhas selecionadas
  • ShiftVe selecione várias linhas, CtrlXpara cancelar o comentário das várias linhas selecionadas
Ronan
fonte
3

O método mais rápido e mais intuitivo de todos eles é remapear )para comentários de linhas e depois (para descomentar. Experimente e você não voltará.

Em Ruby ou Bash , com recuos de 2 espaços:

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

Em C / C ++ ou PHP , com recuos de 4 espaços:

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

As desvantagens são as perdas (e )os movimentos das frases (mas daspodem ser preenchidas lá) e, ocasionalmente, você recorre à seleção e substituição ou CtrlVao lidar com seções longas. Mas isso é muito raro.

E para o estilo C, os comentários longos são mais bem tratados com:

set cindent
set formatoptions=tcqr

... O que combina bem com o uso V[move]gqpara refazer a quebra de linha.

eukras
fonte
2

Este snippet simples é do meu .vimrc:

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

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

É para // - Comentários, mas você pode adaptá-lo facilmente para outros personagens. Você pode usar o autocmd para definir um líder como o jqno sugeriu.

Essa é uma maneira muito simples e eficiente de trabalhar com intervalos e modo visual naturalmente.

Phil
fonte
2

Eu gosto /* ... */(comentários), então aqui está o meu truque para você. Você pode adaptá-lo para uso em diferentes casos, é claro.


Comentar com / * ... * /

Selecione o texto (vá para o início, inicie o bloco visual, pule com }):

<c-V>}

Digite o comando a ser aplicado na seleção

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

O comando será semelhante a: :'<,'>norm i /* ^[$a */

Veja (i *) para detalhes.


Remova o comentário de / * ... * /

Selecione o texto (como antes ou da maneira que desejar):

<c-V>}

Digite o comando a ser aplicado na seleção

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

O comando será semelhante a: :'<,'>norm :s-\s*/\*\s*-^M$bbld$

Veja (ii *) para detalhes.


Resultado

Efeito é comentários linha por linha:

Comment block
Comment block
Comment block

Torna-se (e vice-versa):

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

É melhor salvá-lo como alguns mapou @regno seu .vimrc, porque é muito para digitar. Se você preferir um bloco único /*e */para todo, use:

Comente com um único / * * / todo o bloco

Salve-o em um registro gravando com, digamos qc, então, no início de um parágrafo, para comentar:

v}di/*  */<esc>hhhp

e não se esqueça qnovamente, para terminar o registro.

Veja (iii *) para detalhes.


Descomente um único / * * / de um bloco

Salve-o no registro, digamos @u,. Coloque o cursor em qualquer lugar dentro do bloco e:

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

Salve o registro finalizando q comando.

Veja (iv *) para detalhes.


Resultado

Effect é um único comentário para várias linhas:

Comment block
Comment block
Comment block

Torna-se (e vice-versa):

/* Comment block
Comment block
Comment block */

Explicações

(i *) Funciona usando o normqual aplica o mesmo comando repetidamente em todas as linhas selecionadas. O comando simplesmente insere a /*, localiza o final dessa linha e termina inserindo um*/

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

(ii *) Também é usado normpara repetir a pesquisa / substituição em todas as linhas. Procure spaces /* spacese substitua por nada. Depois disso, encontra o final da linha, retorne duas palavras, uma letra à direita, exclua até o final.

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

(iii *) Seleciona o parágrafo v}, exclua-o, insira um comentário para abrir e fechar, vá para o meio e cole o bloco excluído.

v}di/*  */<esc>hhhp

(iv *) Em qualquer lugar do meio, encontra a para trás a /*e apaga; localiza a frente a */, exclui-a.

?/\*<enter>xx/\*/<enter>xx
Dr Beco
fonte