Czy istnieje najlepsza praktyka składania pliku vimrc

21

Niedawno zdałem sobie sprawę, że moje vimrcma teraz ponad 400 linii (które IMO to za dużo, postaram się to zmniejszyć) i aby ułatwić nawigację, czytanie i edycję, postanowiłem zbadać koncepcję składania w vimie (która Nie znałem) .

  • Próbowałem ustawić metodę składania na, indentale nie podobał mi się wynik (był to zbyt bałagan, głównie dlatego, że duża część mojego vimrcnie jest tak naprawdę wcięta).
  • Próbowałem również do zestawu foldmethoddo expra syntax, ale nie był w stanie prawidłowo złożyć cokolwiek.
  • Tutaj użycie diffmetody składania nie wydaje się istotne. (Lub jeśli tak, nie rozumiem, jak go używać)
  • Na razie używam markermetody, która nie do końca mnie satysfakcjonuje ze względu na znaczniki "{{{i "}}}, które znalazłem w pliku „zaszumione”.

Chciałbym więc wiedzieć, czy istnieją najlepsze praktyki lub wspólne wytyczne dotyczące prawidłowego składaniavimrc .

Uwaga 1: Jak wszyscy wiemy SO nie jest forum i nie jest przeznaczone do zbierania osobistych opinii i nie tego szukam: oczywiście myślę, że niektórzy ludzie mają swoje preferencje, ale chciałbym wiedzieć, dlaczego warto korzystać znaczniki (na przykład) poprawiają czytelność bardziej niż użycie wcięcia.

Uwaga 2: Moim głównym celem jest również vimrcwyjaśnienie tego, jak to możliwe, więc jeśli istnieją inne najlepsze praktyki tworzenia fajnych vimrc, jestem tego ciekawy.

Edycja 1: Powinienem był sprecyzować, że mój vimrcjest już podzielony na sekcje (a czasem podsekcje).

  • ogólne opcje
  • wtyczki (zawierające podsekcję dla każdej wtyczki i jej konfiguracji)
  • mapowania
  • nawigacja (zawierająca także podsekcję)
  • kolor
  • itp...

I to właśnie ta struktura sprawiła, że ​​pomyślałem o zwijaniu: czuję, że możliwość wygenerowania tylko części, która mnie interesuje w pewnym momencie, jest dość wygodna.

Edycja 2: Odpowiedź podająca podział na vimrckilka plików jest poprawna, ale jako osobistą preferencję wolę używać składania, ponieważ myślę, że łatwiej jest utrzymać tylko jeden plik w repozytorium git zawierającym moje pliki dot. To tylko osobiste preferencje i wiem, że można również zastosować to podejście, ale wolałbym używać foldowania.

statox
źródło
Myślę, że korzystanie z tego "{{{jest najbardziej „vimopodobnym” sposobem robienia rzeczy, solaryzowana wtyczka korzysta z tego i chociaż może być głośna, daje najbardziej standardowy sposób ręcznego składania
icc97

Odpowiedzi:

22

Na dole vimrcmam następujące modelki, które skopiowałem od godlygeek, autora tabel :

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

Spowoduje to, że każda linia, zaczynająca się od 2+ ", jest fold. Im więcej ", tym głębsza jest zakładka. To pozwala ci podzielić sekcje, jeśli potrzebujesz.

Peter Rincker
źródło
Nie mogę tego teraz przetestować, ale wydaje mi się to idealnym rozwiązaniem! Dzięki za udostępnienie!
statox
Niektóre wyjaśniają: getline (v: lnum) zwraca ciąg linii podany przez numer linii (v: lnum); = ~ oznacza dopasowanie wyrażenia regularnego; „^” „” oznacza, że ​​wszystkie linie zaczynają się od dwóch „s; matchend (getline (v: lnum),” „„ * *)) - 2 zlicza dodatkową liczbę „, co oznacza, że„ ”„ spasuje z poziomem 1 ”,„ „” „spasuje z poziomem 2 i tak dalej; getline (v: lnum) = ~ '^” „” zwraca true lub false w zależności od linii v: lnum zaczynającej się od dwóch ”lub nie; jeśli true, fde jest ustawione na >extra number of "(poziom początkowy, który jest nasycony liczbą po <w tej linii) lub '='(użyj poziomu poprzedniej linii), znaczenie można znaleźć wfold-expr
van abel
po ostatniej aktualizacji vima 8.1.1517), pojawia się komunikat „Wykryto błąd podczas przetwarzania modelin” w tej konfiguracji
apollo
9

Dobrym pomysłem jest najpierw zdefiniowanie własnych kategorii .vimrc(np. Listy z podlistami i podlistami) i dodanie wszystkich wtyczek / ustawień / funkcji do odpowiednich kategorii. W połączeniu z niestandardowym składaniem może to działać świetnie:

Przykład

Powyższy przykład pokazuje możliwe kategorie, które uważam za pomocne w uporządkowaniu moich .vimrc. Wykorzystuje następujące spersonalizowane ustawienia składania:

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

Aby zdefiniować własne kategorie i podkategorie, użyj następującej składni:

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

Kategorię najwyższego poziomu można utworzyć naprawdę łatwo, jeśli używasz vim-snippets (np. Z UltiSnips ): Po prostu rozwiń boxlub bboxsnippet dostarczony przez vim-snippets (napisz boxlub bboxnaciśnij spust rozwijania).

Aby przełączyć fałdy w tryb otwierania i zamykania jeszcze szybciej, naciskając dwukrotnie spację:

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

W ten sposób masz dobrze zorganizowaną, .vimrcłatwą w obsłudze nawigację.

cbaumhardt
źródło
+1 za fajny animowany gif :) Ciekawe, co wyświetlałeś wpisywane klawisze?
mMontu
@mMontu: Użyłem screenkey do wyświetlenia kluczy i gtk-recordmydesktop do jego nagrania (oba w repozytoriach Debiana). Przy 5 klatkach na sekundę 45 sekundowe klipy to mniej niż MiB. Następnie przekonwertowałem go online na gif (w tym miejscu pojawiły się zniekształcenia, zanim jakość obrazu była idealna).
cbaumhardt
7

Używam mojego podstawowego vimrcjako linku do kilku innych skategoryzowanych plików, pozyskując każdy w miarę upływu czasu, np. Opcje Vima w jednym pliku, ustawienia wtyczki w innym.

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

Jako bardziej bezpośrednią odpowiedź na pytanie OP, używam metody markera, ale w większości z prawej strony z odstępami i wokół większej liczby kategorii niż pojedynczych. Jednak każdą wtyczkę robię osobno.

Pieśń Komiczna
źródło
Zapomniałem sprecyzować to w moim pytaniu: nie jestem fanem „rozdzielania” vimrcróżnych plików, ponieważ (IMO) zwiększa to złożoność i utrudnia utrzymanie. O składaniu, co rozumiesz przez „przesunięcie w prawą stronę z odstępami”?
statox
Mam na myśli " {{{tyle miejsc, ile masz, textwidthwięc znaczniki znajdują się w pobliżu prawej krawędzi. Mam również spersonalizowaną funkcję FoldText w pliku folding.vim. Wolę osobne pliki, aby moje repozytorium git zawierało tylko jeden określony typ modu na zatwierdzenie.
Cometsong
7

Można powiedzieć, że „najlepsza praktyka” jest przede wszystkim kwestią opinii :), ale istnieją dwa podejścia, które (1) mają oczywisty sens i (2) można zastosować do wszystkich plików konfiguracyjnych, nie tylko Vima: składanie według sekcji logicznych i podrozdziały (lub nawet głębsze, jeśli czujesz się odważny), i dzielenie konfiguracji na kilka mniejszych plików i :sourceich używanie.

Osobiście wolę składanie, ponieważ ułatwia dostęp do rzeczy, a jednocześnie daje mi trochę hierarchii do wyboru. autocmdDobrym pomysłem jest również składanie funkcji is na najbardziej wewnętrznych poziomach, ponieważ tworzą one „naturalne” jednostki logiczne. markerSkładanie ma sens w tym wszystkim, ponieważ logiczne hierarchie niekoniecznie odzwierciedlają się w poziomach wcięć lub w podświetlaniu składni. Zwiększam również foldcolumn, co daje mi wizualną wskazówkę, gdzie jestem:

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

Na marginesie, ta foldtextfunkcja (modyfikacja podobnej funkcji przez Drew Neila, IIRC) ma dla mnie większy sens niż domyślna:

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

Przy drugim podejściu do dzielenia plików głównymi problemami są znajdowanie rzeczy i przełączanie się z jednego pliku do drugiego. Bardzo dobrym sposobem rozwiązania obu jest użycie wtyczki takiej jak CtrlSF , CtrlP lub podobnej. Ale prawdopodobnie i tak już używasz jednego z nich.

lcd047
źródło
Więc idź z marker. Rzeczywiście, dostosowanie foldcolumnjest fajną rzeczą, zobaczę, która wartość najlepiej pasuje do moich potrzeb. Podzielam również twój pogląd na podzielone pliki, ale nie wiedziałem CtrlSF, że przyjrzę się temu, nawet jeśli jestem bardzo zadowolony CtrlP.
statox
Czy mógłbyś również wyjaśnić, jak korzystać z niestandardowej metody składania? Próbowałem ustawić fdmsię foldtexti MyFoldText()ale wydaje się, że to nie jest właściwa droga, aby go używać.
statox
@statox CtrlSFdziała najlepiej z ag lub ack , które są zasadniczo wyspecjalizowanymi wersjami grep. foldtextnie jest niestandardową metodą składania, ale funkcją zmieniającą wygląd złożonego tekstu. Ostatni wiersz w moich pokazów urywek, jak to działa: set foldtext=MyFoldText().
lcd047
2

Podstawowe najlepsze praktyki:

  • Podziel na sekcje:

    • Wtyczki
    • Ustawienia
    • Powiąż się
  • Skomentuj każdą sekcję / powiąż ponownie

  • ( wykonaj kopię zapasową swojego .vimrclub _vimrcna Github)

Po prostu moje osobiste preferencje. Może nie tak wiele pomocy.

Gustav Blomqvist
źródło
Ja osobiście nie używam składania, a ty nie powinieneś. Po prostu zorganizuj vimrc i wszystko powinno być dobre.
Gustav Blomqvist,
Mój vimrc jest już zorganizowany w sekcji (opcje ogólne, wtyczki, mapowania, nawigacja, kolor itp.). Fakt, że można złożyć sekcję (lub podsekcję) jest naprawdę dobry, aby skupić się na tym, co edytujesz / szukasz.
statox
W porządku. Przepraszam za złą odpowiedź.
Gustav Blomqvist
To nie jest zła odpowiedź i jestem też winny za to, że nie zadałem wystarczająco szczegółowego pytania, nie trzeba żałować ;-)
statox
2

Zainspirowany @ PeterRincker za odpowiedź , mam przygotowane następujące użyć nagłówków w stylu ATX. Dodaj go na końcu swojego.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
źródło
1

Jeśli masz duże funkcje, takie jak ja, możesz użyć tego do złożenia swoich funkcji:

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

I dodaj tę modelkę do swojego vimrc:

" vim:fde=MyFoldLevel(v\:lnum):fdm=expr:
MichalH
źródło
0

Rozszerzenie idei @Peter Rincker i @ go2null. Jeśli nie chcesz ustawiać opcji składania w modeline Vima. Możesz użyć następującego autocmd, aby ustawić metodę składania i wyrażenie składania.

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

Wprowadziłem małe modyfikacje, aby oryginalna odpowiedź działała jak zwykłe polecenie vima (nie trzeba uciekać dwukropka, ale należy unikać podwójnego cudzysłowu).

Jeśli nie podoba ci się długi foldexprciąg, możemy zdefiniować funkcję:

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

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

endfunction

Następnie wymień autocmd o linię foldexprdo

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
jdhao
źródło