Esiste una procedura ottimale per piegare un file vimrc


21

Di recente mi sono reso conto che il mio vimrcè ora più di 400 righe (che l'IMO è troppo proverò a ridurlo) e per facilitare la navigazione, la lettura e la modifica ho deciso di indagare sul concetto di pieghevole in vim (che Non mi era familiare) .

  • Ho provato a impostare il metodo di piegatura su indentma il risultato non mi è piaciuto (è stato troppo disordinato soprattutto perché gran parte del mio vimrcnon è veramente rientrato).
  • Ho anche cercato di impostare foldmethoda expre syntax, ma non ero in grado di piegare qualsiasi cosa in modo corretto.
  • Qui l'utilizzo diffcome metodo di piegatura non sembra rilevante. (O se è così non ho capito come usarlo)
  • Quindi per ora sto usando il markermetodo che non mi soddisfa totalmente a causa dei marcatori "{{{e "}}}che ho trovato "rumoroso" nel file.

Quindi mi piacerebbe sapere se ci sono buone pratiche o linee guida comuni su come piegare correttamente avimrc .

Nota 1: Come tutti sappiamo SO non è un forum e non è fatto per raccogliere opinioni personali e non è quello che sto cercando: ovviamente credo che alcune persone abbiano le loro preferenze, ma mi piacerebbe sapere perché usare i marker (ad esempio) migliorano la leggibilità più che usare il rientro.

Nota 2: Anche il mio obiettivo principale è quello di renderlo il vimrcpiù chiaro possibile, quindi se esistono altre buone pratiche per creare un bel vimrcsono curioso di questo.

Modifica 1: Avrei dovuto precedere che il mio vimrcè già suddiviso in sezioni (e talvolta sottosezione) in cui le principali sono

  • opzioni generali
  • plugin (contenente una sottosezione per ciascun plugin e la sua configurazione)
  • mappature
  • navigazione (contenente anche la sottosezione)
  • colore
  • eccetera...

Ed è questa struttura che mi ha fatto pensare di piegare: sento che riuscire a produrre solo la sezione che mi interessa a un certo punto è qualcosa di abbastanza conveniente.

Modifica 2: Rispondi menzionando le suddivisioni dei vimrcdiversi file sono validi, ma come preferenza personale preferirei usare il fold perché penso che sia più facile mantenere un solo file nel repository git contenente i miei dotfile. Questa è solo una preferenza personale e sono consapevole che è possibile utilizzare anche questo approccio, ma preferirei usare la piegatura.


Penso che usare "{{{sia il modo più 'vim like' di fare le cose, il plugin solarizzato lo usa e sebbene possa essere rumoroso, ti dà il modo più standard di impostare le piegature manuali
icc97

Risposte:


22

Ho le seguenti modelle in fondo alla mia vimrcche ho copiato da godlygeek, l'autore di tabular :

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

Questo renderà qualsiasi riga che inizia con 2+ "sa fold. Più "è profonda la piega. Ciò consente di suddividere le sezioni se necessario.


Non posso provarlo in questo momento, ma questa sembra essere la soluzione ideale per me! Grazie per la condivisione!
statox

Alcuni spiegano: getline (v: lnum) restituisce la stringa della linea data dal numero di linea (v: lnum); = ~ significa corrispondenza dell'espressione regolare; '^ ""' indica che tutte le righe iniziano con due "s; matchend (getline (v: lnum), '" "*') - 2 conta il numero aggiuntivo di", significa che "" "si piegherà con il livello 1," "" "si piegherà con il livello 2 e così via; getline (v: lnum) = ~ '^" "' restituisce vero o falso a seconda della linea v: lnum inizia con due" oppure no; se vero, il fde è impostato su >extra number of "(livello iniziale che è saturato dal numero dopo <su questa riga) o '='(usa il livello della riga precedente), il significato può essere trovato afold-expr
van abel

dopo il recente aggiornamento vim 8.1.1517), ricevo "" Errore rilevato durante l'elaborazione delle modeline "con questa configurazione.
apollo

9

È una buona idea definire prima le tue categorie nella tua .vimrc(come un elenco con liste e sottoscrizioni) e aggiungere tutti i tuoi plugin / impostazioni / funzioni alle rispettive categorie. In combinazione con la piegatura personalizzata, può funzionare alla grande:

Esempio

L'esempio sopra mostra possibili categorie che trovo utili per strutturare il mio .vimrc. Utilizza le seguenti impostazioni di piegatura personalizzate:

""""""""""""""""""""""""
"  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

Per definire le proprie categorie e sottocategorie, utilizzare la sintassi seguente:

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

La categoria di livello superiore può essere creata facilmente se si utilizzano frammenti di vim (ad esempio con UltiSnips ): basta espandere lo snippet boxo bboxfornito da vim-snippet (scrivere boxo bboxpremere il grilletto di espansione).

Per attivare e disattivare le pieghe ancora più velocemente premendo due volte spazio:

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

In questo modo hai una struttura ben strutturata .vimrcche può essere facilmente navigata.


+1 per la bella gif animata :) Solo curioso, cosa hai usato per visualizzare i tasti digitati?
lunedì

@mMontu: ho usato screenkey per visualizzare i tasti e gtk-recordmydesktop per registrarlo (entrambi nei repository Debian). Con 5 fps, una clip di 45 secondi è inferiore a un MiB. Quindi l'ho convertito online in una gif (ecco dove sono arrivate le distorsioni, prima che la qualità dell'immagine fosse perfetta).
cbaumhardt,

7

Uso il mio primario vimrccome collegamento a molti altri file categorizzati, acquistando ciascuno di essi mentre procede, ad esempio le opzioni di Vim in un file, le impostazioni del plug-in in un altro.

"--- 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

Come risposta più diretta alla domanda OP, uso il metodo marker, ma per lo più sul lato destro con spaziatura e intorno a più categorie rispetto ai singoli, per la maggior parte. Faccio ogni plugin separatamente però.


Ho dimenticato di precisarlo nella mia domanda: non sono un fan di "separare" i vimrcfile diversi perché (IMO) aumenta la complessità e rende più difficile la manutenzione. Riguardo alla piegatura cosa intendi con "fuori dalla parte destra con spaziatura"?
statox

Voglio dire " {{{con tanti spazi quanti sono i tuoi, textwidthquindi i marker si trovano vicino ai bordi giusti. Ho anche una funzione FoldText personalizzata nel file folding.vim. Preferisco file separati in modo che il mio git repository solo un tipo specifico di mod per commit.
Cometsong,

7

Si potrebbe dire che la "best practice" è principalmente una questione di opinione, :) ma ci sono due approcci che (1) hanno un senso ovvio e (2) possono essere applicati a tutti i file di configurazione, non solo a quelli di Vim: piegare per sezioni logiche e sottosezioni (o anche più in profondità, se ti senti coraggioso) e suddividere la configurazione in più file più piccoli e :sourceinserirli.

Personalmente preferisco piegare perché rende più facile l'accesso alle cose, pur continuando a darmi un po 'di gerarchia da cui scegliere. autocmdÈ anche una buona idea ripiegare funzioni e livelli più interni, dal momento che creano unità logiche "naturali". markerla piegatura ha più senso per tutto ciò, perché le gerarchie logiche non si riflettono necessariamente nei livelli di rientro o nell'evidenziazione della sintassi. Inoltre aumento foldcolumn, il che mi dà un indizio visivo di dove sono:

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

In una nota a margine, questa foldtextfunzione (una modifica di una funzione simile di Drew Neil, IIRC) ha più senso per me rispetto al valore predefinito:

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()

Con l'altro approccio, dividere i file, i problemi principali sono trovare cose e passare da un file all'altro. Un modo molto carino di affrontare entrambi è usare un plugin come CtrlSF , CtrlP o simili. Ma probabilmente stai già utilizzando uno di quelli comunque.


Quindi vai con te marker. Effettivamente la personalizzazione foldcolumnè una cosa carina da fare, vedrò quale valore si adatta meglio alle mie esigenze. Inoltre condivido la tua opinione sui file divisi, ma non sapevo CtrlSFche darò un'occhiata anche se ne sono abbastanza soddisfatto CtrlP.
statox

Potresti anche spiegare come utilizzare il metodo di piegatura personalizzato per favore? Ho cercato di impostare fdmper foldtexte MyFoldText()ma sembra che non è il modo giusto per usarlo.
statox

@statox CtrlSFfunziona meglio con ag o ack , che sono essenzialmente versioni specializzate di grep. foldtextnon è un metodo di piegatura personalizzato, ma una funzione per cambiare l'aspetto del testo piegato. L'ultima riga nei miei spettacoli frammento come viene utilizzato: set foldtext=MyFoldText().
lcd047,

2

Best practice di base:

  • Dividi in sezioni:

    • plugin
    • impostazioni
    • Rebinds
  • Commenta ogni sezione / rebind

  • (esegui il backup del tuo .vimrco _vimrcsu Github)

Solo le mie preferenze personali. Forse non tanto aiuto però.


Personalmente non uso il pieghevole e non dovresti averne bisogno. Organizza il tuo vimrc e dovrebbe essere tutto a posto.
Gustav Blomqvist,

Il mio vimrc è già organizzato in sezione (opzioni generali, plugin, mappature, navigazione, colore, ecc ...). Il fatto di essere in grado di piegare una sezione (o sottosezione) è in realtà utile concentrarsi su ciò che si sta modificando / cercando.
statox

Va bene. Ci scusiamo per la cattiva risposta.
Gustav Blomqvist,

Questa non è una brutta risposta e sono anche colpevole di non aver dato abbastanza domande dettagliate, non c'è bisogno di essere dispiaciuto ;-)
statox

2

Ispirato dalla risposta di @ PeterRincker , ho realizzato quanto segue per utilizzare le intestazioni di stile ATX. Aggiungilo alla fine del tuo.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)\:'='

1

Se hai grandi funzioni come me, puoi usarle per piegare le tue funzioni:

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

E aggiungi questa modeline al tuo vimrc:

" vim:fde=MyFoldLevel(v\:lnum):fdm=expr:

0

Ampliare l'idea di @Peter Rincker e @ go2null. Se non si desidera impostare le opzioni di piegatura in Vim modeline. È possibile utilizzare il seguente autocmd per impostare il metodo di piegatura e l'espressione di piegatura.

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

Ho apportato piccole modifiche per rendere la risposta originale per farla funzionare come un normale comando vim (non è necessario sfuggire ai due punti, ma è necessario sfuggire alla doppia virgoletta).

Se non ti piace la foldexprstringa lunga , possiamo definire una funzione per questo:

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

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

endfunction

Quindi sostituire la riga autocmd che sta foldexprper

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.