Como dobrar comentários?

16

A sintaxe foldmethodé ótima, mas às vezes eu só quero dobrar os comentários em um arquivo de origem.

Também a dobragem de sintaxe dos comentários funciona apenas para comentários no estilo C, como:

/*
 ...
 */

Mas não para comentários como:

//
//
// ...
//

Ou mesmo para blocos de comentários em idiomas que não sejam do tipo C, como:

#
#
# ...
#

Como posso configurar isso com o vim?

maxschlepzig
fonte
Deseja usar dobras de sintaxe e comentários? Ou apenas comentar dobrar?
Martin Tournoij 4/15
@Carpetsmoker, dobrar sintaxe + dobrar comentário seria bom se alguém pudesse dizer 'abrir todas as dobras, exceto os comentários'. Caso contrário, a dobra de comentários sem a dobra de sintaxe também seria adequada.
maxschlepzig

Respostas:

14

Dobrar apenas os comentários é bastante fácil usando foldmethod=expr:

set foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*'.&commentstring[0]

Isso simplesmente verificará se a linha começa com qualquer quantidade de espaço em branco + um caractere de comentário. Observe que isso é bastante ingênuo e pode não funcionar para todos os idiomas. Portanto, você pode usar um autocmd para ser mais específico:

autocmd FileType c setlocal foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*//'
autocmd FileType python setlocal foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*#'

Para mais informações sobre fold-expr, consulte:


O uso de dobras de sintaxe e de comentários está mais envolvido; isso exigiria a modificação do arquivo de sintaxe /usr/share/vim/vim74/syntax/*.vime será específico para o idioma que você está usando.

Observe que alguns tipos de arquivos já fazem isso! Por exemplo, de ruby.vim:

if !exists("ruby_no_comment_fold")
  syn region rubyMultilineComment start="\%(\%(^\s*#.*\n\)\@<!\%(^\s*#.*\n\)\)\%(\(^\s*#.*\n\)\{1,}\)\@=" end="\%(^\s*#.*\n\)\@<=\%(^\s*#.*\n\)\%(^\s*#\)\@!" contains=rubyC
  syn region rubyDocumentation    start="^=begin\ze\%(\s.*\)\=$" end="^=end\%(\s.*\)\=$" contains=rubySpaceError,rubyTodo,@Spell fold
else
  syn region rubyDocumentation    start="^=begin\s*$" end="^=end\s*$" contains=rubySpaceError,rubyTodo,@Spell
endif
Martin Tournoij
fonte
2

Gosto de dobrar com recuo, mas incluir os comentários na dobra (quero dizer que cada comentário tem o mesmo nível de dobra da linha anterior).

Infelizmente, a palavra-chave foldignore funciona apenas para comentários de uma linha. Então eu dobrei com expr no vimrc:

set foldmethod=expr
set foldexpr=FoldMethod(v:lnum)

function! FoldMethod(lnum)
  "get string of current line
  let crLine=getline(a:lnum)

  " check if empty line 
  if empty(crLine) "Empty line or end comment 
    return -1 " so same indent level as line before 
  endif 

  " check if comment 
  let a:data=join( map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') )
  if a:data =~ ".*omment.*"
    return '='
  endif

  "Otherwise return foldlevel equal to indent /shiftwidth (like if
  "foldmethod=indent)
  else  "return indent base fold
    return indent(a:lnum)/&shiftwidth
endfunction

O último bloco:

indent(a:lnum)/&shiftwidth

Retorna uma base de nível de dobra no recuo.

E o outro :

join( map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') )

Verifica se o primeiro caractere da linha é considerado como um comentário com a sintaxe. Portanto, é uma boa maneira de mesclar o recuo e a dobra de sintaxe com a expressão, a dobra mais avançada.

Observe que você também pode "definir o texto da dobra", dependendo de como deseja que o resultado seja.

tinmarino
fonte
0

Você pode selecionar visualmente o bloco comentado vace criar uma dobra manual zf.

O objeto de texto do comentário pode ser uma extensão do idioma para o conjunto de objetos de texto padrão do vim. Testei com a sintaxe Go.

AB
fonte
1
Na verdade, acnão é um builtin. Mas com o comentário do tpope gcé um objeto de texto. Assim, as melhores soluções são zfac, zfgcou zfipna pior das hipóteses
D. Ben Knoble