วิธีการตั้งค่า Vim ให้ทำงานกับหนึ่งประโยคต่อหนึ่งบรรทัด?


17

ตอนนี้ฉันกำลังเขียนข้อความธรรมดาจำนวนมาก (และ LaTeX ที่มีการจัดรูปแบบน้อยที่สุดในย่อหน้า) และมันจะดีถ้าฉันสามารถตั้งค่ากลุ่มเพื่อรักษาแต่ละประโยค (สำหรับความเรียบง่ายข้อความถูกยกเลิกด้วย '.', '!' , หรือ '?'; นั่นคือเครื่องหมายวรรคตอนยุติแล้วตามด้วยช่องว่างเพื่อหลีกเลี่ยงการแบ่งจำนวนทศนิยม) ในบรรทัดของตัวเองเพื่อให้ VCS diffs จะมีประโยชน์มากขึ้น

น้อยที่สุดฉันต้องการจัดgqรูปแบบข้อความจาก:

He lay flat on the brown, pine-needled floor of the forest, his chin on his
folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he
could see the dark of the oiled road winding through the pass. There was a
stream alongside the road and far down the pass he saw a mill beside the
stream and the falling water of the dam, white in the summer sunlight. 

ถึง:

He lay flat on the brown, pine-needled floor of the forest, his chin on his folded arms, and high overhead the wind blew in the tops of the pine trees.
The mountainside sloped gently where he lay; but below it was steep and he could see the dark of the oiled road winding through the pass.
There was a stream alongside the road and far down the pass he saw a mill beside the stream and the falling water of the dam, white in the summer sunlight.

แต่มันจะดีถ้ากลุ่มจะดำเนินการจัดรูปแบบนี้ในขณะที่ฉันพิมพ์ (เช่นเดียวกับ text reflow) เป็นไปได้ไหม

ทางออกปัจจุบันของฉันคือเข้าร่วมย่อหน้าด้วยJจากนั้นเรียกใช้:'<,'>s/\. /.\r/gซึ่งค่อนข้างดีเนื่องจากมีเครื่องหมายอัศเจรีย์และเครื่องหมายคำถามอยู่เล็กน้อย แต่จะดีกว่ามากถ้าฉันสามารถทำให้ gq ฉลาดขึ้นเล็กน้อย

คำตอบ:


23

'formatexpr'ตัวเลือก

คุณสามารถทำได้โดยใช้'formatexpr'ตัวเลือก จากความช่วยเหลือ:

นิพจน์ที่ถูกประเมินเพื่อจัดรูปแบบช่วงของบรรทัดสำหรับตัวดำเนินการ gq หรือการจัดรูปแบบอัตโนมัติ (ดูที่ 'การจัดรูปแบบตัวเลือก') เมื่อตัวเลือกนี้ไม่มีข้อมูล 'formatprg' จะถูกใช้

การตั้งค่าของคุณ'formatexpr'อย่างถูกต้องจะทำงานทั้งเมื่อใช้gqและในขณะที่แทรกข้อความ

ตัวอย่างง่ายๆ

นี่คือฟังก์ชั่น VimScript ที่เรียบง่ายและ'formatexpr'ค่าที่สอดคล้องกันซึ่งควรทำงาน ฉันยังไม่ได้ทดสอบกับกรณีขอบทั้งหมด แต่ก็ใช้งานได้ดีสำหรับการทดสอบอย่างง่ายของฉัน

function! MyFormatExpr(start, end)
    silent execute a:start.','.a:end.'s/[.!?]\zs /\r/g'
endfunction

set formatexpr=MyFormatExpr(v:lnum,v:lnum+v:count-1)

คำอธิบาย

นิพจน์คือการเรียกใช้ฟังก์ชันMyFormatExpr()ส่งผ่านในบรรทัดเริ่มต้นและสิ้นสุดที่การจัดรูปแบบจะถูกนำไปใช้ บรรทัดเหล่านี้จะคำนวณโดยใช้ตัวแปรที่มีประชากรอัตโนมัติv:lnum(บรรทัดแรกที่จะจัดรูปแบบ) และv:count(จำนวนบรรทัดที่จะจัดรูปแบบ)

MyFormatExpr()ฟังก์ชั่นโครงสร้าง:substituteคำสั่งกับที่ผ่านมาในช่วงและแทนที่ช่องว่างต่อไปนี้เครื่องหมายวรรคตอนปลายของประโยค ( ., !หรือ?) ด้วยการขึ้นบรรทัดใหม่ ( \r)

คำเตือน

  • MyFormatExpr()ฟังก์ชั่นไม่ได้รักษาเยื้องชั้นนำ จำเป็นต้องใช้ตรรกะที่ซับซ้อนกว่านี้เพื่อแก้ไขปัญหานั้น
  • อาจมีกรณีขอบอื่น ๆ ที่สิ่งนี้แตกสลาย ทดลองขับและปรับแต่งตามความจำเป็น!

อ๋อใช่แล้วนี่เป็นหนทางไปทั้งหมดละเว้นคำตอบของฉัน
Sukima

นี่มันเจ๋งมาก! สิ่งที่ฉันหวังว่าฉันจะทำได้คือให้ฟังก์ชันเรียกใช้แมโครอย่างเช่น "ก้าวไปข้างหน้ากับประโยคถัดไป)และแทรกบรรทัดใหม่ทำซ้ำจนกว่าคุณจะถึงจุดสิ้นสุดของช่วง" จากนั้นจะใช้กฎการเยื้องใด ๆ แต่ Vim-fu ของฉันอ่อนแอเกินไปสำหรับสิ่งนั้น :)
นาธานลอง

นี่เป็นการแยกเช่นe.g. blahและBlah et al. 2018น่ารำคาญเล็กน้อย 's/\(e\.g\|\<al\)\@<![.!?]\zs /\r/g'คุณสามารถยกเลิกรูปแบบการแข่งขันเช่นนั้นกับสิ่งที่ต้องการ เพียงเพิ่มรูปแบบเพิ่มเติมในกลุ่มแรกเพื่อหลีกเลี่ยงสิ่งอื่นที่คุณไม่ต้องการแยก มิฉะนั้นมันจะมีประโยชน์มากขอบคุณ ฉันไม่เคยเจอมาgqก่อนและgqipมีประโยชน์อย่างยิ่งสำหรับการจัดรูปแบบข้อความที่ผู้แก้ไขข้อความของผู้เขียนร่วมมีปัญหา
naught101

มีวิธีเพิ่มพฤติกรรมนี้ในพฤติกรรมเริ่มต้นหรือไม่ ฉันต้องการที่จะสามารถที่จะตัดความกว้างที่ข้อความที่กำหนดเช่นเดียวกับการแยกในตอนท้ายของประโยค ..
naught101

1

คุณสามารถตั้งค่าแผนที่และบันทึกอัตโนมัติได้บ้าง:

function! AddSentenceMaps()
  imap .<Space> .<CR>
  imap !<Space> !<CR>
  imap ?<Space> ?<CR>
  exec "nmap gq vipJ:s/\\([.!?]\\)\\s\\+/\\1\\r/g<CR>"
endfunction

autocmd Filetype customtxt call AddSentenceMaps()

จากนั้นเพียงตั้งประเภทไฟล์เป็น customtxt หรือเรียกใช้AddSentenceMapsฟังก์ชันด้วยตนเอง


0

ฉันต้องการเพิ่มความคิดเกี่ยวกับปัญหานี้ โดยปกติแล้วผู้คนต้องการคุณสมบัติประเภทนี้เพราะกระโดดข้ามเส้นที่ห่อเมื่อคนนำทางผ่านรหัสด้วยjและkคำสั่งซึ่งเป็นพฤติกรรมเริ่มต้นของ Vim สำหรับการนำทางผ่านเส้นที่พันผมใช้gj- เลื่อนลงและgk- เลื่อนขึ้น นอกจากนี้ยังมีความเป็นไปได้ทำการแมปใหม่มาตรฐานjและkคำสั่งในคู่ของ g-prefixed แต่ IMHO มันจะ overkill


หรือมีกุญแจสำคัญในการทำเช่นนั้น remaping jและkไปยังgjและgkเมื่อคุณต้องการมัน ;-) #
anthony

0

ไม่ตอบคำถามเฉพาะของคุณเกี่ยวกับการจัดรูปแบบใหม่ แต่ 'set wrap' พร้อมกับ 'set linebreak' สามารถทำให้การแก้ไขบรรทัดยาวน่าพอใจยิ่งขึ้น รวมสิ่งนี้กับ gj และ gk เพื่อนำทางภายในบรรทัดที่ถูกห่อ ฉันแมปลูกศรขึ้นและลงเพื่อ gj และ gk ตามลำดับเพื่อให้ฉันมีทางเลือกระหว่างการเลื่อนขึ้นและลงของเส้นจริงหรือเส้นภาพ อย่างชาญฉลาดสำหรับบ้าน / สิ้นสุดถึง g0 / g $

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