Portapapeles entre Vim y el sistema GNU/Linux
En este artículo aprenderemos a intercambiar contenidos entre el portapapeles del editor Vim y el portapapeles nativo de un sistema GNU/Linux, incluso usando un Vim en una terminal SSH.
Como últimamente va ocurriendo, en mis tiempos libres escribo artículos para sumar información y aclarar algunos puntos de interesantes intercambios que ocurren en el grupo de telegram asociado a nuestro canal informativo. En este caso, configuraciones especiales del editor de textos Vim.
En esta oportunidad, el tema es el intercambio de datos entre un editor Vim y derivados (como NeoVim, gVim, etc) y el portapapeles del sistema GNU/Linux.
¿Cuántas veces nos ha pasado que editamos un archivo de texto en terminal, y necesitamos pegar contenido copiado en una aplicación gráfica como un navegador, LibreOffice, etc? O al revés, necesitamos copiar un contenido de un archivo de textos que estamos editando con Vim y pegarlo en un documento en LibreOffice, o en algún foro en Internet.
Existen varias alternativas, algunas más simples que otras, algunas más intuitivas y, si se quiere, menos elegantes, y otras más «profesionales» (no se si es la palabra, la verdad) utilizando los recursos propios que nos brinda Vim.
Empecemos!
Copiando y pegando en terminal
El método más simple es utilizar los comandos de copiar y pegar soportados por nuestra terminal, como Vim corre dentro de la misma, debería funcionar. El único problema que tiene es que si nos gusta activar el modo visual con el mouse en Vim, no vamos a poder seleccionar texto «por fuera de vim».
Por ejemplo, podríamos editar un archivo de texto, seleccionar un fragmento, y presionar Ctrl+Shift+c
para copiar al portapapeles, o Ctrl+Shift+v
para pegar desde el portapapeles del sistema.
Estos comandos no son propios de Vim, sino del emulador de terminal, por lo que podríamos seleccionar el texto, luego clic derecho en la terminal (o con el menú contextual) y copiar o pegar según corresponda.
Un inconveniente (además del del modo visual, que yo uso mucho) es que si tenemos la numeración de línea habilitada en el Vim, al copiar fragmentos de texto también va a copiar los números de línea, porque es parte del texto de la terminal (recordemos que esta selección no selecciona (valga la redundancia) texto dentro de vim, sino lo que se ve en el emulador de terminal.
Los registros de Vim: introducción
Hagamos un pequeño paréntesis acá. Vim trabaja con varios buffers o registros, que sirven de portapapeles. Es decir, cuando copiamos una línea con «yy
» y la pegamos con «p
» estamos utilizando el portapapeles predeterminado. No obstante, podemos copiar en varios portapapeles distintos, y mantener todos esos contenidos disponibles.
Veamos un ejemplo. Si en un archivo de texto nos paramos en una línea y en vez de copiar con yy
lo hacemos con "ayy
, estaremos guardando el contenido copiado en el registro "a
. Ahora, podríamos movernos a otra línea y cortar su contenido en el registro "b
, por ejemplo, "bdd
.
Podemos ahora pegar en cualquier lado del documento el contenido de cada registro utilizando "ap
o "bp
respectivamente.
Esto de los registros se puede utilizar para cualquier operación de copiado/cortado/eliminación y pegado del editor, las posibilidades son muchas!
Además, el comando :reg
nos permite listar los registros activos y sus contenidos. Nótese que el contenido copiado aparecerá bajo el registro cuyo nombre hemos especificado luego de las comillas, y también aparecerá bajo el registro sin nombre, ""
, el registro predeterminado.
Vim y el portapapeles de GNU/Linux
Antes que nada una nota: para que Vim pueda interactuar con el portapapeles del sistema, debe estar compilado a tal efecto. Generalmente las distros disponen de la versión de Vim compilada con soporte para el portapapeles, por lo que no debería haber problemas. Sin embargo, no está de mas verificarlo:
diego@cryptos:~$ vim --version | grep +clipboard
+clipboard +jumplist +popupwin +user_commands
diego@cryptos:~$
En sistemas GNU/Linux, específicamente en entornos X11 (gráfica), hay dos tipos de portapapeles, a saber:
- PRIMARY: Este portapapeles es denominado «copy-on-select», y su contenido es el que generalmente pegamos usando el botón medio del ratón.
- CLIPBOARD: este es el portapapeles común del sistema, aquel que se utiliza cuando copiamos contenido con
Ctrl+c
y pegamos conCtrl+v
.
Ahora, bien, si copiamos un texto y luego abrimos un Vim y listamos los registros, veremos algo interesante:
Sí, existen dos registros, "+
y "*
, que contienen el texto que hemos copiado en el editor gráfico… ya tenemos un enlace entre los dos portapapeles!
Es más, si seleccionamos cualquier texto (en la gráfica o en la terminal) y volvemos a listar los registros, veremos algunos cambios:
Al seleccionar texto se ha cambiado el contenido del registro "*
, mientras que el del registro "+
permaneció igual. Esto es porque el registro "*
es un buffer que enlaza al portapapeles PRIMARY del X11, mientras que el buffer "+
enlaza al portapapeles CLIPBOARD del sistema.
Probemos ahora pegar el contenido del portapapeles del sistema usando el comando "+p
, pegando el contenido del registro "+
.
Y no sólo eso, también podríamos copiar dentro del editor, un texto, y almacenarlo en el buffer "+
, es decir, en el CLIPBOARD. Hagamos la prueba. Si esto funciona, deberíamos poder pegarlo en el editor gráfico con un simple Ctrl+v
:
Sí señores: podemos copiar y pegar contenido entre el portapapeles del sistema y el editor Vim utilizando el registro "+
.
¿Y el portapapeles en modo visual?
Me he acostumbrado mucho a usar el modo visual en Vim, para seleccionar caracteres, bloques o líneas, e incluso el modo visual del mouse utilizando la opción «set mouse=a
«.
En este caso, al seleccionar un bloque de texto con el modo visual, podemos también copiarlo, cortarlo, etc, al portapapeles "+
, simplemente seleccionando visualmente el contenido, y con el contenido seleccionado, presionar "+y
(para copiar, por ejemplo). Ahora podremos pegar ese contenido en un editor Vim, o en cualquier editor gráfico.
Clipboard «unnamed» y «unnamedplus»
El registro «unnamed
» de Vim es el registro predeterminado, o ""
. Existe una opción de configuración del portapapeles de Vim muy interesante para trabajar el portapapeles: set clipboard=
.
A esta opción podemos configurarle dos valores clave:
- unnamed: permite configurar al registro
"*
como el portapapeles por defecto. - unnamedplus: permite configurar el registro
"+
como el portapapeles por defecto.
Así, por ejemplo, si en nuestras configuraciones de Vim cargamos set clipboard=unnamed
todo lo que copiemos en Vim podremos pegarlo en cualquier editor gráfico presionando el botón central del ratón.
Igualmente, si configuramos set clipboard=unnamedplus
todo lo que copiemos en Vim podremos pegarlo con la clásica opción Ctrl+v
en cualquier editor.
En ambos casos, ya no es necesario especificar los nombres de registros, como "*
o "+
para copiar o pegar, se utilizará el que se haya configurado por defecto.
Y si usamos Vim en consolas SSH?
Al utilizar Vim en una consola de SSH, el portapapeles "+
es el CLIPBOARD del equipo remoto, por lo que no podremos interactuar directamente con el CLIPBOARD del sistema local… salvo que reenviemos por dentro del túnel SSH el contenido X11 🙂
Primero, debemos tener habilitado el reenvío de X11 en el servidor de SSH. Esto podemos hacerlo activando la opción «X11Forwarding
» en el archivo de configuración /etc/ssh/sshd_config
:
X11Forwarding yes
Luego de eso deberemos reiniciar el servidor SSH, claro:
sudo systemctl restart sshd.service
Finalmente, desde el cliente deberemos conectarnos utilizando estas dos opciones en el comando ssh:
-X
: para habilitar el reenvío X11 en el cliente.-Y
: para habilitar el reenvío X11 confiable, necesario para que el Vim remoto pueda enviar el contenido del portapapeles dentro del túnel. Esta opción únicamente es recomendable en servidores confiables!
Podemos conectar el cliente utilizando este comando:
ssh -XY usuario@servidor
Igualmente, si necesitamos que estas opciones siempre estén activas para no tener que typear -XY
cada vez que conectamos, podemos agregar estas líneas en el archivo ~/.ssh/config
de nuestro usuario:
Host servidor
ForwardX11 yes
ForwardX11Trusted yes
Con esto ya podríamos conectarnos a un equipo remoto, copiar texto en el portapapeles usando el registro «+ (o el clipboard predeterminado si activamos unnamedplus), y pegando el contenido en una gráfica local!
Conclusiones
Hemos llegado al final! Una serie de conceptos y prácticas sobre portapapeles en Vim, y cómo interactuar con el portapapeles de nuestro escritorio GNU/Linux.
La verdad es que me resulta muy útil poder intercambiar información entre los portapapeles, y hacen que Vim o NeoVim se integren mejor con el entorno gráfico (ni hablar de alternativas como gVim o NeoVim-qt, que por cierto, también son compatibles con estas características.
Ahora, si estamos editando archivos de texto en terminales remotas SSH usando Vim, resulta mágico poder intercambiar contenido del portapapeles más allá del sistema local.
Espero les sirva! Si me ha faltado alguna configuración necesaria (mas que nada para el uso del portapapeles en SSH) avisen así actualizamos el artículo! Yo ya tenía paquetes como xauth instalados y funcionando, pero puede que esos detalles sean necesarios en algunos sistemas.
Hasta la próxima!