Conseguir que tmux copie un búfer en el portapapeles

118

Estoy tratando de encontrar una manera decente de copiar lo que tengo en un búfer tmux en mi portapapeles. He intentado un par de cosas diferentes como

bind-key p select-pane -t 2 \; split-window 'xsel -i -b' \; paste-buffer

lo que me acerca bastante, todo lo que tengo que hacer es presionar control-d después de hacer el prefijo-p.

Traté de arreglar eso haciendo

bind-key p select-pane -t 2 \; split-window 'xsel -i -b << HERE\; tmux paste-buffer\; echo HERE'

Pero eso simplemente no funciona. De hecho, si emparejo esto a solo

bind-key p select-pane -t 2 \; split-window 'xsel -i -b << HERE'

no hace nada, así que supongo que a la ventana dividida no le gusta << en un comando de shell.

¿Algunas ideas?

Editar: puede omitirlo select-pane -t 2si lo desea, no es realmente importante. Solo uso un diseño específico y el panel 2 es el que prefiero dividir cuando hago otra cosa para que mis enlaces impliquen divisiones de forma predeterminada.

Poderes digitales
fuente
2
Asegúrese de mirar la respuesta de 2014 a continuación, que es más reciente que algunas de las otras. Recomienda el complemento tmux yank que funciona muy bien.
dmonopolio
Para obtener una respuesta actualizada con Tmux 2.4 (lanzado en abril de 2017) y 2.6, vea mi respuesta
Jason Axelson,

Respuestas:

26

Aquí los documentos necesitan nuevas líneas. Por ejemplo, en un script de shell, puede escribir

cat <<EOF >somefile; echo  done
file contents
EOF

No creo que tmux le permita poner nuevas líneas allí, e incluso si lo hiciera, este no sería un buen enfoque. ¿Qué sucede si los datos en sí contienen HEREsolo en una línea (por ejemplo, porque está copiando su .tmux.conf)?

Sugiero escribir el contenido del búfer en un archivo temporal. No probado:

bind-key p save-buffer ~/.tmux-buffer \; run-shell "xsel -i -b <~/.tmux-buffer && rm ~/.tmux-buffer"

Hay una condición de carrera si usa este comando en dos instancias de tmux separadas. No se como resolver esto.

Gilles
fuente
Gracias funciona perfectamente, la condición de la carrera no es una preocupación para mí, solo uso 1 sesión.
Poderes digitales
Para evitar la condición de carrera, me gustaría sugerir el uso mktempque está ampliamente disponible
Pena
@ Duelo Buena idea. En este caso, usar el PID del proceso tmux también funcionaría y probablemente sería más fácil de organizar ( $PPIDen un shell lanzado por tmux). Pero, ¿cómo se obtiene el nombre de archivo variable (sin embargo, está construido) en el argumento de save-buffer? Supongo que save-buffer - | …como en la respuesta de Grauwolf , que elimina un archivo temporal por completo?
Gilles
Tienes razón, mi culpa, esto no sería posible.
Duelo
93

Esto debería funcionar:

# move x clipboard into tmux paste buffer
bind C-p run "tmux set-buffer \"$(xclip -o)\"; tmux paste-buffer"
# move tmux copy buffer into x clipboard
bind C-y run "tmux save-buffer - | xclip -i"
Grauwolf
fuente
1
Entonces lo hace. Eso es mucho mejor que usar un archivo temporal, gracias. Incluso hace frente automáticamente a múltiples sesiones concurrentes, gracias a las TMUXvariables de entorno.
Gilles
22
Una mejor instrucción para el C-psería: bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer"- no hay problemas de citas o problemas de límite de línea de comando.
docwhat
8
¿Tiene tmux un gancho para copiar la selección en el portapapeles cuando está dentro copy-mode?
Ehtesh Choudhury
1
xclip -ola opción no funcionó para mí, así que he cambiado abind C-c run "tmux save-buffer - | xclip -selection c"\; display-message "Buffer copied to clipboard"
Pawka
66
Cada vez que hago la copia de esta manera, tmux deja de responder a cualquier atajo de teclado. ¿Alguna solución para eso?
skrat
41

Una solución más simple para Mac OS-X

Esto se basa en la respuesta de Alex y usa cosas que no existían en ese momento.

Si está usando homebrew (y si no lo está, ¿por qué no lo hace?), Puede hacer esto:

brew install reattach-to-user-namespace

Luego en tu ~/.tmux.conf:

set-option -g default-command "reattach-to-user-namespace -l zsh" # or bash...
bind C-c run "tmux save-buffer - | reattach-to-user-namespace pbcopy"
bind C-v run "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"

Para copiar el búfer de tmux (ya debería haber copiado algo usando tmux) en el tablero de Mac, use <tmux-key> Control-c. Ahora estará disponible para Command-vopbpaste

Para pegar algo del tablero de Mac, use <tmux-key> Control-v.

docwhat
fuente
2
Esta respuesta es excelente. Estaba usando lo tmux show-bufferque causó problemas de ajuste de línea lo tmux save-buffer -resolvió.
event_jr
¿Qué hace -al final de tmux save-buffer -hacer?
hekevintran
Emite el save-bufferstdout. Puede reemplazarlo -con un nombre de archivo y lo guardará allí. Esto le impide escribir (y tener que limpiar) un archivo.
docwhat
1
A partir de OS X 10.10, ya no es necesario volver a conectar el espacio de nombres de usuario. Casi todos los tutoriales y la documentación sobre tmux y OS X lo mencionan, porque copiar y pegar no era posible hace un par de años. En estos días (en su mayoría) funciona fuera de la caja.
Rafael Bugajewski
40

El copy-pipecomando se agregó a partir de la versión 1.8. Copia una selección al búfer tmux y la canaliza a un comando. Ahora no hay necesidad de un enlace de prefijo. Aquí hay un ejemplo:

bind -t vi-copy y copy-pipe "xclip"

# For OS X users:
bind -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

Ahora, cuando haya seleccionado algún texto copy-mode, ycopiará ese texto en el búfer tmux y en el portapapeles del sistema operativo. Sin embargo, no ayuda si desea obtener texto del portapapeles al búfer tmux.

Tyler Holien
fuente
1
Funciona perfectamente y es la solución más simple del grupo.
Naseer
2
No funciona para mí en Linux, pero este sí: unix.stackexchange.com/a/131074/13601
Sebastian Blask
1
A partir de OS X 10.10, parece reattach-to-user-namespaceque no es necesario.
Chris
funciona en el capitan
olleh
2
Esto ya no funciona para Tmux 2.4, que se lanzó el 20 de abril de 2017. En cambio, debe usar bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip"y para OS X:bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy"
Jason Axelson, el
16

Es posible que desee probar el complemento tmux-yank . Permite copiar directamente al portapapeles del sistema (OS X y Linux) y algunas otras ventajas como quitar la línea de shell actual.


fuente
77
Esta es una excelente solución limpia y debe considerarse más, ya que es una respuesta mucho más reciente que las otras. ¡Gracias por compartir!
dmonopolio
9

Después de probar una solución diferente, aquí está mi configuración final:

# move x clipboard into tmux paste buffer
bind C-p run "xclip -o | tmux load-buffer -
# move tmux copy buffer into x clipboard
bind C-y run "tmux save-buffer - | xclip -i -selection clipboard"

El uso de save-buffer en lugar de show-buffer proporciona los datos reales sin los datos que se muestran con saltos de línea cuando se encuentra en divisiones.

También lo uso para comenzar la selección / copia en el modo de copia tmux:

bind-key -t vi-copy 'v' begin-selection
bind-key -t vi-copy 'y' copy-selection

Supongo que podría ser posible fusionar la selección de copias con la tecla 'y' Y moverla al portapapeles x.

Ownatik
fuente
Intenté fusionar ambos comandos como mencionaste sin éxito. ¿Alguna idea de cómo hacerlo?
Rafael Vega
9

Aquí hay un intento de una respuesta integral.

Primero un poco de historia

Cuando se hizo esta pregunta por primera vez (junio de 2011), copiar texto de Tmux al portapapeles tenía que ser un proceso de dos pasos, primero copie el texto seleccionado al búfer de Tmux, luego copie el texto del búfer de Tmux al portapapeles del sistema.

En 1.8 (marzo de 2013) copy-pipese agregó el comando que le permite copiar el texto seleccionado directamente en el portapapeles del sistema (u otro destino).

Luego, en 2.4 (abril de 2017), las tablas clave cambiaron significativamente, lo que dejó obsoletas muchas de las respuestas en esta página.

Respondiendo la pregunta original

Linux :

bind-key C-y run-shell "tmux save-buffer - | xclip -i -r > /dev/null" \; display-message "Copied tmux buffer to selection"
bind-key C-Y run-shell "tmux save-buffer - | xclip -i -r -selection clipboard > /dev/null" \; display-message "Copied tmux buffer to clipboard"
bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer"

Mac :

Si está utilizando homebrew , debe instalarlo reattach-to-user-namespaceejecutando el siguiente comando en una terminal:

brew install reattach-to-user-namespace

Luego en su ~ / .tmux.conf:

bind-key C-y run-shell "tmux save-buffer - | reattach-to-user-namespace pbcopy" \; display-message "Copied tmux buffer to clipboard"
bind-key C-p run-shell "reattach-to-user-namespace pbpaste | tmux load-buffer - ; tmux paste-buffer"

El método más corto (copie y pegue una selección directamente desde y hacia el portapapeles para tmux> 2.4)

Nota: hay dos versiones para Linux porque Linux tiene un portapapeles primario y secundario (también conocido como selección).

Linux :

bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip -r" \; display-message "Copied to selection"
bind-key -T copy-mode-vi Y send-keys -X copy-pipe "xclip -r -selection clipboard" \; display-message "Copied to clipboard"
bind-key C-p run-shell "xclip -o | tmux load-buffer - && tmux paste-buffer"

Mac :

bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy" \; display-message "Copied to clipboard"

Personalizando estos comandos

  • Si no desea que el comando le diga qué hizo en la línea de estado, simplemente elimine el display-message(así como el \;que viene antes).

  • Si está utilizando el modo de copia de estilo Emacs en lugar de vi, reemplace cualquier instancia de copy-mode-vicon solocopy-mode

  • Si está ejecutando Linux y desea usar en xsellugar de xclipreemplazar xclip -rcon xsel -i -py xclip -oconxsel -o -p

  • El -rde xclip -res opcional, se elimina el último salto de línea. Es útil para copiar comandos, luego, cuando los pegue, no se ejecutarán de inmediato.

  • Si está haciendo un túnel sobre SSH, debe consultar https://unix.stackexchange.com/a/354581/14252

Referencias

Jason Axelson
fuente
¿Es este comando bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer", sigue siendo válido? paratmux>2.4
alpha_989
7

No me gusta tener pulsaciones de teclas adicionales, así que quería algo más ambicioso. Ingrese al modo de copia con [, resalte el texto correcto y luego presione] para copiar el texto en el portapapeles.

Además, a tmux le gusta incluir nuevas líneas en las expresiones que se ajustan (¡y curiosamente esas nuevas líneas están en el lugar equivocado ! No están donde la expresión se ajusta en la pantalla). Entonces quería que C-] copiara la expresión eliminando las nuevas líneas.

En tmux 1.6 probé esto:

bind [ copy-mode
bind -t vi-copy ] run "tmux send-keys Enter; tmux show-buffer | xclip -i -selection clipboard;"
bind -t vi-copy C-] run "tmux send-keys Enter; tmux show-buffer | perl -pe 's/\n//' | xclip -i -selection clipboard;"

pero eso no funcionó porque tmux no parece feliz de vincular cosas complejas a la tabla vi-copy. Así que terminé haciendo esto en su lugar:

bind [ copy-mode \;                                                        \
    bind -n ] run                                                          \
    "tmux send-keys Enter;                                                 \
     tmux show-buffer | xclip -i -selection clipboard;                     \
     tmux unbind -n C-];                                                   \
     tmux unbind -n ]" \;                                                  \
    bind -n C-] run                                                        \
    "tmux send-keys Enter;                                                 \
     tmux show-buffer | perl -pe 's/\n//' | xclip -i -selection clipboard; \
     tmux unbind -n C-];                                                   \
     tmux unbind -n ]"

Esto lleva a cosas extrañas (] o C-] actuará de manera extraña la próxima vez que las use, pero solo una vez) si sale del modo de copia de otra manera además de] o C-]. Esto podría solucionarse con algunos enlaces más que imagino, pero esto hace lo que quiero la mayor parte del tiempo.

Leif
fuente
stackoverflow.com/a/10954274/69663 señala que hay un informe de error relacionado con las limitaciones de bind-key en sourceforge.net/tracker/…
unhammer
4

Hay una solución en Arch Wiki usando xclip:

# move tmux copy buffer into x clipboard
bind-key C-y save-buffer /tmp/tmux-buffer \; run-shell "cat /tmp/tmux-buffer | xclip"

https://wiki.archlinux.org/index.php/Tmux

jasonwryan
fuente
2
¿Crea tmux el save-bufferarchivo de forma segura en un directorio compartido? De lo contrario, ponerlo /tmpes un agujero de seguridad. Hay un uso inútil caty falta la eliminación del archivo temporal. Entonces es una cuestión de xselvs xclip, que son equivalentes aquí, y tienes mi solución (escrita independientemente).
Gilles
1
Gracias Gilles Actualizaré la wiki para reflejar tus puntos.
jasonwryan
4

Una solución para Mac OS X. Siga estos 2 pasos:

  1. Utilice la solución alternativa de Chris Johnsen: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard

  2. Agregue este código a su configuración de tmux (~ / .tmux.conf)

# paste clipboard into tmux buffer
bind v run-shell "reattach-to-user-namespace -l zsh -c 'tmux set-buffer \\"$(pbpaste)\\"; tmux paste-buffer'"
# put tmux buffer into x clipboard
bind y run-shell "reattach-to-user-namespace -l zsh -c 'tmux show-buffer | pbcopy'"

Alex Gaudio
fuente
4

Una variante ligeramente modificada de la respuesta aceptada, que preparé.

También prefiero usar el portapapeles del sistema (Ctrl-C, Ctrl-V) además del primaryportapapeles predeterminado de xclip (el que obtienes con la selección del mouse y los clics medios del mouse). Para elegir el portapapeles del sistema, debe pasar -selection clipboardargumentos a xclip.

Además, al copiar un búfer en un portapapeles, me gusta la posibilidad de elegir qué búfer quiero copiar. Se hace usando choose-buffery luego pasando el argumento al buffer para save-bufferusar -b %%.

# Copy into clipboard
bind C-c choose-buffer "run \"tmux save-buffer -b %% - | xclip -i -selection clipboard\""
# Paste from clipboard
bind C-v run "xclip -o -selection clipboard | tmux load-buffer - ; tmux paste-buffer"
# Copy into primary
bind C-y choose-buffer "run \"tmux save-buffer -b %% - | xclip -i \""
# Paste from primary
bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer"

ACTUALIZACIÓN: De alguna manera con tmux 1.8 y dos de mis instalaciones de openSUSE 12.2, veo un bloqueo cuando tmux run-shellse invoca con la xcliplectura de stdin sobre una tubería. En cambio, decidí xselintentarlo y eso parece funcionar. Estas son las combinaciones de teclas equivalentes que se utilizan xsel. También solía &&encadenar los comandos en pegar para mayor robustez.

# Copy into clipboard
bind C-c choose-buffer "run \"tmux save-buffer -b '%%' - | xsel -i -b\""
# Paste from clipboard
bind C-v run "xsel -o -b | tmux load-buffer - && tmux paste-buffer"
# Copy into primary
bind C-y choose-buffer "run \"tmux save-buffer -b '%%' - | xsel -i\""
# Paste from primary
bind C-p run "xsel -o | tmux load-buffer - && tmux paste-buffer"
Tuxdude
fuente
4

Esta es mi respuesta bastante larga que debería solucionar dos problemas principales con el uso de xclip para copiar el búfer de una sesión tmux remota (ssh):

1. xclip irresponsable

Para mí, la respuesta de @ Grauwolf con xclipno funcionó (hace que tmux pane sea totalmente irresponsable). Descubrí por qué en la página Tmux de la wiki de Arch :

xclip también podría usarse para ese propósito, a diferencia de xsel, funciona mejor en la impresión de flujo de bits sin formato que no se ajusta a la configuración regional actual. Sin embargo, es mejor usar xsel en lugar de xclip, porque xclip no cierra STDOUT después de leer del búfer de tmux. Como tal, tmux no sabe que la tarea de copia se ha completado y continúa esperando la finalización de xclip, lo que hace que tmux no responda. Una solución alternativa es redirigir STDOUT de xclip a / dev / null

Entonces el enlace debe ser:

bind-key C-y run "tmux save-buffer - | xclip -i -sel clip > /dev/null"

Ahora, esto funcionará si su sesión tmux es local.

2. xclip no puede conectarse a X

Si está utilizando tmux sobre ssh -X , hay grandes posibilidades de que esto no funcione directamente.

Esto se debe a que la variable de shell $DISPLAYdebe establecerse correctamente.

Solución completa

Entonces, para mí, la solución de trabajo completa es poner las siguientes líneas en mi ~/.tmux.conf:

set-option -g update-environment "DISPLAY"
bind-key C-y run "export DISPLAY=`tmux show-env | sed -n 's/^DISPLAY=//p'`; tmux save-buffer - | xclip -i -selection clipboard >/dev/null"
# Or more concise:
bind-key C-y run "tmux save-buffer - | xclip -i -selection clipboard -d `tmux show-env | sed -n 's/^DISPLAY=//p'` >/dev/null

Para pegar desde primaria:

bind-key C-p run "xclip -d `tmux show-env | sed -n s/^DISPLAY=//p` -o | tmux load-buffer - && tmux paste-buffer"

No entiendo completamente por qué $DISPLAYno está configurado correctamente durante el abastecimiento .tmux.conf, así que es por eso que tengo que extraerlo con tmux show-envy sed.

Si tiene tmux> = 1.8, puede adaptar este comando con copy-pipe:

bind-key -t vi-copy y copy-pipe 'xclip -in -selection clipboard -d `tmux show-env | sed -n s/^DISPLAY=//p` >/dev/null'
PlasmaBinturong
fuente
/home/linux/.tmux.conf:11: invalid or unknown command: bind-key C-y run "tmux save-buffer - | xclip -i -selection clipboard -d `tmux show-env | sed -n 's[0/0] PLAY=//p'` >/dev/null
usuario
@user el sedcomando que muestra no es el mismo que escribí ... ¿Es esto lo que escribió en su .tmux.conf?
PlasmaBinturong
Acabo de copiar y pegar tu código.
usuario
@usuario, extraño. Podría haber muchas fuentes de errores. Primero verifique que su cita esté bien. Entonces, ¿estás familiarizado con sed? El comando debe ser: sed -n s/^DISPLAY=//p. Alternativamente, se puede utilizar cut: tmux show-env DISPLAY | cut -d'=' -f2. También podría valer la pena revisar su versión de tmux.
PlasmaBinturong
3

Estoy tratando de encontrar una manera decente de copiar lo que tengo en un búfer tmux en mi portapapeles. He intentado un par de cosas diferentes como

Para los enlaces de estilo emacs hay algunas opciones diferentes. (¿El estilo Vi debería ser similar?) El enlace típico para hacer "selección de copia" en emacs es Mw, por lo que sería muy conveniente tener el mismo enlace en tmux.

1 - Sería ideal, pero no funciona (¿debido a la limitación de tmux?)

unbind-key -t emacs-copy M-w
bind-key -t emacs-copy M-w copy-selection\; \
  run-shell "tmux save-buffer - | xsel --input --clipboard"

2 - Compromiso que funciona bien para mí : acepte usar una combinación de teclas diferente para emacs-copy en tmux. Utilice por ejemplo CMw. (Este enlace, que se definirá "globalmente", no solo en modo copia, sino también útil en modo copia)

bind-key -n C-M-w send-keys M-w\; \
 run-shell "tmux save-buffer - | xsel --input --clipboard" 
Hugo Heden
fuente
3

Muchas de estas respuestas no funcionaron para mi Ubuntu 14.04 en zsh tal cual. No estoy seguro de si mi shell tuvo algo que ver con eso, pero aquí está mi versión funcional del uso de esta estrategia para copiar y esta estrategia para pegar.

    bind-key -t vi-copy 'v' begin-selection
    bind-key -t vi-copy 'y' copy-pipe "xclip -sel clip -i"
    bind-key ] run-shell "xclip -sel clip -o | tmux load-buffer - ; tmux paste-buffer" 

Algunas notas:

  • para copy-pipe, necesitaba especificar mi portapapeles con -sel clip -i. Esa línea combina el búfer yank to tmux y lo envía a xclip.
  • para pegarlo realmente, necesitaba especificar nuevamente qué portapapeles con -sel clip -o

Esto funciona muy bien ahora para mi configuración vim / zsh / tmux.

brianclements
fuente
¡gracias! -sel clip -iresuelve el problema Aunque, yo no entiendo por qué es necesario especificar de nuevo portapapeles para pegarlo (estándar ]funciona para mí)
melekes
1

Y la versión mejorada de la respuesta @Leif podría ser:

tmux bind-key '[' run "tmux copy-mode;
tmux bind-key -n ']' run \"tmux send-keys Enter; tmux save-buffer - | xclip -i -selection clipboard;
tmux unbind-key -n ']'\";
tmux bind-key -n q run \"tmux unbind -n ']'; tmux send-keys q\";
tmux bind-key -n C-c run \"tmux unbind -n ']'; tmux send-keys C-c\""

De esta manera no hay consecuencias si sale del modo de copia de otra manera además], el código anterior está envuelto en tundle / tmux-yank un complemento tmux para copiar texto tmux en el portapapeles del sistema, apunta tmux> = 1.6 en OS X y Linux

Javier López
fuente
1

En OS-X con tmux versión 2.2 o posterior, funcionará lo siguiente:

bind-key -t emacs-copy MouseDragEnd1Pane copy-pipe "pbcopy"
bind-key -t vi-copy MouseDragEnd1Pane copy-pipe "pbcopy"
Kyle Kloepper
fuente
1

Yo uso copyqun administrador de portapapeles multilínea. (Funciona con Windows, OSX, Linux).

  • Agregue las siguientes líneas en ~/.tmux.conf:

    set-window-option -g mode-keys vi
    bind C-y run 'out=`tmux save-buffer - ` && copyq add "$out"'
    
  • cygwinexige copyq.exeubicación en ~/.bashrc:

    export PATH="$PATH:/cygdrive/c/Program Files (x86)/CopyQ"
    
Oleg Svechkarenko
fuente