Qual è un modo rapido per commentare / commentare le righe in Vim?


1172

Ho un file di codice Ruby aperto in vi, ci sono righe commentate 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

Di 'che voglio decommentare tutte le righe nella prima def ... endsezione. Qual è un modo efficace per farlo in Vim?

In generale, sto cercando un modo semplice e fluido per commentare e commentare le righe. Qui ho a che fare con il codice Ruby, ma potrebbe essere JavaScript ( //) o Haml ( -#).


20
La risposta accettata dovrebbe essere cambiata in una delle risposte che ha istruzioni dettagliate su come realizzare blocchi di commento / decommenting senza usare un plugin. La risposta attualmente accettata è fondamentalmente solo un collegamento a un plug-in di terze parti.
faintsignal

La risposta più votata non menziona alcun plugin, @rationalè il tuo commento è fuorviante, potresti per favore correggerlo o rimuoverlo, grazie.
bonobo,

Risposte:


181

Uso lo script NERD Commenter . Ti consente di commentare, rimuovere il commento o attivare o disattivare facilmente i commenti nel tuo codice.

Come menzionato nei commenti :

per chiunque sia confuso dall'uso, il leader predefinito è "\", quindi 10 \ cc commenterà dieci righe e 10 \ cu rimuoverà quelle dieci righe


Interessante! Ho letto il documento e ho scoperto che c'è un "commento sexy" - basta usare "\ cs". Per Ruby, utilizzerà =begine =endcommenterà più righe anziché i tag hash.
Hegwin,

Penso che non sia il modo più veloce per farlo con Vim poiché richiede l'installazione di un plugin. Inoltre, la risposta migliore ha già ricevuto più voti ma non è stata contrassegnata come soluzione.
Whirmill

138
Non fermarti qui. Le risposte più votate sono riportate di seguito senza la necessità di plug-in. stackoverflow.com/a/15588798/2117868 e stackoverflow.com/a/1676690/2117868
kuttumiah

@whirmill Penso che il "migliore" dipenda davvero dal caso d'uso. La modalità blocco visivo è più veloce se voglio attivare o disattivare i commenti una volta nella vita. Ma se non mi dispiace installare un plugin e voglio fare il minor numero possibile di tasti per attivare / disattivare i commenti e non dover differenziare l'operazione tra l'aggiunta o la rimozione di commenti, allora questa potrebbe essere la "migliore risposta".
Carolus,

@ Carolus Sarei stato d'accordo con te se la domanda fosse iniziata con "qual è il modo migliore" invece di "cos'è un modo rapido".
Whirmill

2545

Per queste attività utilizzo la maggior parte della selezione a tempo .

Posiziona il cursore sul primo #carattere, premi CtrlV(o CtrlQper gVim) e scendi fino all'ultima riga commentata e premi x, che eliminerà tutti i #caratteri in verticale.

Per commentare un blocco di testo è quasi lo stesso:

  1. Innanzitutto, vai alla prima riga che desideri commentare, premi CtrlV. Questo metterà l'editor in VISUAL BLOCKmodalità.
  2. Quindi utilizzando il tasto freccia e selezionare fino all'ultima riga
  3. Ora premi ShiftI, che metterà l'editor in INSERTmodalità e poi premi #. Questo aggiungerà un hash alla prima riga.
  4. Quindi premi Esc(dagli un secondo) e inserirà un #carattere su tutte le altre linee selezionate.

Per la versione ridotta di vim fornita con debian / ubuntu per impostazione predefinita, digitare : s/^/#invece il terzo passaggio (è possibile rimuovere qualsiasi evidenziazione rimanente del primo carattere di ogni riga con :nohl).

Ecco due registrazioni di piccoli schermi per riferimento visivo.

Commento: Commento

Rimuovere il commento: Rimuovere il commento


87
Di default è CTRL + V. La versione Windows di gvim usa Ctrl + Q perché Ctrl + V è già usato per incollare.
R. Martinho Fernandes,

8
@amindfv Ctrl + V, n(dove n è num lines - 1), j, n(dove n num number della lunghezza della sequenza di caratteri di commento - 1), l, x.
michael.bartnett,

28
Come faresti con '//'?
Austin,

74
Puoi cliccare Esc due volte per non aspettare quel secondo;)
Ahmed Hegazy il

45
Questo non ha funzionato per me. Maiusc-Sono entrato in modalità di inserimento semplice.
Geremia,

828

Per commentare i blocchi in vim:

  • premere Esc(per uscire dalla modalità modifica o altra modalità)
  • premi ctrl+ v(modalità blocco visivo)
  • usa i tasti freccia / per selezionare le linee che vuoi (non evidenzierà tutto - va bene!)
  • Shift+ i(maiuscola I)
  • inserisci il testo desiderato, ad es %
  • stampa EscEsc

Per rimuovere il commento dai blocchi in vim:

  • premere Esc(per uscire dalla modalità modifica o altra modalità)
  • premi ctrl+ v(modalità blocco visivo)
  • utilizzare i tasti freccia / per selezionare le righe da decommentare.

    Se si desidera selezionare più caratteri, utilizzare uno o combinare questi metodi:

    • utilizzare i tasti freccia sinistra / destra per selezionare più testo
    • per selezionare blocchi di testo utilizzare il tasto shift+ / freccia
    • puoi premere ripetutamente i tasti Elimina di seguito, come un normale pulsante Elimina

  • premere do xper eliminare i caratteri, ripetutamente se necessario

34
@amelia: la scorciatoia per i commenti non funziona per me. Maiusc + i mi porta a inserire la modalità. Dipende dalla versione di vim?
user3527975

7
Perché ci vuole un secondo?
Conor Patrick,

24
L'unico problema che ho con questa risposta è che ti dice di usare i tasti freccia .
cozyconemotel,

6
Premi Esc due volte invece. :)
Aaron Alphonsus,

22
Inizialmente abilitare i commenti non ha funzionato per me, ma dopo aver letto che ancora una volta ha funzionato bene: 1. assicurati di usare Ctrl-V, non V per la selezione 2. quando lo inserisci apparirà come stai modificando solo una singola riga 3. tutti gli inserimenti si verificano quando si
preme

335

A volte vengo bombardato in una scatola remota in cui i miei plugin e .vimrc non possono aiutarmi, oppure a volte NerdCommenter sbaglia (ad esempio JavaScript incorporato in HTML).

In questi casi, un'alternativa a bassa tecnologia è il normcomando integrato , che esegue semplicemente qualsiasi comando vim arbitrario su ciascuna riga nell'intervallo specificato. Per esempio:

Commentando con # :

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

Ciò inserisce "#" all'inizio di ogni riga. Nota che quando digiti: l'intervallo verrà riempito, quindi sembrerà davvero:'<,'>norm i#

Uncommenting # :

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

Questo elimina il primo carattere di ogni riga. Se avessi usato un commento a 2 caratteri come // allora farei semplicemente :norm xxper eliminare entrambi i caratteri.

Se i commenti sono rientrati come nella domanda del PO, puoi ancorare la tua cancellazione in questo modo:

:norm ^x

che significa "vai al primo carattere non spaziale, quindi elimina un carattere". Nota che a differenza della selezione dei blocchi, questa tecnica funziona anche se i commenti hanno un rientro irregolare!

Nota : poiché normsta letteralmente solo eseguendo i normali comandi di vim, non sei limitato ai commenti, potresti anche effettuare delle modifiche complesse su ogni riga. Se hai bisogno del carattere di escape come parte della sequenza di comandi, digita ctrl-v, quindi premi il tasto Esc (o ancora più semplice, registra una macro veloce e usa la norma per eseguire quella macro su ogni riga).

Nota 2 : puoi ovviamente aggiungere una mappatura se ti ritrovi a usare normmolto. Ad esempio, inserendo la seguente riga in ~ / .vimrc è possibile digitare ctrl-nanziché :normdopo aver effettuato la selezione visiva

vnoremap <C-n> :norm

Nota 3 : A volte Bare-Bones vim non ha normcompilato il comando, quindi assicurati di usare la versione rinforzata, cioè tipicamente / usr / bin / vim, non / bin / vi

(Grazie a @Manbroski e @rakslice per i miglioramenti integrati in questa risposta)


Ho pensato che fosse la strada da percorrere fino a quando non ho fatto scorrere la lettura per leggere questa risposta stackoverflow.com/a/1676690/850996 La selezione del blocco usando CTRL + V (al contrario della selezione della linea con MAIUSC + V) offre un controllo molto più preciso su dove il commento ha luogo l'inserimento del personaggio.
Shyam Habarakada,

2
@Shyam La tecnica ctrl-v combinata con comandi speciali di sola selezione a blocchi è ciò che la maggior parte delle altre risposte raccomanda; tuttavia trovo personalmente che la tecnica "norm" che ho descritto sia più semplice perché non introduce alcuna nuova sintassi oltre al comando norm stesso, quindi posso riutilizzare ciò che già so di vim.
Magnus,

2
Per decommentare un blocco rientrato, è utile dire :norm ^x. Questo metodo in generale ha il vantaggio di lavorare con le selezioni della regione (ad es. vi{Selezionerà tra parentesi graffe). Tali selettori di oggetti di testo non funzionano con Visual Block.
Ivan-K,

1
Ah, l'ho appena capito - su centos 6 /bin/viè vim 7.2, ma è una build diversa rispetto a /usr/bin/vim, e ha funzionalità come questa disattivate.
rakslice,

4
Questa è di gran lunga la risposta migliore. Soprattutto se combinato con vipper selezionare un intero paragrafo.
Meh,

122

Ho il seguente nel mio .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>

Ora puoi digitare ,ccper commentare una riga e ,curimuovere il commento da una riga (funziona sia in modalità normale che visiva).

(L'ho rubato da qualche sito web molti anni fa, quindi non posso più spiegare completamente come funziona :). C'è un commento in cui è spiegato.)


qual è la scorciatoia che dovrei usare? Non posso proprio assicurarmi dal codice vim stesso!
Gideon,

in modalità normale o visiva, utilizzare ", cc" (sequenza di 3 caratteri) per commentare la riga corrente e ", cu" per decommentare la riga corrente.
Dan,

8
mi piace :)! Grazie! In una nota a margine non trovo difficile da spiegare. a) rimappa un comando (in modo non ricorsivo [vedi questo] ( stackoverflow.com/questions/3776117/… ) quindi ora quando premi, cc la cosa: ... viene eseguita. b) ora questo è fondamentalmente un sed / what / towhat / where) modifica ^ (inizio della riga) nel carattere di commento impostato correttamente in base al tipo di file che hai aperto c) come per le cose silenziose che semplicemente sopprimono l'output dai comandi. d): nohlsearch impedisce di evidenziare la ricerca sed
ramrunner,

14
Nota, questo non è il modo corretto di caricare i autocomandi. Dovrebbero essere all'interno di un gruppo, altrimenti verranno aggiunti per girare più volte e causare molto rallentamento. Vedi: learnvimscriptthehardway.stevelosh.com/chapters/14.html . Ho aggiunto la mia risposta a questa domanda.

Bello. Questa è una vera risposta alla domanda che ho avuto su come (dis) commentare mentre hai una selezione di blocchi.
Erwin Rooijakkers,

120

Specifica quali righe commentare in vim:

Rivela i numeri di riga:

:set number

poi

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

o questo:

:%s/^/#/        will comment out all lines in file

11
Dato che stai cambiando il primo carattere di ogni riga, non hai bisogno della "g" alla fine
Magnus,

1
Alcuni film su scatole incorporate (come openwrt) non hanno la modalità visiva .. Quindi questo è davvero fantastico :)
kim0

puoi spiegare perché :%s/^/#/gcommenterà tutte le righe? Mi chiedevo il segno di percentuale%
Bin

18
E per rimuovere il commento da queste righe puoi scrivere: 5,17s / ^ # /
Iraklis Moutidis,

Grande! Funziona davvero bene con la selezione dei blocchi come: va{o con varper il rubino.
Artur Małecki,

58

Ecco come lo faccio:

  1. Vai al primo carattere della prima riga che desideri commentare.

  2. Premi Ctrl+ qin GVIM o Ctrl+ vin VIM, quindi scorri verso il basso per selezionare il primo carattere sulle righe per commentare.

  3. Quindi premere ce aggiungere il carattere di commento.

Uncommenting funziona allo stesso modo, basta digitare uno spazio anziché il carattere di commento.


44
celimina anche il primo personaggio. La risposta di CMS ha ragione, cioè premendo, Iquindi digitando i caratteri del commento e poi Esc(questo è su Windows
VIM

6
Funziona, tranne "r" deve essere premuto al passaggio tre, non "c".
David Baucum,

in alternativa puoi premere ESCdue volte dopo aver premuto ce questo dovrebbe fare il trucco
nihiser

Tutte queste opzioni sono distruttive per il primo personaggio sulla linea.
Giosia

36

Ho escogitato una semplice aggiunta al mio file .vimrc che funziona abbastanza bene e può essere esteso facilmente. È sufficiente aggiungere un nuovo tipo di file a comment_map e al relativo leader dei commenti.

Ho aggiunto una mappatura alle modalità normali e visive, ma puoi rimappare a tutto ciò che ti piace. Preferisco solo avere una funzione di stile "toggle". Uno ha più mappature ecc.

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:

Non utilizzo alcun callback o hook nei tipi di file / caricamento, perché trovo che rallentino l'avvio di Vim più della .vimrcfunzione statica / mappa ma questa è solo la mia preferenza. Ho anche cercato di renderlo semplice e performante. Se si utilizzano i autocomandi, è necessario assicurarsi di inserirli in un gruppo di autocommand, altrimenti i callback vengono aggiunti al tipo di file più volte per file caricato e causano un notevole deterioramento delle prestazioni.


1
Sono completamente nuovo per vim, quale pulsante devo premere per attivare la funzione mappata? Qual è quella <leader><Space>dichiarazione in fondo?
Jens Kohl,

2
Puoi sostituire <leader> con una chiave come <,>. Quindi premi, SPAZIO e commuta lo stato del commento della riga. Il leader è qualunque sia il tuo leader, il <leader> predefinito di Vim è \, ma puoi impostarlo come "let mapleader = ','"

Ottima risposta, una seccatura però, i blocchi di commenti che hanno già alcuni commenti, sostituiranno i commenti con righe non commentate. QtCreator, ad esempio, rimuove i commenti solo se tutte le righe non vuote hanno commenti iniziali, altrimenti aggiungi un commento iniziale.
ideasman42

1
Ho realizzato una versione leggermente diversa usando \zse \zeregex trick, il codice è diventato un po 'più piccolo. puoi vederlo qui
SergioAraujo

33

Attiva / disattiva i commenti

Se tutto ciò che serve è attivare / disattivare i commenti , preferirei commentary.vim di tpope .

inserisci qui la descrizione dell'immagine

Installazione

patogeno:

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

VIM-Spina:

Plug 'tpope/vim-commentary'

Vundle:

Plugin 'tpope/vim-commentary'

Ulteriore personalizzazione

Aggiungi questo al tuo file .vimrc: noremap <leader>/ :Commentary<cr>

Ora puoi attivare o disattivare i commenti premendo Leader+ /, proprio come Sublime e Atom.


Grazie! supporterà i commenti CSS in un html in futuro?
Dan Oak,

25

Usa Control-V per selezionare rettangoli di testo: vai al primo #carattere, digita Ctrl+ V, muoviti a destra una volta, quindi verso il basso, fino alla fine dei commenti. Ora digita x: stai eliminando tutti i #caratteri seguiti da uno spazio.


18

Ecco una mia sezione .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>

In modalità normale e visiva, questo mi consente di premere ,icper inserire commenti e ,rcper rimuovere commenti.


Questo è molto utile per un principiante come imparare a scrivere da solo .vimrc.
cool

3
mapcopre le modalità normali e visive, quindi non hai bisogno delle vmaplinee
doubleDown

Il posto migliore è dentro after/ftplugin/ruby.vim.
Santosh Kumar,

usa anche <leader>ice<leader>rc
Hans Kristian il

15

Uso vim 7.4 e questo funziona per me.
Supponendo che stiamo commentando / commentando 3 righe.

Commentare:

se la linea non ha alcuna scheda / spazio all'inizio:
ctrl + Vpoi jjjpoi shift + I (cappital i)poi //poi esc esc
se la linea ha scheda / spazio a voi che inizia ancora in grado di fare quanto sopra o swap per c:
ctrl + V allora jjjpoi cpoi //poiesc esc

togliere il commento:

Se le linee non hanno alcuna scheda / spazio all'inizio:
ctrl + Vpoi jjjpoi ll (lower cap L)poic

se le linee hanno scheda / spazio all'inizio, poi lo spazio uno sopra e esc
ctrl + Vpoi jjjpoi ll (lower cap L)poi cpoispace poiesc



9

Con 30 risposte davanti a me, proverò a fornire una soluzione ancora più semplice: inserisci #a all'inizio della riga. Quindi scendi una linea e premi punto ( .). Per ripetere, non j, ., j, ., ecc ... Per rimuovere il commento, rimuove un #(si può colpire xil #), e fare il contrario utilizzando k, ., ecc ...


1
È una risposta molto semplice che anche i principianti possono capire e usare. Tuttavia, funziona abbastanza lentamente su grandi quantità di righe per commentare. Per ovviare a ciò, è possibile scrivere I#<Esc>jnel buffer, ad esempio, ce quindi fare 10@c, o il numero di righe adatto a te.
Daerdemandt,

9

Come decommentare le seguenti tre righe in vi:

#code code
#code
#code code code

Posiziona il cursore sul #simbolo in alto a sinistra e premi CtrlV. Questo ti mette in modalità blocco visivo. Premere la freccia giù o Jtre volte per selezionare tutte e tre le linee. Quindi premere D. Tutti i commenti scompaiono. Per annullare, premere U.

Come commentare le seguenti tre righe in vi:

code code
code
code code code

Posiziona il cursore sul carattere in alto a sinistra, premi CtrlV. Questo ti mette in modalità blocco visivo. Premere o Jtre volte per selezionare tutte e tre le linee. Quindi premere:

I//Esc

Questa è una I maiuscola, //, ed Escape.

Quando si preme ESC, tutte le righe selezionate riceveranno il simbolo di commento specificato.


1
se perdi l'hash "in alto a sinistra", puoi premere o per spostare il cursore sull'altro lato in modalità visiva.
dylnmc,

Penso che questo sia il migliore da usare. Non sono necessarie terze parti, basta usare Vim nativo
Ardi Nusawan,

migliore risposta, semplice e senza terze parti
aze

8

Sì, ci sono già 33 risposte (per lo più ripetitive) a questa domanda.

Ecco un altro approccio a come commentare le righe in Vim: i movimenti . L'idea di base è commentare o rimuovere il commento dalle righe usando lo stesso metodo di strappare un paragrafo digitando yipo eliminando 2 righe digitandodj .

Questo approccio ti permetterà di fare cose come:

  • ccjcommentare le 2 righe successive e cukrimuoverle;

  • cci{commentare un blocco e cui{rimuoverlo;

  • ccipcommentare un intero paragrafo e cuiprimuoverlo.

  • ccGcommentare tutto fino all'ultima riga e cuggdecommentare tutto fino alla prima riga.

Tutto ciò che serve sono 2 funzioni che operano su movimenti e 2 mappature per ogni funzione. Innanzitutto, i mapping:

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>

(Vedi il manuale g@sull'operatore e iloperatorfunc variabile.)

E ora le funzioni:

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

Modifica le espressioni regolari sopra per soddisfare i tuoi gusti su dove #dovrebbe essere:


"movimenti completamente nuovi [...]" sembrano un po 'esagerati: i plugin t_comment e vim-commentary, entrambi precedenti a questa risposta, consentono di commentare usando i movimenti.
Ricco il

Roba buona! Upvoted. (Penso anche che potrei iniziare a utilizzare questo approccio anziché il plug-in che stavo usando in precedenza, quindi grazie per averlo scritto!)
Rich

7

Se conosci già i numeri di riga, n,ms/# //funzionerebbe.


questo dovrebbe probabilmente essere: n, ms / ^ \ s. # // Perché potresti avere uno spazio bianco iniziale e non seguire l'hash con uno
Skip Huffman

7

Contrassegno la prima e l'ultima riga (ma e mb), quindi faccio: 'a,' bs / ^ # //


6

Uso EnhancedCommentify . Commenta tutto ciò di cui avevo bisogno (linguaggi di programmazione, script, file di configurazione). Lo uso con i collegamenti in modalità visiva. Basta selezionare il testo che si desidera commentare e premere co / cc / cd.

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

5

Ho combinato la risposta di Phil e jqno e ho fatto commenti commutabili con spazi:

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>

5

C'è questo plugin che cambia la vita tpopechiamatovim-commentary

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

Questo plugin fornisce :

  • salute mentale
  • Commenti correttamente rientrati
  • Non commenta le righe vuote / non necessarie

Utilizzo :

  • Installa tramite Vundle (o Pathogen immagino).
  • Evidenzia il tuo testo e premi :quale verrà visualizzato come:<,'>
  • Scrivi qui il commento :<,'>Commentarye premi Enter.
  • Boom. Il tuo amico fatto.

vim-commentary(come tutti i plugin di tpope) ha il vantaggio di essere vim idiomatico. gc= "vai commento", gcap= "vai commento un paragrafo", ecc.
goldenratio,

Potrebbe essere stata solo una modifica della risposta di Tim Pope di Jim Stewart?
jdk1.0,

5

Questa risposta è molto utile se non sei in grado di installare plugin ma vuoi comunque che i tuoi caratteri di commento seguano i livelli di rientro esistenti.

Questa risposta è qui per 1) mostrare il codice corretto da incollare in .vimrca vim 7.4+per fare in modo da bloccare i commenti / i commenti, mantenendo il livello di rientro con 1 scorciatoia in modalità visiva e 2) per spiegarlo. Ecco il codice:

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>

Come funziona:

  • let b:commentChar='//': Questo crea una variabile in vim. il bqui si riferisce al campo di applicazione, che in questo caso è contenuto al buffer, cioè il file aperto. I caratteri del tuo commento sono stringhe e devono essere racchiusi tra virgolette, le virgolette non fanno parte di ciò che verrà sostituito quando si alternano i commenti.

  • autocmd BufNewFile,BufReadPost *...: I comandi automatici si attivano su cose diverse, in questo caso si attivano quando un nuovo file o il file letto termina con una determinata estensione. Una volta attivato, esegui il seguente comando, che ci consente di modificare il commentCharsecondo tipo di file. Ci sono altri modi per farlo, ma sono più confusi per i principianti (come me).

  • function! Docomment(): Le funzioni vengono dichiarate iniziando con functione terminando con endfunction. Le funzioni devono iniziare con un capitale. le !assicura che questa funzione sovrascrive qualsiasi precedenti funzioni definite Docomment()con questa versione di Docomment(). Senza il !, ho avuto errori, ma potrebbe essere perché stavo definendo nuove funzioni tramite la riga di comando di vim.

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e': Esegui chiama un comando. In questo caso, stiamo eseguendo substitute, che può assumere un intervallo (per impostazione predefinita questa è la riga corrente) come %per l'intero buffer o '<,'>per la sezione evidenziata. ^\s*è regex in modo che corrisponda all'inizio di una riga seguita da qualsiasi quantità di spazio bianco, che viene quindi aggiunto (a causa di &). Il .qui è usato per la concatenazione di stringhe, poiché escape()non può essere racchiuso tra virgolette. escape()ti permette di sfuggire al carattere commentCharche corrisponde agli argomenti (in questo caso \e /) anteponendoli con a \. Dopo questo, ci concateniamo di nuovo con la fine della nostrasubstitute stringa, che ha ilebandiera. Questo flag ci consente di fallire silenziosamente, il che significa che se non troviamo una corrispondenza su una determinata linea, non urleremo al riguardo. Nel complesso, questa riga ci consente di inserire un carattere di commento seguito da uno spazio appena prima del primo testo, il che significa che manteniamo il nostro livello di rientro.

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e': Questo è simile al nostro ultimo enorme comando lungo. Unico a questo, abbiamo \v, il che ci assicura che non dobbiamo sfuggire al nostro (), e 1che si riferisce al gruppo che abbiamo fatto con il nostro (). Fondamentalmente, stiamo abbinando una linea che inizia con qualsiasi quantità di spazio bianco e quindi il nostro carattere di commento seguito da qualsiasi quantità di spazio bianco, e stiamo solo mantenendo il primo set di spazi bianchi. Ancora una volta, epossiamo fallire in silenzio se non abbiamo un carattere di commento su quella riga.

  • let l:line=getpos("'<")[1]: imposta una variabile come abbiamo fatto con il nostro carattere di commento, ma si lriferisce all'ambito locale (locale a questa funzione). getpos()ottiene la posizione, in questo caso, l'inizio della nostra evidenziazione e i [1]mezzi che ci interessano solo del numero di riga, non di altre cose come il numero di colonna.

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1: sai come iffunziona. match()controlla se la prima cosa contiene la seconda cosa, quindi prendiamo la linea su cui abbiamo iniziato la nostra evidenziazione e controlliamo se inizia con uno spazio bianco seguito dal nostro carattere di commento. match()restituisce l'indice dove questo è vero e -1se non sono state trovate corrispondenze. Poiché ifvaluta che tutti i numeri diversi da zero sono veri, dobbiamo confrontare il nostro output per vedere se è maggiore di -1. Il confronto tra vimrestituisce 0 se falso e 1 se vero, che è ciò che ifvuole vedere per valutare correttamente.

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>: vnoremapsignifica mappare il seguente comando in modalità visiva, ma non mapparlo in modo ricorsivo (il che significa che non cambia altri comandi che potrebbero essere utilizzati in altri modi). Fondamentalmente, se sei un principiante, usa sempre noremapper assicurarti di non rompere le cose. <silent>significa "Non voglio le tue parole, solo le tue azioni" e gli dice di non stampare nulla sulla riga di comando. <C-r>è la cosa che stiamo mappando, che in questo caso è ctrl + r (nota che puoi sempre usare Cr normalmente per "ripetere" in modalità normale con questa mappatura). C-uè un po 'confuso, ma fondamentalmente si assicura che non si perda traccia dell'evidenziazione visiva (secondo questa risposta si fa iniziare il comando qui solo dice a Vim di eseguire la funzione che abbiamo nominato, e riferisce alla pressione del pulsante.'<,'> quale è quello che vogliamo).call<cr>entercall function() sulla riga di comando e dobbiamo premerlo di nuovo per far sì che i nostri sostituti procedano fino in fondo (non sono proprio sicuro del perché, ma qualunque cosa).

Comunque, si spera che questo aiuti. Ciò richiederà qualsiasi cosa evidenziata con v, Vo C-v, controlla se la prima riga è commentata, in caso affermativo, prova a rimuovere il commento da tutte le righe evidenziate e, in caso contrario, aggiungi un ulteriore livello di caratteri di commento a ciascuna riga. Questo è il mio comportamento desiderato; Non volevo solo cambiare se ogni riga del blocco è stata commentata o meno, quindi funziona perfettamente per me dopo aver fatto più domande sull'argomento.



3

Puoi usare vim-commentary di tpope ( https://github.com/tpope/vim-commentary ) puoi usarlo come segue:

Accedere alla modalità visiva premendo

'v'

Quindi premere

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

Ora tutto ciò che devi fare con la selezione è inserire i tasti:

'gc'

Questo commenterà tutta la selezione, per rimuovere il commento dai tasti repead:

'gc'

3

Ecco un one-liner di base basato sul metodo C-vseguito dal Isopra descritto.

Questo comando ( :Comment) aggiunge una stringa scelta all'inizio di qualsiasi riga selezionata.

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

Aggiungi questa riga alla tua .vimrcper creare un comando che accetta un singolo argomento e posiziona l'argomento all'inizio di ogni riga nella selezione corrente.

Ad esempio se è selezionato il seguente testo:

1
2

e tu esegui questo:, :Comment //il risultato sarà:

//1
//2

3

A partire dalle idee nelle risposte qui, ho iniziato la mia funzione di commento. Attiva e disattiva i commenti. Può gestire cose del genere //print('blue'); //this thing is bluee attiva e disattiva il primo commento. Inoltre aggiunge commenti e un singolo spazio proprio dove si trova il primo spazio non bianco e non all'inizio della riga. Adizionale, non copia inutilmente gli spazi bianchi, ma usa gli zoom (: h \ zs per aiuto) per evitare questo lavoro extra, quando si commentano e rientrano le righe. Spero che aiuti alcuni minimalisti là fuori. Suggerimenti sono ben accetti

" 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>

1
Ho realizzato una versione leggermente diversa della tua soluzione che ripristina anche la posizione del cursore, mi piacerebbe la tua opinione al riguardo. su github
SergioAraujo,

Freddo. Puoi modificare il mio post e aggiungere la tua soluzione (a causa della somiglianza)!
Mike

È stato modificato per evitare il backslashing di c, cpp, java e l'utilizzo di un altro separatore nelle sostituzioni per evitare E488. Anche la spaziatura cambia per java, cpp perché i commenti hanno tre caratteri, // più spazio, questo è fatto da l: spazio.
SergioAraujo,

3

Uso comment.vim di Jasmeet Singh Anand (disponibile su vim.org),

Funziona 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 e file normali

Commenta e rimuove le righe di commento in diversi file sorgente in modalità normale e visiva

Uso:

  • CtrlCper commentare una sola riga
  • CtrlXper annullare il commento di una singola riga
  • ShiftVe selezionare più righe, quindi CtrlCcommentare le righe multiple selezionate
  • ShiftVe seleziona più righe, quindi CtrlXper annullare il commento delle più righe selezionate

3

Il metodo più rapido e intuitivo di tutti è rimappare )per commentare le righe e poi( per commentare senza motivo. Provalo e non tornerai indietro.

In Ruby o Bash , con rientri a 2 spazi:

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

In C / C ++ o PHP , con rientri di 4 spazi:

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

Gli svantaggi sono che perdi (e )per il movimento di frase (ma daspuoi riempire lì), e di tanto in tanto ricadrai su seleziona e sostituisci oCtrlV per gestire sezioni lunghe. Ma è piuttosto raro.

E per lo stile C, i commenti lunghi vengono gestiti al meglio con:

set cindent
set formatoptions=tcqr

... Che si combina bene con l'uso V[move]gqper ripetere il ritorno a capo automatico.


2

Questo semplice frammento proviene dal mio .vimrc:

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

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

È per // - Commenti, ma puoi adattarlo facilmente ad altri personaggi. È possibile utilizzare autocmd per impostare un leader come suggerito da jqno.

Questo è un modo molto semplice ed efficace per lavorare con le gamme e la modalità visiva in modo naturale.


2

Mi piace /* ... */(commenti C ansi), quindi ecco il mio trucco per te. Ovviamente puoi adattarlo per l'uso in diversi casi.


Commenta con / * ... * /

Seleziona il testo (vai all'inizio, avvia il blocco visivo, salta con }):

<c-V>}

Digita il comando da applicare nella selezione

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

Il comando sarà simile a: :'<,'>norm i /* ^[$a */

Vedi (i *) per i dettagli.


Annulla commento / / ... * /

Seleziona il testo (come prima o in altro modo):

<c-V>}

Digita il comando da applicare nella selezione

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

Il comando sarà simile a: :'<,'>norm :s-\s*/\*\s*-^M$bbld$

Vedere (ii *) per i dettagli.


Risultato

L'effetto è commenti riga per riga:

Comment block
Comment block
Comment block

Diventa (e viceversa):

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

È meglio salvarlo come alcuni mapo @regnel tuo .vimrc, perché è molto da digitare. Se preferisci un singolo /*e */l'intero blocco, usa:

Commenta con un singolo / * * / l'intero blocco

Salvalo in un registro registrando con, diciamo qc, quindi, all'inizio di un paragrafo per commentare:

v}di/*  */<esc>hhhp

e non dimenticare di qnuovo, per finire il disco.

Vedi (iii *) per i dettagli.


Sblocca un singolo / * * / da un blocco

Salva nel registro, ad esempio, @u. Posiziona il cursore ovunque all'interno del blocco e:

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

Salvare il registro finendo q comando.

Vedere (iv *) per i dettagli.


Risultato

Effect è un singolo commento per più righe:

Comment block
Comment block
Comment block

Diventa (e viceversa):

/* Comment block
Comment block
Comment block */

spiegazioni

(i *) Funziona usando normquale applica ripetutamente lo stesso comando in ogni riga selezionata. Il comando inserisce semplicemente a /*, trova la fine di quella riga e termina inserendo a*/

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

(ii *) Utilizza anche normper ripetere la ricerca / sostituzione su ogni riga. Cerca spaces /* spacese sostituisci con niente. Successivamente, trova la fine della riga, torna indietro di due parole, a destra una lettera, elimina fino alla fine.

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

(iii *) Seleziona il paragrafo con v}, eliminalo, inserisci un commento aperto e chiuso, sposta al centro e incolla il blocco cancellato.

v}di/*  */<esc>hhhp

(iv *) Ovunque nel mezzo, trova indietro a /*, lo elimina; trova avanti a */, lo elimina.

?/\*<enter>xx/\*/<enter>xx
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.