Apakah ada praktik terbaik untuk melipat file vimrc

21

Baru-baru ini saya menyadari bahwa panjang saya vimrcsekarang lebih dari 400 baris (yang IMO terlalu banyak akan saya coba kurangi) dan untuk membuatnya lebih mudah dinavigasi, membaca dan mengeditnya saya memutuskan untuk menyelidiki konsep lipat dalam vim (yang Saya tidak terbiasa dengan) .

  • Saya mencoba untuk mengatur metode lipat indenttetapi saya tidak suka hasilnya (Itu terlalu berantakan karena sebagian besar dari saya vimrctidak benar-benar menjorok).
  • Saya juga mencoba untuk set foldmethodke exprdan syntaxtapi aku tidak bisa melipat sesuatu dengan benar.
  • Di sini menggunakan diffmetode melipat sepertinya tidak relevan. (Atau jika itu saya tidak mengerti bagaimana menggunakannya)
  • Jadi untuk saat ini saya menggunakan markermetode yang tidak sepenuhnya memuaskan saya karena tanda "{{{dan "}}}yang saya temukan "berisik" dalam file.

Jadi saya ingin tahu apakah ada praktik terbaik atau pedoman umum tentang melipat dengan benar avimrc .

Catatan 1: Seperti kita semua tahu, SO bukan forum dan tidak dibuat untuk mengumpulkan pendapat pribadi dan bukan itu yang saya cari: tentu saja saya kira beberapa orang memiliki preferensi mereka, tetapi saya ingin tahu mengapa menggunakan spidol (misalnya) meningkatkan keterbacaan lebih dari menggunakan indentasi.

Catatan 2: Juga tujuan utama saya adalah untuk membuat vimrcsejelas mungkin saya jadi jika praktik terbaik lain ada untuk membuat yang bagus vimrcsaya ingin tahu tentang hal itu.

Sunting 1: Saya seharusnya tahu bahwa saya vimrcsudah dibagi dalam beberapa bagian (dan kadang-kadang subbagian) yang utama

  • pilihan umum
  • plugins (berisi subbagian untuk setiap plugin dan konfigurasinya)
  • pemetaan
  • navigasi (juga berisi ayat)
  • warna
  • dll ...

Dan struktur inilah yang membuat saya berpikir untuk melipat: Saya merasa hanya bisa menampilkan bagian yang saya minati pada titik tertentu adalah sesuatu yang cukup nyaman.

Sunting 2: Menjawab menyebutkan subdivisi vimrcdalam beberapa file adalah valid, tetapi sebagai preferensi pribadi saya lebih suka menggunakan pelipatan karena saya pikir lebih mudah untuk mempertahankan hanya satu file dalam git repo yang berisi dotfile saya. Itu hanya preferensi pribadi dan saya sadar bahwa mungkin juga menggunakan pendekatan ini, tetapi saya lebih suka menggunakan lipat.

statox
sumber
Saya pikir menggunakan cara "{{{yang paling 'vim like' dalam melakukan sesuatu, plugin solarized menggunakan ini dan meskipun mungkin berisik itu memberi Anda cara paling standar untuk mengatur lipatan manual
icc97

Jawaban:

22

Saya memiliki modelines berikut di bagian bawah vimrcyang saya salin dari godlygeek, penulis tabel :

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

Ini akan membuat garis apa pun dimulai dengan "lipatan 2+ . Semakin banyak "lipatan semakin dalam. Ini memungkinkan Anda untuk membagi bagian jika perlu.

Peter Rincker
sumber
Saya tidak bisa mengujinya sekarang tetapi itu tampaknya menjadi solusi ideal bagi saya! Terima kasih telah berbagi!
statox
Beberapa menjelaskan: getline (v: lnum) mengembalikan string garis yang diberikan oleh nomor baris (v: lnum); = ~ berarti kecocokan ekspresi reguler; '^ ""' berarti semua baris dimulai dengan dua "; matchend (getline (v: lnum), '" "*') - 2 menghitung jumlah tambahan", yang berarti "" "akan dilipat dengan level 1," "" "akan dilipat dengan level 2 dan seterusnya; getline (v: lnum) = ~ '^" "' mengembalikan benar atau salah tergantung pada v: lnum baris mulai dengan dua" atau tidak; jika benar, fde diatur ke >extra number of "(level awal yang diduduki oleh angka setelah <pada baris ini) atau '='(gunakan level baris sebelumnya), artinya dapat ditemukan difold-expr
van abel
setelah pembaruan vim baru-baru ini 8.1.1517), saya mendapatkan "" Kesalahan terdeteksi saat memproses modelines "dengan konfigurasi ini.
apollo
9

Sebaiknya tentukan kategori Anda sendiri di .vimrc(seperti daftar dengan sublists dan subsublists) dan tambahkan semua plugin / pengaturan / fungsi Anda ke kategori masing-masing. Dikombinasikan dengan lipat khusus, ini bisa bekerja dengan baik:

Contoh

Contoh di atas menunjukkan kemungkinan kategori yang menurut saya bermanfaat untuk menyusun .vimrc. Ini menggunakan pengaturan lipatan yang disesuaikan berikut ini:

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

Untuk menentukan kategori dan subkategori Anda sendiri, gunakan sintaks berikut:

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

Kategori tingkat atas dapat dibuat dengan sangat mudah jika Anda menggunakan vim-snippet (mis. Dengan UltiSnips ): Cukup rentangkan boxatau bboxsnippet yang disediakan oleh vim-snippet (tulis boxatau bboxtekan peluas pemicu).

Untuk beralih lipatan terbuka dan tertutup lebih cepat dengan menekan spasi dua kali:

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

Dengan begitu Anda memiliki struktur .vimrcyang baik yang dapat dinavigasi dengan mudah.

cbaumhardt
sumber
+1 untuk gif animasi yang bagus :) Hanya ingin tahu, apa yang Anda gunakan untuk menampilkan kunci yang diketik?
mMontu
@ mMontu: Saya menggunakan layar kunci untuk menampilkan kunci dan gtk-recordmydesktop untuk merekamnya (keduanya di repo Debian). Dengan 5fps, 45 detik klip kurang dari satu MiB. Kemudian dikonversi secara online ke gif (di situlah distorsi masuk, sebelum kualitas gambar sempurna).
cbaumhardt
7

Saya menggunakan primer saya vimrc sebagai tautan ke beberapa file yang dikategorikan lainnya, sumber masing-masing saat berjalan, misalnya opsi Vim dalam satu file, pengaturan plugin di yang lain.

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

Sebagai jawaban yang lebih langsung untuk pertanyaan OP, saya menggunakan metode marker, tetapi ke sisi kanan dengan spasi, dan sekitar lebih banyak kategori daripada individu, untuk sebagian besar. Saya melakukan masing-masing plugin secara terpisah.

Cometsong
sumber
Saya lupa tepat bahwa dalam pertanyaan saya: Saya bukan penggemar "memisahkan" vimrcdalam file yang berbeda karena (IMO) itu meningkatkan kompleksitas dan membuatnya lebih sulit untuk dipertahankan. Tentang lipatan, apa yang Anda maksud dengan "pergi ke sisi kanan dengan jarak"?
statox
Maksud saya " {{{dengan banyak ruang di sana textwidthsehingga Anda penanda di dekat tepi kanan. Saya juga memiliki fungsi FoldText yang dipersonalisasi dalam file folding.vim. Saya lebih suka file terpisah sehingga git saya repo hanya satu jenis mod khusus per komit.
Cometsong
7

Anda dapat mengatakan bahwa "praktik terbaik" adalah masalah pendapat, :) tetapi ada dua pendekatan yang (1) masuk akal, dan (2) dapat diterapkan ke semua file konfigurasi, tidak hanya Vim: melipat oleh bagian logis dan subbagian (atau bahkan lebih dalam, jika Anda merasa berani), dan membelah konfigurasi Anda menjadi beberapa file yang lebih kecil dan menyimpannya :source.

Saya pribadi lebih suka melipat karena membuat hal-hal lebih mudah diakses, sambil tetap memberi saya beberapa hierarki untuk diambil. Fungsi lipat dan autocmds pada level terdalam juga merupakan ide yang baik, karena ini membuat unit logis "alami". markermelipat paling masuk akal untuk semua ini, karena hierarki logis tidak harus tercermin ke dalam level indent, atau ke dalam penyorotan sintaksis. Saya juga meningkat foldcolumn, yang memberi saya petunjuk visual tentang keberadaan saya:

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

Di samping catatan, foldtextfungsi ini (modifikasi dari fungsi yang sama oleh Drew Neil, IIRC) lebih masuk akal bagi saya daripada default:

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

Dengan pendekatan lain, membagi file, masalah utama adalah menemukan sesuatu, dan beralih dari satu file ke yang lain. Cara yang sangat baik untuk mengatasi keduanya adalah dengan menggunakan plugin seperti CtrlSF , CtrlP , atau yang serupa. Tapi Anda mungkin sudah menggunakan salah satu dari itu.

lcd047
sumber
Jadi kamu ikut marker. Memang menyesuaikan foldcolumnadalah hal yang baik untuk dilakukan, saya akan melihat nilai mana yang paling sesuai dengan kebutuhan saya. Saya juga membagikan pandangan Anda tentang file-file yang dibagi tetapi saya tidak tahu CtrlSFsaya akan melihatnya meskipun saya cukup senang CtrlP.
statox
Bisakah Anda menjelaskan cara menggunakan metode pelipatan khusus? Aku mencoba untuk mengatur fdmuntuk foldtextdan MyFoldText()tapi sepertinya itu bukan cara yang tepat untuk menggunakannya.
statox
@statox CtrlSFberfungsi paling baik dengan ag atau ack , yang pada dasarnya adalah versi khusus grep. foldtextbukan metode pelipatan khusus, tetapi fungsi untuk mengubah cara tampilan teks yang dilipat. Baris terakhir dalam acara potongan saya bagaimana itu digunakan: set foldtext=MyFoldText().
lcd047
2

Praktik terbaik dasar:

  • Membagi menjadi beberapa bagian:

    • Plugin
    • Pengaturan
    • Rebinds
  • Komentar setiap bagian / rebind

  • (Cadangkan Anda .vimrcatau _vimrcdi Github)

Hanya preferensi pribadi saya. Mungkin tidak banyak membantu.

Gustav Blomqvist
sumber
Saya pribadi tidak menggunakan lipat, dan Anda tidak perlu melakukannya. Hanya mengatur vimrc Anda dan itu semua harus baik.
Gustav Blomqvist
Vmrc saya sudah diatur dalam bagian (opsi umum, plugin, pemetaan, navigasi, warna, dll ...). Fakta untuk dapat melipat bagian (atau subbagian) sebenarnya bagus untuk fokus pada apa yang sedang Anda edit / cari.
statox
Baik. Maaf atas jawaban yang buruk.
Gustav Blomqvist
Itu bukan jawaban yang buruk dan saya juga bersalah karena tidak memberikan pertanyaan yang cukup, tidak perlu minta maaf ;-)
statox
2

Terinspirasi oleh jawaban @ PeterRincker , saya membuat yang berikut untuk menggunakan header gaya ATX. Tambahkan ke akhir.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
sumber
1

Jika Anda memiliki fungsi besar seperti saya, Anda dapat menggunakan ini untuk melipat fungsi Anda:

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

Dan tambahkan modeline ini ke vimrc Anda:

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

Memperluas gagasan @Peter Rincker dan @ go2null. Jika Anda tidak ingin mengatur opsi lipat di Vim modeline. Anda dapat menggunakan autocmd berikut untuk mengatur metode lipat dan ekspresi lipat.

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

Saya membuat modifikasi kecil untuk membuat jawaban asli agar berfungsi sebagai perintah vim biasa (tidak perlu melarikan diri dari titik dua, tetapi kutipan ganda perlu diloloskan).

Jika Anda tidak menyukai foldexprstring yang panjang , kami dapat mendefinisikan fungsi untuk itu:

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

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

endfunction

Kemudian ganti baris autocmd yang foldexprakan

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
jdhao
sumber