web-dev-qa-db-ja.com

Vim:改行で自動コメント

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

// this is a comment*

<Enter>(挿入モード)またはo(通常モード)を押した後、次のようになります。

// this is a comment
// *

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

  • ヒット<Esc>S
  • <BS>を3回押す

これらは両方とも、<Enter>と合わせて3つのキーストロークを提供します。これは、新しい行に対して4つのキーストロークを意味します。これは多すぎると思います。理想的には、もう一度<Enter>を押して、次のようにします。

// 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でこれを行うソリューションを知っている人はいますか?私自身のソリューションをどのように展開するかについての正しい方向へのポインタも大歓迎です。

9
Patrick Oscity

これを試して:

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

imap <expr> <CR> EnterEnter()
4
romainl

@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>を使用します。

3
Patrick Oscity

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

2
Etan Reisner