Comment plier les commentaires?

16

La syntaxe foldmethodest excellente, mais parfois je veux simplement plier les commentaires dans un fichier source.

Le pliage syntaxique des commentaires ne fonctionne que pour les commentaires de style C comme:

/*
 ...
 */

Mais pas pour un commentaire comme:

//
//
// ...
//

Ou même pour des blocs de commentaires dans des langages non similaires à C comme:

#
#
# ...
#

Comment puis-je configurer cela avec vim?

maxschlepzig
la source
Voulez-vous utiliser le pliage de syntaxe et le pliage de commentaires? Ou seulement comment plier?
Martin Tournoij
@Carpetsmoker, le pliage de syntaxe + le pliage de commentaires serait correct si l'on pouvait dire "ouvrir tous les plis, sauf pour les commentaires". Sinon, le pliage de commentaires sans pliage de syntaxe conviendrait également.
maxschlepzig

Réponses:

14

Plier uniquement les commentaires est assez facile en utilisant foldmethod=expr:

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

Cela vérifiera simplement si la ligne commence par un espace quelconque + un caractère de commentaire. Notez que cela est assez naïf et peut ne pas fonctionner pour toutes les langues. Donc, vous voudrez peut-être utiliser un autocmd pour être plus précis:

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

Pour plus d'informations sur fold-expr, voir:


L'utilisation du pliage de syntaxe et du pliage de commentaires est plus complexe; cela nécessiterait de modifier le fichier de syntaxe dans /usr/share/vim/vim74/syntax/*.vim, et sera spécifique à la langue que vous utilisez.

Notez que certains types de fichiers le font déjà! Par exemple 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
la source
2

J'aime le pliage avec retrait mais en incluant les commentaires dans le pli (je veux dire que chaque commentaire obtient le même niveau de pli que la ligne précédente).

Malheureusement, le mot clé foldignore ne fonctionne que pour les commentaires d'une ligne. Je plie donc avec expr dans 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

Le dernier bloc:

indent(a:lnum)/&shiftwidth

Renvoie une base de niveau de repli au retrait.

Et l'autre :

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

Vérifie si le premier caractère de la ligne est considéré comme un commentaire avec la syntaxe. C'est donc un bon moyen de fusionner le pliage de retrait et de syntaxe avec l'expression, le pliage le plus avancé.

Notez que vous pouvez également "définir le texte de pliage" en fonction de l'apparence du résultat.

tinmarino
la source
0

Vous pouvez sélectionner visuellement le bloc commenté avec vacpuis créer un pli manuel zf.

L'objet texte de commentaire peut être une extension de langue pour un ensemble d'objets texte vim standard. Testé avec la syntaxe Go.

UN B
la source
1
En effet, acn'est pas une fonction intégrée. Mais avec le commentaire de tpope gcest un objet texte. Donc, de meilleures solutions sont zfac, zfgcou zfipau pire
D. Ben Knoble