Чи є найкраща практика скласти файл vimrc


21

Нещодавно я зрозумів, що у мене vimrcзараз більше 400 рядків (що IMO занадто багато, я намагаюся зменшити це), і щоб полегшити його навігацію, читання та редагування, я вирішив дослідити концепцію складання in vim (яка Я не був знайомий) .

  • Я спробував встановити метод складання, indentале результат мені не сподобався (це було занадто безладним здебільшого тому, що велика частина моєї vimrcне дуже розрізна).
  • Я також спробував встановити foldmethodна exprі , syntaxале я не був в змозі скласти що - або правильно.
  • Тут використання diffметоду складання не здається актуальним. (Або якщо це так, я не розумів, як ним користуватися)
  • Так що зараз я використовую markerметод , який в повному обсязі задовольняє мене через "{{{та "}}}маркерів , які я знайшов «галасливий» в файлі.

Тож я хотів би знати, чи є найкращі практики чи загальні рекомендації щодо правильного складанняvimrc .

Примітка 1: Оскільки ми всі знаємо, що SO не є форумом і не створений для збору особистої думки, і це не те, що я шукаю: звичайно, я думаю, деякі люди мають свої вподобання, але я хотів би знати, чому користуватися маркери (наприклад) покращують читабельність більше, ніж використання відступу.

Примітка 2: Також моя головна мета - зробити це vimrcякомога зрозумілішим, тому якщо існують інші найкращі практики для створення приємного, vimrcмені цікаво про це.

Редагувати 1: Я повинен був уточнити, що мій vimrcвже підрозділений на розділи (а іноді і підрозділ), основні з яких

  • загальні варіанти
  • плагіни (містять підрозділ для кожного плагіна та його конфігурацію)
  • відображення
  • навігація (також містить підрозділ)
  • колір
  • тощо ...

І саме ця структура змусила мене подумати про складання: я відчуваю, що вміти виводити лише той розділ, який мене цікавить у певний момент, - це щось досить зручне.

Редагувати 2: Відповідь, що згадує про підрозділи vimrcв декількох файлах, є дійсним, але в якості особистого уподобання я скоріше використовую складання, оскільки я думаю, що простіше підтримувати лише один файл у git repo, що містить мої dotfiles. Це лише особисті переваги, і я усвідомлюю, що можливо також використовувати такий підхід, але я вважаю за краще використовувати розкладний.


Я думаю, що використання цього "{{{способу є найбільш «vim like», соляризований плагін використовує це, і хоча це може бути галасливо, він дає вам
найстандартніший

Відповіді:


22

У мене в нижній частині таких моделей, vimrcякі я скопіював з godlygeek, автора табличної таблиці :

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

Це зробить будь-який рядок, починаючи зі "згину 2+ . Чим більше ", тим глибше складка. Це дозволяє розділити розділи, якщо вам потрібно.


Я не можу перевірити його зараз, але це здається ідеальним рішенням для мене! Дякую, що поділились!
statox

Деякі пояснюють: getline (v: lnum) повертає рядок рядка, заданий номером рядка (v: lnum); = ~ означає збіг регулярних виразів; '^ ""' означає, що всі рядки починаються з двох matchend (getline (v: lnum), '"" *') - 2 рахує додаткове число ", що означає, що" "" складеться з рівня 1, " "" "складеться з рівня 2 і так далі; getline (v: lnum) = ~ '^" "' повертає значення true або false, залежно від v: lnum рядок починається з двох" чи ні; якщо вірно, fde встановлено на >extra number of "(початковий рівень, який знаходиться за номером після <у цьому рядку) або '='(використовуйте рівень попереднього рядка), значення можна знайти уfold-expr
van abel

після останнього оновлення vim 8.1.1517) я отримую "" помилку, виявлену під час обробки моделей "з цією конфігурацією.
apollo

9

Добре .vimrcзаздалегідь визначити власні категорії у своєму списку (наприклад, у списку із підсписками та підпублістами) та додати всі свої плагіни / налаштування / функції у відповідні категорії. У поєднанні з індивідуальним складанням це може чудово працювати:

Приклад

Наведений вище приклад показує можливі категорії, які мені здаються корисними для структури .vimrc. Він використовує такі налаштовані налаштування складки:

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

Для визначення власних категорій та підкатегорій використовуйте такий синтаксис:

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

Категорію верхнього рівня можна створити дуже просто, якщо ви використовуєте vim-фрагменти (наприклад, для UltiSnips ): просто розгорніть boxабо bboxфрагмент, наданий vim-snippets (напишіть boxабо bboxнатисніть тригер розширення).

Щоб перемкнути відкриті та закриті складки ще швидше, натиснувши пробіл двічі:

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

Таким чином у вас є добре структурована структура, по .vimrcякій можна легко переміщуватися.


+1 для приємного анімаційного gif :) Просто цікаво, що ви використовували для відображення введених клавіш?
mMontu

@mMontu: Я використовував screenkey для відображення клавіш та gtk-recordmydesktop, щоб записати їх (обидва в репозиції Debian). При 5 кадрів в секунду кліп на 45 секунд менше, ніж на МіБ. Потім перетворив його в Інтернеті в gif (саме там і з’явилися спотворення, перш ніж якість зображення була ідеальною).
cbaumhardt

7

Я використовую свою основну vimrcяк посилання на кілька інших категоризованих файлів, що надходять у міру проходження, наприклад, параметри Vim в одному файлі, налаштування плагінів в іншому.

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

Як більш прямий відповідь на питання про ОП, я використовую метод маркера, але з правого боку з проміжком, і здебільшого більше категорій, ніж окремі, здебільшого. Я хоч кожен плагін окремо.


Я забув уточнити, що в своєму запитанні: я не любитель "розділяти" vimrcрізні файли, оскільки (IMO) це збільшує складність і ускладнює підтримку. Щодо складання, що ви маєте на увазі під "відімкнути на праву сторону з пробілом"?
statox

Я маю на увазі " {{{з такою кількістю пробілів, як і ваші, textwidthтому маркери знаходяться біля правого краю. У мене також є персоналізована функція FoldText у файлі folding.vim. Я віддаю перевагу окремим файлам, щоб мій git репонував лише один конкретний тип мода на коміт.
Cometsong

7

Можна сказати, що "найкраща практика" є винятково питанням думки, але є два підходи, які (1) мають очевидний сенс, і (2) можна застосувати до всіх конфігураційних файлів, не тільки до Vim: складання за логічними розділами і підрозділи (або навіть глибші, якщо ви відчуваєте хоробрість), і розділіть свій конфігурацію на кілька менших файлів і :sourceвставте їх.

Я особисто віддаю перевагу складенню, тому що це полегшує доступ до речей, і все ж дає мені певну ієрархію. Складні функції та autocmds на найпотужніших рівнях також є хорошою ідеєю, оскільки вони складають "природні" логічні одиниці. markerскладання має найбільше сенс у всьому цьому, оскільки логічні ієрархії не обов'язково відображаються на рівнях відступу чи підкресленні синтаксису. Я також збільшуюсь foldcolumn, що дає мені наочний натяк на те, де я перебуваю:

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

З іншого боку, ця foldtextфункція (модифікація аналогічної функції від Дрю Ніла, IIRC) має для мене більше сенсу, ніж за замовчуванням:

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

При іншому підході, розділенні файлів, основними проблемами є пошук речей та перехід з одного файлу в інший. Дуже приємний спосіб звернутися до обох - використовувати плагін, такий як CtrlSF , CtrlP або подібний. Але ви, мабуть, уже використовуєте один із таких.


Так ви йдете з marker. Насправді налаштування foldcolumn- це приємна річ, я побачу, яке значення найкраще відповідає моїм потребам. Також я поділяю вашу думку щодо розділених файлів, але я не знав, що CtrlSFя погляну на це, навіть якщо я дуже задоволений CtrlP.
statox

Також ви могли б пояснити, як користувальницький метод складання, будь ласка? Я намагався встановити fdmв foldtextі , MyFoldText()але здається, що це не правильний шлях , щоб використовувати його.
statox

@statox CtrlSFнайкраще працює з ag або ack , які по суті є спеціалізованими версіями grep. foldtextце не власний метод складання, а функція зміни способу вигляду складеного тексту. Останній рядок у моїй фрагмент коду показує , як вона використовується: set foldtext=MyFoldText().
lcd047

2

Основні найкращі практики:

  • Розділіть на розділи:

    • Плагіни
    • Налаштування
    • Відновлюється
  • Прокоментуйте кожен розділ / перезавантаження

  • ( створити резервну копію вашого .vimrcабо _vimrcв Github)

Просто мої особисті переваги. Можливо, не так вже й багато допомоги.


Я особисто не використовую складання, і вам не потрібно. Просто організуйте свій vimrc, і це повинно бути добре.
Густав Бломквіст

Мій vimrc вже організований у розділі (загальні параметри, плагіни, відображення, навігація, колір тощо). Факт, коли можна скласти розділ (або підрозділ), насправді добре зосередитись на тому, що ви редагуєте / шукаєте.
statox

Гаразд. Вибачте за погану відповідь.
Густав Бломквіст

Це не погана відповідь, і я також винен, що не дав достатньо
деталізованого

2

Натхненний @ PeterRincker в відповідь , я обробив наступне використовувати заголовки в стилі ATX. Додайте його до кінця.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

Якщо у вас є такі великі функції, як я, ви можете використовувати цю функцію для складання своїх функцій:

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

І додайте цей моделін у свій vimrc:

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

0

Розширення ідеї @Peter Rincker та @ go2null. Якщо ви не хочете встановлювати параметри складання у Vim modeline. Ви можете використовувати наступний autocmd, щоб встановити спосіб складання та вираз складання.

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

Я вніс невеликі зміни, щоб зробити оригінальну відповідь, щоб вона працювала як звичайна команда vim (не потрібно бігати з двокрапки, але потрібно уникати подвійної лапки).

Якщо вам не подобається довга foldexprструна, ми можемо визначити функцію для цього:

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

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

endfunction

Потім замініть рядок autocmd близько foldexprдо

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.