Vim:新しい行の自動コメント


9

私はを設定しているため、コメントアウトされた行から新しい行を開始すると、Vimは自動的にコメントを挿入しformatoptions=tcroqlます。例(カーソルは*):

// this is a comment*

そして、打った後<Enter>(挿入モード)またはo(ノーマルモード)私がが残っています:

// this is a comment
// *

この機能は、長い複数行のコメントを書くときに非常に便利ですが、多くの場合、1行のコメントだけが必要です。コメントシリーズを終了したい場合は、いくつかのオプションがあります。

  • ヒット <Esc>S
  • <BS>3回ヒット

これらの両方とも、3つのキーストロークを提供します。<Enter>これと合わせて、新しい行に対して4つのキーストロークを意味します。理想的には<Enter>、2回目にヒットして、次のように残しておきたいと思います。

// this is a comment
*

ソリューションがさまざまなインデントレベルでも機能することが重要です。

int main(void) {
    // this is a comment*
}

ヒット <Enter>

int main(void) {
    // this is a comment
    // *
}

ヒット <Enter>

int main(void) {
    // this is a comment
    *
}

私はこの機能を数年前に一部のテキストエディタで見たと思いますが、どの機能だったか覚えていません。Vimでこれを行うソリューションを知っている人はいますか?私自身のソリューションをどのように展開するかに関する正しい方向へのポインタも大歓迎です。


3
挿入モードでctrl-uを使用すると、1つのキーコードに自動的に挿入されたコメントマーカーを削除できます。
Etan Reisner、2013年

1
@EtanReisnerの方が実際には優れていますが、一般的な使用例であるため、キーストロークは1回では多すぎます:)
Patrick Oscity 2013年

もう一度Enterキーを押して必要な動作を取得できるようにすることを提案しましたが、ctrl-uは多すぎますか?挿入モードで<enter> <enter>をマッピングしてctrl-uを自動的に実行することもできますが、<enter>を1回だけ押すと(何もヒットせずに)、遅延が発生します。
Etan Reisner、2013年

さらに、コメント行が空の場合にのみトリガーする必要があります。<Enter>を押したときの顕著な遅延も許容できません。
Patrick Oscity 2013年

vimは別のキーを押すつもりがないことを確認するために待機する必要があるため、他のキーを押していない場合にのみ遅延します。関数を使用してそのチェックを実行することもできますが、特に簡単ではないかもしれません。
Etan Reisner、2013年

回答:


4

これを試して:

function! EnterEnter()
  if getline(".") =~ '^\s*\(//\|#\|"\)\s*$'
    return "\<C-u>"
  else
    return "\<CR>"
  endif
endfunction

imap <expr> <CR> EnterEnter()

ありがとうございます。家に帰ったら試してみます。コメントマーカーの言語に個別に一致するように正規表現を拡張する方法を知っていますか?情報は構文ファイルなどにあるはずです。多分私はこれのために構文機能を活用することができます...
Patrick Oscity


明らかに、この関数はまったくジェネリックではありません。:h 'comment'およびを参照してください:h format-comment'
romainl 2013年

クラシックに加えて、#rubyと"vimscriptのofで動作するように変更された関数//。それはとにかく終了*する必要があるため、Cスタイルの複数行コメントに対して何もすることは実際には意味がありませ*/ん。
romainl 2013年

うーん、多分<CR><CR>コメントを終了するために使用できます...
romainl '11

3

@romainlの回答を拡張して、Vimから正規表現を生成することにより、任意の言語で動作するようにしました&commentstring

function! s:IsOnlyComment(getlineArg)
  let commentRegex='^\s*'.substitute(&commentstring,'%s','\\s*','').'$'
  return strlen(matchstr(getline(a:getlineArg), commentRegex)) > 0
endfunction

function! SmartEnter()
  if s:IsOnlyComment('.')
    return "\<Esc>S"
  else
    return "\<CR>"
  endif
endfunction

inoremap <expr> <CR> SmartEnter()

しかし、私はまったくリマップできないよう<CR>で、これは機能しません。今のところ、<CR><CR>この問題が解決するまで使用します。


1
なんで<Esc>S<C-u>挿入モードを終了せずに同じことを行います。とにかく、私はたくさんのことを行うカスタム関数を持っていて、答えを投稿<CR>したSmartEnter()直後の昨日の名前に変更しました;-) また&commentstring、通常は1つのフォームのみを含み、「行ごと」または「ブロックごと」(/*%s*/C、//%sJavascriptなど)になる可能性があるため、正しい選択かどうかはわかりません。
romainl 2013年

2

'formatoptionsからrを削除します。それがそのオプションが行うことです。これをオフにすると、vimがそれを実行することはありません。つまり、実際にコメントマーカーが必要な場合は、先頭のコメントマーカーを追加する必要がありますが、それはトレードオフです。


2
私が実際にしたい、私はこれを愛し、Vimは私のためにコメントマーカーを追加します。しかし、コメントを終了する簡単な方法も必要です。回答ありがとうございます。
Patrick Oscity 2013年

通常モードの「o」コマンドの場合、「r」を削除する必要がありますformatoptions
elig
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.