G: clipboard khusus menghasilkan `p` yang selalu ditempelkan ke baris yang sama

Aug 20 2020

Latar Belakang

Saya menggunakan wayland dan neovim dan ketika menempelkan teks eksternal itu akan ditambahkan ^Mke akhir setiap baris. Ini adalah "bug" yang dikenal (https://github.com/neovim/neovim/issues/10223) dan ada solusi: Menggunakan sed untuk memangkas ^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 default ke wl-pastesistem saya, jika g:clipboardtidak disetel.

Masalah

Dengan solusi yang tersedia, neovim tidak menempelkan salinan secara bergaris di baris baru.

  • Perilaku yang Diharapkan : Pergi ke baris -> tekan Y-> pergi ke tengah baris lain -> tekan p-> Baris yang disalin ditempelkan di baris baru . Inilah yang terjadi jika tidak g:clipboard disetel.

  • Perilaku yang diamati : Pergi ke baris -> tekan Y-> pergi ke tengah baris lain -> tekan p-> Garis yang disalin ditempelkan ke baris saat ini. Inilah yang terjadi jika g:clipboarddisetel.

Saat mengamati isi clipboard wayland, ( wl-paste --no-newline | cat -A) mereka sama. Keduanya diakhiri dengan karakter LF.

Pertanyaan:

Kenapa ini? Apa yang dilakukan neovim untuk membedakan antara menempelkan ke baris baru dan mengapa neovim tidak menempel ke baris baru saat ada kebiasaan g:clipboard?

Jawaban

3 Matt Aug 20 2020 at 01:40

Secara default systemlist()tidak mempertahankan baris baru akhir (yaitu membuang item "string kosong" terakhir dari Daftar yang dihasilkan). Itu membuat Neovim berpikir bahwa konten clipboard adalah tipe "char", bukan "line".

Karenanya Anda harus melakukan hal berikut sebagai gantinya (lihat :h systemlist(), perhatikan bahwa versi Neovim berbeda dari versi Vim):

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

Pilihan lain, jika Anda menggunakan versi GUI dari Neovim secara eksklusif, Anda mungkin lebih suka mengirim permintaan RPC ke aplikasi frontend GUI Anda yang mungkin dapat menyajikannya secara platform-independen (melalui Qt, Gtk, dll. Dll. .).

Misalnya, nvim-qt dikirimkan dengan plugin "nvim_gui_shim" standar yang menyediakan GuiClipboard()fungsi. Jadi mengeksekusi hanya :call GuiClipboard()akan secara otomatis mengatur untuk Anda "custom" g:clipboardyang sudah memiliki panggilan rpcrequest()dan itu rpcnotify().

Namun, selain itu tidak akan berfungsi di bawah konsol nvim biasa, saya menemukan masalah buruk lainnya: setidaknya di nvim-qt itu mengharuskan UI telah dimasukkan dan disiapkan sepenuhnya. Jadi mungkin tidak nyaman untuk mengaturnya saat startup Neovim. Tentu saja, Anda dapat memberikan g:clipboardpanggilan RPC Anda sendiri sebagai gantinya (catatan: parameter RPC mungkin berbeda di antara frontend GUI yang berbeda; juga beberapa aplikasi mungkin memilih untuk tidak mengimplementasikan permintaan tersebut sama sekali).

Namun opsi lain adalah menerapkan akses papan klip sendiri. Berikut adalah penyedia clipboard Neovim saya sendiri yang dapat melakukan ini tanpa ketergantungan eksternal. Namun, sejauh ini saya hanya mengimplementasikan versi Xlib, jadi tidak ada modul asli untuk Wayland.