Есть ли лучшая практика, чтобы сложить файл vimrc

21

Недавно я понял, что моя vimrcдлина теперь больше 400 строк (что для ИМО слишком много, я постараюсь уменьшить ее), и чтобы упростить навигацию, чтение и редактирование, я решил исследовать концепцию свертывания в vim (которая Я не был знаком с) .

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

Поэтому я хотел бы знать, есть ли лучшие практики или общие рекомендации по правильному сворачиванию avimrc .

Примечание 1: Как мы все знаем, SO не форум и не предназначен для сбора личных мнений, и это не то, что я ищу: конечно, я думаю, что у некоторых людей есть свои предпочтения, но я хотел бы знать, почему маркеры (например) улучшают читаемость больше, чем с помощью отступа.

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

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

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

И именно эта структура заставила меня задуматься о сворачивании: я чувствую, что возможность выводить только интересующий меня раздел в определенный момент является чем-то довольно удобным.

Редактировать 2: Ответ с упоминанием подразделов vimrcв нескольких файлах действителен, но в качестве личного предпочтения я бы предпочел использовать свертывание, потому что я думаю, что проще поддерживать только один файл в репозитории git, содержащий мои точечные файлы. Это только личное предпочтение, и я знаю, что возможно также использовать этот подход, но я бы предпочел использовать свертывание.

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

Ответы:

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); = ~ означает совпадение регулярного выражения; '^ ""' означает, что все строки начинаются с двух "s; matchend (getline (v: lnum), '" "*') - 2 подсчитывает дополнительное число", то есть "" "сворачивается с уровнем 1" "" "сворачивается с уровнем 2 и т. д .; getline (v: lnum) = ~ '^" "' возвращает true или false в зависимости от того, начинается ли строка v: lnum с двух" или нет; если значение true, для fde установлено значение >extra number of "(начальный уровень, за которым следует число после <в этой строке) или '='(используйте уровень предыдущей строки), значение можно найти по адресуfold-expr
van abel
после недавнего обновления vim 8.1.1517) я получаю "" Обнаружена ошибка при обработке modelines "с этой конфигурацией
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-snippets (например, с 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которой легко ориентироваться.

cbaumhardt
источник
+1 за хороший анимированный GIF :) Просто любопытно, что вы использовали для отображения набранных клавиш?
mMontu
@mMontu: я использовал screenkey для отображения ключей и gtk-recordmydesktop для его записи (оба в репозиториях Debian). При 5 кадрах в секунду клипы продолжительностью 45 секунд меньше, чем MiB. Затем преобразуйте его в режиме онлайн в формат 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

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

Cometsong
источник
Я забыл уточнить это в своем вопросе: я не фанат «разделения» vimrcв разных файлах, потому что (IMO) это увеличивает сложность и усложняет обслуживание. Что касается складывания, что вы подразумеваете под "с правой стороны с разнесением"?
statox
Я имею в виду " {{{столько пробелов, сколько у вас, textwidthпоэтому маркеры находятся у правых краев. У меня также есть персонализированная функция FoldText в файле fold.vim. Я предпочитаю отдельные файлы, чтобы мой git-репо имел только один конкретный тип мода на коммит.
Cometsong
7

Вы могли бы сказать, что «наилучшая практика» - это, в первую очередь, вопрос мнения :), но есть два подхода, которые (1) имеют очевидный смысл, и (2) могут применяться ко всем файлам конфигурации, а не только к Vim: сворачивание по логическим разделам и подразделы (или даже более глубокие, если вы чувствуете себя смелыми), и разделение вашей конфигурации на несколько небольших файлов и :source-ing их.

Лично я предпочитаю сворачивание, потому что оно облегчает доступ к вещам, и в то же время дает некоторую иерархию, из которой можно выбирать. Сворачивание функций и 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 или аналогичный. Но вы, вероятно, уже используете один из них в любом случае.

lcd047
источник
Итак, вы идете с 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
Хорошо. Извините за плохой ответ.
Густав Бломквист
Это не плохой ответ, и я также виновен в том, что не дал достаточно подробный вопрос, не нужно извиняться ;-)
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)\:'='
go2null
источник
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:
MichalH
источник
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)
jdhao
источник