เปลี่ยนการเยื้อง 2 ช่องว่างเป็น 4 ช่องว่างในกลุ่ม


93

ฉันคัดลอกรหัสมาจากอินเทอร์เน็ตที่มีการเยื้อง 2 ช่องว่างและฉันต้องการเปลี่ยนเป็นการเยื้อง 4 ช่องว่าง ฉันสงสัยว่ามีกิจวัตรกลุ่มสั้น ๆ เพื่อให้งานสำเร็จโดยไม่ต้องเขียน vim script หรือไม่ นี่คือวิธีที่ฉันกำลังทำกับไฟล์ HTML:

  • บันทึกมาโคร
  • ไปที่จุดเริ่มต้นของบรรทัด
  • ภาพเลือกช่องว่างทั้งหมดจนกระทั่งเกิด "<" ครั้งแรก
  • ดึงและวางช่องว่างทั้งหมด (โดยทั่วไปเพื่อเพิ่มเป็นสองเท่า)
  • เล่นมาโครซ้ำจนจบไฟล์

ในระยะสั้น qa0vt<yp<esc>jq

หลุมพราง:

มาโครล้มเหลวสำหรับบรรทัดว่างหรือบรรทัดที่ไม่ได้ขึ้นต้นด้วย "<" และฉันไม่รู้ว่าจะขยายโซลูชันนี้ไปยังไฟล์ที่ไม่ใช่ HTML ได้อย่างไร

คำตอบ:


175

วิธีทั่วไปในการเปลี่ยนการเยื้องคือการเปลี่ยนแท็บสต็อป:

วางไฟล์ของคุณลงในบัฟเฟอร์ว่างจากนั้น:

:set ts=2 sts=2 noet
:retab!

สิ่งนี้จะเปลี่ยนทุกๆ 2 ช่องว่างเป็นอักขระ TAB จากนั้น:

:set ts=4 sts=4 et
:retab

สิ่งนี้จะเปลี่ยนทุก TAB เป็น 4 ช่องว่าง

ข้อดีของวิธีนี้คือคุณสามารถใช้วิธีอื่นเพื่อแปลงจาก 4 เป็น 2 ช่องว่างได้เช่นกัน


16
@ XavierT ฉันคิดว่าคำตอบนี้ค่อนข้างเข้าใจง่าย และบางทีมันอาจจะมีความชัดเจนมากขึ้นถ้าชื่อคำสั่งสั้น ๆ แทนที่ด้วยชื่อเต็มของพวกเขา: ts= tabstop, sts= softtabstopและ=[no]et [no]expandtab
YaOzI

retabข้อโต้แย้งของสถานการณ์ใดจะเป็นประโยชน์และเหตุใดเราจึงไม่สามารถใช้กับงานนี้ได้
joeytwiddle

@joeytwiddle ขณะที่ผมเข้าใจว่าคุณสามารถใช้และบรรลุผลเช่นเดียวกับคำตอบนี้โดยใช้:set sts=2 noetและ:retab! 2ดังนั้นมันจะเป็นบิตสั้น (แม้ว่าอาจจะอ่านได้น้อยลง) วิธีการที่
Daan Bakker

วิธีนี้ยังเปลี่ยน 2 ช่องว่างเป็น 4 ช่องว่างภายในตัวอักษรสตริงและตำแหน่งอื่น ๆ แทนที่จะเป็นแค่จุดเริ่มต้นของบรรทัด
นาคออกเดินทาง

3
รวมทั้งหมดเข้าด้วยกัน: :set ts=2 sts=2 noet | retab! | set ts=4 sts=4 et | retab!จากนั้นใช้@:ในไฟล์ต่างๆเพื่อใช้การกระทำเดียวกันอย่างรวดเร็ว
L__

59

มันอาจจะเป็นไปได้ด้วยและ:set shiftwidth=4gg=G


โปรดทราบว่าหากไม่ได้ผลคุณอาจเปิดใช้งานโหมดที่มีผลกระทบอื่น ๆ ต่อการเยื้อง
Dav Clark

1
แม้ว่าคำถามจะไม่เกี่ยวกับวิธีแก้ปัญหาทั่วไป แต่โปรดทราบว่าวิธีนี้ใช้ไม่ได้เสมอไปโดยเฉพาะกับรหัส python
0xc0de

5
อะไรgg=Gหมายถึง exatly? ฉันเข้าใจว่าggหมายถึง "ย้ายไปที่ 1,1" และGหมายถึง "ย้ายไปที่บรรทัดสุดท้าย"
Jonathon Reinhart

5
@JonathonReinhart =ทำการเยื้องดังนั้นจึงหมายถึงการเยื้องตั้งแต่ต้นจนจบข้อความ
alex

ทำงานได้ดีกว่า%retabซึ่งแปลงช่องว่างที่ฝังอยู่ภายในตัวอักษรสตริงอย่างไม่ถูกต้อง
Alnitak

34

สิ่งที่ฉันทำคล้ายกับแนวทางของ esneider และ cforbish มาก แต่พิมพ์เร็วกว่าเล็กน้อย:

:%s/^\s*/&&

เพียงแทนที่ช่องว่างนำหน้า (ช่องว่างหรือแท็บ) ด้วยช่องว่างนำหน้าเป็นสองเท่า ( &แทนที่ด้วยนิพจน์ที่ตรงกัน)


2
สิ่งนี้มีประโยชน์เพราะใช้งานได้กับการเลือกภาพ (V) เพียงแค่วางไฟล์%.
Trevor Robinson

1
ฉันชอบอันนี้เช่นกัน b / c มันไม่ยุ่งกับการจัดตำแหน่งตารางด้วยตนเองใด ๆ ที่ฉันมีในความคิดเห็นเป็นต้น
stephenmm

@TrevorRobinson คำตอบสองอันดับแรกใช้ได้กับช่วง
Brian McCutchon

นอกจากนี้ยังมีประโยชน์เพิ่มเติมที่คุณสามารถขยายออกเพื่อใช้sedและนำไปใช้กับไฟล์ทั้งหมดในไดเรกทอรีsuperuser.com/a/159286/41494
icc97

3

ฉันใช้นิพจน์ทั่วไปนี้ (เพิ่มจำนวนช่องว่างนำหน้าเป็นสองเท่า):

%s;^\(\s\+\);\=repeat(' ', len(submatch(0))*2);g

ไม่%s/\s\+/&&/ทำแบบเดียวกัน? Btw ฉันคิดว่าgธงไม่จำเป็น (สำหรับหนึ่งจะมีการแข่งขันเพียง 1 ครั้ง^patternในทุกบรรทัดไม่?)
doubleDown

ขอขอบคุณที่ชี้ให้เห็น '&' ฉันมีการแก้ไขเล็กน้อยสำหรับของคุณส่วนใหญ่เนื่องจากคุณลืม '^' %s/^\s\+/&&/gอยู่ใกล้กว่า
cforbish

1
สิ่งนี้คล้ายกับคำตอบของ spro แต่ฉันขอขอบคุณคำตอบที่ช่วยให้คุณสามารถทำได้ง่ายขึ้นสองครั้งหากคุณต้องการทำบางสิ่งที่ซับซ้อนขึ้นเล็กน้อย
stephenmm

3

นี่เป็นคำถามเก่ามาก แต่คำตอบทั้งหมด ... ผิด ... Vim มีวิธีที่ง่ายมากในการย้อนกลับไฟล์ทั้งหมด ฉันเรียนรู้สิ่งนี้หลังจากเขียนฟังก์ชันของตัวเองที่จะทำดังนั้นฉันจึงอยู่ในเรือที่ไม่รู้เหมือนกัน;)

ชนิด

gg=G

นี่คือสมมติว่าคุณตั้งค่าแท็บสต็อปเป็นสิ่งที่คุณต้องการ (ดังนั้นสำหรับ OP จะเป็น ts = 4)

ฉันเรียนรู้สิ่งนี้จากhttp://vim.wikia.com/wiki/Fix_indentationซึ่งกล่าวถึง

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


2
1. หากคุณเลื่อนลงไปจนสุดคุณจะเห็นคำตอบที่ระบุว่า gg = G 2. มันไม่ได้ผลเสมอไป
Lim H.

1

คล้ายกัน (แต่ค่อนข้างง่ายกว่า) กับคำตอบของ cforbish regex นี้จะทำซ้ำช่องว่างนำหน้า

:%s/^\( \+\)/\1\1

หรือคุณสามารถใช้ regex อื่นนี้เพื่อเปลี่ยนช่องว่าง 2 ช่องเป็น 4 ช่องว่างโดยคงช่องว่างเดียว (และจำนวนคี่โดยทั่วไป)

:%s/^\(\(  \)\+\)/\1\1

นั่นคือ,

  • 1 ช่อง⇢ 1 ช่อง
  • 2 คัน⇢ 4 คัน
  • 3 ช่อง⇢ 5 ช่อง
  • 4 ช่อง⇢ 8 ช่อง

1

นอกจากคำตอบของ @ spro แล้วฉันยังใส่สิ่งนี้ไว้ในไฟล์ .vimrc

command! -range=% Format :<line1>,<line2>s/^\s*/&&

:Formatเพียงพิมพ์

ด้วยการเลือกภาพสิ่งนี้จะจัดรูปแบบเฉพาะเส้นที่เลือก

หากไม่มีการเลือกภาพสิ่งนี้จะจัดรูปแบบทั้งไฟล์


0

นี่คือตัวแปรของคำตอบที่อิงตามนิพจน์ทั่วไป

ฉันมีสคริปต์ทุบตีในไดเร็กทอรี bin ในเครื่องของฉันซึ่งจะเพิ่มช่องว่างเป็นสองเท่าที่จุดเริ่มต้นของบรรทัด อินพุตสามารถเป็น stdin หรือไฟล์:

$ cat ~/bin/dblsp
#!/bin/bash

file=${1--}

while IFS= read -r line; do
    echo "$line" | sed 's/\s*/&&/'
done < <(cat -- "$file")

ฉันใช้สิ่งนี้ภายในกลุ่มโดยการเลือกบรรทัดด้วยสายตาและออกคำสั่งต่อไปนี้:

:'<,'>!dblsp

สิ่งนี้ช่วยให้ฉันไม่ต้องพิมพ์ (หรือจำ) regex

ฉันยังใช้ในแผนที่ดังต่อไปนี้:

nnoremap <leader>] `[V`]!dblsp<CR>

ซึ่งจะนำไปใช้กับบล็อกของข้อความที่เพิ่งวาง ฉันมักจะใช้แผนที่ต่อไปนี้ในการวางมากกว่า:set paste

nnoremap <leader>p :r !xclip -o<CR>

ขั้นตอนการทำงานปกติของฉันคือ:

  • เลือกข้อมูลโค้ด (เช่นโค้ดตัวอย่างในหน้านี้คือ 2 ช่องว่าง แต่ฉันต้องการ 4)
  • วางข้อมูลโค้ด (, p)
  • เปลี่ยนระยะห่าง (,])

หรือเพียงแค่เปลี่ยนการเยื้องบนบล็อกที่ดึงมาจากบัฟเฟอร์อื่น

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