สร้างเครื่องมือจับคู่อัตโนมัติในกลุ่ม


17

ฉันจะสร้างวงเล็บปีกกาที่จับคู่ในกลุ่มโดยอัตโนมัติได้อย่างไร?

มันควรจะทำงานดังนี้: ถ้าฉันใส่วงเล็บปีกกาเปิดหนึ่งปิดจะปรากฏขึ้นโดยอัตโนมัติและเคอร์เซอร์ควรอยู่ในระหว่าง ในการกระโดดออกจากคู่รั้งCtrl-jจะใช้การรวมกัน

มีปลั๊กอินมากมายที่ให้การแทรกรั้งอัตโนมัติ แต่พวกเขา

  • อาจใช้การผสมผสานคีย์ที่แตกต่างจากCtrl-jการกระโดดออกจากคู่รั้งหรือ
  • รบกวนการผูกคีย์UltiSnips

งานดังต่อไปนี้ตามที่คาดไว้

:inoremap ( ()<Esc>:let leavechar=")"<CR>i
:imap <C-j> <Esc>:exec "normal f" . leavechar<CR>a

แต่ด้วยการตั้งค่าเหล่านี้ตัวอย่าง UltiSnips จะไม่ทำงานอีกต่อไป ดังนั้นฉันจึงใช้ UltiSnips เพื่อแทรกรั้งปิด:

inoremap ( (<C-R>=UltiSnips_Anon('($1)$0', '(')<CR>

เกือบจะใช้งานได้แล้ว Ctrl-jรั้งจับคู่ถูกแทรกและฉันสามารถข้ามหนึ่งปิดด้วย อย่างไรก็ตามสิ่งนี้จะทำงานได้ก็ต่อเมื่อมีช่องว่างด้านหน้าวงเล็บปีกกาเปิด

main () // works, the closing parentheses is added
main(   // fails without a space

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

หมายเหตุ: ฉันใช้วงเล็บเป็นตัวอย่าง มันควรจะทำงานกับวงเล็บวงเล็บวงเล็บและเครื่องหมายน้อยกว่าและไม่รบกวนปลั๊กอิน UltiSnips


1
คุณลองปิดอัตโนมัติหรือไม่ คุณสามารถกระโดดออกมาจากคู่กับ)แมปc-jไปที่อาจทำงาน
เควิน

คำตอบ:


4

ฉันจะสร้างวงเล็บปีกกาที่จับคู่ในกลุ่มโดยอัตโนมัติได้อย่างไร?

ปัญหานี้เป็นเรื่องไม่สำคัญอย่างที่คุณจะเห็น คำตอบง่ายๆคือ: ใช้ปลั๊กอินเช่นAutoCloseหรือsmartinput เพียงแค่ทำการแมปใหม่อย่างไร้เดียงสา ([.. แป้นจะนำเสนอคุณด้วย edgecases ในสองบรรทัดนั่นคือสาเหตุที่ปลั๊กอินเหล่านี้ถูกสร้างขึ้นมาและทำไมพวกเขาจึงมักจะค่อนข้างซับซ้อน (ถ้ามี)

ดังนั้นฉันจึงใช้ UltiSnips เพื่อแทรกรั้งปิด

คุณสามารถลองสิ่งนี้แทน (ซึ่งต่างจากคำแนะนำดั้งเดิมของฉัน):

inoremap ( ()<CR>=UltiSnips_Anon('$1)$0', ')')<CR>

โดยที่ UltiSnips จะแยกบรรทัด(แทนที่จะรวมmainอยู่ในการแข่งขัน ปัญหาของการใช้ส่วนเสริมปลั๊กอินสำหรับสิ่งนี้คือพวกเขา (ปกติ) ไม่สนับสนุนการซ้อนดังนั้นพวกเขาจะลืมตำแหน่งกระโดดใด ๆ เมื่อแทรกส่วนย่อย (ซ้อน) ถัดไป

ในการกระโดดออกจากคู่รั้งCtrl-jจะใช้การรวมกัน

คุณสามารถทำการแมปใหม่Ctrl-jสำหรับ UltiSnips หรือปลั๊กอินที่ขัดแย้งกัน หากการแมปนั้นไม่ปรากฏในเอกสารคุณสามารถใช้:map/imap/nmap <key>เพื่อแสดงการแมป หากคุณต้องการCtrl-jเลือกและเลือกและทำงานของปลั๊กอินทั้งสองคุณกำลังขอ:

  1. บางอย่างก้าวหน้าไปกว่าที่ฉันคิดว่าคุณอาจคิด
  2. สิ่งที่ฉันสงสัยว่าคุณไม่ต้องการจริงๆ

พิจารณาวน bash นี้:

while (( ${arr1[i]} < ${arr2[i<CURSOR>]} )); do
  [next_snippet_position_marker]
done

ในกรณีนี้คุณจะต้องกดCtrl-j5 ครั้งเพื่อไปที่ลูปบอดี้ การใช้วงเล็บปีกกาปิดเพื่อกระโดดออกมาจากคู่ที่เกี่ยวข้องช่วยให้คุณควบคุมได้มากขึ้นว่าคุณต้องการให้เคอร์เซอร์เคลื่อนที่ไปที่ใด คุณสามารถติดตั้งสแต็กเพื่อติดตามคู่ที่แทรกไว้และใช้Ctrl-jในการป๊อปและย้าย แต่คุณจะพบปัญหาหากคุณเริ่มต้นการลบเครื่องหมายวงเล็บด้วยตนเองโดยไม่ลบออกจากสแต็ก ดังนั้นคุณจะเริ่มแก้ปัญหาที่ตัวยึดรั้งกำลังพยายามแก้ไข นี่คือวงล้อหนักที่จะบูรณาการ

เมื่อขยายออกไปคุณจะได้รับสิ่งที่คุณต้องการในตอนแรกโดยใช้Ctrl-jเพื่อกระโดดออกจากวงเล็บปีกกาและตัวอย่าง หากคุณใช้ค่าดัมมี่เพื่อเป็นตัวแทนตำแหน่งตัวอย่างและผลักดันพวกเขาไปยังสแต็คนอกเหนือจากวงเล็บปีกกาปิดด้วยการแมปแบบไดนามิกของCtrl-jเพื่อให้สอดคล้องกับการส่งตัวอย่างหรือวงเล็บปีกกา แต่คุณจะต้องใช้ฮิวริสติกขั้นสูงพอสมควรเพื่อหาว่าเวทมนตร์ควรจะเกิดอะไรขึ้นเนื่องจากคุณต้องเผชิญกับปัญหาสองอย่างในเวลาเดียวกันซึ่งขณะนี้ผู้แก้ไขของปลั๊กอินแทรกตัวอย่างและปลั๊กอินจับคู่ที่แยกออกจากกันนั้นกำลังแก้ไขอยู่ อีกครั้งการแก้ปัญหาเหล่านี้อีกครั้งด้านบนของพวกเขาแก้ปัญหาเพื่อให้เกิดความสะดวกสบายและดีวิเศษ

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


1

ฉันคิดว่าdelimitMateทำในสิ่งที่คุณต้องการ

มันปิดวงเล็บหรือคำพูดโดยอัตโนมัติและทำให้เคอร์เซอร์ของคุณในระหว่าง หากต้องการกระโดดออกจากวงเล็บคู่ (ในขณะที่อยู่ในโหมดแทรก) คุณต้องทำCtrl-g+ gแต่คุณสามารถทำการแมปนี้ให้เป็นCtrl-jโดยการเพิ่มลงในvimrc:

% Jump out of a block of parentheses (uses delimitMate)
imap <C-j> <C-g>g

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

1

ฉันได้พบกับการปิดอัตโนมัติเพิ่มบิตของความล่าช้าและรบกวนการตั้งค่าของฉัน (Ultisnips และ Supertab) แต่ฉันชอบวิธีการเลียนแบบ Eclipse CDT

ฉันใช้delimitMateกับแผนที่ต่อไปนี้เพื่อช่วยในการนำทางและการเยื้องพยายามรับผลลัพธ์เดียวกัน:

imap <C-F> <C-G>g           " To jump out brackets in same line.
inoremap <C-K> <ESC>ki<TAB> " To move and insert an indent on the line before the current cursor (assuming empty line)

ฉันใช้วิธีนี้แทรกการเปิด{ <CR><CR><C-K>และเริ่มเขียนในบรรทัดที่เยื้อง


ฉันพบว่า delimitMate จะเพิ่มความล่าช้าเล็กน้อยเช่นกัน
icc97

1

ส่วนตัวผมใช้smartinputสำหรับการใส่เครื่องหมายวงเล็บและเครื่องหมายคำพูดอัตโนมัติ ตัวอย่างเช่นการพิมพ์{ที่ใดก็ได้จะ{}มีเคอร์เซอร์อยู่ตรงกลาง ที่จะออกจาก{กลุ่มวงเล็บคุณเพียงแค่พิมพ์เมื่อติดกับแทรก }}

อย่างไรก็ตามสิ่งนี้จะรองรับความต้องการของ tabstops และกระโดดไปที่ด้านนอกของวงเล็บ นอกจากนี้ยังไม่ได้สร้างใหม่ระหว่างวงเล็บของคุณ แต่คุณเพียงแค่ต้องหนึ่งที่สำคัญพิเศษสำหรับที่อยู่แล้ว <CR>-

คุณสามารถแมป<C-J>เพื่อข้ามไปยังบรรทัดถัดไปลง:

:inoremap <C-J> <C-O>j

หรือถ้าคุณต้องการที่จะย้ายไปที่จุดเริ่มต้นของบรรทัดถัดไป:

:inoremap <C-J> <C-O>+

0

บางอย่างเช่นนี้อาจได้ผลสำหรับคุณ

inoremap {      {}<Left>
inoremap {<CR>  {<CR>}<Esc>O
inoremap {{     {
inoremap {}     {}

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

0

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

inoremap () ()<C-R>=UltiSnips#Anon('($1)$0', '()', 'double parentheses', 'i')<CR>

หนึ่งจะต้องพิมพ์()ที่ค้นหาได้ดีขึ้น แต่ที่สามารถเปลี่ยน(เป็น จากนั้นอาร์กิวเมนต์เพิ่มเติมที่เป็นทางเลือกเพิ่มเติมUltiSnips#Anonคือคำอธิบายและตัวแก้ไขiซึ่งอนุญาตการขยายในคำ

กระโดดออกจากวงเล็บด้วย<c-j>ผลงานซ้อนกันในตัวอย่างอื่น อย่างไรก็ตามการเรียกใช้()วงเล็บที่ซ้อนกันดูเหมือนว่าจะทำลายคุณสมบัตินี้ซึ่งไม่ใช่เรื่องใหญ่

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