การตั้งค่า Tab Vs Space ใน Vim


87

Vim รองรับมากเมื่อพูดถึงแท็บ Vs. การตั้งค่าพื้นที่ ตามที่ฉันเข้าใจแล้วการtabstopตั้งค่าจะระบุความกว้างของอักขระแท็บ shiftwidthการตั้งค่าที่ระบุว่าหลายคอลัมน์ที่จะเพิ่มขึ้น / ลดลงเมื่อใช้<<และ>>คำสั่งในขณะที่softtabstopการตั้งค่ามีผลต่อปริมาณของช่องว่างที่จะแทรกเมื่อคุณกดTabคีย์ในโหมดแทรก หากexpandtabเปิดอยู่แป้นแท็บจะแทรกsofttabstopจำนวนอักขระเว้นวรรค ในขณะที่มีexpandtabการปิดการกดTabแทรกคีย์ตัวเลขที่เป็นไปได้ที่เล็กที่สุดของอักขระแท็บ + softtabstopพื้นที่ที่การแข่งขัน (กรุณาแก้ไขฉันถ้าฉันผิด)

ประเด็นสุดท้ายนี้ทำให้ฉันสงสัยว่ามีกรณีปฏิบัติที่คุณไม่ต้องการshiftwidth == tabstop && tabstop == softtabstopหรือไม่? คิดไม่ออกสักอย่าง เท่าที่ฉันกังวลมันจะสะดวกที่สุดถ้าฉันสามารถตั้งค่าทั้ง 3 อย่างนี้เป็นค่าเดียวกันในการมอบหมายงานเดียว เช่นโทร:

:set stab=4

ซึ่งจะเทียบเท่ากับการทำงาน:

:set tabstop=4 softtabstop=4 shiftwidth=4 

ใครสามารถแนะนำวิธีนี้ได้บ้าง?


อัปเดต

ขอบคุณสำหรับการตอบกลับจากphp , hobbsและkaiser.seมากเกินไป แทนที่จะตอบกลับทีละคำถามฉันกำลังอัปเดตคำถามที่นี่

Softtabstop ที่ปิด expandtab

ผมกล่าวข้างต้นว่ามีการ expandtab ปิดกดปุ่ม Tab แทรกจำนวนน้อยที่สุดของตัวละครแท็บ + softtabstopพื้นที่ที่การแข่งขัน ฉันยืนอยู่ข้างนั้น แต่ฉันคิดว่าฉันต้องอธิบายว่าฉันหมายถึงอะไร ฉันจะพยายามทำโดยใช้ตัวอย่างบางส่วน ในการทำตามให้เรียกใช้:set listเพื่อให้คุณเห็นอักขระแท็บ

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

ในโหมดแทรกการกดแป้นแท็บจะแทรกอักขระเว้นวรรค 2 ตัว กดแป้นแท็บเป็นครั้งที่สองและแทนที่จะแทรกอักขระเว้นวรรคอีกสองตัว (รวมเป็น 4 อักขระเว้นวรรค) จะแทนที่ช่องว่าง 2 ช่องก่อนหน้าด้วยอักขระแท็บเดียว Tabstop ถูกตั้งค่าเป็น 4 ดังนั้นอักขระแท็บเดียวจึงมีความกว้างเท่ากับ 4 ช่องว่าง

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

ในโหมดแทรกการกดแป้นแท็บจะแทรกอักขระแท็บ 1 ตัวบวกช่องว่าง 2 ช่อง อักขระแท็บมีความกว้าง 4 ดังนั้นความกว้างทั้งหมดคือ 6 และสามารถทำได้โดยใช้อักขระ 3 ตัว การกดแป้นแท็บเป็นครั้งที่สองจะแทรกอักขระแท็บสองตัวและลบช่องว่างสองช่องที่แทรกไว้ก่อนหน้านี้ ความกว้างทั้งหมดคือ 12 และทำได้โดยใช้อักขระ 3 ตัว

ในทั้งสองตัวอย่างนี้ Vim จะแทรกจำนวนอักขระแท็บ + ช่องว่างขั้นต่ำที่เป็นไปได้ที่ตรงกับ softtabstop

ถ้าฉันกำลังทำงานกับแท็บขยายปิดอยู่ฉันไม่เห็นว่าตัวเองต้องการการควบคุมแบบละเอียดพิเศษที่สามารถทำได้โดยการตั้งค่า softtabstop เป็นค่าที่แตกต่างจาก tabstop ก็ยังจะเป็นประโยชน์สำหรับผมที่จะสามารถตั้งค่าtabstop, softtabstopและshiftwidthค่าที่เหมือนกันกับคำสั่งเดียว

expandtab ทำให้ softtabstop ซ้ำซ้อนหรือไม่

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

ในโหมดแทรกการกดแป้นแท็บจะแทรกช่องว่าง 4 ช่อง การกดปุ่มลบจะเป็นการลบช่องว่างเดียวดังนั้นคุณต้องถอยหลัง 4 ครั้งหากคุณกดปุ่มแท็บโดยไม่ได้ตั้งใจ

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

ในโหมดแทรกการกดแป้นแท็บจะแทรกช่องว่าง 4 ช่อง การกดแป้น backspace จะลบช่องว่าง 4 ช่อง

ถ้าฉันกำลังทำงานกับการexpandtabเปิดสวิตช์ฉันต้องการให้ปุ่มลบเพื่อลบช่องว่างจำนวนเท่ากันกับที่ใส่แป้นแท็บ ดังนั้นในกรณีนี้ก็เช่นกันผมรู้สึกว่ามันจะเป็นประโยชน์เพื่อให้สามารถที่จะกำหนดค่าเดียวกันtabstop, softtabstopและshiftwidthพร้อมกัน

ทางลัดจะยังคงมีประโยชน์

เป็นเรื่องดีที่ Vim ให้ความยืดหยุ่นมาก แต่ฉันไม่เห็นว่าตัวเองต้องการมัน ฉันแค่ต้องการให้สามารถเลือกความกว้างของแท็บและไม่ว่าจะเป็นแท็บ 'ยาก' (โดยใช้อักขระแท็บ) หรือแท็บ 'อ่อน' (ประกอบด้วยช่องว่าง) การสลับระหว่างแท็บแบบแข็งและแบบอ่อนทำได้ง่ายพอสมควร ( :set expandtab!) แต่ฉันหวังว่าการตั้งค่าความกว้างของแท็บจะตรงไปตรงมากว่านี้โดยไม่ต้องใช้พารามิเตอร์ 3 ตัวที่แตกต่างกัน

ดังนั้นข้อเสนอแนะของฉันสำหรับบางสิ่งบางอย่าง:set stab=4ก็ยังฟังดูดีสำหรับฉัน


ดูเหมือนว่าคุณมีคำถามสองข้อที่แตกต่างกันที่นี่บางทีคุณควรแยกคำถามออกเป็นสองข้อ
Greg Hewgill

คุณถูก! ฉันได้ย้ายคำถามที่สองเป็นหัวข้อของตัวเองแล้ว
nelstrom

1
ดูเหมือนว่าจะเป็น RFE มากกว่าคำถาม ดังนั้นคุณควรเสนอต่อชุมชน VIM: vim.org/community.phpหรือเขียนแพตช์ นอกจากนั้น VIM ยังมีสิ่งอำนวยความสะดวกมาโครมากมายที่ช่วยให้คุณกำหนดการดำเนินการใหม่ ๆ ได้ดังนั้นจึงมีโอกาสมากที่คุณจะสามารถสร้างมาโครที่ทำสิ่งที่คุณต้องการได้
kdgregory

@nelstrom ในเรื่องคำถามของคุณis there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, set shiftwidth=4 tabstop=8 noexpandtabเป็นกลุ่มของตัวเองใช้รหัสที่มา ใช่โดยทั่วไปแล้วใคร ๆ ก็ต้องการshiftwidth == softtabstopแต่ไม่ขึ้นอยู่กับสิ่งที่tabstopมีค่า
jamessan

คำตอบ:


56

การสร้างstabตัวเลือกใน Vim นั้นไม่ใช่เรื่องง่าย แต่ฉันได้รวบรวมคำสั่ง / ฟังก์ชันนี้ไว้ซึ่งคุณสามารถวางลงใน.vimrc(หรือไฟล์ปลั๊กอินได้หากคุณจัดระบบขั้นสูง) การใช้งานและคุณจะได้รับแจ้งสำหรับระดับเยื้องและหรือไม่ที่จะใช้:Stab expandtabหากคุณกด Enter โดยไม่ให้ระดับการเยื้องใหม่มันจะพิมพ์การตั้งค่าปัจจุบัน

"ใส่ทั้งหมดนี้ไว้ใน. vimrc หรือไฟล์ปลั๊กอิน
คำสั่ง! -nargs = * แทงโทรแทง ()
ฟังก์ชัน! แทง()
  ให้ l: tabstop = 1 * input ('set shiftwidth =')

  ถ้า l: tabstop> 0
    "เราต้องการ expandtab ด้วยหรือไม่?
    ให้ l: expandtab = confirm ('set expandtab?', "& Yes \ n & No \ n & Cancel")
    ถ้า l: expandtab == 3
      “ แท้ง?
      กลับ
    endif

    ให้ & l: sts = l: tabstop
    ให้ & l: ts = l: tabstop
    ให้ & l: sw = l: tabstop

    ถ้า l: expandtab == 1
      setlocal expandtab
    อื่น
      setlocal noexpandtab
    endif
  endif

  "แสดงตัวเลือกที่เลือก
  ลอง
    โหมดเสียงก้อง
    echon 'ตั้งค่า tabstop ='
    คำถาม echohl
    echon & l: ts
    โหมดเสียงก้อง
    echon 'shiftwidth ='
    คำถาม echohl
    echon & l: sw
    โหมดเสียงก้อง
    echon 'sts ='
    คำถาม echohl
    echon & l: sts. ''. (& l: et? '': 'ไม่')
    โหมดเสียงก้อง
    echon 'expandtab'
  ในที่สุด
    echohl ไม่มี
  พยายาม
สิ้นสุดการทำงาน

3
ขอบคุณสำหรับสคริปต์! มันทำได้มากกว่าที่ฉันขอ - ฉันคิดว่าฉันต้องการที่จะเก็บ expandtab เอาไว้ - แต่ฉันสามารถปรับแต่งได้ตามความต้องการของฉัน คุณได้จัดหาหลักสูตรความผิดพลาดเล็ก ๆ ใน Vimscript ฉันจึงรู้สึกขอบคุณมาก ค่าหัว 100 แต้มเป็นของคุณ!
nelstrom

9

นี่เป็นความพยายามครั้งแรกของฉันในการเขียน VimScript แต่ต่อไปนี้:

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

ถ้าฉันใส่ไว้ในไฟล์. vimrc ของฉันฉันสามารถเรียกมันได้โดยการเรียกใช้โดย:call Stab(X)ที่ X คือความกว้างของแท็บที่ต้องการ นี่เป็นวิธีแก้ปัญหาที่เพียงพอสำหรับตอนนี้ แต่ถ้าใครสามารถแนะนำวิธีการโทรได้ง่ายขึ้นฉันจะขอบคุณ

ฉันยังสร้างฟังก์ชันที่สรุปการตั้งค่าปัจจุบันอย่างรวดเร็วซึ่งฉันได้แมปกับ ctrl-Tab:

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

ฉันวางค่าหัว 100 คะแนนสำหรับคำตอบนี้และตอนนี้ฉันแก้มันไปแล้วครึ่งหนึ่ง ไม่แน่ใจว่ายอมรับคำตอบของตัวเองได้ไหม ...


+1 ใช่ แต่ถ้านี่คือสิ่งที่คุณต้องการจริงๆก็ยังเป็นคำตอบที่โอเค
DaveParillo

2
คุณอาจต้องการใช้ let & l: shiftwidth ฯลฯ เพื่อตั้งค่าเวอร์ชันท้องถิ่น
SystemParadox

7

คุณสามารถในโหมดแก้ไขยังใช้Ctrl-Tการเยื้องและCtrl-Dจะ deindent ถึงระดับเยื้องถัดไปเป็นชุดโดยshiftwidthไม่คำนึงถึงtabstop, softtabstopหรือexpandtabการตั้งค่า กลุ่มจะเพิ่ม / ลบช่องว่างหรือแท็บโดยอัตโนมัติเพื่อนำคุณไปยังคอลัมน์ด้านขวา

หากคุณใช้คำสั่งเหล่านี้เพื่อควบคุมการเยื้องแทนที่จะเป็นTab/ Backspaceคุณไม่ต้องกังวลเกี่ยวกับการตั้งค่าแท็บทั้งหมดเหล่านี้ให้เข้ากันและไปถึงระดับการเยื้องที่ถูกต้องเสมอ


3

หากexpandtabตั้งค่าไว้แล้ว (เนื่องจาก php ชี้ให้เห็นมากเกินไป) softtabstopจะซ้ำซ้อน เหตุผลเดียวที่คุณอาจตั้งค่าให้shiftwidthแตกต่างไปจากเดิมtabstopคือเพื่อรองรับนิสัยแปลก ๆ ตัวอย่างเช่นคุณใช้การเว้นวรรคสี่ช่อง แต่คุณต้องการtabแทรกช่องว่างแปดช่อง

หากexpandtabไม่ได้ตั้งค่าสิ่งต่างๆจะเลือนลาง หากคุณต้องการให้โค้ดของคุณมีลักษณะเหมือนกันกับcatตัวแก้ไขแบบกลุ่มและไม่ใช่แบบกลุ่มเหมือนในกลุ่มคุณtabstopควรตั้งค่าไว้ที่ 8 เสมอ ในกรณีนี้คุณจะตั้งค่าsofttabstopและshiftwidthทั้งสองเป็นระดับการเยื้องที่คุณต้องการ หากคุณต้องการให้ทุก "แท็บทางกายภาพ" ในไฟล์แทนระดับการเยื้องหนึ่งระดับคุณจะต้องตั้งค่าtabstopและshiftwidthเป็นระดับการเยื้องที่คุณต้องการและปล่อยไว้softtabstopที่ศูนย์ (การตั้งค่าให้เท่ากับเท่ากับtabstopยกเว้นว่าหากคุณเปลี่ยนแท็บtabstopจะไม่ซิงค์กัน ในขณะที่ศูนย์หมายถึง "ละเว้นสิ่งนี้โปรด")


3
ฉันคิดว่านี่ผิดเพราะเมื่อsofttabstopตั้งค่าเป็นค่าที่ถูกต้องเท่านั้น backspace จะลบการเยื้องที่เว้นระยะราวกับว่าเป็นแท็บ ซึ่งเป็นสิ่งจำเป็นสำหรับการใช้งานอย่างมีสติ
u0b34a0f6ae

2

คุณเข้าใจsofttabstopและexpandtabไม่ถูกต้อง - ดังนั้นstabตัวเลือกที่คุณแนะนำจะไม่มีประโยชน์มากนัก

expandtabสำหรับเมื่อคุณต้องการที่จะใช้ช่องว่างแทนแท็บสำหรับทุกอย่าง หากคุณตั้งค่าexpandtabVim จะไม่สนใจsofttabstopตัวเลือกและใช้tabstopและshiftwidthคำนวณจำนวนช่องว่างที่จะแทรก

softtabstopมีไว้สำหรับเมื่อคุณต้องการใช้การผสมผสานระหว่างแท็บและช่องว่างทำให้คุณสามารถเยื้องด้วยการควบคุมที่ดี (2 หรือ 4 ช่องว่าง) ในขณะที่รักษาความกว้างของแท็บไว้ที่ค่าที่สูงขึ้น (โดยปกติคือ 8) เพื่อให้ข้อความปรากฏในแอปพลิเคชันอื่น ๆ . การตั้งค่าsofttabstop=tabstopไม่ประสบความสำเร็จเพราะ Vim จะใช้แท็บสำหรับการเยื้องเสมอ

อัปเดต:ตามที่kaizer.seได้ระบุไว้หากคุณใช้expandtabงานคุณยังต้องตั้งค่าsofttabstopว่าคุณต้องการให้ Vim backspace หลายช่องว่างเหมือนกับว่าเป็นแท็บ


ในขณะที่คุณพูดถูกtabstopและsofttabstopกลายเป็นตัวแปรเดียวมากเกินไปเมื่อextpandtabตั้งค่าไว้ฉันคิดว่าคุณผิดลำดับความสำคัญ เพียงแค่ลอง: ตั้งค่าts=8 sts=4 etและกดแท็บ; ts=4 sts=0 etเคอร์เซอร์จะอยู่ในคอลัมน์ห้าและสี่ช่องว่างที่จะแทรกเช่นเดียวกับถ้าคุณได้ตั้ง
hobbs

5
ฉันคิดว่านี่ผิดเพราะเมื่อsofttabstopตั้งค่าเป็นค่าที่ถูกต้องเท่านั้น backspace จะลบการเยื้องที่เว้นระยะราวกับว่าเป็นแท็บ ซึ่งเป็นสิ่งจำเป็นสำหรับการใช้งานอย่างมีสติ
u0b34a0f6ae

2

คุณเปลี่ยนการตั้งค่าพื้นที่สีขาวบ่อยครั้งที่คุณต้องการฟังก์ชั่นในการจัดการหรือไม่? หากคุณยุ่งกับ tabstop มากและตั้งค่า expandtab ด้วยคุณอาจจะยุ่งอยู่ตลอดเวลาเมื่อคุณเปลี่ยนไฟล์ที่มีค่าstabต่างๆ วันนี้ฉันใช้:call stab (4)พรุ่งนี้มันเป็น:call stab (2)และสัปดาห์ที่:call stab (8)แล้ว ดูเหมือนแม้ว่าคุณจะเขียนมัน แต่คุณจะหยุดใช้ในไม่ช้า

หากคุณวางแผนที่จะส่งค่าเดียวกันไปแทงเสมอทำไมไม่เพียงแก้ไขการตั้งค่าส่วนกลางของคุณ ในกลุ่ม:

:e $MYVIMRC

และเพิ่มสิ่งต่อไปนี้:

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

นี่คือวิธีการตั้งค่า. vimrc ของฉัน


1

ตัวเลือกหนึ่งที่มีประโยชน์คือsofttabstop=-1จะตั้งค่าshiftwidthเป็น
คุณยังสามารถตั้งค่าshiftwidthเป็น 0 ซึ่งในกรณีนี้tabstopจะใช้ค่านี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.