จะแทนที่แท็บด้วยช่องว่างได้อย่างไร


85

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

เพียงแทนที่งานได้อย่างเป็นประโยชน์เมื่อไม่มีตัวอักษรนำ


หากคุณติดตั้งเป็นกลุ่มคำถามที่พบบ่อย , คุณจะได้รับคำตอบแบบออฟไลน์ที่นั่นและค้นหา:h vim-faq ยากที่จะจดจำแท็ก/tab characters :h faq-14.16
Hotschke

คำตอบ:


98

คุณสามารถใช้:retabคำสั่ง จาก :help :retab

แทนที่ลำดับทั้งหมดของ white-space ที่มี a <Tab>ด้วยสตริงใหม่ของ white-space โดยใช้ค่า tabstop ใหม่ที่กำหนด หากคุณไม่ได้ระบุขนาด tabstop ใหม่หรือเป็นศูนย์ Vim จะใช้ค่าปัจจุบัน'tabstop'เป็น [... ] 'expandtab'เมื่อเปิดเป็นกลุ่มจะแทนที่แท็บทั้งหมดด้วยจำนวนช่องว่างที่เหมาะสม

โปรดทราบว่าคำสั่งยอมรับช่วงเพื่อให้คุณสามารถเลือกภาพและจากนั้นเพียงแค่:retabบรรทัดที่เลือก


เย็น! ทำงานได้ง่ายและรวดเร็ว!
DenisKolodin

2
วิธีการเกี่ยวกับการให้ตัวอย่าง?
ปีเตอร์

23

อย่างไรก็ตามคุณสามารถใช้:retabตามที่ระบุไว้ซึ่งจะเปลี่ยนแท็บทั้งหมดเป็นช่องว่างไม่ใช่แค่แท็บที่จุดเริ่มต้นของบรรทัด

ดังนั้นนี่ ( ตัวอักษรของแท็บอยู่ที่ไหน):

if :; do
⇥echo "⇥hello"
end

ถูกเปลี่ยนเป็น (โดยที่อักขระเว้นวรรค):

if :; do
␣␣echo "␣␣hello"
end

สิ่งนี้สามารถสร้างผลข้างเคียงที่ไม่คาดคิดในบางสถานการณ์และเป็นปัญหามากขึ้นเมื่อเปลี่ยนช่องว่างเป็นแท็บ!

ดังนั้นฉันจึงเขียนฟังก์ชั่นเล็ก ๆ น้อย ๆ เพื่อเปลี่ยนเฉพาะแท็บ / ช่องว่างที่จุดเริ่มต้นของบรรทัด:

" :retab changes *everything*, not just start of lines
fun! Retab(expandtab)
    let l:spaces = repeat(' ', &tabstop)

    " Replace tabs with spaces
    if a:expandtab
        silent! execute '%substitute#^\%(' . l:spaces . '\)\+#\=repeat("\t", len(submatch(0)) / &tabstop)#e'
    " Replace spaces with tabs
    else
        silent! execute '%substitute#^\%(\t\)\+#\=repeat("' . l:spaces . '", len(submatch(0)))#e'
    endif
endfun

กับรุ่นนี้คุณต้องระบุด้วยตนเองexpandtabในการเรียกใช้ฟังก์ชัน (ie. :call Retab(1)เพื่อเปลี่ยนแท็บไปที่ช่องว่าง) แต่คุณยังสามารถปรับเปลี่ยนให้ใช้ค่าปัจจุบันของ&expandtab(มันไม่อยู่แล้วด้วย&tabstop) เช่นเดียว:retabไม่ (ฉันบังเอิญต้องการระบุด้วยตนเอง)


6
นอกจากนี้ยังมีคำตอบสำหรับ SOที่ครอบคลุมการรีแท็บที่จุดเริ่มต้นของบรรทัดเท่านั้น มันคุ้มค่าที่จะเชื่อมโยงเพราะความชัดเจนของคำอธิบายนั้น
jalanb

ใครสามารถอธิบายสิ่งที่ไม่ตัวอักษรaในif a:expandtabหมายถึง?
john cj

นอกจากนี้ดูเหมือนว่าเงื่อนไขจะกลับรายการ (เป็นเรื่องตลก: D?) หากคุณมีset expandtab. vimrc และจากนั้นautocmd BufWritePre * :call Retab(&expandtab)- การเยื้องจะเปลี่ยนเป็นแท็บแทนที่จะเว้นวรรค
john cj

11

Vim จัดเตรียม!retabคำสั่งซึ่งจะแทนที่ลำดับทั้งหมด<Tab>ด้วยสตริงใหม่ของ white-space โดยใช้ค่า tabstop ใหม่ (เช่น:set tabstop=2) ที่กำหนด แต่แท็บทั้งหมดภายในสตริงสามารถแก้ไขได้ (เช่นในโปรแกรม C คุณควรใช้\tเพื่อหลีกเลี่ยงสิ่งนี้)!

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

:%s/\t/  /g

หรือตามที่แนะนำโดย@Shahbaz :

:%s/^\t\+/ g

ดังนั้นแท็บที่ใช้ในการเยื้องเท่านั้นจึงถูกแปลง

คำอธิบาย:

  • %แสดงถึงบัฟเฟอร์ / ไฟล์ทั้งหมด ( :help :%)
  • sย่อมาจากทดแทน ( :help sub-replace-special)
  • \tหรือ^Iย่อมาจากแท็บ
  • - ใช้ช่องว่างมากเท่าที่คุณต้องการต่อหนึ่งแท็บ
  • g - ย่อมาจากทั่วโลกและมันจะแปลงแท็บหลายรายการในบรรทัดเดียวกัน

gg=Gจากนั้นในการแก้ไขการเยื้องของไฟล์ทั้งหมดที่คุณอาจลอง: ตรวจสอบ: การเยื้องรหัสเยื้องที่ไม่ดีสำหรับรายละเอียดเพิ่มเติม

หากต้องการใช้ช่องว่างเป็นค่าเริ่มต้นแทนที่จะเป็นแท็บคุณจะต้องเพิ่มการตั้งค่าต่อไปนี้ใน.vimrcไฟล์ของคุณ:

set tabstop=2     " (ts) width (in spaces) that a <tab> is displayed as
set expandtab     " (et) expand tabs to spaces (use :retab to redo entire file)
set shiftwidth=2  " (sw) width (in spaces) used in each step of autoindent (aswell as << and >>)

โซลูชันทางเลือกคือการใช้ tidy


ที่เกี่ยวข้อง:


1
อย่างน้อยฉันจะทำอย่าง%s/^\t\+/ gนั้นเฉพาะแท็บที่ใช้ในการเยื้องเท่านั้นที่จะถูกแปลง นอกจากนี้gg=Gอาจเป็นความหายนะกับภาษาเช่นหลาม
Shahbaz

3

ลองใช้:

expand -t 4 input_filename output_filename

expand:!expandเป็นเครื่องมือบรรทัดคำสั่งเพื่อแปลงแท็บไปที่ช่องว่างซึ่งคุณสามารถเรียกใช้จากเปลือกหรือ

มันอยู่ใน POSIXดังนั้นจึงควรมีอยู่ในระบบส่วนใหญ่ unexpandจะทำสิ่งที่ตรงกันข้ามโดยวิธี


2
คือexpandอะไร
muru

Expand เป็นคำสั่งเทอร์มินัล inbuilt เพื่อคัดลอกอักขระแท็บไปยังช่องว่าง กรุณาหารายละเอียดการแยกแยะในลิงค์ต่อไปนี้ computerhope.com/unix/uexpand.htm
Ankit Shah

2
หากคำสั่งเหล่านี้เป็นคำสั่งภายนอกคุณควรระบุไว้
muru

เพิ่มคำอธิบายเพิ่มเติม โปรดตรวจสอบ
Ankit Shah

5
นอกจากนี้คุณยังสามารถทำ:%!expand -t 4ภายในของกลุ่ม ยิ่งไปกว่านั้นคุณยังสามารถใช้ตัวเลือกความกว้างของการเลื่อนปัจจุบัน: :exe '%!expand -t ' . &shiftwidth
EvergreenTree

1

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

  • ในโหมด Visual บุคคลเดียว=จะแก้ไขการเยื้องของบล็อกรหัสที่เลือก
  • ในโหมดปกติgg=Gจะแก้ไขไฟล์ทั้งหมดซึ่งggจะย้ายเคอร์เซอร์ไปที่ตำแหน่งเริ่มต้นของไฟล์จากนั้น=นำไปใช้และGย้ายเคอร์เซอร์ไปที่ท้ายไฟล์

อ้างอิง: ลิงค์


สิ่งนี้ถือว่าเป็นกลุ่มสามารถคำนวณการเยื้องในปัจจุบันได้อย่างถูกต้อง(อาจไม่ใช่กรณี) - สำหรับไฟล์ที่ไม่มีโครงสร้างหรือรหัสที่เขียนในโปรแกรมแก้ไขที่แตกต่างกับกฎการเยื้องที่แตกต่างกันเล็กน้อย
ideasman42

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