Có cách nào tốt nhất để gấp tập tin vimrc không


21

Gần đây tôi nhận ra rằng tôi vimrchiện dài hơn 400 dòng (mà IMO quá nhiều, tôi sẽ cố gắng giảm bớt điều đó) và để dễ điều hướng, đọc và chỉnh sửa nó, tôi quyết định tìm hiểu khái niệm về gấp trong vim (mà Tôi không quen thuộc) .

  • Tôi đã cố gắng thiết lập phương pháp gấp indentnhưng tôi không thích kết quả (Nó quá lộn xộn vì phần lớn tôi vimrckhông thực sự thụt vào).
  • Tôi cũng đã cố gắng để thiết lập foldmethodđể exprsyntaxnhưng tôi đã không thể gấp bất cứ điều gì đúng.
  • Ở đây sử dụng diffnhư phương pháp gấp dường như không liên quan. (Hoặc nếu tôi không hiểu cách sử dụng nó)
  • Vì vậy, hiện tại tôi đang sử dụng markerphương pháp không hoàn toàn làm tôi hài lòng vì các dấu hiệu "{{{"}}}dấu mà tôi thấy "nhiễu" trong tệp.

Vì vậy, tôi muốn biết nếu có các thực tiễn tốt nhất hoặc hướng dẫn chung về cách gấp đúng cáchvimrc .

Lưu ý 1: Như chúng ta đều biết SO không phải là một diễn đàn và không được thực hiện để thu thập ý kiến ​​cá nhân và đó không phải là điều tôi đang tìm kiếm: tất nhiên tôi đoán một số người có sở thích của họ nhưng tôi muốn biết tại sao sử dụng đánh dấu (ví dụ) cải thiện khả năng đọc nhiều hơn là sử dụng thụt lề.

Lưu ý 2: Ngoài ra, mục tiêu chính của tôi là làm cho tôi vimrcrõ ràng nhất có thể để nếu các thực tiễn tốt nhất khác tồn tại để tạo ra một điều tốt đẹp vimrctôi tò mò về nó.

Chỉnh sửa 1: Tôi nên có tiền đề rằng phần của tôi vimrcđã được chia nhỏ trong các phần (và đôi khi là phần phụ)

  • lựa chọn chung
  • plugin (chứa phần phụ cho mỗi plugin và cấu hình của nó)
  • ánh xạ
  • điều hướng (cũng chứa tiểu mục)
  • màu
  • v.v ...

Và đó là cấu trúc này khiến tôi nghĩ đến việc gấp lại: Tôi cảm thấy rằng việc chỉ có thể xuất ra phần tôi quan tâm ở một điểm nào đó là một điều gì đó khá thuận tiện.

Chỉnh sửa 2: Trả lời đề cập đến các phân mục vimrctrong một số tệp là hợp lệ, nhưng theo sở thích cá nhân, tôi muốn sử dụng tính năng gấp vì tôi nghĩ việc duy trì một tệp trong repit chứa tệp dotfiles của tôi sẽ dễ dàng hơn. Đó chỉ là một sở thích cá nhân và tôi biết rằng cũng có thể sử dụng phương pháp này nhưng tôi thích sử dụng phương pháp gấp.


Tôi nghĩ rằng việc sử dụng "{{{cách thức hoạt động giống như "vim like" nhất, plugin được sử dụng năng lượng mặt trời sử dụng điều này và mặc dù nó có thể gây ồn ào nhưng nó mang đến cho bạn cách cài đặt thủ công chuẩn nhất
icc97

Câu trả lời:


22

Tôi có các mô hình sau ở dưới cùng vimrcmà tôi đã sao chép từ godlygeek, tác giả của bảng :

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

Điều này sẽ làm cho bất kỳ dòng nào bắt đầu với 2+ "'sa gấp. Càng nhiều "nếp gấp càng sâu. Điều này cho phép bạn phân chia các phần nếu bạn cần.


Tôi không thể kiểm tra nó ngay bây giờ nhưng đó dường như là một giải pháp lý tưởng cho tôi! Cám ơn vì đã chia sẻ!
statox

Một số giải thích: getline (v: lnum) trả về chuỗi của dòng được cho bởi số dòng (v: lnum); = ~ có nghĩa là kết hợp biểu thức chính quy; '^ ""' có nghĩa là tất cả các dòng bắt đầu bằng hai "s; matchend (getline (v: lnum), '" "*') - 2 đếm số lượng thêm của", có nghĩa là "" "sẽ gấp với cấp 1," "" "sẽ gập với cấp 2, v.v., getline (v: lnum) = ~ '^" "' trả về đúng hay sai tùy thuộc vào dòng v: lnum bắt đầu bằng hai" hay không; nếu đúng, fde được đặt thành >extra number of "(mức bắt đầu được đặt theo số sau <tại dòng này) hoặc '='(sử dụng cấp của dòng trước), ý nghĩa có thể được tìm thấy tạifold-expr
van abel

sau bản cập nhật vim gần đây 8.1.1517), tôi nhận được "" Lỗi được phát hiện trong khi xử lý các mô hình "với cấu hình này.
apoche

9

Trước tiên, bạn nên xác định danh mục của riêng mình trong .vimrcdanh sách (như danh sách có danh sách phụ và danh sách phụ) và thêm tất cả các bổ trợ / cài đặt / chức năng của bạn vào danh mục tương ứng. Kết hợp với tùy chỉnh gấp này có thể làm việc tuyệt vời:

Thí dụ

Ví dụ trên cho thấy các danh mục có thể mà tôi thấy hữu ích để cấu trúc của tôi .vimrc. Nó sử dụng các cài đặt gấp tùy chỉnh sau:

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

Để xác định danh mục và danh mục con của riêng bạn, hãy sử dụng cú pháp sau:

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

Danh mục cấp cao nhất có thể được tạo thực sự dễ dàng nếu bạn sử dụng vim-snippets (ví dụ với UltiSnips ): Chỉ cần mở rộng boxhoặc bboxđoạn trích được cung cấp bởi vim-snippets (viết boxhoặcbbox nhấn nút kích hoạt mở rộng).

Để chuyển các nếp gấp mở và đóng thậm chí nhanh hơn bằng cách nhấn phím cách hai lần:

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

Bằng cách đó bạn có một cấu trúc tốt .vimrccó thể được điều hướng dễ dàng.


+1 cho gif hoạt hình đẹp :) Chỉ tò mò, bạn đã sử dụng gì để hiển thị các phím đã gõ?
mMontu

@mMontu: Tôi đã sử dụng keykey để hiển thị các phím và gtk-recordmydesktop để ghi lại nó (cả trong repos Debian). Với 5 khung hình / giây, clip 45 giây ít hơn MiB. Sau đó chuyển đổi nó trực tuyến thành một gif (đó là nơi các biến dạng xuất hiện, trước khi chất lượng hình ảnh hoàn hảo).
cbaumhardt

7

Tôi sử dụng chính của mình vimrclàm liên kết đến một số tệp được phân loại khác, tìm nguồn cung ứng cho từng tệp khi nó đi cùng, ví dụ: tùy chọn Vim trong một tệp, cài đặt plugin trong một tệp khác.

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

Là một câu trả lời trực tiếp hơn cho câu hỏi OP, tôi sử dụng phương pháp đánh dấu, nhưng ở phía bên phải với khoảng cách và xung quanh nhiều danh mục hơn cá nhân, trong phần lớn. Tôi làm từng plugin riêng biệt mặc dù.


Tôi đã quên chính xác rằng trong câu hỏi của mình: Tôi không phải là người thích "tách" các vimrctệp khác nhau vì (IMO) nó làm tăng sự phức tạp và khiến việc bảo trì khó khăn hơn. Về việc gấp bạn có ý gì khi "tắt sang bên phải với khoảng cách"?
statox

Ý tôi là " {{{có nhiều khoảng trống trong đó textwidthvì vậy các điểm đánh dấu nằm gần các cạnh phải. Tôi cũng có một chức năng FoldText được cá nhân hóa trong tệp gập.vim. Tôi thích các tệp riêng biệt để git repo của tôi chỉ có một loại mod cụ thể cho mỗi lần xác nhận.
Cometsong

7

Bạn có thể nói rằng "thực tiễn tốt nhất" là vấn đề quan trọng, :) nhưng có hai cách tiếp cận (1) có ý nghĩa rõ ràng và (2) có thể được áp dụng cho tất cả các tệp cấu hình, không chỉ Vim: gấp bởi các phần logic và các phần phụ (hoặc thậm chí sâu hơn, nếu bạn cảm thấy dũng cảm), và chia cấu hình của bạn thành nhiều tệp nhỏ hơn và :source-ing chúng.

Cá nhân tôi thích gấp vì nó làm cho mọi thứ dễ dàng truy cập hơn, trong khi vẫn cung cấp cho tôi một số thứ bậc để nhận. Các hàm gấp và autocmds ở các mức trong cùng cũng là một ý tưởng tốt, vì chúng tạo ra các đơn vị logic "tự nhiên". markergấp có ý nghĩa nhất đối với tất cả điều này, bởi vì hệ thống phân cấp logic không nhất thiết được phản ánh thành các mức thụt lề hoặc làm nổi bật cú pháp. Tôi cũng tăng foldcolumn, điều này cho tôi một gợi ý trực quan về nơi tôi đang ở:

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

Mặt khác, foldtextchức năng này (một sửa đổi của một chức năng tương tự của Drew Neil, IIRC) có ý nghĩa với tôi hơn là mặc định:

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

Với cách tiếp cận khác, chia nhỏ tệp, vấn đề chính là tìm kiếm mọi thứ và chuyển từ tệp này sang tệp khác. Một cách rất hay để giải quyết cả hai là sử dụng một plugin như CtrlSF , CtrlP hoặc tương tự. Nhưng dù sao bạn cũng có thể đã sử dụng một trong số đó.


Vì vậy, bạn đi với marker. Thật vậy, tùy chỉnh foldcolumnlà một điều tốt đẹp để làm, tôi sẽ xem giá trị nào phù hợp nhất với nhu cầu của tôi. Ngoài ra tôi cũng chia sẻ quan điểm của bạn về các tệp được chia nhưng tôi không biết CtrlSFtôi sẽ xem nó ngay cả khi tôi khá hài lòng CtrlP.
statox

Ngoài ra bạn có thể giải thích làm thế nào để sử dụng phương pháp gấp tùy chỉnh xin vui lòng? Tôi cố gắng để thiết lập fdmđể foldtextMyFoldText()nhưng nó có vẻ như nó không phải là cách đúng đắn để sử dụng nó.
statox

@statox CtrlSFhoạt động tốt nhất với ag hoặc ack , về cơ bản là các phiên bản chuyên biệt của grep. foldtextkhông phải là một phương pháp gấp tùy chỉnh, mà là một chức năng để thay đổi cách nhìn văn bản gấp. Dòng cuối cùng trong đoạn trích của tôi cho thấy cách nó được sử dụng : set foldtext=MyFoldText().
lcd047

2

Thực hành cơ bản tốt nhất:

  • Chia thành các phần:

    • bổ sung
    • Cài đặt
    • Rebinds
  • Nhận xét từng phần / rebind

  • (sao lưu .vimrchoặc _vimrctrên Github)

Chỉ là sở thích cá nhân của tôi. Có lẽ không có nhiều giúp đỡ mặc dù.


Cá nhân tôi không sử dụng gấp, và bạn không cần. Chỉ cần tổ chức vimrc của bạn và tất cả sẽ tốt.
Gustav Blomqvist

Vimrc của tôi đã được tổ chức trong phần (tùy chọn chung, plugin, ánh xạ, điều hướng, màu sắc, v.v.). Thực tế để có thể gấp một phần (hoặc tiểu mục) thực sự tốt để tập trung vào những gì bạn đang chỉnh sửa / tìm kiếm.
statox

Đuợc. Xin lỗi vì câu trả lời không hay.
Gustav Blomqvist

Đó không phải là một câu trả lời tồi và tôi cũng có tội vì đã không trả lời đủ câu hỏi, không cần phải xin lỗi ;-)
statox

2

Lấy cảm hứng từ câu trả lời của @ PeterRincker's , tôi đã tạo ra những điều sau đây để sử dụng các tiêu đề kiểu ATX. Thêm nó vào cuối của bạn.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

Nếu bạn có các chức năng lớn như tôi, bạn có thể sử dụng chức năng này để gấp các chức năng của mình:

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

Và thêm modeline này vào vimrc của bạn:

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

0

Mở rộng ý tưởng của @Peter Rincker và @ go2null. Nếu bạn không muốn đặt các tùy chọn gấp trong mô hình Vim. Bạn có thể sử dụng autocmd sau để đặt phương thức gấp và biểu thức gấp.

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

Tôi đã thực hiện các sửa đổi nhỏ để đưa ra câu trả lời ban đầu để làm cho nó hoạt động như một lệnh vim thông thường (không cần thoát dấu hai chấm, nhưng cần trích dẫn gấp đôi).

Nếu bạn không thích foldexprchuỗi dài , chúng ta có thể định nghĩa một hàm cho điều đó:

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

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

endfunction

Sau đó, thay thế dòng autocmd về foldexprđể

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.