Existe-t-il une meilleure pratique pour plier un fichier vimrc

21

Je me suis récemment rendu compte que ma vimrclongueur dépasse maintenant 400 lignes (ce qui est trop pour l'OMI, je vais essayer de le réduire) et pour faciliter la navigation, la lecture et la modification, j'ai décidé d'étudier le concept de pliage dans vim (qui Je ne connaissais pas) .

  • J'ai essayé de régler la méthode de pliage sur indentmais je n'ai pas aimé le résultat (c'était trop compliqué surtout parce qu'une grande partie de mon vimrcn'était pas vraiment en retrait).
  • J'ai aussi essayé de mettre foldmethodà expret , syntaxmais je ne pouvais rien à plier correctement.
  • Ici, l'utilisation diffcomme méthode de pliage ne semble pas pertinente. (Ou si c'est le cas, je n'ai pas compris comment l'utiliser)
  • Donc pour l'instant j'utilise la markerméthode qui ne me satisfait pas totalement à cause des marqueurs "{{{et "}}}que j'ai trouvé "bruyant" dans le fichier.

J'aimerais donc savoir s'il existe des bonnes pratiques ou des directives communes pour bien plier avimrc .

Note 1: Comme nous le savons tous, SO n'est pas un forum et n'est pas fait pour recueillir des opinions personnelles et ce n'est pas ce que je recherche: bien sûr, je suppose que certaines personnes ont leurs préférences, mais j'aimerais savoir pourquoi utiliser les marqueurs (par exemple) améliorent davantage la lisibilité que l'utilisation du retrait.

Note 2: Mon objectif principal est également de faire en sorte que mes informations soient vimrcaussi claires que possible, donc si d'autres bonnes pratiques existent pour créer une belle, vimrcje suis curieux de le savoir.

Edit 1: j'aurais dû préciser que mon vimrcest déjà subdivisé en sections (et parfois sous-sections) les principales étant

  • Options générales
  • plugins (contenant une sous-section pour chaque plugin et sa configuration)
  • mappings
  • navigation (contenant également une sous-section)
  • Couleur
  • etc...

Et c'est cette structure qui m'a fait penser au pliage: je pense qu'être capable de sortir uniquement la section qui m'intéresse à un moment donné est quelque chose de très pratique.

Edit 2: La réponse mentionnant que les subdivisions de vimrcplusieurs fichiers sont valides, mais comme préférence personnelle, je préfère utiliser le pliage car je pense qu'il est plus facile de ne conserver qu'un seul fichier dans le dépôt git contenant mes fichiers dot. Ce n'est qu'une préférence personnelle et je suis conscient qu'il est possible d'utiliser également cette approche, mais je préférerais utiliser le pliage.

statox
la source
Je pense que l'utilisation de la "{{{façon de faire est la plus `` similaire à Vim '', le plugin Solarized l'utilise et bien qu'il puisse être bruyant, il vous offre la manière la plus standard de définir des plis manuels
icc97

Réponses:

22

J'ai les modèles suivants au bas de mon vimrcque j'ai copié de godlygeek, l'auteur de tabular :

"" vim:fdm=expr:fdl=0
"" vim:fde=getline(v\:lnum)=~'^""'?'>'.(matchend(getline(v\:lnum),'""*')-2)\:'='

Cela fera de n'importe quelle ligne commençant par 2+ "un pli. Plus "le pli est profond. Cela vous permet de subdiviser les sections si vous en avez besoin.

Peter Rincker
la source
Je ne peux pas le tester pour le moment mais cela semble être une solution idéale pour moi! Merci d'avoir partagé!
statox
Certains expliquent: getline (v: lnum) renvoie la chaîne de la ligne donnée par le numéro de ligne (v: lnum); = ~ signifie correspondance d'expression régulière; '^ ""' signifie que toutes les lignes commencent par deux "; matchend (getline (v: lnum), '" "*') - 2 compte le nombre supplémentaire de", ce qui signifie que "" "se repliera avec le niveau 1," "" "se repliera avec le niveau 2 et ainsi de suite; getline (v: lnum) = ~ '^" "' renvoie vrai ou faux selon le début de la ligne v: lnum avec deux" ou pas; si vrai, le fde est défini sur >extra number of "(niveau de départ qui est assis par le nombre après <à cette ligne) ou '='(utiliser le niveau de la ligne précédente), la signification peut être trouvée àfold-expr
van abel
après la récente mise à jour de vim 8.1.1517), je reçois "" Erreur détectée lors du traitement des modelines "avec cette configuration.
apollo
9

C'est une bonne idée de définir d'abord vos propres catégories dans votre .vimrc(comme une liste avec des sous-listes et sous-listes) et d'ajouter tous vos plugins / paramètres / fonctions aux catégories respectives. Combiné avec un pliage personnalisé, cela peut très bien fonctionner:

Exemple

L'exemple ci-dessus montre les catégories possibles que je trouve utiles pour structurer mon .vimrc. Il utilise les paramètres de pliage personnalisés suivants:

""""""""""""""""""""""""
"  THIS IS A CATEGORY  "
""""""""""""""""""""""""
"" Autofolding .vimrc
" see http://vimcasts.org/episodes/writing-a-custom-fold-expression/
""" defines a foldlevel for each line of code
function! VimFolds(lnum)
  let s:thisline = getline(a:lnum)
  if match(s:thisline, '^"" ') >= 0
    return '>2'
  endif
  if match(s:thisline, '^""" ') >= 0
    return '>3'
  endif
  let s:two_following_lines = 0
  if line(a:lnum) + 2 <= line('$')
    let s:line_1_after = getline(a:lnum+1)
    let s:line_2_after = getline(a:lnum+2)
    let s:two_following_lines = 1
  endif
  if !s:two_following_lines
      return '='
    endif
  else
    if (match(s:thisline, '^"""""') >= 0) &&
       \ (match(s:line_1_after, '^"  ') >= 0) &&
       \ (match(s:line_2_after, '^""""') >= 0)
      return '>1'
    else
      return '='
    endif
  endif
endfunction

""" defines a foldtext
function! VimFoldText()
  " handle special case of normal comment first
  let s:info = '('.string(v:foldend-v:foldstart).' l)'
  if v:foldlevel == 1
    let s:line = ' ◇ '.getline(v:foldstart+1)[3:-2]
  elseif v:foldlevel == 2
    let s:line = '   ●  '.getline(v:foldstart)[3:]
  elseif v:foldlevel == 3
    let s:line = '     ▪ '.getline(v:foldstart)[4:]
  endif
  if strwidth(s:line) > 80 - len(s:info) - 3
    return s:line[:79-len(s:info)-3+len(s:line)-strwidth(s:line)].'...'.s:info
  else
    return s:line.repeat(' ', 80 - strwidth(s:line) - len(s:info)).s:info
  endif
endfunction

""" set foldsettings automatically for vim files
augroup fold_vimrc
  autocmd!
  autocmd FileType vim 
                   \ setlocal foldmethod=expr |
                   \ setlocal foldexpr=VimFolds(v:lnum) |
                   \ setlocal foldtext=VimFoldText() |
     "              \ set foldcolumn=2 foldminlines=2
augroup END

Pour définir vos propres catégories et sous-catégories, utilisez la syntaxe suivante:

""""""""""""""
"  Category  "
""""""""""""""
"" Subcategory
""" Subsubcategory
" Just a comment, gets ignored no matter where

La catégorie de niveau supérieur peut être créée très facilement si vous utilisez vim-snippets (par exemple avec UltiSnips ): Développez simplement le boxou le bboxsnippet fourni par vim-snippets (écrivez boxou bboxet appuyez sur le déclencheur de développement).

Pour basculer les plis ouverts et fermés encore plus rapidement en appuyant deux fois sur l'espace:

let mapleader = "\<space>"
" Toggle folds
nnoremap <silent> <leader><Space> @=(foldlevel('.')?'za':"\<Space>")<CR>
vnoremap <leader><space> zf

De cette façon, vous avez une structure bien structurée .vimrcqui peut être parcourue facilement.

cbaumhardt
la source
+1 pour le joli gif animé :) Juste curieux, qu'avez-vous utilisé pour afficher les touches tapées?
mMontu
@mMontu: J'ai utilisé screenkey pour afficher les clés et gtk-recordmydesktop pour l'enregistrer (les deux dans les dépôts Debian). Avec 5 images par seconde, un clip de 45 secondes est inférieur à un MiB. Puis converti en ligne en un gif (c'est là que les distorsions sont intervenues, avant que la qualité de l'image ne soit parfaite).
cbaumhardt
7

J'utilise mon principal vimrccomme lien vers plusieurs autres fichiers classés, en les approvisionnant au fur et à mesure, par exemple les options Vim dans un fichier, les paramètres de plugin dans un autre.

"--- Vim Options
source ~/.vim/config/vim_options.vim

"--- Here Be Functions!
" (need to be sourced before stuff that uses 'em)
runtime! functions/*.vim

"--- Key Mapping
source ~/.vim/config/key_mapping.vim

"--- Folding
source ~/.vim/config/folding.vim

"--- Autocmds
source ~/.vim/config/autocmds.vim

"--- We Are Plugged In!
source ~/.vim/config/plugins.vim

" vim: ft=vim fdm=marker

En tant que réponse plus directe à la question OP, j'utilise la méthode du marqueur, mais sur le côté droit avec un espacement et autour de plus de catégories qu'individuel, pour la plupart. Je fais cependant chaque plugin séparément.

Cometsong
la source
J'ai oublié de préciser cela dans ma question: je ne suis pas fan de "séparer" les vimrcdifférents fichiers car (IMO) cela augmente la complexité et le rend plus difficile à maintenir. À propos du pliage, que voulez-vous dire par «à droite avec espacement»?
statox
Je veux dire " {{{avec autant d'espaces là-dedans que le vôtre textwidth, les marqueurs sont donc près des bords droits. J'ai également une fonction FoldText personnalisée dans le fichier folding.vim. Je préfère les fichiers séparés afin que mon git ne repo qu'un seul type spécifique de mod par commit.
Cometsong
7

Vous pourriez dire que les "meilleures pratiques" sont avant tout une question d'opinion, :) mais il existe deux approches qui (1) ont un sens évident et (2) peuvent être appliquées à tous les fichiers de configuration, pas seulement Vim: pliage par sections logiques et des sous-sections (ou même plus profondément, si vous vous sentez courageux), et diviser votre configuration en plusieurs fichiers plus petits et :source-les.

Personnellement, je préfère le pliage, car cela facilite l'accès aux choses, tout en me donnant une certaine hiérarchie. Plier les fonctions et les autocmds aux niveaux les plus intimes est également une bonne idée, car ceux-ci font des unités logiques "naturelles". markerle pliage est plus logique pour tout cela, car les hiérarchies logiques ne sont pas nécessairement reflétées dans les niveaux de retrait ou dans la coloration syntaxique. J'augmente également foldcolumn, ce qui me donne une indication visuelle de ma position:

# vim: filetype=vim foldmethod=marker foldlevel=0 foldcolumn=3

D'un autre côté, cette foldtextfonction (une modification d'une fonction similaire par Drew Neil, IIRC) a plus de sens pour moi que la valeur par défaut:

function! MyFoldText()
    let line = getline(v:foldstart)

    let nucolwidth = &foldcolumn + &number * &numberwidth
    let windowwidth = winwidth(0) - nucolwidth - 3
    let foldedlinecount = v:foldend - v:foldstart

    " expand tabs into spaces
    let chunks = split(line, "\t", 1)
    let line = join(map(chunks[:-2], 'v:val . repeat(" ", &tabstop - strwidth(v:val) % &tabstop)'), '') . chunks[-1]

    let line = strpart(line, 0, windowwidth - 2 - len(foldedlinecount))
    let fillcharcount = windowwidth - len(line) - len(foldedlinecount) - 1
    return line . '...' . repeat(' ', fillcharcount) . foldedlinecount . ' '
endfunction
set foldtext=MyFoldText()

Avec l'autre approche, les fichiers divisés, les principaux problèmes sont de trouver des choses et de passer d'un fichier à un autre. Une très bonne façon de résoudre les deux est d'utiliser un plugin tel que CtrlSF , CtrlP ou similaire. Mais vous en utilisez probablement déjà un de toute façon.

lcd047
la source
Alors, allez-y marker. En effet, la personnalisation foldcolumnest une bonne chose à faire, je vais voir quelle valeur correspond le mieux à mes besoins. Je partage également votre point de vue sur les fichiers divisés, mais je ne savais pas que CtrlSFj'y jetterai un coup d'œil même si je suis assez satisfait CtrlP.
statox
Pouvez-vous également expliquer comment utiliser la méthode de pliage personnalisée, s'il vous plaît? J'ai essayé de mettre fdmà foldtextet MyFoldText()mais il semble que ce n'est pas la bonne façon de l' utiliser.
statox
@statox CtrlSFfonctionne mieux avec ag ou ack , qui sont essentiellement des versions spécialisées de grep. foldtextn'est pas une méthode de pliage personnalisée, mais une fonction pour changer l'apparence du texte plié. La dernière ligne dans mes snippet comment montre il est utilisé: set foldtext=MyFoldText().
lcd047
2

Meilleures pratiques de base:

  • Divisez en sections:

    • Plugins
    • Paramètres
    • Relie
  • Commenter chaque section / relier

  • (sauvegardez votre .vimrcou _vimrcsur Github)

Juste ma préférence personnelle. Peut-être que ça n'aide pas tellement.

Gustav Blomqvist
la source
Personnellement, je n'utilise pas le pliage et vous n'en aurez pas besoin. Organisez simplement votre vimrc et tout devrait être bon.
Gustav Blomqvist
Mon vimrc est déjà organisé en section (options générales, plugins, mappages, navigation, couleur, etc ...). Le fait de pouvoir plier une section (ou une sous-section) est en fait bon de se concentrer sur ce que vous modifiez / recherchez.
statox
D'accord. Désolé pour mauvaise réponse.
Gustav Blomqvist
Ce n'est pas une mauvaise réponse et je suis également coupable de ne pas avoir posé suffisamment de questions
détaillées
2

Inspiré par la réponse de @ PeterRincker , j'ai conçu ce qui suit pour utiliser des en-têtes de style ATX. Ajoutez-le à la fin de votre.vimrc

"# Folding

" Fold with ATX style headers - "# is H1, "## is H2, and so on
" vim:fdm=expr:fdl=0
" vim:fde=getline(v\:lnum)=~'^"#'?'>'.(matchend(getline(v\:lnum),'"#*')-1)\:'='
go2null
la source
1

Si vous avez de grandes fonctions comme moi, vous pouvez l'utiliser pour replier vos fonctions:

fun! MyFoldLevel(linenum)
    if ! exists('w:nextline')
        let w:nextline = 0
        let w:insideafun = 0
    endif

    if w:nextline == 1
        let w:nextline = 0
        let w:insideafun = 0
    endif

    let l:line = getline(a:linenum)

    if l:line =~# '^[[:space:]]*fun'
        let w:insideafun = 1
        return '>1'
    elseif l:line =~# '^[[:space:]]*endf'
        let w:nextline = 1
        return '<1'
    endif

    if w:insideafun == 1
        return 1
    else
        return 0
    endif
endfun

Et ajoutez cette modeline à votre vimrc:

" vim:fde=MyFoldLevel(v\:lnum):fdm=expr:
MichalH
la source
0

Développer l'idée de @Peter Rincker et @ go2null. Si vous ne souhaitez pas définir les options de pliage dans la modélisation Vim. Vous pouvez utiliser l'autocmd suivant pour définir la méthode de pliage et l'expression de pliage.

augroup vim_folding
    autocmd!
    autocmd FileType vim set foldmethod=expr foldlevel=0
    " note that double quote in foldexpr has to be escaped with backslash
    autocmd FileType vim set foldexpr=getline(v:lnum)=~'^\"#'?'>'.(matchend(getline(v:lnum),'\"#*')-1):'='
augroup END

J'ai fait de petites modifications pour faire la réponse d'origine pour la faire fonctionner comme une commande vim régulière (pas besoin d'échapper aux deux points, mais les guillemets doivent être échappés).

Si vous n'aimez pas la longue foldexprchaîne, nous pouvons définir une fonction pour cela:

function! VimFolds(lnum)
    let s:cur_line = getline(a:lnum)

    if s:cur_line =~ '^"#'
        return '>' . (matchend(s:cur_line, '"#*')-1)
    else
        return '='
    endif

endfunction

Remplacez ensuite la ligne autocmd sur le point foldexprde

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
jdhao
la source