Quel est un moyen rapide de commenter / décommenter des lignes dans Vim?

1172

J'ai un fichier de code Ruby ouvert dans vi, il y a des lignes commentées avec #:

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

Supposons que je souhaite décommenter toutes les lignes de la première def ... endsection. Quel est un moyen efficace de le faire dans Vim?

En général, je recherche un moyen simple et fluide de commenter et de commenter les lignes. Ici, je traite du code Ruby, mais il peut s'agir de JavaScript ( //) ou Haml ( -#).

Ethan
la source
20
La réponse acceptée doit être remplacée par l'une des réponses contenant des instructions détaillées sur la façon de réaliser des blocs de commentaires / décommentation sans utiliser de plug-in. La réponse actuellement acceptée est simplement un lien vers un plugin tiers.
faintsignal
La réponse la mieux notée ne mentionne aucun plugin, @rationalis votre commentaire est trompeur, pourriez-vous s'il vous plaît le corriger ou le supprimer, merci.
bonobo

Réponses:

181

J'utilise le script NERD Commenter . Il vous permet de commenter, de décommenter ou de basculer facilement les commentaires dans votre code.

Comme mentionné dans les commentaires :

pour tous ceux qui sont confus par l'utilisation, le repère par défaut est "\" donc 10 \ cc commentera dix lignes et 10 \ cu décommentera ces dix lignes

Manuel Ceron
la source
Intéressant! J'ai lu le Doc et trouve qu'il y a un "commentaire sexy" - utilisez simplement "\ cs". Pour Ruby, il utilisera =beginet =endpour commenter plusieurs lignes au lieu de balises de hachage.
Hegwin
Je pense que ce n'est pas le moyen le plus rapide de le faire avec vim car il nécessite d'installer un plugin. De plus, la meilleure réponse a déjà reçu plus de votes, mais elle n'a pas été marquée comme solution.
2018
138
Ne vous arrêtez pas ici. La plupart des réponses votées sont ci-dessous sans aucun plugin. stackoverflow.com/a/15588798/2117868 et stackoverflow.com/a/1676690/2117868
kuttumiah
@whirmill Je pense que "le meilleur" dépend vraiment du cas d'utilisation. Le mode de blocage visuel est plus rapide si je veux basculer les commentaires une fois dans ma vie. Mais si cela ne me dérange pas d'installer un plugin et que je souhaite effectuer le moins de frappes possible pour basculer les commentaires et ne pas avoir à différencier le fonctionnement entre l'ajout ou la suppression de commentaires - alors cela pourrait être la "meilleure réponse".
Carolus
@Carolus J'aurais été d'accord avec vous si la question avait commencé par "quelle est la meilleure façon" au lieu de "quelle est la voie rapide".
whillill
2546

Pour ces tâches, j'utilise la plupart de la sélection de bloc de temps .

Placez votre curseur sur le premier #caractère, appuyez sur CtrlV(ou CtrlQpour gVim), descendez jusqu'à la dernière ligne commentée et appuyez sur x, cela supprimera tous les #caractères verticalement.

Pour commenter un bloc de texte c'est presque pareil:

  1. Tout d'abord, allez à la première ligne que vous souhaitez commenter, appuyez sur CtrlV. Cela mettra l'éditeur en VISUAL BLOCKmode.
  2. Ensuite, utilisez la touche fléchée et sélectionnez jusqu'à la dernière ligne
  3. Maintenant, appuyez sur ShiftI, ce qui mettra l'éditeur en INSERTmode, puis appuyez sur #. Cela ajoutera un hachage à la première ligne.
  4. Appuyez ensuite sur Esc(donnez-lui une seconde), et il insérera un #caractère sur toutes les autres lignes sélectionnées.

Pour la version allégée de vim fournie avec debian / ubuntu par défaut, saisissez : s/^/#plutôt la troisième étape (toute surbrillance restante du premier caractère de chaque ligne peut être supprimée avec :nohl).

Voici deux petits enregistrements d'écran pour référence visuelle.

Commentaire: Commentaire

Décommenter: Décommenter

CMS
la source
87
Par défaut, c'est CTRL + V. La version Windows de gvim utilise Ctrl + Q car Ctrl + V est déjà utilisé pour coller.
R. Martinho Fernandes
8
@amindfv Ctrl + V, n(où n est num lignes - 1), j, n(où n num nombre de longueur de séquence de caractères de commentaire - 1), l, x.
michael.bartnett
28
Comment feriez-vous cela avec '//'?
AustinT
74
Vous pouvez cliquer deux fois sur Echap pour ne pas attendre cette seconde;)
Ahmed Hegazy
45
Ça n'a pas marché pour moi. Shift-I est passé en mode d'insertion simple.
Geremia
829

Pour commenter des blocs dans vim:

  • appuyez sur Esc(pour quitter l'édition ou un autre mode)
  • appuyez sur ctrl+ v(mode de blocage visuel)
  • utilisez les touches fléchées / pour sélectionner les lignes que vous voulez (cela ne mettra pas tout en évidence - c'est OK!)
  • Shift+ i(majuscule I)
  • insérez le texte que vous voulez, par exemple %
  • presse EscEsc

Pour décommenter des blocs dans vim:

  • appuyez sur Esc(pour quitter l'édition ou un autre mode)
  • appuyez sur ctrl+ v(mode de blocage visuel)
  • utilisez les touches de direction / pour sélectionner les lignes à décommenter.

    Si vous souhaitez sélectionner plusieurs caractères, utilisez-en un ou combinez ces méthodes:

    • utilisez les touches fléchées gauche / droite pour sélectionner plus de texte
    • pour sélectionner des morceaux de texte, utilisez la touche shift+ / flèche
    • vous pouvez appuyer plusieurs fois sur les touches de suppression ci-dessous, comme un bouton de suppression standard

  • appuyez sur dou xpour supprimer des caractères, plusieurs fois si nécessaire
amelia
la source
35
@amelia: Le raccourci de commentaires ne fonctionne pas pour moi. Shift + i m'emmène en mode insertion. Cela dépend-il de la version de vim?
user3527975
7
Pourquoi faut-il une seconde?
Conor Patrick
24
Le seul problème que j'ai avec cette réponse est qu'elle vous indique d'utiliser les touches fléchées .
cozyconemotel
6
Appuyez deux fois sur Esc. :)
Aaron Alphonsus
22
Au début, l'activation des commentaires n'a pas fonctionné pour moi, mais après avoir lu, cela a encore une fois fonctionné: 1. assurez-vous d'utiliser Ctrl-V, pas V pour la sélection 2. lors de l'insertion, il apparaîtra car vous ne modifiez qu'une seule ligne 3. tous les insertions se produisent lorsque vous appuyez sur Échap à la fin
timurb
336

Parfois, je suis bombardé dans une boîte distante où mes plugins et .vimrc ne peuvent pas m'aider, ou parfois NerdCommenter se trompe (par exemple JavaScript intégré à HTML).

Dans ces cas, une alternative low-tech est la normcommande intégrée , qui exécute simplement toutes les commandes vim arbitraires sur chaque ligne de votre plage spécifiée. Par exemple:

Commentant avec # :

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

Cela insère "#" au début de chaque ligne. Notez que lorsque vous tapez: la plage sera remplie, donc elle ressemblera vraiment à:'<,'>norm i#

Sans commentaires # :

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

Cela supprime le premier caractère de chaque ligne. Si j'avais utilisé un commentaire à 2 caractères tel que // alors je ferais simplement :norm xxpour supprimer les deux caractères.

Si les commentaires sont en retrait comme dans la question du PO, vous pouvez ancrer votre suppression comme ceci:

:norm ^x

ce qui signifie "aller au premier caractère non espace, puis supprimer un caractère". Notez que contrairement à la sélection de bloc, cette technique fonctionne même si les commentaires ont une indentation inégale!

Remarque : comme il ne norms'agit que d'exécuter des commandes vim régulières, vous n'êtes pas limité aux commentaires, vous pouvez également effectuer des modifications complexes sur chaque ligne. Si vous avez besoin du caractère d'échappement dans le cadre de votre séquence de commandes, tapez ctrl-v puis appuyez sur la touche d'échappement (ou encore plus simple, enregistrez simplement une macro rapide et utilisez la norme pour exécuter cette macro sur chaque ligne).

Remarque 2 : Vous pouvez bien sûr également ajouter une cartographie si vous vous en servez normbeaucoup. Par exemple, mettre la ligne suivante dans ~ / .vimrc vous permet de taper ctrl-nplutôt :normqu'après avoir fait votre sélection visuelle

vnoremap <C-n> :norm

Note 3 : la normcommande Bim est parfois compilée, donc assurez-vous d'utiliser la version renforcée, c'est-à-dire généralement / usr / bin / vim, pas / bin / vi

(Merci à @Manbroski et @rakslice pour les améliorations intégrées à cette réponse)

Magnus
la source
Je pensais que c'était la voie à suivre jusqu'à ce que je fasse défiler pour lire cette réponse stackoverflow.com/a/1676690/850996 La sélection de bloc à l'aide de CTRL + V (par opposition à la sélection de ligne avec SHIFT + V) donne un contrôle beaucoup plus agréable de l'endroit où le commentaire l'insertion de caractères a lieu.
Shyam Habarakada
2
@Shyam La technique ctrl-v combinée à des commandes spéciales de sélection de bloc uniquement est ce que la plupart des autres réponses recommandent; cependant, je trouve personnellement la technique "norm" que j'ai décrite plus facile car elle n'introduit pas de nouvelle syntaxe en plus de la commande norm elle-même, donc je peux réutiliser ce que je sais déjà sur vim.
Magnus
2
Pour décommenter un bloc en retrait, il est utile de le dire :norm ^x. Cette méthode a en général l'avantage de travailler avec des sélections de régions (par exemple vi{, sélectionnera à l'intérieur des accolades). Ces sélecteurs d'objets texte ne fonctionnent pas Visual Block.
ivan-k
1
Ah, je viens de comprendre - sur centos 6, /bin/vic'est vim 7.2, mais c'est une construction différente de /usr/bin/vim, et il a des fonctionnalités comme celle-ci désactivées.
rakslice
4
C'est de loin la meilleure réponse. Surtout lorsqu'il est combiné avec vippour sélectionner un paragraphe entier.
meh
122

J'ai les éléments suivants dans mon .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>

Vous pouvez maintenant taper ,ccpour commenter une ligne et ,cupour décommenter une ligne (fonctionne à la fois en mode normal et visuel).

(Je l'ai volé sur un site Web il y a plusieurs années, je ne peux plus expliquer comment cela fonctionne :). Il y a un commentaire où il est expliqué.)

jqno
la source
quel raccourci dois-je utiliser? Je ne peux pas vraiment m'assurer du code vim lui-même!
gideon
en mode normal ou visuel, utilisez ", cc" (séquence de 3 caractères) pour commenter la ligne actuelle et ", cu" pour décommenter la ligne actuelle.
Dan
8
je l'aime :)! Merci! En passant, je ne trouve pas difficile à expliquer. a) il remappe une commande (non récursivement [voir ceci] ( stackoverflow.com/questions/3776117/… ) alors maintenant quand vous appuyez sur, cc la: ... chose est exécutée. b) maintenant c'est fondamentalement un sed (s / what / towhat / where) en changeant ^ (début de ligne) en caractère de commentaire correctement défini en fonction du type de fichier que vous avez ouvert c) quant aux trucs silencieux, ils suppriment simplement la sortie des commandes. d): nohlsearch l'empêche de mettre en évidence la recherche sed
ramrunner
14
Notez que ce n'est pas la bonne façon de charger les autocommandes. Ils devraient être à l'intérieur d'un augroup ou bien ils seront ajoutés à vim plusieurs fois et causeront beaucoup de ralentissement. Voir: learnvimscriptthehardway.stevelosh.com/chapters/14.html . J'ai ajouté ma réponse à cette question.
Agréable. Il s'agit d'une véritable réponse à la question que j'avais sur la façon de (dé) commenter pendant que vous avez une sélection de bloc.
Erwin Rooijakkers
120

Spécifiez les lignes à commenter dans vim:

Révélez les numéros de ligne:

:set number

puis

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

ou ca:

:%s/^/#/        will comment out all lines in file
Carlos
la source
11
Puisque vous ne faites que changer le 1er caractère de chaque ligne, vous n'avez pas besoin du "g" à la fin
Magnus
1
Quelques VIMS sur les boîtes intégrées (comme openwrt) ne sont pas en mode visuel .. Donc , ce flippe génial :)
kim0
pouvez-vous expliquer pourquoi :%s/^/#/gcommentera toutes les lignes? Je me demandais le signe du pourcentage%
Bin
18
Et pour décommenter ces lignes, vous pouvez écrire: 5,17s / ^ # /
Iraklis Moutidis
Génial! Cela fonctionne vraiment bien avec la sélection de blocs comme: va{ou avec varpour rubis.
Artur Małecki
58

Voici comment je le fais:

  1. Accédez au premier caractère de la première ligne à commenter.

  2. Appuyez sur Ctrl+ qdans GVIM ou Ctrl+ vdans VIM, puis descendez pour sélectionner le premier caractère sur les lignes à commenter.

  3. Appuyez ensuite sur cet ajoutez le caractère de commentaire.

La décommentation fonctionne de la même manière, il suffit de taper un espace au lieu du caractère de commentaire.

Marcin
la source
44
csupprime également le premier caractère. La réponse de CMS a raison, c'est-à-dire en appuyant sur Ipuis en tapant le (s) caractère (s) de commentaire, puis Esc(c'est sur windows vim)
Samaursa
6
Cela fonctionne, sauf que «r» doit être pressé à l'étape trois, pas «c».
David Baucum
Alternativement, vous pouvez appuyer ESCdeux fois après avoir appuyé cet cela devrait faire l'affaire
nihiser
Toutes ces options détruisent le premier caractère de la ligne.
Josiah
36

J'ai trouvé un simple ajout à mon fichier .vimrc qui fonctionne assez bien et peut être étendu facilement. Vous ajoutez simplement un nouveau type de fichier à la comment_map et à son leader de commentaire.

J'ai ajouté un mappage aux modes normal et visuel, mais vous pouvez remapper à tout ce que vous aimez. Je préfère seulement avoir une fonction de style «bascule». On porte plusieurs mappages, 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>

Remarque:

Je n'utilise aucun rappel ou crochet dans les types de fichiers / chargement, car je trouve qu'ils ralentissent le démarrage de Vim plus que la .vimrcfonction / carte statique, mais c'est juste ma préférence. J'ai également essayé de rester simple et performant. Si vous utilisez des commandes automatiques, vous devez vous assurer de les placer dans un groupe de commandes automatiques, sinon les rappels seront ajoutés au type de fichier plusieurs fois par fichier chargé et entraîneront une dégradation considérable des performances.

ideasman42
la source
1
Je suis complètement nouveau sur vim, sur quel bouton dois-je appuyer pour basculer la fonction mappée? Quelle est cette <leader><Space>déclaration au fond?
Jens Kohl
2
Vous pouvez remplacer <leader> par une clé comme <,>. Ensuite, vous appuyez sur, ESPACE et cela basculera l'état de commentaire de la ligne. Le leader est quel que soit votre leader, le <leader> par défaut de Vim est \, mais vous pouvez définir le vôtre comme "let mapleader = ','"
Excellente réponse, une gêne cependant, les blocs de commentaires qui ont déjà des commentaires échangeront les commentaires pour les lignes non commentées. Par exemple, QtCreator ne supprime les commentaires que si toutes les lignes non vides ont des commentaires de tête, sinon ajoutez un commentaire de tête.
ideasman42
1
J'ai fait une version légèrement différente en utilisant \zset \zeastuce regex, le code est devenu un peu plus petit. vous pouvez le voir ici
SergioAraujo
33

Basculer les commentaires

Si tout ce dont vous avez besoin est de basculer les commentaires, je préfère utiliser commentary.vim de tpope .

entrez la description de l'image ici

Installation

Agent pathogène:

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

vim-plug:

Plug 'tpope/vim-commentary'

Vundle:

Plugin 'tpope/vim-commentary'

Personnalisation supplémentaire

Ajoutez ceci à votre fichier .vimrc: noremap <leader>/ :Commentary<cr>

Vous pouvez désormais basculer les commentaires en appuyant sur Leader+ /, tout comme Sublime et Atom.

Flavio Wuensche
la source
Merci! est-ce que ça va supporter les commentaires css dans un html dans le futur?
Dan Oak
25

Utilisez Control-V pour sélectionner des rectangles de texte: allez au premier #caractère, tapez Ctrl+ V, déplacez-vous une fois vers la droite, puis vers le bas, jusqu'à la fin des commentaires. Tapez maintenant x: vous supprimez tous les #caractères suivis d'un espace.

Arthur Reutenauer
la source
18

Voici une section de mon .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 mode normal et en mode visuel, cela me permet d'appuyer sur ,icpour insérer des commentaires et ,rcpour supprimer des commentaires.

innaM
la source
C'est très utile pour un débutant d'apprendre à écrire lui-même .vimrc.
coolesting
3
mapcouvre les modes normal et visuel, donc vous n'avez pas besoin des vmaplignes
doubleDown
Un meilleur endroit est dedans after/ftplugin/ruby.vim.
Santosh Kumar
également utiliser <leader>icet<leader>rc
Hans Kristian
16

J'utilise vim 7.4 et cela fonctionne pour moi.
En supposant que nous commentons / décommentons 3 lignes.

Commenter:

si la ligne n'a pas de tabulation / espace au début:
ctrl + Valors jjjpuis shift + I (cappital i)alors //puis esc esc
si la ligne a pas de tabulation / espace au début, vous pouvez toujours faire ce qui précède ou échanger pour c:
ctrl + Vpuis jjjpuis cpuis //puis esc esc

Pour décommenter:

si les lignes n'ont pas de tabulation / espace au début:
ctrl + Valors jjjalors ll (lower cap L)puisc

si les lignes ont onglet / espace au début, alors vous un espace sur et esc
ctrl + Vpuis jjjensuite , ll (lower cap L)puis censuite spacealorsesc

Andy
la source
9

Avec 30 réponses devant moi, je vais essayer de donner une solution encore plus simple: insérez un #au début de la ligne. Descendez ensuite une ligne et appuyez sur le point ( .). Pour répéter, ne j, ., j, ., etc ... décommenter, supprimez un #(vous pouvez frapper xsur #), et faire l'inverse en utilisant k, ., etc ...

imagineerThat
la source
1
C'est une réponse très simple que même les débutants peuvent comprendre et utiliser. Cependant, cela fonctionne assez lentement sur de grandes quantités de lignes à commenter. Pour contourner cela, vous pouvez écrire I#<Esc>jdans le tampon - disons, c- puis le faire 10@c, ou le nombre de lignes qui vous convient.
Daerdemandt
9

Comment décommenter les trois lignes suivantes dans vi:

#code code
#code
#code code code

Placez le curseur sur le #symbole supérieur gauche et appuyez sur CtrlV. Cela vous met en mode de blocage visuel. Appuyez sur la flèche vers le bas ou Jtrois fois pour sélectionner les trois lignes. Appuyez ensuite sur D. Tous les commentaires disparaissent. Pour annuler, appuyez sur U.

Comment commenter les trois lignes suivantes dans vi:

code code
code
code code code

Placez le curseur sur le caractère supérieur gauche, appuyez sur CtrlV. Cela vous met en mode de blocage visuel. Appuyez sur ouJ trois fois pour sélectionner les trois lignes. Puis appuyez:

I//Esc

C'est un capital I, // et Escape.

Lorsque vous appuyez sur ESC, toutes les lignes sélectionnées obtiendront le symbole de commentaire que vous avez spécifié.

Ivor Scott
la source
1
si vous manquez le hachage "en haut à gauche", vous pouvez appuyer sur o pour déplacer le curseur sur "l'autre côté" en mode visuel.
dylnmc
Je pense que c'est le meilleur à utiliser. Pas besoin de tiers, utilisez simplement natif vim
Ardi Nusawan
meilleure réponse, simple et sans tiers
aze
8

Oui, il y a déjà 33 réponses (pour la plupart répétitives) à cette question.

Voici une autre approche pour commenter les lignes dans Vim: les motions . L'idée de base est de commenter ou de décommenter des lignes en utilisant la même méthode que de tirer un paragraphe en tapant yipou en supprimant 2 lignes en tapantdj .

Cette approche vous permettra de faire des choses comme:

  • ccj commenter les 2 lignes suivantes, et cuk les décommenter;

  • cci{ pour commenter un blocage, et cui{ le décommenter;

  • ccipcommenter un paragraphe entier et cuiple décommenter.

  • ccGpour tout commenter jusqu'à la dernière ligne et cuggpour tout commenter jusqu'à la première ligne.

Tout ce dont vous avez besoin est de 2 fonctions qui fonctionnent sur les mouvements et de 2 mappages pour chaque fonction. Tout d'abord, les mappages:

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>

(Voir le manuel de l' g@opérateur et duoperatorfunc variable.)

Et maintenant les fonctions:

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

Modifiez les expressions régulières ci-dessus selon vos goûts quant à l'endroit où elles #devraient se trouver:

nr
la source
"complètement nouveaux [...] mouvements" semble un peu exagéré: les plugins t_comment et vim-commentary, qui sont tous deux antérieurs à cette réponse, vous permettent de commenter en utilisant des mouvements.
Rich
Bon produit! A voté. (Je pense également que je pourrais commencer à utiliser cette approche au lieu du plugin que j'utilisais précédemment, alors merci de l'avoir écrit!)
Rich
7

Si vous connaissez déjà les numéros de ligne, n,ms/# //cela fonctionnerait.

uckelman
la source
vraiment cela devrait probablement être: n, ms / ^ \ s. # // Parce que vous pourriez avoir un espace blanc en tête et ne pas suivre le hachage avec un
Skip Huffman
7

Je marque les première et dernière lignes (ma et mb), puis je fais: 'a', bs / ^ # //

SDGator
la source
6

J'utilise EnhancedCommentify . Il commente tout ce dont j'avais besoin (langages de programmation, scripts, fichiers de configuration). Je l'utilise avec des liaisons en mode visuel. Sélectionnez simplement le texte que vous souhaitez commenter et appuyez sur co / cc / cd.

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

J'ai combiné la réponse de Phil et de jqno et j'ai fait des commentaires décousus avec des espaces:

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
la source
5

Il y a ce plugin qui change la vie par tpopeappelévim-commentary

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

Ce plugin fournit :

  • Santé mentale
  • Commentaires correctement en retrait
  • Ne met pas en commentaire les lignes vides / inutiles

Utilisation :

  • Installez via Vundle (ou Pathogen je suppose).
  • Mettez en surbrillance votre texte et appuyez sur :qui montrera que:<,'>
  • Tapez Commentaire ici :<,'>Commentaryet appuyez sur Enter.
  • Boom. Votre bourgeon fini.
Weston Ganger
la source
vim-commentary(comme tous les plugins de tpope) a l'avantage d'être un vim idiomatique. gc= "aller commenter", gcap= "aller commenter un paragraphe", etc.
goldenratio
Serait-ce juste une révision de la réponse de Tim Pope par Jim Stewart?
jdk1.0
5

Cette réponse est très utile si vous ne parvenez pas à installer les plugins mais que vous souhaitez que vos caractères de commentaire suivent les niveaux d'indentation existants.

Cette réponse est ici à 1) montrer le bon code à coller dans un .vimrcpour obtenir le vim 7.4+faire bloc commenter / décommenter tout en gardant le niveau d'indentation avec 1 raccourci en mode visuel et 2) pour l' expliquer. Voici le code:

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>

Comment ça fonctionne:

  • let b:commentChar='//': Cela crée une variable dans vim. le bfait référence ici à la portée, qui dans ce cas est contenu dans la mémoire tampon, ce qui signifie le fichier actuellement ouvert. Vos caractères de commentaire sont des chaînes et doivent être entourés de guillemets, les guillemets ne font pas partie de ce qui sera remplacé lors du basculement des commentaires.

  • autocmd BufNewFile,BufReadPost *...: Les commandes automatiques se déclenchent sur différentes choses, dans ce cas, elles se déclenchent lorsqu'un nouveau fichier ou le fichier lu se termine par une certaine extension. Une fois déclenchée, exécutez la commande suivante, qui nous permet de changer le type commentCharde fichier en fonction. Il existe d'autres façons de le faire, mais elles sont plus déroutantes pour les novices (comme moi).

  • function! Docomment(): Les fonctions sont déclarées en commençant par functionet en terminant par endfunction. Les fonctions doivent commencer par un capital. le !garantit que cette fonction écrase toutes les fonctions précédentes définies comme Docomment()avec cette version de Docomment(). Sans le !, j'ai eu des erreurs, mais c'est peut-être parce que je définissais de nouvelles fonctions via la ligne de commande vim.

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e': Exécuter appelle une commande. Dans ce cas, nous exécutons substitute, ce qui peut prendre une plage (par défaut, c'est la ligne actuelle) comme %pour tout le tampon ou '<,'>pour la section en surbrillance. ^\s*est regex pour correspondre au début d'une ligne suivie par n'importe quelle quantité d'espace, qui est ensuite ajoutée à (en raison de &). L' .ici est utilisé pour la concaténation de chaînes, car escape()il ne peut pas être placé entre guillemets. escape()vous permet d'échapper le caractère commentCharqui correspond aux arguments (dans ce cas, \et /) en les ajoutant au début par un \. Après cela, nous concaténons à nouveau avec la fin de notresubstitute chaîne, qui a leedrapeau. Ce drapeau nous permet d'échouer en silence, ce qui signifie que si nous ne trouvons pas de correspondance sur une ligne donnée, nous ne crierons pas à ce sujet. Dans l'ensemble, cette ligne nous permet de mettre un caractère de commentaire suivi d'un espace juste avant le premier texte, ce qui signifie que nous conservons notre niveau d'indentation.

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e': Ceci est similaire à notre dernière énorme commande longue. Unique à celui-ci, nous l'avons \v, ce qui garantit que nous n'avons pas à échapper à notre (), et 1, qui fait référence au groupe que nous avons fait avec notre (). Fondamentalement, nous faisons correspondre une ligne qui commence par n'importe quelle quantité d'espace, puis notre caractère de commentaire suivi par n'importe quelle quantité d'espace, et nous ne conservons que le premier ensemble d'espaces. Encore une fois, elaissez-nous échouer en silence si nous n'avons pas de caractère de commentaire sur cette ligne.

  • let l:line=getpos("'<")[1]: cela définit une variable un peu comme nous l'avons fait avec notre caractère de commentaire, mais lfait référence à la portée locale (locale à cette fonction). getpos()obtient la position, dans ce cas, le début de notre surbrillance, et les [1]moyens que nous nous soucions uniquement du numéro de ligne, pas d'autres choses comme le numéro de colonne.

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1: vous savez comment ça ifmarche. match()vérifie si la première chose contient la deuxième chose, nous prenons donc la ligne sur laquelle nous avons commencé notre surbrillance, et vérifions si elle commence par un espace suivi de notre caractère de commentaire. match()renvoie l'index où cela est vrai et -1si aucune correspondance n'a été trouvée. Étant donné que iftous les nombres différents de zéro sont vrais, nous devons comparer notre sortie pour voir si elle est supérieure à -1. La comparaison en vimretourne 0 si faux et 1 si vrai, c'est ce ifque l' on veut voir pour évaluer correctement.

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>: vnoremapsignifie mapper la commande suivante en mode visuel, mais ne la mappez pas récursivement (c'est-à-dire ne changez aucune autre commande qui pourrait être utilisée d'une autre manière). Fondamentalement, si vous êtes un novice vim, utilisez toujours noremappour vous assurer de ne pas casser les choses. <silent>signifie "Je ne veux pas de vos mots, juste de vos actions" et lui dit de ne rien imprimer sur la ligne de commande. <C-r>est la chose que nous mappons, qui est ctrl + r dans ce cas (notez que vous pouvez toujours utiliser Cr normalement pour "refaire" en mode normal avec ce mappage). C-uest un peu déroutant, mais fondamentalement, il garantit que vous ne perdez pas la trace de votre mise en évidence visuelle (selon cette réponse, cela fait démarrer votre commande avec '<,'>ce que nous voulons).call ici juste dit à vim d'exécuter la fonction que nous avons nommée, et<cr>fait référence au fait d' enterappuyer sur le bouton. Nous devons le frapper une fois pour appeler la fonction (sinon nous venons de taper call function()sur la ligne de commande, et nous devons le frapper à nouveau pour que nos remplaçants passent au travers (pas vraiment pourquoi, mais peu importe).

Quoi qu'il en soit, j'espère que cela aide. Cela prendra tout ce qui est mis en surbrillance avec v, Vou C-v, vérifiez si la première ligne est commentée, si oui, essayez de décommenter toutes les lignes en surbrillance et sinon, ajoutez une couche supplémentaire de caractères de commentaire à chaque ligne. C'est mon comportement souhaité; Je ne voulais pas simplement qu'il permute si chaque ligne du bloc était commentée ou non, donc cela fonctionne parfaitement pour moi après avoir posé plusieurs questions sur le sujet.

jeremysprofile
la source
3

Vous pouvez utiliser vim-commentary par tpope ( https://github.com/tpope/vim-commentary ), vous pouvez l'utiliser comme suit:

Entrez en mode visuel en appuyant sur

'v'

Puis appuyez

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

Maintenant, tout ce que vous avez à faire avec la sélection est d'entrer les touches:

'gc'

Cela mettra en commentaire toute la sélection, pour décommenter les touches de relecture:

'gc'
Kingsley Ijomah
la source
3

Voici une doublure de base basée sur la méthode C-vsuivie Idécrite ci-dessus.

Cette commande ( :Comment) ajoute une chaîne choisie au début de toutes les lignes sélectionnées.

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

Ajoutez cette ligne à votre .vimrcpour créer une commande qui accepte un seul argument et place l'argument au début de chaque ligne dans la sélection actuelle.

Par exemple, si le texte suivant est sélectionné:

1
2

et vous exécutez ceci:, :Comment //le résultat sera:

//1
//2
bgran
la source
3

En commençant par les idées dans les réponses ici, j'ai commencé ma propre fonction de commentaire. Il active et désactive les commentaires. Il peut gérer des choses comme //print('blue'); //this thing is blueet basculer simplement le premier commentaire. De plus, il ajoute des commentaires et un seul espace juste là où se trouve le premier espace non blanc et pas au tout début de la ligne. De plus, il ne copie pas inutilement les espaces blancs, mais utilise des zooms (: h \ zs pour l'aide) pour éviter ce travail supplémentaire, lors du commentaire et de la ligne en retrait. J'espère que cela aide certains minimalistes. Les suggestions sont les bienvenues.

" 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
la source
1
J'ai fait une version légèrement différente de votre solution qui restaure également la position du curseur, j'aimerais votre avis à ce sujet. sur github
SergioAraujo
Cool. Vous pouvez modifier mon article et ajouter votre solution (en raison de la similitude)!
mike
Il a changé pour éviter les barres obliques inverses c, cpp, java et l'utilisation d'un autre séparateur pour remplacer E488. De plus, l'espacement change pour java, cpp parce que les commentaires ont trois caractères, // plus espace, cela se fait par l: espace.
SergioAraujo
3

J'utilise comments.vim de Jasmeet Singh Anand (trouvé sur vim.org),

Il fonctionne avec 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 et fichiers normaux

Il commente et dé-commente les lignes dans différents fichiers source en mode normal et visuel

Usage:

  • CtrlCpour commenter une seule ligne
  • CtrlXpour annuler le commentaire d' une seule ligne
  • ShiftVet sélectionnez plusieurs lignes, puis CtrlCpour commenter les plusieurs lignes sélectionnées
  • ShiftVet sélectionnez plusieurs lignes, puis CtrlXpour ne pas commenter les plusieurs lignes sélectionnées
Ronan
la source
3

La méthode la plus rapide et la plus intuitive de toutes consiste à remapper )pour commenter les lignes en descendant, puis (pour décommenter en marchant. Essayez-le et vous ne reviendrez pas.

En Ruby ou Bash , avec des retraits à 2 espaces:

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

En C / C ++ ou PHP , avec des retraits à 4 espaces:

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

Les inconvénients sont que vous perdez (et )pour le déplacement de la phrase (mais vous daspouvez le remplir), et vous aurez parfois recours à la sélection et au remplacement ou CtrlVà la gestion de longues sections. Mais c'est assez rare.

Et pour le style C, les longs commentaires sont mieux gérés avec:

set cindent
set formatoptions=tcqr

... Ce qui se combine bien avec l'utilisation V[move]gqpour refaire le retour à la ligne.

eukras
la source
2

Ce simple extrait est de mon .vimrc:

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

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

C'est pour // - Commentaires, mais vous pouvez l'adapter facilement pour d'autres personnages. Vous pouvez utiliser autocmd pour définir un leader comme l'a suggéré jqno.

C'est une manière très simple et efficace de travailler avec les plages et le mode visuel naturellement.

Phil
la source
2

J'aime /* ... */(commentaires C ansi), alors voici mon truc pour vous. Vous pouvez bien sûr l'adapter pour l'utiliser dans différents cas.


Commentaire avec / * ... * /

Sélectionnez le texte (allez au début, démarrez le bloc visuel, sautez avec }):

<c-V>}

Tapez la commande à appliquer dans la sélection

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

La commande ressemblera à: :'<,'>norm i /* ^[$a */

Voir (i *) pour plus de détails.


Décommentez le / * ... * /

Sélectionnez le texte (comme précédemment, ou d'une autre manière que vous aimez):

<c-V>}

Tapez la commande à appliquer dans la sélection

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

La commande ressemblera à: :'<,'>norm :s-\s*/\*\s*-^M$bbld$

Voir (ii *) pour plus de détails.


Résultat

L'effet est des commentaires ligne par ligne:

Comment block
Comment block
Comment block

Devient (et vice-versa):

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

Il vaut mieux l'enregistrer en tant que certains mapou @regdans votre .vimrc, car c'est beaucoup à taper. Si vous préférez un seul /*et */au bloc entier, utilisez:

Commentaire avec un seul / * * / tout le bloc

Enregistrez-le dans un registre en enregistrant avec, disons qc, puis, au début d'un paragraphe pour commenter:

v}di/*  */<esc>hhhp

et n'oubliez pas q, pour finir le record.

Voir (iii *) pour plus de détails.


Décommenter un seul / * * / d'un bloc

Enregistrez-le dans le registre, par exemple @u. Placez votre curseur n'importe où dans le bloc et:

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

Enregistrez le registre en terminant q commande.

Voir (iv *) pour plus de détails.


Résultat

L'effet est un seul commentaire pour plusieurs lignes:

Comment block
Comment block
Comment block

Devient (et vice-versa):

/* Comment block
Comment block
Comment block */

Explications

(i *) Il fonctionne en utilisant normqui applique la même commande à plusieurs reprises sur chaque ligne sélectionnée. La commande insère simplement un /*, trouve la fin de cette ligne et termine en insérant un*/

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

(ii *) Il permet également normde répéter la recherche / remplacement sur chaque ligne. Recherchez spaces /* spaceset remplacez par rien. Après cela, trouve la fin de la ligne, deux mots en arrière, une lettre à droite, supprimer jusqu'à la fin.

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

(iii *) Sélectionne le paragraphe par v}, supprimez-le, insérez un commentaire ouvert et fermé, déplacez-vous au milieu et collez le bloc supprimé.

v}di/*  */<esc>hhhp

(iv *) N'importe où au milieu, trouve en arrière a /*, le supprime; trouve un avant */, le supprime.

?/\*<enter>xx/\*/<enter>xx
Dr Beco
la source