คำอธิบายที่เป็นไปได้ของปัญหา
ฉันคิดว่าเหตุผลที่ทำไม:g/;/j
ไม่ทำงานเป็นเพราะ:g
คำสั่งทำงานด้วยอัลกอริทึม 2 รอบ:
- ในช่วงแรกที่ผ่านมันทำเครื่องหมายเส้นที่มีรูปแบบ
;
- ในระหว่างรอบที่สองมันทำงานบนเส้นที่ทำเครื่องหมายไว้
ในระหว่างรอบที่สอง:g
เข้าร่วมสาย1;
กับสาย2;
เพราะ1;
ถูกทำเครื่องหมายในระหว่างรอบแรก อย่างไรก็ตามฉันสงสัย (ไม่แน่ใจ) ว่ามันไม่ได้เข้าร่วม1; 2;
ด้วย3;
เพราะ2;
ไม่มีอีกต่อไปแล้วเนื้อหาของมันถูกรวมเข้ากับบรรทัด1;
ที่ได้รับการประมวลผลแล้ว
ดังนั้น:g
มองหาบรรทัดถัดไปซึ่งถูกทำเครื่องหมายระหว่างการผ่านครั้งแรก ( 3;
) และรวมกับหนึ่งบรรทัดต่อไปนี้ ( 4;
) หลังจากนั้นซ้ำปัญหาก็ไม่สามารถเข้าร่วม3; 4;
ด้วย5;
เพราะสาย4;
ไม่อยู่อีกต่อไป
โซลูชันที่ 1 (พร้อม vimscript)
บางทีคุณอาจเรียกฟังก์ชันเมื่อใดก็ตามที่;
พบบรรทัดที่มีเพื่อตรวจสอบว่าบรรทัดก่อนหน้ามีอัฒภาคอยู่หรือไม่:
function! JoinLines()
if getline(line('.')-1) =~ ';'
.-1join
endif
endfunction
จากนั้นใช้คำสั่งโกลบอลต่อไปนี้:
:g/;/call JoinLines()
หรือไม่มีฟังก์ชั่น:
:g/;/if getline(line('.')-1) =~ ';' | -j | endif
โซลูชันที่ 2 (ไม่มี vimscript)
:g/;/.,/^[^;]*$/-1j
เมื่อใดก็ตามที่คำสั่ง global :g
พบรูปแบบ;
มันจะรันคำสั่ง: .,/^[^;]*$/-1j
มันสามารถถูกทำลายลงเช่นนี้
:g/pattern/a,bj
ที่ไหน:
pattern = ;
a = . = number of current line
b = /^[^;]*$/-1 = number of next line without any semicolon minus one
b
สามารถแยกย่อยได้มากขึ้นเช่นนี้
/ = look for the number of the next line matching the following pattern
^ = a beginning of line
[^;] = then any character except a semicolon
* = the last character can be repeated 0 or more times
$ = an end of line
/ = end of pattern
-1 = removes one to the number you just got
j
เป็นรูปแบบย่อของคำสั่ง Ex :join
ซึ่งเหมือนกับคำสั่ง Ex อื่น ๆ ส่วนใหญ่สามารถนำหน้าด้วยช่วง
ที่นี่มันนำหน้าด้วยช่วง: .,/^[^;]*$/-1
( a,b
)
ช่วงต่อจากรูปแบบa,b
ที่a
และb
โดยทั่วไปคือหมายเลขบรรทัด 2 และช่วยให้คุณสามารถทำงานกับกลุ่มของเส้นที่มีจำนวนอยู่ระหว่างa
และb
แทนที่จะเป็นเพียงหนึ่ง
ดังนั้นj
คำสั่งจะรวมบรรทัดทั้งหมดระหว่างหนึ่งบรรทัดปัจจุบัน ( a
) และบรรทัดถัดไปที่ไม่มีเซมิโคลอนใด ๆ ลบหนึ่ง ( b
)
สำหรับข้อมูลเพิ่มเติมดู:
:help :global
:help :join
:help :range
:g/;/j
ไม่ทำงานเพราะทำในสองรอบ: ก่อนสแกนบัฟเฟอร์แล้วคำสั่งจะถูกนำไปใช้กับบรรทัดที่ตรงกัน