กำหนดเอง g: คลิปบอร์ดส่งผลให้ "p" วางในบรรทัดเดียวกันเสมอ

Aug 20 2020

พื้นหลัง

ฉันใช้ wayland และ neovim และเมื่อวางข้อความภายนอกมันจะเพิ่ม^Mที่ส่วนท้ายของแต่ละบรรทัด นี่คือ "บั๊ก" ที่รู้จักกันดี (https://github.com/neovim/neovim/issues/10223) และมีวิธีแก้ปัญหาอยู่: การใช้ sed เพื่อตัดแต่ง^M:

let g:clipboard = {
            \   'name': 'WL-Clipboard with ^M Trim',
            \   'copy': {
            \      '+': 'wl-copy --foreground --type text/plain',
            \      '*': 'wl-copy --foreground --type text/plain --primary',
            \    },
            \   'paste': {
            \      '+': {-> systemlist('wl-paste --no-newline | sed -e "s/\r$//"')}, \ '*': {-> systemlist('wl-paste --no-newline --primary | sed -e "s/\r$//"')},
            \   },
            \   'cache_enabled': 1,
            \ }

Neovim ตั้งค่าเริ่มต้นเป็นwl-pasteระบบของฉันเมื่อg:clipboardไม่ได้ตั้งค่า

ปัญหา

เมื่อใช้วิธีแก้ปัญหานี้แล้ว neovim จะไม่วางสำเนา linewise ในบรรทัดใหม่

  • พฤติกรรมที่คาดหวัง : ไปที่บรรทัด -> กดY-> ไปที่ตรงกลางของบรรทัดอื่น -> กดp-> บรรทัดที่คัดลอกจะถูกวางในบรรทัดใหม่ นี่คือสิ่งที่เกิดขึ้นเมื่อไม่มีการ g:clipboardตั้งค่า

  • พฤติกรรมที่สังเกตได้ : ไปที่บรรทัด -> กดY-> ไปที่ตรงกลางของบรรทัดอื่น -> กดp-> บรรทัดที่คัดลอกจะถูกวางลงในบรรทัดปัจจุบัน นี่คือสิ่งที่เกิดขึ้นเมื่อg:clipboardถูกตั้งค่า

เมื่อสังเกตเนื้อหาของคลิปบอร์ด wayland ( wl-paste --no-newline | cat -A) จะเหมือนกัน ทั้งสองลงท้ายด้วยอักขระ LF

คำถาม:

ทำไมถึงเป็นแบบนี้? อะไร neovim ทำเพื่อแยกความแตกต่างระหว่างการวางลงในบรรทัดใหม่และทำไมไม่ neovim ไม่วางลงในบรรทัดใหม่เมื่อมีการกำหนดเองg:clipboardในสถานที่?

คำตอบ

3 Matt Aug 20 2020 at 01:40

โดยค่าเริ่มต้นsystemlist()จะไม่เก็บการขึ้นบรรทัดใหม่สุดท้าย (กล่าวคือจะทิ้งรายการ "สตริงว่าง" สุดท้ายจากรายการผลลัพธ์) นั่นทำให้ Neovim คิดว่าเนื้อหาของคลิปบอร์ดเป็นประเภท "char" ไม่ใช่ "line"

ดังนั้นคุณต้องทำสิ่งต่อไปนี้แทน (ดู:h systemlist()โปรดทราบว่าเวอร์ชัน Neovim แตกต่างจาก Vim's one):

{-> systemlist('wl-paste...', '', 1)}

อีกทางเลือกหนึ่งหากคุณใช้ Neovim เวอร์ชัน GUI โดยเฉพาะคุณอาจต้องการเพียงแค่ส่งคำขอ RPC ไปยังแอปพลิเคชันส่วนหน้า GUI ของคุณซึ่งอาจให้บริการในลักษณะที่ไม่ขึ้นกับแพลตฟอร์ม (ผ่าน Qt, Gtk และอื่น ๆ เป็นต้น .).

ตัวอย่างเช่น nvim-qt มาพร้อมกับปลั๊กอิน "nvim_gui_shim" มาตรฐานซึ่งมีGuiClipboard()ฟังก์ชัน ดังนั้นการดำเนินการก็:call GuiClipboard()จะตั้งค่า "กำหนดเอง" ให้คุณโดยอัตโนมัติg:clipboardซึ่งมีสิ่งเหล่านั้นrpcrequest()และการrpcnotify()โทรอยู่แล้ว

อย่างไรก็ตามนอกจากมันจะไม่ทำงานภายใต้ nvim คอนโซลธรรมดาแล้วฉันยังค้นพบปัญหาที่น่ารังเกียจอีกอย่าง: อย่างน้อยใน nvim-qt มันต้องมีการป้อน UI และเตรียมพร้อมอย่างเต็มที่ ดังนั้นจึงอาจไม่สะดวกในการติดตั้งเมื่อเริ่มต้น Neovim แน่นอนคุณสามารถให้การg:clipboardเรียก RPC ของคุณเองแทนได้ (หมายเหตุ: พารามิเตอร์ RPC อาจแตกต่างกันระหว่างส่วนหน้าของ GUI ที่แตกต่างกันนอกจากนี้แอปพลิเคชันบางตัวอาจเลือกที่จะไม่ใช้คำขอดังกล่าวเลย)

อีกทางเลือกหนึ่งคือใช้การเข้าถึงคลิปบอร์ดด้วยตัวคุณเอง นี่คือผู้ให้บริการคลิปบอร์ด Neovim ของฉันเองซึ่งสามารถทำได้โดยไม่ต้องพึ่งพาภายนอก อย่างไรก็ตามจนถึงตอนนี้ฉันใช้งานเวอร์ชัน Xlib เท่านั้นดังนั้นจึงไม่มีโมดูลเนทีฟสำหรับ Wayland