ตั้งค่าตัวเลือกการวาง แต่สำหรับการแทรกเพียงครั้งเดียวเท่านั้น


16

ฉันต้องการวิธีที่รวดเร็วในการตั้งค่า'paste'ตัวเลือกVim การแทรกข้อความบางส่วนและเปลี่ยนเป็นค่าก่อนหน้า'paste'เป็น

กรณีการใช้งานทั่วไปแทรกเนื้อหาคลิปบอร์ดของระบบปฏิบัติการอย่างแท้จริงโดยไม่คำนึงถึงการเขียนโหมดแทรกใด ๆ ที่อาจใช้งานเช่นการเยื้องอัตโนมัติและโดยไม่ต้องเปลี่ยนสถานะของ Vim อีกกรณีการใช้งานคือการอนุญาตให้มีคุณสมบัติแมโคร OS เพื่อแทรกการกดแป้นพิมพ์เป็นกลุ่มและให้พวกเขาตีความเป็นข้อความตามตัวอักษร

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

โดยทั่วไปฉันต้องการผูกลำดับสำคัญ (พูด_i) กับมาโครที่ทำสิ่งนี้

:set paste
i…<Esc>
:set nopaste

โดยที่i…<Esc>ฉันหมายถึงเปลี่ยนเป็นโหมดแทรก (เช่นเดียวกับiคำสั่ง) และกลับมาโครเมื่อกลับสู่โหมดคำสั่งยกเว้นว่าฉันต้องการที่จะจบลงด้วยการ'paste'ยังคงใช้งานอยู่หากมันใช้งานอยู่ก่อน ฉันจะทำสิ่งนี้ได้อย่างไร

หมายเหตุ: เนื้อหาของคลิปบอร์ด OS ที่ถูกแมปไปลงทะเบียน"* เมื่อใช้งานได้'paste'ตัวเลือกจะไม่มีประโยชน์มาก สถานการณ์ที่สร้างแรงจูงใจสำหรับคำถามนี้สำหรับช่วงเวลาที่ไม่ตรงตามเงื่อนไขสำหรับ"*การสนับสนุนการลงทะเบียน - Vim ไม่ได้รวบรวม+xterm_clipboardคุณสมบัติหรือกำลังทำงานในเทอร์มินัลเช่นหน้าจอหรือ SSH เหนือซึ่งแยกจากเซิร์ฟเวอร์ X แวดล้อม


1
ฉันชอบคำถามของคุณ (ฉันอยู่ที่นั่นหลายครั้งแล้ว) อย่างไรก็ตามการวางจาก+หรือ*ลงทะเบียนง่ายกว่าไหม?
yo '

@yo' เฉพาะเมื่อพวกเขาทำงาน ซึ่งสำหรับการใช้งาน Vim ของฉันมักจะไม่เป็นเช่นนั้น
Gilles 'SO- หยุดความชั่วร้าย'

คำตอบ:


15

ลองดูสิ:

function! Paste_Func()
    let s:inPaste = &paste
    if !s:inPaste
        set paste
    endif

    echom s:inPaste
    augroup paste_callback
        autocmd!
        autocmd InsertLeave <buffer> call Paste_End()
    augroup END

    startinsert
endfunction

function! Paste_End()
    augroup paste_callback
        autocmd!
    augroup END
    augroup! paste_callback

    if !s:inPaste
        set nopaste
    endif
endfunction

map _i :call Paste_Func()<cr>

มันเก็บสถานะการวางปัจจุบันของคุณในตัวแปร inPaste และตั้งค่าการวางหากยังไม่ได้ตั้งค่า จากนั้นจะตั้งค่า autocmd ให้เมื่อคุณออกจากโหมดแทรกแล้วทำให้คุณอยู่ในโหมดแทรก

เมื่อคุณออกจากโหมดแทรกมันจะรัน autocmd ซึ่งจะเอา autocmd ออกไปก่อน (ดังนั้นมันจะไม่ถูกเรียกใช้เมื่อคุณออกจากโหมดแทรกด้วยวิธีอื่น) และสุดท้ายตั้ง nopaste หากคุณไม่ได้อยู่ในโหมดวางเดิม

นอกจากนี้หากคุณใช้ vim ในเทอร์มินัลคุณอาจต้องการดูที่vim-bracketed-pasteซึ่งใช้ฟีเจอร์โหมด pasteed paste ที่จัดทำโดยเทอร์มินัลอีมูเลเตอร์หลายเครื่องเพื่อตรวจสอบว่าคุณกำลังวางและตั้งโหมดโดยอัตโนมัติ

แก้ไข: แก้ไขสคริปต์


ดูเหมือนว่าในเส้นทางที่ถูกต้อง (โดยเฉพาะอย่างยิ่งฉันไม่รู้ว่าจะ“ ใส่วงเล็บ” การแทรกโดยคำสั่งของโลกปกติได้อย่างไร) ขอบคุณ แต่ก็เป็นสิ่งที่ไม่ถูกต้องและผมไม่เห็นว่าปัญหาคือหลังจาก_iที่pasteตัวเลือกที่จะปิดแม้ว่ามันจะเป็นก่อน
Gilles 'ดังนั้นหยุดความชั่วร้าย'

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

4

ยกเว้นว่าฉันต้องการที่จะจบลงด้วยการ'paste'ใช้งานยังคงถ้ามันใช้งานได้ล่วงหน้า

'paste'ควรจะแอคทีฟให้สั้นที่สุดเท่าที่จะทำได้ มันปิดการใช้งานฟังก์ชั่นจำนวนมาก (รวมถึงแผนที่) เพราะวัตถุประสงค์เพียงอย่างเดียวคือเพื่อหลีกเลี่ยงการตีความข้อความที่วางผิด ดังนั้นฉันคิดว่าข้อกำหนดที่ยกมาไม่น่าจะจำเป็นจริงๆ

'paste'ที่ถูกกล่าวว่าก็จริงค่อนข้างง่ายที่จะวางโดยไม่จำเป็นต้องตั้งค่า หากคุณใช้ gvim หรือ+xterm_clipboardอยู่ในคอนโซล vim คุณสามารถใช้"+pเพื่อวางจากคลิปบอร์ด OS

ปัญหาการเยื้องอัตโนมัติในขณะที่วางจะเกิดขึ้นจริงในสองสถานการณ์เท่านั้น การแทรกเนื้อหาของรีจิสเตอร์ขณะอยู่ในโหมดแทรก ( <C-r>+) หรือคลิกกลางวางด้วยเมาส์

แทนที่จะแทรกเนื้อหาของรีจิสเตอร์ขณะอยู่ในโหมดแทรกการวางจากรีจิสเตอร์ในโหมดปกติจะหลีกเลี่ยงปัญหาการฟอร์แมตใหม่

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


2
สิ่งนี้ไม่ตอบคำถามของฉัน ฉันใส่ข้อกำหนดที่ชัดเจนไว้ด้วยเหตุผล! โดยปกติแล้ว'paste'จะไม่ได้ใช้งานล่วงหน้า แต่ฉันไม่ต้องการที่จะคิดเกี่ยวกับเรื่องนี้ ฉันมักจะทำงานใน Vim ที่ไม่สามารถเข้าถึง X คลิปบอร์ดหรือเมาส์ได้เพราะ Vim build ของฉันไม่มีxterm_clipboardคุณสมบัติหรือเพราะฉันกำลังทำงานในเช่นเซสชันหน้าจอที่ติดอยู่กับ เทอร์มินัล X
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

@Gilles คุณช่วยอธิบายว่าคุณวางอย่างไร นั่นคือข้อมูลที่เกี่ยวข้องเพื่อให้สามารถให้คำตอบที่สามารถปิดล้อมการกระทำนั้นในสิ่งที่คุณต้องการทำ
jamessan

1
กรณีการใช้งานพื้นฐานของฉันคือการวางด้วยปุ่มกลางของเมาส์หรือ Shift + Insert นั่นไม่เกี่ยวข้องจริง ๆ : หลักของคำถามคือวิธีการตั้งค่าตัวเลือกสลับไปยังโหมดแทรก (ด้วยiฉันไม่ได้ถามวิธีการ parametrize นี้) และเรียกคืนค่าของตัวเลือกเมื่อกลับมาจากโหมดแทรก
Gilles 'หยุดชั่วร้าย'

1
@Gilles หลักของคำถามของคุณตามที่ระบุไว้ในความคิดเห็นนี้ชัดเจนมากสำหรับฉันกว่าคำถามเดิมของคุณ ขอบคุณ
jamessan

1
@Gilles ไม่เกี่ยวข้องกับคุณแต่สามารถเกี่ยวข้องกับผู้เยี่ยมชมในอนาคต ดังนั้นคุณสามารถตั้งคำถามเองได้ ("ฉันรู้ว่าฉันสามารถใช้"*pหรือ"+pวางจากคลิปบอร์ด แต่ฉันไม่ต้องการใช้ความสามารถในการวางของระบบ") จากนั้นคำตอบนี้ไม่จำเป็น หรือคุณไม่ทำแล้วฉันคิดว่าคำตอบนี้มีที่นี่
yo '

4

โดยส่วนตัวฉันใช้การyoโยงจากปลั๊กอินvim-unimpaired ที่ยอดเยี่ยมของ Tim Pope ด้วยเหตุผลนี้ จากเอกสารของเขา:

ไม่มีการให้สลับสำหรับ 'แปะ' เนื่องจากกรณีการใช้งานโดยทั่วไปของการห่อของการแทรกโดดเดี่ยวนั้นสิ้นเปลืองอย่างมาก: คุณสลับสองครั้ง แต่คุณวางเพียงครั้งเดียว (YOPO) ให้กดyoหรือyOเพื่อเรียก|o|หรือ|O|ตั้งค่า 'วาง' แทน การออกจากโหมดแทรกจะตั้ง 'nopaste' โดยอัตโนมัติ

มันอาจ overkill ในการติดตั้งปลั๊กอินสำหรับคำถามของคุณ แต่ฉันพบว่ามันมีประโยชน์มากมายสำหรับการโยงคีย์อื่น ๆ ด้วย (ข้อมูลเพิ่มเติมในREADME )


1

ด้วย Vim 8+ บน Linux หรือ Mac ตอนนี้คุณสามารถใช้ native paste ของเทอร์มินัลได้ (เช่นปุ่มกลางของเมาส์ctrl+shift+Vใน Gnome cmd+Vบน Mac) ถ้าเทอร์มินัลรองรับการวางแบบวงเล็บ อย่ากดiสำหรับโหมดแทรก

มันจะวางเนื้อหาของคลิปบอร์ด OS ของคุณรักษาช่องว่างและแท็บโดยไม่ต้องเพิ่มการใส่ข้อความอัตโนมัติ มันเทียบเท่ากับเก่า:set paste, i, ctrl+shift+V, esc, :set nopasteวิธีการ

คุณไม่จำเป็นต้องมีคุณสมบัติ+clipboardหรือ+xterm_clipboardเป็นกลุ่มติดตั้งอีกต่อไป คุณสมบัตินี้เรียกว่า "pasteed paste" สำหรับรายละเอียดเพิ่มเติมดู/programming/2514445/turning-off-auto-indent-when-pasting-text-into-vim/56781763#56781763

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