G personalizado: el portapapeles da como resultado que `p` siempre se pegue en la misma línea

Aug 20 2020

Antecedentes

Utilizo wayland y neovim y al pegar texto externo se agregaría ^Mal final de cada línea. Este es un "error" conocido (https://github.com/neovim/neovim/issues/10223) y existe una solución alternativa: usar sed para recortar ^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 se activa de forma predeterminada wl-pasteen mi sistema, cuando g:clipboardno está configurado.

Problema

Una vez implementada la solución alternativa, neovim no pega copias lineales en una nueva línea.

  • Comportamiento esperado : Vaya a una línea -> presione Y-> vaya al medio de otra línea -> presione p-> La línea copiada se pega en una nueva línea. Esto es lo que sucede cuando no g:clipboard se establece.

  • Comportamiento observado : Vaya a una línea -> presione Y-> vaya al medio de otra línea -> presione p-> La línea copiada se pega en la línea actual. Esto es lo que sucede cuando g:clipboardse establece.

Al observar el contenido del portapapeles de wayland, ( wl-paste --no-newline | cat -A) son iguales. Ambos terminan con un carácter LF.

Pregunta:

¿Por qué es esto? ¿Qué hace neovim para distinguir entre una pasta en una nueva línea y por qué neovim no se pega en una nueva línea cuando se tiene la costumbre g:clipboard?

Respuestas

3 Matt Aug 20 2020 at 01:40

De forma predeterminada systemlist(), no conserva una nueva línea final (es decir, elimina el último elemento de "cadena vacía" de la Lista resultante). Eso hace que Neovim piense que el contenido del portapapeles es de tipo "char", no de "línea".

Por lo tanto, debe hacer lo siguiente en su lugar (vea :h systemlist(), tenga en cuenta que la versión de Neovim difiere de la de Vim):

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

Otra opción, si está utilizando una versión GUI de Neovim exclusivamente, puede preferir simplemente enviar la solicitud RPC a su aplicación de interfaz GUI que puede servirla de una manera independiente de la plataforma (a través de Qt, Gtk, etc., etc.) .).

Por ejemplo, nvim-qt se envía con un complemento estándar "nvim_gui_shim" que proporciona una GuiClipboard()función. Y así, la ejecución simplemente :call GuiClipboard()configurará automáticamente un "personalizado" g:clipboardque ya tiene esas rpcrequest()y rpcnotify()llamadas.

Sin embargo, además de que no funcionará bajo la consola nvim simple, descubrí otro problema desagradable: al menos en nvim-qt requiere que se haya ingresado la interfaz de usuario y esté completamente preparada. Por lo tanto, podría ser inconveniente configurarlo al iniciar Neovim. Por supuesto, puede proporcionar las suyas propias g:clipboardcon llamadas RPC en su lugar (nota: los parámetros RPC pueden diferir entre diferentes interfaces GUI; también algunas aplicaciones pueden optar por no implementar dichas solicitudes en absoluto).

Otra opción más es implementar el acceso al portapapeles usted mismo. Aquí está mi propio proveedor de portapapeles Neovim que puede hacer esto sin dependencias externas. Sin embargo, hasta ahora solo he implementado la versión Xlib, por lo que no hay un módulo nativo para Wayland.