ฉันจะแทรกเส้นแบ่งโดยที่เคอร์เซอร์อยู่โดยไม่เข้าสู่โหมดแทรกใน Vim ได้อย่างไร


89

เป็นไปได้ไหมที่จะแทรกตัวแบ่งบรรทัดโดยที่เคอร์เซอร์อยู่ใน Vim โดยไม่ต้องเข้าสู่โหมดแทรก นี่คือตัวอย่าง ( [x]หมายถึงเคอร์เซอร์เปิดอยู่x):

if (some_condition) {[ ]return; }

ในบางครั้งฉันอาจต้องการป้อนรหัสเพิ่มเติม ผมจะกดiเพื่อเข้าสู่โหมดแทรกกดEnterเพื่อแทรกตัวแบ่งบรรทัดแล้วลบช่องว่าง ต่อไปฉันจะเข้าสู่โหมดปกติและวางเคอร์เซอร์ก่อนวงเล็บปีกกาปิดจากนั้นทำสิ่งเดียวกันเพื่อให้มันอยู่ในบรรทัดของตัวเอง

ฉันทำมาระยะหนึ่งแล้ว แต่มีวิธีที่ดีกว่านี้แน่ ๆ ?


คุณต้องการแทรกบางสิ่งโดยไม่ต้องเข้าสู่โหมด INSERT?
Jeremy Cantrell

26
@ jeremy-cantrell ใช่เหมือน "J" เข้าร่วมบรรทัดถัดไปและแทรกช่องว่างโดยไม่ต้องเข้าสู่โหมด INSERT!
awendt

คำตอบ:


108

สำหรับตัวอย่างที่คุณให้ไว้คุณสามารถใช้rEnterเพื่อแทนที่อักขระเดี่ยว (ช่องว่าง) ด้วย Enter จากนั้นfspace.เพื่อไปยังช่องว่างถัดไปและทำซ้ำคำสั่งสุดท้าย

ขึ้นอยู่กับการตั้งค่าการระบุอัตโนมัติของคุณข้างต้นอาจเยื้องคำสั่ง return อย่างถูกต้องหรือไม่ก็ได้ ถ้าไม่เช่นนั้นใช้sEnterTabEscแทนเพื่อแทนที่ช่องว่างด้วยการขึ้นบรรทัดใหม่เยื้องบรรทัดและออกจากโหมดแทรก คุณจะต้องแทนที่ช่องว่างที่สองด้วยคำสั่งอื่นดังนั้นคุณจึงไม่สามารถใช้ "." ในกรณีนี้.


1
ฉันคิดว่านี่เป็นทางออกที่ง่ายที่สุด ขอบคุณ Greg
Mark A. Nicolosi

4
'f [space]' ควรจะเทียบเท่ากับ 'W' (เช่นย้ายไปที่ whitepsace ถัดไป)
Nathan Fellman

4
'W' ย้ายอักขระหนึ่งตัวไปไกลเกินไปมันจะย้ายไปยังอักขระถัดไปหลังจากเว้นวรรคถัดไป
Greg Hewgill

1
นอกจากนี้คุณยังสามารถใช้>>และช่วยเยื้องถ้าคุณไม่ต้องการที่จะเข้าสู่โหมดแทรกด้วย<< s
Conner

12

วิธีสร้างมาโครที่แทรกขึ้นบรรทัดใหม่ที่เคอร์เซอร์เมื่อใดก็ตามที่คุณกด 'g' ในขณะที่ไม่ได้อยู่ในโหมดแทรก:

จากภายในกลุ่มให้พิมพ์:

:map g i[Ctrl+V][Enter][Ctrl+V][Esc][Enter]

ที่ไหน:

  • [Ctrl + V] หมายถึงกดปุ่ม Ctrl ค้างไว้แล้วกด 'v'
  • [Enter] หมายถึงกดปุ่ม Enter
  • [Esc] หมายถึงกดแป้น Esc

คุณจะเห็นสิ่งต่อไปนี้ที่ด้านล่างของหน้าต่างกลุ่มจนกว่าคุณจะกด Enter สุดท้าย:

:map g i^M^[

คำอธิบาย:

[Ctrl + V] หมายถึง "อ้างอิงอักขระต่อไปนี้" - ช่วยให้คุณสามารถฝังอักขระขึ้นบรรทัดใหม่และอักขระ Escape ในคำสั่งได้

ดังนั้นคุณกำลังจับคู่คีย์ 'g' กับลำดับ:

ฉัน [Enter] [Escape]

นี่คือเป็นกลุ่มสำหรับแทรกขึ้นบรรทัดใหม่ก่อนเคอร์เซอร์แล้วออกจากโหมดแทรก

ปรับแต่ง:

  • คุณสามารถแทนที่ 'g' ด้วยอักขระใด ๆ ที่ยังไม่ได้เชื่อมโยงกับคำสั่งที่คุณใช้
  • เพิ่มคำสั่งให้มากขึ้นเช่น f}i^M^[O - นี่จะf ind the }และi nsert ขึ้นบรรทัดใหม่จากนั้นออกจากโหมดแทรกและOปากกาบรรทัดว่างให้คุณป้อนรหัสเพิ่มเติม
  • คุณสามารถเพิ่มคำสั่งลงในไฟล์. vimrc หรือ. exrc ของคุณเพื่อทำให้เป็นไฟล์ถาวร เพียงเว้นเครื่องหมายจุดคู่ไว้ตั้งแต่ต้นดังนั้นคำสั่งจึงเริ่มต้นด้วย "map"

สนุก!


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

ขอบคุณ. อัปเดตส่วน "Tweaks" เพื่อให้บรรลุสิ่งที่ (ฉันคิดว่า) ผู้เขียนร้องขอ เมื่อฉันทดสอบ vi จะลบช่องว่างส่วนเกินให้ฉันโดยอัตโนมัติ ใช้ 'x' เพื่อลบหากคุณไม่ทำ แล้วทำไมคำสั่ง vi จึงดูเหมือนสัญญาณรบกวนของสายโมเด็ม? :-)
Adam Liss

11

การแมปง่ายๆเพื่อทำลายเส้นที่เคอร์เซอร์โดยกด Ctrl + Enter:

:nmap <c-cr> i<cr><Esc>

เข้าสู่โหมด 'แทรก' เป็นหลักแทรกตัวแบ่งบรรทัดและกลับสู่โหมดปกติ

ใส่ไว้ในไฟล์. vimrc ของคุณเพื่อใช้ในอนาคต


5

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

คำสั่งสำหรับการแทนที่วงเล็บ / return สำหรับวงเล็บมีลักษณะดังนี้:

:s/{/{\r/

เนื่องจากคุณต้องการใช้สิ่งนี้บ่อยๆคุณสามารถแมปลำดับแบบเต็มกับการกดแป้นพิมพ์ที่ไม่ได้ใช้ดังนี้:

:map <F7> :s/{/{\r/ ^M :s/}/\r}/ ^M

ที่คุณเห็น^ Mในลำดับให้พิมพ์[Ctrl-V]จากนั้นกดป้อน

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

ตรวจสอบ:help map-which-keysคำแนะนำในการเลือกการกดแป้นพิมพ์ที่ไม่ได้ใช้ลงในแผนที่


BTW: gไม่ได้รับการแมปเนื่องจากใช้เป็นคีย์ 'เนมสเปซ' สำหรับการแมปแบบกลุ่มจำนวนมากซึ่งประกอบด้วยการกดแป้นพิมพ์สองครั้ง (ดู:h g) ดังนั้นการทำแผนที่นี้จึงไม่ต้องดำเนินการใด ๆ
Hotschke

มีคำสั่งที่ดีที่รายงานที่gใช้เป็นคีย์ 'เนมสเปซ' อยู่แล้วหรือไม่?
slothbear

โดยเฉพาะอย่างยิ่ง อย่างที่บอก:help gเป็นวิธีหนึ่งในการดูรายการค่าเริ่มต้นg+ การแมปบางอย่าง z, [ ]มีอีกปุ่ม 'namespace' :help indexดูเช่น คุณสามารถเรียก:verbose map gดูการแมปที่กำหนดปัจจุบันทั้งหมดที่เริ่มต้นด้วย g แหล่งที่มาของเว็บที่เป็นประโยชน์ ได้แก่viemu.com/vi-vim-cheat-sheet.gif , vimcasts.org/blog/2014/02/follow-my-leader , vimeo.com/85343734 (สไลด์: speakerdeck.com/nelstrom/follow-my -leader )
Hotschke

3

สมมติว่าคุณโอเคกับการแมปKอย่างอื่น (เลือกคีย์อื่นที่คุณชอบ) และการใช้เครื่องหมาย'เป็นเครื่องหมายชั่วคราวก็โอเคทำไมไม่ทำเช่นนี้

:nmap K m'a<CR><Esc>`'

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


1

กลุ่มจะฆ่าช่องว่างใด ๆ ทางด้านขวาของเคอร์เซอร์โดยอัตโนมัติหากคุณแบ่งบรรทัดเป็นสองขณะ autoindentเปิดใช้งาน (หรือตัวช่วยการเยื้องอื่น ๆ )

หากคุณไม่ต้องการที่จะใช้ใด ๆ ของการตั้งค่าผู้ใช้sแทนiเพื่อs ubstitute ข้อความใหม่ของคุณว่างเปล่ามากกว่าแค่แทรก (หากมีช่องว่างหลายช่องให้วางเคอร์เซอร์ไว้ทางซ้ายสุดแล้วใช้cwแทน)


1

โดยทั่วไปเมื่อคุณแยกบรรทัดคุณต้องการเพียงแค่ใส่การกลับแคร่หรือในกรณีที่คุณอยู่ในช่องว่างให้แทนที่ด้วยการกลับแคร่ ทำไมต้องเลือกอย่างใดอย่างหนึ่ง? นี่คือแผนที่ของฉันสำหรับ K:

"Have K split lines the way J joins lines
nnoremap <expr>K getline('.')[col('.')-1]==' ' ? "r<CR>" : "i<CR><Esc>"

ฉันใช้ตัวดำเนินการ ternary เพื่อย่อการกระทำทั้งสองให้เป็นแผนที่สำคัญเดียว การทำลายมันลง<expr>หมายความว่าเอาต์พุตของแผนที่สำคัญสามารถไดนามิกได้และในกรณีนี้จะขึ้นอยู่กับเงื่อนไขgetline('.')[col('.')-1]==' 'ซึ่งเป็นวิธีที่ยืดยาวเพื่อถามกลุ่มว่าอักขระที่อยู่ใต้เคอร์เซอร์เป็นช่องว่างหรือไม่ ในที่สุดตัวดำเนินการ ternary ที่คุ้นเคย? :อาจแทนที่ช่องว่างด้วย linebreak ( r<CR>) หรือแทรกอันใหม่ ( i<CR><Esc>)

ตอนนี้คุณมีแผนที่สำคัญน้องสาวที่น่ารักสำหรับJคำสั่ง


นี่คือเนียนสวย ฉันไม่แน่ใจว่าฉันเคยใช้ K โดยเจตนาหรือไม่ แต่อาจทำให้คุ้มค่าที่จะกำจัดหรือรีแมปที่อื่น
dragon788

0

ตั้งค่าการแมปคีย์นี้ใน vimrc ของคุณ

:map <C-m> i<CR><Esc>h

จากนั้นกด Ctrl + m หากคุณต้องการใช้ในกลุ่มของคุณ


0

IMHO การทำแผนที่ในตัวgsไม่ใช่การทำแผนที่ที่เป็นประโยชน์ (ทำให้ vim เข้าสู่โหมดสลีป) สามารถใช้สิ่งนี้เพื่อแยก:

nmap gs i<CR><ESC>

0

ในVrapperคุณสามารถใช้ gql ซึ่งจะแยกบรรทัดโดยไม่ต้องเข้าสู่โหมดแทรก แต่อาจไม่รักษาการเยื้องเสมอไป


0

ในความเป็นจริงคุณต้องมีการดำเนินการร่วมกันดังต่อไปนี้:

  1. กด vเพื่อเข้าสู่โหมดภาพ
  2. เลือกบรรทัดที่คุณต้องการแยก
  3. กด:เพื่อเข้าสู่โหมดคำสั่ง
  4. s/\s/\r/g
  5. เสร็จแล้ว

0

หากคุณมีข้อมูลเข้า:

aaa bbb ccc ddd

และต้องการส่งออก

aaa
bbb
ccc
ddd

คุณสามารถใช้คำสั่ง

f r<ENTER>;.;.

0

ฉันพบว่านี่เป็นการดำเนินการอย่างซื่อสัตย์ที่สุดในสิ่งที่ฉันคาดหวังว่าจะเกิดพฤติกรรมตรงกันข้าม J

nnoremap S i<cr><esc>^mwgk:silent! s/\v +$//<cr>:noh<cr>`w

มันทำบรรทัดใหม่อย่างง่ายที่เคอร์เซอร์ดูแลช่องว่างต่อท้ายในบรรทัดก่อนหน้าหากมีอยู่แล้วส่งเคอร์เซอร์กลับไปยังตำแหน่งที่ถูกต้อง

i <cr> <esc> - นี่เป็นวิธีแก้ปัญหาทั่วไปที่แนะนำโดยจะไม่ลบอักขระที่ไม่ใช่ช่องว่างใต้เคอร์เซอร์ของคุณ แต่ยังทำให้คุณมีช่องว่างต่อท้าย

^mw - ไปที่จุดเริ่มต้นของบรรทัดใหม่และสร้างเครื่องหมายภายใต้ w

gk - ขึ้นไปหนึ่งบรรทัด

:silent! s/\v +$//<cr> - regex แทนที่ช่องว่างที่ท้ายบรรทัด

:noh<cr> - ล้างการค้นหาที่เน้นว่า regex อาจเปิดอยู่

`w - คืนเครื่องหมายภายใต้ w

ผสมผสานสิ่งที่ดีที่สุดของทั้งคู่r<esc><cr>และi<cr><esc>

หมายเหตุ: ฉันมีข้อผูกมัดSซึ่งอาจเขียนทับคีย์ที่มีประโยชน์ แต่เป็นคำพ้องความหมายccและเนื่องจากฉันไม่ได้ใช้บ่อยเท่าที่ฉันแยกฉันก็โอเคกับการเขียนทับ



-1

การทำแผนที่นี้จะแยกฟังก์ชันบรรทัดเดียวที่คุณมี เพียงวางเคอร์เซอร์ของคุณบนบรรทัดและกด 'g' ในโหมดปกติ:

:map g ^f{malr<CR>`a%hr<CR>`a

สิ่งนี้ถือว่าคุณมีช่องว่างหลังวงเล็บปีกกาเปิดและช่องว่างก่อนวงเล็บปีกกาปิด ดูว่าเหมาะกับคุณหรือไม่

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