Preferensi Tab Vs Space di Vim

87

Vim sangat akomodatif dalam hal tab Vs. preferensi ruang. Seperti yang saya pahami, tabstoppengaturan menunjukkan lebar karakter tab. The shiftwidthPengaturan menetapkan berapa kolom untuk kenaikan / pengurangan bila menggunakan <<dan >>perintah, sedangkan softtabstoppengaruh pengaturan jumlah spasi untuk dimasukkan saat Anda menekan Tabtombol dalam modus insert. Jika expandtabaktif, tombol tab menyisipkan softtabstopjumlah karakter spasi. Sedangkan dengan expandtabdimatikan, menekan Tabtombol akan menyisipkan sesedikit mungkin jumlah karakter tab + spasi yang cocok softtabstop. (Harap perbaiki saya jika saya salah.)

Poin terakhir ini membuat saya bertanya-tanya: adakah kasus praktis yang tidak Anda inginkan shiftwidth == tabstop && tabstop == softtabstop? Saya tidak bisa memikirkan satu pun. Sejauh yang saya ketahui, akan sangat mudah jika saya dapat mengatur semua 3 ini ke nilai yang sama, dalam satu tugas tunggal. misalnya menelepon:

:set stab=4

yang setara dengan berlari:

:set tabstop=4 softtabstop=4 shiftwidth=4 

Adakah yang bisa menyarankan bagaimana ini bisa dilakukan?


MEMPERBARUI

Terima kasih atas balasan begitu jauh dari terlalu banyak php , Hobbs dan kaiser.se . Daripada membalas satu per satu, saya memperbarui pertanyaan di sini.

Softtabstop dengan expandtab dimatikan

Saya katakan di atas bahwa dengan expandtab dimatikan, menekan tombol Tab akan menyisipkan sesedikit mungkin jumlah karakter tab + spasi yang cocok softtabstop. Saya mendukungnya, tetapi saya pikir saya perlu menjelaskan apa yang saya maksud. Saya akan mencoba melakukannya dengan beberapa contoh. Untuk mengikuti, jalankan :set listsehingga Anda dapat melihat karakter tab.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

Dalam mode sisip, menekan tombol tab menyisipkan 2 karakter spasi. Tekan tombol tab untuk kedua kalinya, dan alih-alih memasukkan dua karakter spasi lagi (dengan total 4 karakter spasi), 2 spasi sebelumnya diganti dengan karakter tab tunggal. Tabstop disetel ke 4, jadi satu karakter tab memiliki lebar yang sama dengan 4 spasi.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

Dalam mode sisip, menekan tombol tab akan menyisipkan 1 karakter tab ditambah 2 spasi. Karakter tab memiliki lebar 4, jadi total lebar adalah 6, dan ini dicapai dengan menggunakan 3 karakter. Menekan tombol tab untuk kedua kalinya menyisipkan dua karakter tab, dan menghapus dua spasi yang telah disisipkan sebelumnya. Lebar totalnya adalah 12, dan ini dicapai dengan menggunakan 3 karakter.

Dalam kedua contoh ini, Vim menyisipkan jumlah minimum karakter tab + spasi yang cocok dengan softtabstop.

Jika saya bekerja dengan expandtab dimatikan, saya tidak dapat melihat diri saya menginginkan kontrol ekstra granular yang dapat dicapai dengan mengatur softtabstop ke nilai yang berbeda dari tabstop. Akan tetap berguna bagi saya untuk dapat mengatur tabstop, softtabstopdan shiftwidthke nilai yang sama dengan satu perintah.

Apakah expandtab membuat softtabstop menjadi mubazir?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

Dalam mode sisip, menekan tombol tab menyisipkan 4 spasi. Menekan tombol hapus menghapus satu spasi - jadi Anda harus mundur 4 kali jika Anda menekan tombol tab secara tidak sengaja.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

Dalam mode sisip, menekan tombol tab menyisipkan 4 spasi. Menekan tombol spasi mundur menghapus 4 spasi.

Jika saya bekerja dengan expandtabdihidupkan, saya lebih suka tombol hapus untuk menghapus jumlah spasi yang sama seperti sisipan tombol tab. Jadi dalam kasus ini, juga, saya merasa akan berguna untuk dapat menetapkan nilai yang sama tabstop, softtabstopdan shiftwidthsecara bersamaan.

Jalan pintas akan tetap berguna

Sangat bagus bahwa Vim memberikan begitu banyak fleksibilitas, tetapi saya tidak dapat melihat diri saya membutuhkannya. Saya hanya ingin dapat memilih lebar tab, dan apakah itu tab 'keras' (menggunakan karakter tab) atau tab 'lunak' (terdiri dari spasi). Beralih antara tab keras dan lunak cukup mudah ( :set expandtab!), tetapi saya berharap lebih mudah untuk mengatur lebar tab, tanpa harus mengutak-atik 3 parameter berbeda.

Jadi saran yang saya usulkan untuk sesuatu seperti :set stab=4masih terdengar bagus bagi saya.

nelstrom
sumber
Sepertinya Anda memiliki dua pertanyaan berbeda di sini, mungkin Anda harus membagi pertanyaan Anda menjadi dua.
Greg Hewgill
Kamu benar! Saya telah memindahkan pertanyaan kedua ke topiknya sendiri.
nelstrom
1
Ini sepertinya RFE dan bukan pertanyaan. Karena itu, Anda mungkin harus mengusulkan ke komunitas VIM: vim.org/community.php - atau cukup tulis tambalan. Selain itu, VIM memiliki fasilitas makro yang luas yang memungkinkan Anda untuk menentukan operasi baru, jadi sangat mungkin Anda dapat membuat makro yang melakukan apa yang Anda inginkan.
kdgregory
@nelstrom Berkenaan dengan pertanyaan Anda is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, kode sumber Vim sendiri menggunakan set shiftwidth=4 tabstop=8 noexpandtab. Ya, seseorang biasanya menginginkan shiftwidth == softtabstop, tetapi itu terlepas dari nilai yang tabstopdimilikinya.
jamessan

Jawaban:

56

Membuat stabopsi di Vim itu sendiri tidak mudah, tetapi saya telah menyiapkan perintah / fungsi ini yang dapat Anda masukkan .vimrc(atau file plugin jika Anda sangat terorganisir). Gunakan :Stabdan Anda akan diminta untuk tingkat indentasi dan apakah akan digunakan atau tidak expandtab. Jika Anda menekan enter tanpa memberikan level indentasi baru, itu hanya akan mencetak pengaturan saat ini.

"taruh semua ini di .vimrc atau file plugin Anda
perintah! -nargs = * Stab call Stab ()
fungsi! Menusuk()
  biarkan l: tabstop = 1 * input ('set shiftwidth =')

  jika l: tabstop> 0
    "apakah kami juga ingin mengembangkan tab?
    let l: expandtab = confirm ('set expandtab?', "& Ya \ n & Tidak \ n & Batal")
    jika l: expandtab == 3
      "batalkan?
      kembali
    berakhir jika

    let & l: sts = l: tabstop
    biarkan & l: ts = l: tabstop
    biarkan & l: sw = l: tabstop

    jika l: expandtab == 1
      setlocal expandtab
    lain
      setlocal noexpandtab
    berakhir jika
  berakhir jika

  "tampilkan opsi yang dipilih
  mencoba
    echohl ModeMsg
    echon 'setel tabstop ='
    echohl Pertanyaan
    echon & l: ts
    echohl ModeMsg
    echon 'shiftwidth ='
    echohl Pertanyaan
    echon & l: sw
    echohl ModeMsg
    echon 'sts ='
    echohl Pertanyaan
    echon & l: sts. ''. (& l: et? '': 'tidak')
    echohl ModeMsg
    echon 'expandtab'
  akhirnya
    echohl Tidak ada
  endtry
fungsi akhir
terlalu banyak php
sumber
3
Terima kasih untuk naskahnya! Ia melakukan lebih dari yang saya minta - saya pikir saya lebih suka tidak menggunakan tab perluasan - tetapi saya dapat dengan mudah menyesuaikannya dengan keinginan saya. Anda telah memberi saya kursus kilat kecil di Vimscript, jadi saya sangat berterima kasih. Hadiah 100 poin adalah milik Anda!
nelstrom
9

Ini adalah upaya pertama saya untuk menulis VimScript, tetapi begini:

function! Stab(value)
    let &shiftwidth  = a:value
    let &softtabstop = a:value
    let &tabstop     = a:value
endfunc

Jika saya meletakkan ini di file .vimrc saya, saya dapat memanggilnya dengan menjalankan :call Stab(X), di mana X adalah lebar tab yang diinginkan. Ini adalah solusi yang memadai untuk saat ini, tetapi jika ada yang bisa menyarankan cara untuk mempermudah panggilan, saya akan berterima kasih.

Saya juga telah membuat fungsi yang dengan cepat merangkum pengaturan saat ini, yang telah saya petakan ke ctrl-Tab:

nmap <C-Tab> :call TabParams()<CR>
function! TabParams()
    echo "tabstop:     ".&tabstop
    echo "shiftwidth:  ".&shiftwidth
    echo "softtabstop: ".&softtabstop
endfunc

Baiklah, saya memberikan hadiah 100 poin untuk jawaban ini, dan sekarang saya sudah setengah menyelesaikannya sendiri. Tidak yakin apakah saya dapat menerima jawaban saya sendiri ...

nelstrom
sumber
+1 ya, tetapi jika ini yang benar-benar Anda inginkan, tetaplah jawaban yang oke.
DaveParillo
2
Anda mungkin ingin menggunakan let & l: shiftwidth, dll untuk menyetel versi lokal.
SystemParadox
7

Anda dapat dalam mode edit juga menggunakan Ctrl-Tuntuk membuat indentasi dan Ctrl-Duntuk membatalkan ke tingkat indentasi berikutnya seperti yang diatur oleh shiftwidth, terlepas dari tabstop, softtabstopatau expandtabpengaturannya. Vim secara otomatis akan menambah / menghapus spasi atau tab untuk membawa Anda ke kolom kanan.

Jika Anda menggunakan perintah ini untuk mengontrol indentasi alih-alih Tab/ BackspaceAnda tidak perlu khawatir tentang semua pengaturan tab ini cocok bersama dan selalu mendapatkan tingkat indentasi yang benar.

sth
sumber
3

Jika expandtabdiset maka (seperti yang ditunjukkan oleh banyak php), softtabstopmenjadi mubazir. Satu-satunya alasan Anda mungkin menetapkan secara shiftwidthberbeda tabstopadalah untuk memenuhi kebiasaan aneh; misalnya, Anda menggunakan indentasi empat spasi tetapi lebih suka tabmemasukkan delapan spasi.

Jika expandtabtidak disetel maka segalanya menjadi lebih kabur. Jika Anda ingin kode Anda terlihat sama di cateditor with dan non-vim seperti di vim, maka tabstopharus selalu disetel ke 8; dalam hal ini Anda akan menyetel softtabstopdan shiftwidthkeduanya ke tingkat indentasi pilihan Anda. Jika Anda lebih suka bahwa setiap "tab fisik" dalam file mewakili satu tingkat indentasi, Anda akan menyetel tabstopdan shiftwidthke tingkat indentasi yang Anda inginkan dan membiarkannya softtabstopdi nol (menyetelnya sama dengan tabstopsama kecuali jika Anda mengubahnya tabstopakan tidak sinkron, sedangkan nol berarti "tolong abaikan ini").

hobbs
sumber
3
Menurut saya ini salah karena hanya dengan softtabstopset ke nilai yang benar, backspace akan menghapus indentasi spasi seolah-olah itu adalah tab. yang merupakan keharusan untuk penggunaan yang waras.
u0b34a0f6ae
2

Pemahaman Anda tentang softtabstopdan expandtabsalah - jadi stabopsi yang Anda sarankan tidak akan terlalu berguna.

expandtabadalah saat Anda ingin menggunakan spasi, bukan tab untuk semuanya . Jika Anda mengatur expandtab, maka Vim mengabaikan softtabstopopsi dan menggunakan tabstopdan shiftwidthuntuk mengetahui berapa banyak spasi untuk disisipkan.

softtabstophanya untuk saat Anda ingin menggunakan campuran tab dan spasi, memungkinkan Anda membuat indentasi dengan kontrol halus (2 atau 4 spasi), sambil menjaga lebar tab pada nilai yang lebih tinggi (biasanya 8) sehingga teks muncul di aplikasi lain . Pengaturan softtabstop=tabstoptidak mencapai apa-apa karena Vim akan selalu menggunakan tab untuk membuat indentasi.

Pembaruan: Seperti yang telah ditunjukkan oleh kaizer.se , jika Anda menggunakan expandtab, maka Anda masih perlu mengatur softtabstopjika Anda ingin Vim mundur beberapa spasi seolah-olah itu adalah tab.

terlalu banyak php
sumber
Meskipun Anda benar tabstopdan softtabstopmenjadi satu variabel terlalu banyak ketika extpandtabditetapkan, saya pikir Anda salah dalam prioritas. Coba saja: setel ts=8 sts=4 etdan tekan tab; kursor akan berada di kolom lima, dan empat spasi akan disisipkan, seperti jika Anda telah mengaturnya ts=4 sts=0 et.
Hobbs
5
Menurut saya ini salah karena hanya dengan softtabstopset ke nilai yang benar, backspace akan menghapus indentasi spasi seolah-olah itu adalah tab. yang merupakan keharusan untuk penggunaan yang waras.
u0b34a0f6ae
2

Apakah Anda sering mengubah pengaturan ruang putih sehingga Anda benar-benar membutuhkan fungsi untuk mengelolanya? Jika Anda sering mengotak-atik tabstop dan juga menyetel expandtab, Anda mungkin akan mengalami kekacauan seiring waktu saat Anda mengubah file dengan nilai berbeda yang diteruskan stab. Hari ini saya gunakan :call stab (4), besok itu :call stab (2)dan minggu lalu itu :call stab (8). Kedengarannya bahkan jika Anda menulisnya, Anda akan segera berhenti menggunakannya.

Jika Anda berencana untuk selalu memberikan nilai yang sama untuk menusuk, mengapa tidak mengedit pengaturan global Anda saja? Dalam vim:

:e $MYVIMRC

dan tambahkan yang berikut ini:

set tabstop=4
set shiftwidth=4  "tabs are 4 spaces wide (default = 8)
set expandtab     "Convert tabs to spaces

Ini adalah bagaimana saya .vimrc diatur.

DaveParillo
sumber
1

Salah satu opsi yang berguna adalah softtabstop=-1yang akan mengaturnya ke nilai shiftwidth.
Anda juga dapat menyetel shiftwidthke 0, dalam hal ini tabstopnilainya akan digunakan.

pauloue
sumber