Mengubah perilaku indentasi Vim berdasarkan jenis file

379

Bisakah seseorang menjelaskan kepada saya secara sederhana cara termudah untuk mengubah perilaku indentasi Vim berdasarkan jenis file? Misalnya, jika saya membuka file Python seharusnya indent dengan 2 spasi, tetapi jika saya membuka skrip Powershell itu harus menggunakan 4 spasi.

EBGreen
sumber
9
Konvensi BTW - PEP8 untuk Python mengatakan bahwa tabstop harus 4 spasi dan tab harus 4 spasi. ref: stackoverflow.com/questions/120926/…
cgseller

Jawaban:

304

Anda dapat menambahkan .vimfile yang akan dieksekusi setiap kali vim beralih ke tipe file tertentu.

Misalnya, saya punya file ~/.vim/after/ftplugin/html.vim dengan konten ini:

setlocal shiftwidth=2
setlocal tabstop=2

Yang menyebabkan vim menggunakan tab dengan lebar 2 karakter untuk indentasi ( noexpandtabopsi diatur secara global di tempat lain dalam konfigurasi saya).

Ini dijelaskan di sini: http://vimdoc.sourceforge.net/htmldoc/usr_05.html#05.4 , gulir ke bawah ke bagian tentang plugin filetype.

SpoonMeiser
sumber
229
Anda harus memasukkan itu ~/.vim/after/ftplugin/html.vimsebagai gantinya. Tetapi seperti yang orang lain tunjukkan di bawah ini, jauh lebih baik untuk hanya menambahkannya autocmd FileType html setlocal shiftwidth=2 tabstop=2ke Anda .vimrc.
Aristoteles Pagaltzis
10
Ups, sebenarnya, itu adalah / di mana saya memiliki file itu. Saya akan memperbaiki jawabannya. Saya tidak setuju, saya pikir memisahkan perintah untuk tipe file yang berbeda menjadi file yang terpisah membuat semuanya jauh lebih mudah, terutama jika Anda memiliki persyaratan untuk banyak tipe file, atau banyak pilihan untuk beberapa tipe file.
SpoonMeiser
3
Sebenarnya, tidak ada banyak alasan untuk menggunakan direktori after untuk ftplugins. Vim akan memuat semuanya yang ditemukan di runtimepath Anda, bukan hanya yang pertama seperti untuk file sintaks.
graywh
36
FYI: jangan gunakan js untuk filetype javascript. Gunakan javascript sebagai gantinya. ( autocmd FileType javascript setlocal shiftwidth=2 tabstop=2)
Kiddo
13
Anda perlu menambahkan filetype plugin onke vimrc Anda juga.
gatoatigrado
191

Gunakan ftplugins atau perintah otomatis untuk mengatur opsi.

ftplugin

Di ~/.vim/ftplugin/python.vim:

setlocal shiftwidth=2 softtabstop=2 expandtab

Dan jangan lupa untuk menyalakannya ~/.vimrc:

filetype plugin indent on

( :h ftpluginuntuk informasi lebih lanjut)

perintah otomatis

Dalam ~/.vimrc:

autocmd FileType python setlocal shiftwidth=2 softtabstop=2 expandtab

Anda dapat mengganti salah satu perintah panjang atau pengaturan dengan versi pendek mereka:
autocmd: au
setlocal: setl
shiftwidth: sw
tabstop: ts
softtabstop: sts
expandtab:et

Saya juga menyarankan mempelajari perbedaan antara tabstopdan softtabstop. Banyak orang tidak tahu softtabstop.

greywh
sumber
1
Terima kasih! Juga terima kasih atas sedikit tentang 'ts' dan 'sts'. Apakah ada halaman tertentu yang Anda rekomendasikan untuk membahas perbedaan ini dan bagaimana menggunakannya?
jvriesem
11
@jvriesem Tidak banyak artinya: 'ts' adalah bagaimana karakter tab ditampilkan; 'sts' adalah berapa banyak "spasi" yang akan disisipkan ketika tombol tab ditekan; 'sw' adalah berapa banyak "spasi" yang digunakan per level indent; 'et' adalah apakah akan menggunakan spasi atau tab; 'sta' memungkinkan Anda memasukkan 'sw' "spasi" saat menekan tab di awal baris.
graywh
10
Saya bertanya-tanya apakah bentuk lengkap akan lebih baik digunakan, untuk kejelasan, daripada kalimat singkat di akhir.
icedwater
23
swkependekan softwidth, stskependekan softtabstop, etkependekan expandtab, setlkependekan setlocal, dan aukependekan autocmd. Anda bisa menggunakan formulir panjang dan bukan formulir pendek.
Flimm
13
Saya percaya swmemperluas ke shiftwidthbukan softwidth.
johncip
83

edit Anda ~/.vimrc, dan tambahkan jenis file yang berbeda untuk indentasi yang berbeda, misalnya saya ingin html/rbindentasi untuk 2 spasi, dan js/coffeefile indentasi untuk 4 spasi:

" by default, the indent is 2 spaces. 
set shiftwidth=2
set softtabstop=2
set tabstop=2

" for html/rb files, 2 spaces
autocmd Filetype html setlocal ts=2 sw=2 expandtab
autocmd Filetype ruby setlocal ts=2 sw=2 expandtab

" for js/coffee/jade files, 4 spaces
autocmd Filetype javascript setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype coffeescript setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype jade setlocal ts=4 sw=4 sts=0 expandtab

lihat: Mengatur preferensi spasi putih Vim berdasarkan jenis file

Siwei Shen 申思维
sumber
Komentar untuk vimrc adalah tunggal ":)
sdkks
@ skdk, kurasa tidak. kutipan ganda adalah komentar, kutipan tunggal 'memberikan kesalahan pada semua vim Linux saya. (7.3+, 8.0 ...)
Siwei Shen 申思维
Ya. Komentar saya mengatakan gunakan satu ", artinya jangan menutupnya dengan yang lain ". Tidak yakin mengapa saya berkomentar demikian.
sdkks
ok, saya salah paham. Saya pikir kutipan tunggal berarti 'tetapi tidak dibiarkan "tanpa " @ kanan .
pikir
60

Masukkan perintah autocmd berdasarkan akhiran file di ~ / .vimrc Anda

autocmd BufRead,BufNewFile   *.c,*.h,*.java set noic cin noexpandtab
autocmd BufRead,BufNewFile   *.pl syntax on

Perintah yang Anda cari mungkin ts = dan sw =

Paul Tomblin
sumber
18
Apa keuntungan dari ini FileType?
Casey Chow
3
Apakah ada cara untuk membalikkan pertandingan?
SystemParadox
7
Saya memiliki masalah dalam mendapatkan filetypes untuk bekerja dengan file html (karena file .html tidak benar-benar HTML, tetapi file template HTML dengan bahasa templating). Tipe file tampaknya tidak mengenalinya sebagai html, tetapi metode ini akan melakukannya.
Mark Hildreth
3
@digitxp - keuntungannya adalah ekstensi yang Anda gunakan tidak cocok dengan "FileType" yang ditentukan. Sebagai contoh, dalam instalasi saya, * .md berarti tipe file dari Modula2 sedangkan saya menggunakannya untuk penurunan harga. Saya dapat (a) mengubah pengaturan FileType default (b) mengubah pengaturan filetype dengan konfigurasi khusus atau (c) dengan cepat mendapatkan apa yang saya inginkan menggunakan pengaturan ini dalam 1 .vimrc file yang saya gunakan (c).
pdwalker
Akan bermanfaat untuk menunjukkan bahwa - dengan asumsi pembacaan cepat saya tentang dokumen sudah benar - Anda dapat menambahkan beberapa perintah per jenis file dengan cara ini, dan mereka dijamin akan dieksekusi dalam urutan yang diberikan.
underscore_d
23

Saya biasanya bekerja dengan expandtabset, tapi itu buruk untuk makefiles. Saya baru-baru ini menambahkan:

:autocmd FileType make set noexpandtab

ke akhir file .vimrc saya dan mengenali Makefile, makefile, dan * .mk sebagai makefile dan tidak membuka tab. Agaknya, Anda dapat memperpanjang ini.

Jonathan Leffler
sumber
Opsi yang lebih baik adalah dengan mengaktifkan: plugin filetype. Yang default untuk Vim meliputi: setl noet, jadi Anda bahkan tidak memerlukan itu di vimrc Anda.
graywh
BAIK. Bisakah Anda menjelaskan manfaatnya, dan apa yang terlibat dalam melakukannya? Mengapa plugin tipe file lebih baik daripada autocmd? Kapan autocmd digunakan? Tidak digunakan?
Jonathan Leffler
5
Plugin filetype yang datang dengan Vim akan melakukan hal-hal bermanfaat seperti "setlocal noexpandtab" untuk makefile, misalnya. Perintah otomatis vs ftplugins untuk hal-hal pribadi seperti shiftwidth tidak masalah - itu hanya bagaimana Anda memilih untuk menyusun konfigurasi vim Anda.
graywh
17

Secara pribadi, saya menggunakan pengaturan ini di .vimrc:

autocmd FileType python set tabstop=8|set shiftwidth=2|set expandtab
autocmd FileType ruby set tabstop=8|set shiftwidth=2|set expandtab
Nello
sumber
22
Banyak bahasa telah lama didirikan, seperti halnya perusahaan-perusahaan tertentu. Ambil NodeJS sebagai contoh dari yang pertama. Tab harus dua spasi. Sakit kepala, dan cukup konyol, tetapi penting.
Paul Hazen
3
Mengapa tab harus sama untuk semua keadaan? Untuk file konfigurasi, 8 tab spasi berfungsi dengan baik, tetapi untuk kode dengan banyak indentasi, 2 lebih mudah dikelola. Dan kemudian ada konvensi tetap: node.js harus memiliki 2 tab spasi, dan python sebenarnya secara sintaks tidak valid dengan apa pun selain 4 tab ruang.
felixphew
1
@felixphew Python sangat benar dengan sejumlah spasi (atau bahkan tab) asalkan tetap sama sepanjang jalan.
James
@DJMcMayhem Anda benar - saya seharusnya mengatakan "sangat merekomendasikan".
felixphew
1
+1 ke Nello. Karakter tab memiliki tradisi lama yang berarti melompat ke posisi berikutnya di kelipatan 8 karakter. Hanya karena orang ingin menggunakan tab untuk "indentasi berikutnya yang terlihat bagus dalam bahasa saya" dan karena beberapa editor teks tidak repot-repot membuat perbedaan antara "menambahkan karakter tab" dan "menambahkan ruang untuk indentasi", dan orang-orang mengubah editor mereka agar sesuai keinginan mereka, bahwa kami sekarang memiliki kekacauan ini di mana tab tidak pernah menampilkan cara yang dimaksud. Kode sumber adalah teks dan standar untuk teks adalah tab 8 karakter.
Florian F
6

Ini mungkin diketahui oleh sebagian besar dari kita, tetapi bagaimanapun (saya bingung pertama kali saya): Melakukan :set et( :setexpandtab) tidak mengubah tab yang sudah ada dalam file, yang harus dilakukan :retab. Sebagai contoh:

:set et
:retab

dan tab dalam file digantikan oleh ruang yang cukup. Untuk memiliki tab kembali cukup lakukan:

:set noet
:retab
Juan Lanus
sumber
4

Hari ini, Anda dapat mencoba editorconfig , ada juga plugin vim untuk itu. Dengan ini, Anda tidak hanya dapat mengubah ukuran lekukan dalam vim, tetapi di banyak editor lainnya, menjaga gaya pengkodean yang konsisten.

Di bawah ini adalah konfigurasi editor yang sederhana, seperti yang Anda lihat, file python akan memiliki 4 spasi untuk indentasi, dan file template pug hanya akan memiliki 2.

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

# 2 space indentation for pug templates
[*.pug]
indent_size = 2
chengbo
sumber
3

Meskipun Anda dapat mengkonfigurasi lekukan Vim dengan baik menggunakan plugin indent atau secara manual menggunakan pengaturan, saya sarankan menggunakan skrip python yang disebut Vindect yang secara otomatis menetapkan pengaturan yang relevan untuk Anda ketika Anda membuka file python. Gunakan tip ini untuk menjadikan penggunaan Vindect lebih efektif. Ketika saya pertama kali mulai mengedit file python yang dibuat oleh orang lain dengan berbagai gaya lekukan (tab vs spasi dan jumlah spasi), itu sangat membuat frustrasi. Tapi Vindect bersama dengan file indent ini

Juga merekomendasikan:

haridsv
sumber
2

Bagi mereka yang menggunakan autocmd, itu adalah praktik terbaik untuk mengelompokkan mereka bersama. Jika pengelompokan terkait dengan deteksi tipe file, Anda mungkin memiliki sesuatu seperti ini:

augroup filetype_c
    autocmd!
    :autocmd FileType c setlocal tabstop=2 shiftwidth=2 softtabstop=2 expandtab
    :autocmd FileType c nnoremap <buffer> <localleader>c I/*<space><esc><s-a><space>*/<esc>
augroup end

Pengelompokan membantu menjaga .vimrcterorganisir terutama sekali filetype memiliki beberapa aturan yang terkait dengannya. Dalam contoh di atas, pintasan komentar khusus untuk file .c ditentukan.

Panggilan awal untuk autocmd!memberitahu vim untuk menghapus perintah otomatis yang ditentukan sebelumnya dalam pengelompokan tersebut. Ini akan mencegah definisi duplikat jika .vimrcbersumber lagi. Lihat :help augroupuntuk info lebih lanjut.

67 hz
sumber
1

Saya menggunakan utilitas yang saya tulis di C disebut autotab. Ini menganalisis beberapa ribu baris pertama file yang Anda muat dan menentukan nilai untuk parameter Vim shiftwidth, tabstopdan expandtab.

Ini dikompilasi menggunakan, misalnya gcc -O autotab.c -o autotab,. Petunjuk untuk berintegrasi dengan Vim ada di tajuk komentar di bagian atas.

Autotab cukup pintar, tetapi dapat menjadi bingung dari waktu ke waktu, khususnya oleh yang telah dipertahankan secara tidak konsisten menggunakan gaya indentasi yang berbeda.

Jika file jelas menggunakan tab, atau kombinasi tab dan spasi, untuk lekukan, Autotab akan mencari tahu ukuran tab apa yang digunakan dengan mempertimbangkan faktor-faktor seperti penyelarasan elemen internal melintasi garis-garis berturut-turut, seperti komentar.

Ini bekerja untuk berbagai bahasa pemrograman, dan memaafkan untuk elemen "out of band" yang tidak mematuhi kenaikan indentasi, seperti arahan preprocessing C, label pernyataan C, belum lagi garis kosong yang jelas.

Kaz
sumber