Vim:在新行中自动注释


9

当我从注释行开始新行时,Vim自动插入注释,因为我已经设置了formatoptions=tcroql。例如(光标是*):

// this is a comment*

并击中<Enter>(插入模式)或o(普通模式)后,我留下:

// this is a comment
// *

编写长的多行注释时,此功能非常方便,但通常我只想单行注释。现在,如果我想结束评论系列,我有几种选择:

  • 击中 <Esc>S
  • <BS>三遍

这两个都提供了三个击键,与<Enter>这一起意味着新行的四个击键,我认为这太多了。理想情况下,我想再打<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中为我做到这一点的解决方案?也欢迎欢迎就正确的方向提出自己的解决方案。


3
您可以在插入模式下使用ctrl-u删除一个键和弦中自动插入的注释标记。
Etan Reisner

1
@EtanReisner实际上更好,但是对我来说仍然是一个按键,因为这是一个非常常见的用例:)
Patrick Oscity

您建议您希望能够再次按Enter来获得所需的行为,但是ctrl-u太多了?您可以尝试在插入模式下映射<enter> <enter>来自动为您执行ctrl-u,但是如果您只击过一次<enter>(不击中其他任何东西),则会带来延迟。
Etan Reisner

另外,它仅应在注释行为空时触发。按下<Enter>时出现明显的延迟也是不可接受的。
Patrick Oscity

如果您不按我相信的任何其他键,这只会延迟,因为vim将需要等待以确保您仍然不打算按其他键。我认为您也可以使用一个函数来执行该检查,尽管这样做可能并不是特别简单。
Etan Reisner

Answers:


4

尝试这个:

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

imap <expr> <CR> EnterEnter()

谢谢,看起来很棒!我回家后会尝试的。您知道扩展正则表达式以独立匹配注释标记语言的方法吗?该信息应该在语法文件中或其他内容中。也许我可以为此使用语法功能...
Patrick Oscity

我的意思是在C中它应该匹配//和/ *和*(多行注释),在ruby中以此类推
Patrick Oscity

显然,此功能不是通用的。请参阅:h 'comment':h format-comment'
romainl

修改了功能以与#红宝石和"vimscript一起使用//*对C风格的多行注释做任何事情都没有任何意义,因为它必须以结尾结尾*/
romainl

嗯,也许<CR><CR>可以用来完成多行注释…
romainl

3

我通过从Vim生成正则表达式来扩展@romainl的答案以使用任意语言&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是正确的选择,因为它通常只包含一种形式,并且可能是“逐行”或“逐行”(/*%s*/在C,//%sJavascript等中)。
romainl 2013年

2

从'formatoptions中删除r。这就是该选项的作用。禁用它将意味着您永远不会为自己做到这一点,这意味着当您确实需要它们时,需要添加前导注释标记,但这是一个折衷。


2
我真的希望 Vim为我添加评论标记,我喜欢这个。但是我也想要一种退出评论的快速方法。谢谢您的回答。
Patrick Oscity

对于普通模式的“ o”命令,必须从formatoptions
–elig
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.