ビジュアルモードで選択された一連の行をコメントアウトする方法は?


35

ビジュアルモードで選択した行を複数コメントアウトするにはどうすればよいですか?言語固有にする方法は?

たとえば、最初の4行が選択されている場合:

def foo(a,b):
    for each in (a,b):
        print each
    return a+b
print "2"

コマンド/マクロの操作の結果は次のとおりです(Pythonで):

#def foo(a,b):
#    for each in (a,b):
#        print each
#    return a+b
print "2"

回答:


31

言語固有のコメントが必要な場合は、nerdcommenterのようなプラグインが必要です

または、実際の質問には答えませんが、組み込みのvimアクションと各言語のコメント文字に関する知識を使用できます...

オプション#1:Vブロック

  1. :1 Enter (1行目に移動)
  2. Ctrl-V(Vブロックモード)
  3. jjj (さらに3行下)
  4. Shift-I(ブロックの前に挿入モードに入ります)
  5. # (「#」を挿入)
  6. Esc (通常モードに戻る)

オプション#2:置換

:1,4s/^/#/

壊す:

  1. : Exコマンドが続きます
  2. 1,4 1〜4行目
  3. s 代替
  4. /置換コマンドの断片の区切り文字。
    (別の文字を使用することもできます、例えば:
  5. ^ 行頭
  6. / 区切り
  7. # Pythonのコメント文字
  8. / 最終区切り

オプション#3:マクロの適用を繰り返す(ソース

  1. :1 Enter (1行目に移動)
  2. qa(登録時に記録を開始a
  3. Shift-I(行の先頭で挿入モードに入ります
  4. # (行の先頭に「#」を追加します)
  5. Esc (通常モードに戻る)
  6. q (記録停止)

  7. :2,4 normal @a(記録されたマクロを再実行してa、2〜4行の間に登録します)

    または

    ビジュアルモードで行を選択してヒット:すると、Ex行に自動的に:'<,'>(ビジュアル選択の開始から終了までの範囲)が入力され、入力normal @aしてヒットEntersource)できます。

さて、いくつかの行をコメントしたいときはいつでも、記録されたマクロを再実行aしてそれらの行に登録してください:

:9,22 normal @a (comment out lines 9-22)

1
オプション4:プラグイン
コーディポール

:9,22 normal I#私の答えに従ってできるのに、なぜ単一のコマンドにマクロを使用するのか理解できません。
ベン

ggを使用できるのに、なぜ:1 <enter>を使用するのですか?
タナス

最初の行からの@Tanathコメントは、この例に固有のものでした。著者が9行目から22行目までコメントしたい場合、ggを使用することはできません。
bsmith89

@Ben normalこの回答を書く前に、コマンドについて何も知りませんでした。あなたが正しい; :9,22 normal I#同様に動作します。
bsmith89

26

ビジュアルブロックモード(CtrlV)を使用して、行の先頭を選択します。次に、I#(大文字のI)ヒットして、これらの各行にハッシュ文字を挿入します。次に、を押しEscて、挿入モードから通常モードに戻ります。


私にはうまくいきません。最初の行にのみコメントを挿入します。
gon1332

押していctrlますか?そのためctrl+vだけでは異なるものですv
コーディポール

@CodyPoll私は知っています。すべては大丈夫Iです。Iを押すとI、そして#唯一の最初の行の前に配置されます。
gon1332

@CodyPollわかりました。私は入院患者でした。Esc説明した手順の後、私は押しませんでした。
gon1332

@ gon1332私の知る限りEsc、最後に押す必要があります。
ゴンサロリベイロ

18

現在使用している言語に対応した迅速なソリューションが必要なだけで、ビジュアルモードで既にテキストが選択されている場合は、

:norm 0i#

仕事をします。(各ラインについて、通常モードでは、最初の列とインサートに行く#。使用して:norm I#、あなたが望むものではないかもしれない最初の非空白文字、前にそれを挿入します。)を使用して:norm i#も動作します、なぜなら:normの初めに開始行ですが、それがわからない場合は、明示的ではなく明確ではありません。

もちろん、これを頻繁に行う場合は、マッピングを設定するか、プラグインを探してください。


1
デフォルトでnormalは、コマンドは行の先頭にカーソルを置いて実行されるため、0は必要ありません。
nitishch

1
もちろん、行番号、%、マークにはこのコマンドの接頭辞を付けることができます。例::1,5norm i#(または): 'a、' bnorm i#(または):10%norm i#
SibiCoder

9

自動的に実行するには、次のようなものをvimrcファイル(source)に追加する必要があります。

au FileType haskell,vhdl,ada let b:comment_leader = '-- '
au FileType vim let b:comment_leader = '" '
au FileType c,cpp,java let b:comment_leader = '// '
au FileType sh,make let b:comment_leader = '# '
au FileType tex let b:comment_leader = '% '
noremap <silent> ,c :<C-B>sil <C-E>s/^/<C-R>=escape(b:comment_leader,'\/')<CR>/<CR>:noh<CR>
noremap <silent> ,u :<C-B>sil <C-E>s/^\V<C-R>=escape(b:comment_leader,'\/')<CR>//e<CR>:noh<CR>

,cリージョンをコメント化したり、リージョンのコメント,uを外したりするために使用します。これにより、異なる言語のコメント記号が手動で設定されます。

2番目のオプションは、tcommentvim-commentary、またはcomments.vimのようなプラグインを使用することです。私は自分でtcommentを使用しています。私はそれが質問のトピックを超えていると信じているので、使用とインストールの手順をページで読んでください。

プラグイン(上記のリンクの1つまたは別のプラグイン)を使用することをお勧めしvimrcます。ファイル内のコードを維持するよりもはるかに簡単だからです。

編集:質問が変更されたため手動の方法を削除し、200_successで正しい方法が回答されました。


追加のプラグインの提案:NERD Commenter-vim.org/scripts/script.php?script_id=1218 – 15
降格

注:これは、行ごとのコメントのみをサポートします。たとえば、ANSI Cは認識しません//(のみ/* */)。
-wchargin

私はこのアプローチが好きですが、コメントを切り替える方法はありますか?
ideasman42

1
@ ideasman42代わりに関数を作成し、現在の行がコメントで始まるかどうかを確認し、その呼び出しに応じて:s、回答の抜粋に示されているコマンドのいずれかを実行する必要があります。チェック自体は次のようになりgetline('.') =~ "^" . escape(b:comment_leader, '\/')ます。それが本当のコメント解除である場合、そうでなければコメントします。これはテストされていないため、例としてのみ使用してください。
とこやみ

5

これにはscrooloose / nerdcommenterを使用します。

このプラグインを使用すると、行を視覚的に選択し、leader+ cを押してコメントを切り替えることができます。ファイルの種類に応じて、コメントに異なる記号を使用します。


5

行を選択したら、単に入力します

:norm I#

:'<,'>選択の開始から終了までの範囲であるコマンドラインに自動的に配置されます。norm通常モードのコマンドを実行し、その範囲で動作します。I#行の先頭に「#」を挿入する通常モードのコマンドです。


4

私はTCommentの大ファンです。ファイルタイプ固有のコメントスタイルを実行できるだけでなく、ブロックコメントをサポートする言語に対してブロック対行ごとに指定することもできます。

    gc{motion}   :: Toggle comments (for small comments within one line 
                    the &filetype_inline style will be used, if 
                    defined)
    gcc          :: Toggle comment for the current line

Explicit commenting/uncommenting:

    g<{motion}   :: Uncomment region
    g<c          :: Uncomment the current line
    g<b          :: Uncomment the current region as block

    g>{motion}   :: Comment region
    g>c          :: Comment the current line
    g>b          :: Comment the current region as block

In visual mode:

    gc           :: Toggle comments
    gC           :: Comment selected text

ご回答有難うございます!おそらく拡張してもらえますか?プラグインの回答を提供することは問題ありませんが、現時点ではプラグインへのリンクのみです。少なくとも、それが何をするのか、そしてそれをどのように使うかの基本的な説明が答えに期待されています。このメタ投稿もご覧ください
マーティントゥルノイ

キーバインドをコピー/貼り付けするのは馬鹿げているようですが、そこに行きます。私はすでにそれが何をするかを説明しました。
コリングラディ

3

私は見つけるのvim-解説プラグインが遠く離れにより、これを行うための最も簡単な方法です。行の範囲を選択して、を押しgcます。開いているファイルタイプに適切なコメント文字を使用します。視覚的な選択をせずに、gcuまたはで隣接するコメント行のコメントを外すこともでき gcgcます。


2

行の先頭にある5行にプレフィックスを追加する場合、Searchとreplaceを使用できます。

:.,+5s/^/prefix_/g

または行末に:

:.,+5s/$/suffix_/g

または、ビジュアルモード(Ctrl+ v)を使用してテキストの垂直ブロックを選択し、挿入モード(I)を入力して何かを入力し、を押しEscて変更を確認して他の行に適用します。

関連:


2

この答えは、に貼り付けるために、正しいコードを表示する)1に、ここで.vimrc取得するためにvim 7.4+それを説明するために)ビジュアルモードと2で1つのショートカットでインデントレベルを維持しながらアンコメント/コメントブロックを行うこと。

コードは次のとおりです。

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>

使い方:

  • let b:commentChar='//':これにより、vimに変数が作成されます。bここでは、現在開いているファイルを意味し、この場合にはバッファに含まれる範囲を指します。コメント文字は文字列であり、引用符で囲む必要があります。引用符はコメントを切り替えるときに置き換えられるものの一部ではありません。

  • autocmd BufNewFile,BufReadPost *...:オートコマンドはさまざまなことでトリガーします。この場合、これらは新しいファイルまたは読み取りファイルが特定の拡張子で終了したときにトリガーされます。トリガーされたら、次のコマンドを実行します。これによりcommentChar、ファイルタイプに応じて変更できます。これを行う方法は他にもありますが、初心者(私のような)にとって混乱を招くものです。

  • function! Docomment():関数は、で始まり、functionで終わることによって宣言されendfunctionます。関数は大文字で始める必要があります。!この機能は、次のように定義以前の機能を上書きすることが保証さDocomment()のこのバージョンではDocomment()。がなければ、!エラーが発生しましたが、vimコマンドラインを使用して新しい関数を定義していた可能性があります。

  • execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e':Executeはコマンドを呼び出します。この場合、を実行substituteします。これは、%バッファー全体または'<,'>強調表示されたセクションなどの範囲(デフォルトでは現在の行)を取ることができます。^\s*は、行の先頭に一致する正規表現であり、その後に任意の量の空白が続き、その後に(のために&)追加されます。.ので、ここでは、文字列の連結のために使用されているescape()缶は、引用符で囲まれていません。escape()commentChar、引数を前に付けることで、引数(この場合、\および/)に一致する文字をエスケープできます\。この後、substitute文字列の最後に再び連結します。eフラグ。このフラグを使用すると、黙って失敗することができます。つまり、特定の行で一致するものが見つからない場合、それについて叫ぶことはありません。全体として、この行を使用すると、最初のテキストの直前にコメント文字とそれに続くスペースを挿入できます。これは、インデントレベルを維持することを意味します。

  • execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e':これは最後の巨大な長いコマンドに似ています。この1のユニークな、我々は\v我々が我々をエスケープする必要がないことを確認しますこれは、()1、私たちは私たちで作ったグループを指しています()。基本的に、任意の量の空白で始まり、コメント文字の後に任意の量の空白が続く行を照合し、最初の空白のみを保持します。繰り返しeますが、その行にコメント文字がない場合、静かに失敗します。

  • let l:line=getpos("'<")[1]:これは、コメント文字で行ったように変数を設定しますがl、ローカルスコープ(この関数に対してローカル)を参照します。getpos()この場合、強調表示の開始位置を取得し[1]、列番号などの他の項目ではなく、行番号のみを考慮します。

  • if match(getline(l:line), '^\s*'.b:commentChar)>-1:あなたはどのようにif機能するか知っています。match()最初のものに2番目のものが含まれているかどうかを確認します。したがって、強調表示を開始した行を取得し、コメント文字が続く空白で始まるかどうかを確認します。match()これが当てはまるインデックスを返します-1。一致するものが見つからなかった場合。以来if評価するすべての非ゼロの数字が真であることが、我々はそれの-1より大きいかどうかを確認するために私たちの出力を比較する必要があります。比較in vimは、falseの場合は0 を返し、trueの場合は1 を返します。これは、if正しく評価するために見たいものです。

  • vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>vnoremapは、次のコマンドをビジュアルモードでマップしますが、再帰的にマップしないことを意味します(他の方法で使用する可能性のある他のコマンドを変更しないことを意味します)。基本的に、もしあなたがvim初心者なら、常にnoremap物事を壊さないようにするために使用してください。<silent>「私はあなたの言葉が欲しくなく、あなたの行動だけが欲しい」という意味で、コマンドラインに何も出力しないように指示します。<C-r>マッピングしているものです。この場合はctrl + rです(このマッピングを使用すると、通常モードで「やり直し」に通常どおりCrを使用できます)。C-uちょっと紛らわしいですが、基本的には、視覚的な強調表示を忘れないようにします(この答えによれば、コマンド'<,'>は私たちが望むものから始めます)。callここですると、指定した関数を実行するようにvimに指示ます<cr>enterボタンを押すことを示しています。実際に関数を呼び出すには、1回押す必要があります(そうでない場合はcall function()、コマンドラインに入力したばかりで、代わりのものをすべて取得するためにもう一度押す必要があります(理由はわかりませんが、何でも)。

とにかく、うまくいけばこれが役立つ。これは、と強調し何もかかりますvVまたはC-v、最初の行をコメント化されているかどうかをチェックし、そうならば、すべての強調表示された行のコメントを解除しようとすると、そうでない場合、各行にコメント文字の追加の層を追加します。これは私の希望する動作です。それは後に私のために完璧に動作だから、僕は、それがブロックの各行がコメントされたかどうかを切り替えるにはしたくなかった尋ねる 複数の主題に関する質問を。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.