Vim: menerapkan pengaturan pada file dalam direktori

103

Bagaimana cara menentukan pengaturan Vim untuk semua file di bawah direktori saat ini?

Solusi ideal adalah jika Vim mencari dan membaca .vimrc di direktori saat ini sebelum mencari ~ / .vimrc, dan menerapkan pengaturan di sana untuk keseluruhan struktur.

Saya telah melihat plugin , tetapi ini berarti pengaturan yang diterapkan tidak transparan karena mereka memerlukan plugin untuk diinstal. Sebaliknya, modeline transparan karena terlepas dari vimrc pengguna atau pemanggilan vim tertentu, pengaturan modeline akan diterapkan untuk file itu.

Hal yang saya coba adalah

  • menempatkan .vimrc di direktori kerja
  • :so vimrc di modeline.

Saya kira keduanya tidak bekerja untuk alasan keamanan. Saya tidak membutuhkan kekuatan penuh dari vimrc; terikat ke pengaturan yang dapat diterima oleh modeline sudah cukup. Tujuan saya adalah memudahkan vimmers untuk mengadopsi standar pengkodean dalam sebuah proyek.

wilhelmtell.dll
sumber

Jawaban:

42

Saya penganjur cara plugin . Untuk beberapa alasan:

  • Modelines sangat terbatas: kami tidak dapat menyetel variabel (yang menyesuaikan plugin (ft) lainnya, seperti "haruskah kurung kurawal dari for-snippet berada pada baris baru?"), Atau memanggil fungsi dari mereka (Saya tidak membatasi diri ke standar pengkodean, saya juga mengatur makefile untuk digunakan tergantung pada direktori saat ini)
  • KERING : dengan modelines, pengaturan perlu diulang di setiap file, jika ada terlalu banyak hal yang harus diatur atau penyetelan untuk diubah, akan dengan cepat menjadi sulit untuk dipelihara, terlebih lagi akan membutuhkan penggunaan plugin template-expander ( yang harus Anda pertimbangkan jika Anda memiliki beberapa vimmers dalam proyek Anda).
  • Tidak semua orang menggunakan vim untuk berkembang. Saya tidak ingin diganggu oleh pengaturan editor orang lain, mengapa saya harus membuat mereka menjadi parasit?
  • Lebih mudah meminta vimmers untuk menginstal plugin yang sama, daripada meminta mereka untuk menyalin-menempel, dan memelihara, baris yang sama di .vimrc mereka
  • Pengaturan dapat disimpan dengan file proyek lainnya (cvs / svn / git / apa saja)
  • Sangat mudah untuk memiliki file konfigurasi per proyek - dengan plugin, saya memiliki file konfigurasi global untuk standar pengkodean keseluruhan proyek, dan file konfigurasi khusus untuk setiap sub-proyek (yang makefile untuk digunakan, yang dapat dieksekusi untuk memanggil , ...)

BTW, solusi sth dapat digunakan untuk sumber file konfigurasi tunggal. Ini sangat mirip dengan pendekatan plugin kecuali .vimrc harus dipasit dengan opsi non global, dan tidak mendukung banyak file konfigurasi / bersama dengan mudah.

Luc Hermitte
sumber
Saya perhatikan Anda harus menyimpan file baru di jalur sebelum itu akan menjalankan plugin dengan benar
cmcginty
Memang. Keluarga plugin ini hanya mendefinisikan kerangka kerja. Anda masih harus menulis definisi spesifik proyek dalam sebuah file - yang akan secara otomatis diambil oleh framework.
Luc Hermitte
1
Perlu diketahui, Luc menautkan plugin miliknya sendiri. Ini tampaknya bekerja jauh lebih baik daripada yang ditautkan dalam pertanyaan. Terima kasih.
data
Baik. Saya tidak tahu. Karena saya telah menggunakan milik saya selama bertahun-tahun, saya tidak pernah melihat lebih dekat pada implementasi lainnya. Dari waktu ke waktu saya menerima laporan bug yang akhirnya saya perhitungkan. BTW, versi saya diimplementasikan untuk dipicu sebelum mu-template untuk mengatur variabel khusus proyek sebelum memperluas templat (yang cukup berguna untuk mengambil direktori akar proyek saat ini dan memangkasnya dari nama jalur yang diperluas)
Luc Hermitte
1
@JasonMcCarrell Implementasi local_vimrc dan Markus "embear" Braun mendukung blacklist, whitelist ... Jika Anda hanya perlu menentukan bagaimana indentasi dilakukan, mungkin plugin EditorConfig-vim akan menjadi pilihan yang lebih baik.
Luc Hermitte
91

Anda bisa memasukkan sesuatu seperti ini $VIM/vimrc

autocmd BufNewFile,BufRead /path/to/files/* set nowrap tabstop=4 shiftwidth=4
sth
sumber
1
Ini rekursif, tetapi hanya dengan *. Jika Anda mencoba menguranginya ke / path / ke / files / atau / path / to / files itu tidak akan berhasil.
SystemParadox
Ini bagus jika proyek Anda memiliki pohon file yang ditulis dengan "noexpandtab" dan pohon lain dengan semua file "expandtab" (misalnya CodeIgniter). Anda dapat menyetel tindakan yang tepat untuk file di setiap pohon satu per satu dengan satu file konfigurasi.
pengguna9645
2
Anehnya, ini tidak berhasil ketika jalur saya menyertakan symlink; Saya harus meletakkan path lengkap tanpa symlink sebelum bisa berfungsi.
Dolan Antenucci
Lihat jawaban joseph07 tentang menggunakan "vim tepercaya" sebagai alternatif, inversi dari pendekatan ini (terdistribusi .vimrc vs terpusat).
Nathan Schulte
50

Saya sangat menyarankan untuk tidak menggunakan set exrc

Bahkan dengan set secure, di bawah * nix, vim masih akan menjalankan perintah otomatis, shell, dkk, jika Anda memiliki file tersebut. Jadi jika Anda senang mengedit file di tarball itu saya mengirimi Anda dengan yang .vimrcberisi:

autocmd BufEnter * :silent! !echo rm -rf ~/

Anda mungkin tidak akan terlalu senang dibandingkan saya.

phen
sumber
6
Ini juga berlaku dengan plugin yang secara otomatis dijalankan saat vim dimuat.
Luc Hermitte
31

Pertanyaan ini sudah lama, tetapi sepertinya kekhawatiran yang cukup alami dan terus-menerus.

Solusi saya cukup sederhana. Saya menempatkan .vimrcfile di direktori root proyek saya. Baris pertama .vimrcfile biasanya sumber ~/.vimrc, dan kemudian menambahkan konfigurasi tertentu yang saya inginkan. Saya alias tvim='vim -u .vimrc', dan digunakan tvimdalam direktori proyek pribadi saya. "tvim" untuk "vim tepercaya", artinya jika saya menjalankannya di direktori dengan .vimrcfile dan terjadi kesalahan, saya tidak menyalahkan siapa-siapa selain diri saya sendiri, karena saya secara eksplisit mengatakan bahwa saya mempercayainya. Juga, saya menyimpan sekelompok ini disimpan sehingga saya kadang-kadang dapat hanya melakukan softlink yang saya inginkan untuk jenis proyek tertentu.

joseph07
sumber
1
Pendekatan ini sangat mudah dan sangat sesuai dengan kebutuhan saya.
Jinxed
Ketika saya mencoba ini dan source $HOME/.vimrcdari lokal saya .vimrc, Vim mengeluh tidak dapat menemukan plugin yang diinstal di seluruh sistem saya (patogen dalam kasus ini; execute pathogen#infect()perintah di atas saya $HOME/.vimrcgagal dengan Unknown function ...). Bagaimana cara memperbaikinya?
Nathan Schulte
20

Menempatkan .vimrc di direktori kerja sebenarnya didukung, hanya dinonaktifkan secara default. Lihat :h 'exrc'dan :h startupuntuk detailnya, pengaturan 'exrc'akan memungkinkan membaca .vimrcdari direktori saat ini.

Ini juga disarankan :set securesaat menggunakan ini. Ini mengunci :autocmd, shell, dan menulis perintah .vimrcdi direktori saat ini.

Hal lain yang mungkin perlu diperhatikan adalah menyiapkan sesi ( :h session) dengan tampilan standar dan pengaturan untuk proyek tersebut.

Semua yang dikatakan, saya mungkin akan menggunakan opsi plugin yang dirinci oleh Luc Hermitte sendiri.

gravious
sumber
6
Silakan lihat komentar oleh phen. Ini dapat menyebabkan implikasi keamanan yang serius.
data
11

Untuk meminimalkan risiko keamanan dengan fitur "autorun" APA PUN untuk APA SAJA saat ini, bolehkah saya menyarankan Anda untuk menggunakan fitur vim yang sudah ada alih-alih plugin (bagasi portabilitas)?

Misalnya.

File vimrc folder lokal saya bernama "_gvimrc" (sengaja). Ini mengurangi harapan bagi orang-orang seperti phen untuk menghibur dirinya sendiri atas biaya kita. :-)

Di file $ VIM / .vimrc saya, saya memasukkan:

if filereadable("_gvimrc")
    source _gvimrc
endif

pada akhirnya.

Saya menggunakan "filereadable ()" di atas "fileexists ()" karena nanti memiliki beberapa keanehan ketika disiksa dengan membuka beberapa (10+) file secara bersamaan, (tidak yakin mengapa).

Tentu saja, Anda dapat memberikan nama file unik Anda sendiri untuk mengaburkan pembuat masalah potensial lebih lanjut. Seperti "_mygvimrc", "_gobbledygook", dll. Anda hanya perlu menentukan satu nama standar dan sumber sesuai dengan itu di $ VIM / .vimrc Anda. Mengandalkan internal vi / vim untuk mengesampingkan masalah portabilitas. TAPI, JANGAN beri nama .vimrc (atau _vimrc) untuk mencegah sumber rekursif jika Anda mengedit file $ VIM / .vimrc dengan vim nanti.

Telah menggunakan ini sejak Windoze 98SE, melalui Windork XP Pro, dan sekarang Windorkier 7 (5+ tahun sudah). Saya akan menandai daftar file .txt di Explorer dan kemudian menggunakan "Edit with multiple Vim", menghasilkan beberapa jendela vim yang terbuka secara bersamaan. Untuk pekerjaan saya, saya melakukan ini beberapa kali sehari, setiap hari. Semua file diperlakukan dengan apa yang saya tetapkan di _gvimrc lokal saya.

XEQtor
sumber
Di sini, ketidakpercayaan akan portabilitas plugin tidak memiliki dasar karena plugin local_vimrc ini (setidaknya milik saya) bersifat portabel (dulu dipertahankan pada berbagai OS yang berbeda, dan bahkan windows 95). Masalah tentang risiko keamanan juga dibesar-besarkan: jika kita mengikuti cara ini, kita tidak akan pernah memasang apapun untuk memudahkan pekerjaan kita.
Luc Hermitte
Namun, sejauh yang saya ketahui, masalah nyata pertama adalah, dengan pendekatan Anda, Anda harus bekerja dari direktori yang berisi file _gvimrc (yang merupakan nama yang buruk karena dimaksudkan untuk memuat hal-hal khusus gvim). Jika proyek Anda terdiri dari beberapa direktori, yang mungkin memerlukan konfigurasi umum, dan yang spesifik (untuk beberapa modul), ini akan segera menunjukkan batasannya.
Luc Hermitte
Masalah kedua adalah Anda hanya dapat mengerjakan satu proyek pada satu waktu - jika saya ingin mengerjakan OTB, openjpeg, dan proyek yang melibatkan kedua pustaka, solusi ini tidak akan mengizinkan saya memiliki pengaturan khusus untuk masing-masing tiga proyek.
Luc Hermitte
Ini juga berfungsi untuk daisy-chain yang memuat file sintaks dari direktori lokal.
maharvey67
2

Dengan asumsi orang tidak menambahkan file setiap beberapa hari, Anda mungkin dapat menambahkan modeline di bagian atas setiap file. Faktanya, jika sistem kontrol versi Anda mengizinkannya, Anda mungkin dapat menerapkan aturan yang mengatakan bahwa setiap file harus memiliki modeline saat check in.

Nathan Fellman
sumber
2

Gunakan "editorconfig"

Jika jenis standar pengkodean yang ingin Anda terapkan terkait dengan gaya indentasi, ukuran tab, format file, dan rangkaian karakter, Anda mungkin ingin melihat "editorconfig" , yang merupakan standar editor silang untuk menentukan jenis pengaturan ini di proyek tertentu, dan minta semua editor mengikuti konfigurasi itu.

Spesifikasi "editorconfig" memungkinkan proyek meminta pengaturan berbeda bergantung pada ekstensi file atau nama dalam proyek. (Jadi Anda dapat memiliki Makefile menggunakan TAB, skrip Python Anda menggunakan 4 spasi dan skrip shell Anda menggunakan 2 spasi untuk indentasi.)

Anda membutuhkan plug-in untuk menggunakan "editorconfig" di Vim. Situs web resminya menyediakan satu, tetapi secara pribadi saya akan merekomendasikan sgur / vim-editorconfig , yang ditulis dalam Vimscript murni, jadi Anda tidak perlu terlalu khawatir tentang ketergantungan eksternal terlalu banyak.

Karena "editorconfig" bertujuan untuk kompatibilitas lintas editor, ini sangat terbatas dalam apa yang dilakukannya, jadi jika Anda menginginkan spasi kosong yang konsisten, format file (DOS vs. Unix) dan pengkodean (Unicode utf-8, dll.), Maka "editorconfig " adalah untukmu.

filbranden.dll
sumber
0

Saya melihat plugin yang ada dan tidak benar-benar menyukainya, jadi saya menulis fungsi sederhana yang mendukung vim-fugitive . Keuntungan dari ini adalah ia mengetahui bahwa root proyek selalu merupakan root dari repositori, dan sebagai tambahan saya dapat melakukan hash file untuk menyimpan tabel kepercayaan. Letakkan saja yang berikut ini di .vimrcfile Anda .

function LoadRepoVimrc()
  let l:path = fugitive#repo().tree('.vimrc')
  if filereadable(l:path)
    let l:sha1 = fugitive#repo().git_chomp('hash-object',l:path)
    if !exists('g:SAFE_VIMRC') | let g:SAFE_VIMRC = {} | endif
    if has_key(g:SAFE_VIMRC,l:path) && g:SAFE_VIMRC[l:path] ==? l:sha1
      execute 'source '.fnameescape(l:path)
    elseif confirm("Trust ".l:path."?", "&Yes\n&No",2) == 1
      let g:SAFE_VIMRC[l:path] = l:sha1
      execute 'source '.fnameescape(l:path)
    else
      execute 'sandbox source '.fnameescape(l:path)
    endif
  endif
endfunction
autocmd User FugitiveBoot call LoadRepoVimrc()
set viminfo ^= !

Jika !opsi disetel pada viminfopengaturan, maka SAFE_VIMRCkamus akan dipertahankan di antara proses (perhatikan ^untuk menambahkan opsi agar tidak mengacaukan nopsi).

Parakleta
sumber