Fazendo o tmux copiar um buffer para a área de transferência

118

Estou tentando descobrir uma maneira decente de copiar o que tenho em um buffer tmux na minha área de transferência. Eu tentei algumas coisas diferentes, como

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

o que me aproxima bastante, tudo o que preciso fazer é pressionar control-d após executar o prefixo-p.

Eu tentei consertar isso fazendo

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

Mas isso simplesmente não funciona. De fato, se eu juntar isso a apenas

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

não faz nada, então estou assumindo que a janela dividida não gosta de << em um comando shell.

Alguma ideia?

Edit: Você pode pular o select-pane -t 2se quiser, não é realmente importante. Eu apenas uso um layout específico e o painel 2 é o que eu prefiro dividir quando faço outra coisa, de modo que entre minhas ligações envolvendo divisões por padrão.

Poderes Digitais
fonte
2
Verifique a resposta abaixo de 2014, que é mais recente do que algumas das outras. Ele recomenda o plugin tmux yank, que funciona muito bem.
Dmonopoly
Para uma resposta que esteja atualizada com o Tmux 2.4 (lançado em abril de 2017) e 2.6, veja minha resposta
Jason Axelson

Respostas:

26

Aqui, os documentos precisam de novas linhas. Por exemplo, em um script de shell, você pode escrever

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

Eu não acho que o tmux permita que você coloque novas linhas lá, e mesmo que isso acontecesse, essa não seria uma boa abordagem. E se os dados em si contiverem HEREsozinhos em uma linha (por exemplo, porque você está copiando seus .tmux.conf)?

Sugiro escrever o conteúdo do buffer em um arquivo temporário. Não testado:

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

Há uma condição de corrida se você usar este comando em duas instâncias tmux separadas. Não sei como resolver isso.

Gilles
fonte
Obrigado funciona perfeitamente, a condição de corrida não é uma preocupação para mim, eu uso apenas uma sessão.
Digital Powers
Para evitar condição de corrida, eu sugiro usar mktempo que está amplamente disponível
Grief
@ Grief Boa ideia. Nesse caso, o uso do PID do processo tmux também funcionaria e provavelmente seria mais fácil de organizar ( $PPIDem um shell lançado pelo tmux). Mas como você obtém o nome do arquivo variável (no entanto, ele é construído) no argumento de save-buffer? Acho que, save-buffer - | …como na resposta de Grauwolf , que acaba com um arquivo temporário?
Gilles
Você está correto, minha culpa, isso não seria possível.
Luto
93

Isso deve 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
fonte
11
O mesmo acontece. Isso é muito melhor do que usar um arquivo temporário, obrigado. Ele até lida automaticamente com várias sessões simultâneas, graças às TMUXvariáveis ​​de ambiente.
Gilles
22
Uma instrução melhor para o C-pseria: bind C-p run "xclip -o | tmux load-buffer - ; tmux paste-buffer"- sem problemas de citação ou limite de linha de comando.
docwhat
8
O tmux tem um gancho para copiar a seleção para a área de transferência quando está dentro copy-mode?
Ehtesh Choudhury
11
xclip -oopção não trabalhou para mim, então eu mudei parabind C-c run "tmux save-buffer - | xclip -selection c"\; display-message "Buffer copied to clipboard"
Pawka
6
Toda vez que faço a cópia dessa maneira, o tmux para de responder a qualquer atalho do teclado. Alguma solução para isso?
Skrat
41

Uma solução mais simples para Mac OS-X

Isso se baseia na resposta de Alex e usa coisas que não existiam na época.

Se você estiver usando homebrew (e se não estiver, por que não está?), Poderá fazer o seguinte:

brew install reattach-to-user-namespace

Então no seu ~/.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 o buffer do tmux (você já deve ter copiado algo usando o tmux) na área de trabalho do Mac, use <tmux-key> Control-c. Agora estará disponível para Command-voupbpaste

Para colar algo da área de trabalho do Mac, use <tmux-key> Control-v.

docwhat
fonte
2
Esta resposta é excelente. Eu estava usando o tmux show-bufferque causou problemas de quebra de linha tmux save-buffer -resolvidos.
event_jr 18/03/12
O que faz o -final de tmux save-buffer -?
hekevintran
Emite o save-bufferto stdout. Você pode substituir -por um nome de arquivo e ele será salvo lá. Isso impede que você grave (e precise limpar) um arquivo.
docwhat
11
A partir do OS X 10.10, o espaço de nome de reconectar ao usuário não é mais necessário. Quase todo tutorial e documentação sobre tmux e OS X menciona isso, porque copiar e colar não era facilmente possível alguns anos atrás. Hoje em dia (principalmente) funciona fora da caixa.
Rafael Bugajewski
40

O copy-pipecomando foi adicionado a partir da versão 1.8. Ele copia uma seleção para o buffer tmux e a envia para um comando. Agora não há necessidade de uma ligação de prefixo. Aqui está um exemplo:

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

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

Agora, quando você tiver selecionado algum texto copy-mode, ycopiará esse texto para o buffer tmux, bem como para a área de transferência do SO. No entanto, não ajuda se você deseja obter texto da área de transferência para o buffer tmux.

Tyler Holien
fonte
11
Funciona perfeitamente e é a solução mais simples do grupo.
Naseer
2
Não funciona para mim no Linux, este faz embora: unix.stackexchange.com/a/131074/13601
Sebastian Blask
11
No OS X 10.10, parece que reattach-to-user-namespacenão é necessário.
23415 Chris
trabalha em el capitan
olleh 26/10/2015
2
Isso não funciona mais para o Tmux 2.4, lançado em 20 de abril de 2017. Em vez disso, você precisa usar bind-key -T copy-mode-vi y send-keys -X copy-pipe "xclip"e para o OS X:bind-key -T copy-mode-vi y send-keys -X copy-pipe "reattach-to-user-namespace pbcopy"
Jason Axelson
16

Você pode tentar o plugin tmux-yank . Permite copiar diretamente para a área de transferência do sistema (OS X e Linux) e algumas outras vantagens, como puxar a linha de shell atual.


fonte
7
Essa é uma solução ótima e limpa e deve ser considerada mais, pois é uma resposta muito mais recente que as outras. Obrigado por compartilhar!
dmonopoly
9

Depois de tentar uma solução diferente, aqui está minha configuração 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"

o uso de save-buffer em vez de show-buffer fornece os dados reais sem os dados, como mostra as quebras de linha quando você está dividido.

Também uso isso para iniciar a seleção / cópia no modo de cópia tmux:

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

Acho que seria possível mesclar a seleção de cópias com a tecla 'y' E movê-la para a área de transferência x.

Ownatik
fonte
Eu estava tentando mesclar os dois comandos, como você mencionou, sem sucesso. Alguma idéia de como fazer isso?
Rafael Vega
9

Aqui está uma tentativa de uma resposta abrangente.

Primeiro um pouco de história

Quando esta pergunta foi feita pela primeira vez (junho de 2011), a cópia de texto do Tmux para a área de transferência tinha que ser um processo de duas etapas, primeiro copie o texto selecionado para o buffer do Tmux e, em seguida, copie o texto do buffer do Tmux para a área de transferência do sistema.

Em 1.8 (março de 2013), copy-pipefoi adicionado o comando que permite copiar o texto selecionado diretamente na área de transferência do sistema (ou outro destino).

Então, em 2.4 (abril de 2017), as tabelas principais foram alteradas significativamente, tornando obsoletas muitas das respostas nesta página.

Respondendo à pergunta 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 :

Se você estiver usando o homebrew , instale-o reattach-to-user-namespaceexecutando o seguinte comando em um terminal:

brew install reattach-to-user-namespace

Depois, no seu ~ / .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"

O método mais curto (copie e cole uma seleção diretamente de e para a área de transferência do tmux> 2.4)

Nota: existem duas versões para Linux porque o Linux possui uma área de transferência primária e secundária (também conhecida como seleção).

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"

Customizando esses comandos

  • Se você não deseja que o comando lhe diga o que ele fez na linha de status, remova o display-message(assim como o \;que vem antes dele).

  • Se você estiver usando o modo de cópia no estilo Emacs em vez de vi, substitua qualquer instância de copy-mode-viporcopy-mode

  • Se você estiver executando o Linux e quiser usar, em xselvez de xclipsubstituir xclip -rpor xsel -i -pe xclip -ocomxsel -o -p

  • O -rin xclip -ré opcional, ele remove a última nova linha. É útil para copiar comandos, quando você os cola, eles não serão executados imediatamente.

  • Se você estiver encapsulando o SSH, consulte https://unix.stackexchange.com/a/354581/14252

Referências:

Jason Axelson
fonte
Este comando bind-key C-p run-shell "xclip -o | tmux load-buffer - ; tmux paste-buffer"ainda é válido? fortmux>2.4
alpha_989
7

Não gosto de pressionar teclas adicionais, então queria algo mais ambicioso. Entre no modo de cópia com [, realce o texto à direita e pressione] para copiar o texto na área de transferência.

Além disso, o tmux gosta de incluir novas linhas nas expressões que quebram (e estranhamente essas novas linhas estão no lugar errado ! Elas não estão onde a expressão está quebrada na tela). Então, eu queria que C-] copiasse a expressão removendo as novas linhas.

No tmux 1.6, tentei o seguinte:

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;"

mas isso não funcionou porque o tmux não parece feliz em vincular coisas complexas à tabela vi-copy. Então acabei fazendo isso:

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 ]"

Isso leva a coisas estranhas (] ou C-] agirão engraçadas na próxima vez que você as usar, mas apenas uma vez) se você sair do modo de cópia de outra maneira além de] ou C-]. Isso poderia ser corrigido com mais algumas ligações, imagino, mas isso faz o que quero na maioria das vezes.

Leif
fonte
stackoverflow.com/a/10954274/69663 observa que há um relatório de bug relacionado nas limitações de bind-chave na sourceforge.net/tracker/...
unhammer
4

Existe uma solução no 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
fonte
2
O tmux cria o save-bufferarquivo com segurança em um diretório compartilhado? Caso contrário, colocá-lo /tmpé uma falha de segurança. Há um uso inútil cate a remoção do arquivo temporário está ausente. Então é uma questão de xselvs xclip, que é equivalente aqui, e você tem minha solução (escrita indenpendentemente).
Gilles
11
Obrigado Gilles. Vou atualizar o wiki para refletir seus pontos.
jasonwryan
4

Uma solução para o Mac OS X. Siga estas 2 etapas:

  1. Use a solução alternativa de Chris Johnsen: https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard

  2. Adicione este código à sua configuração 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
fonte
4

Uma variante ligeiramente modificada da resposta aceita, que eu preparei.

Também prefiro usar a área de transferência do sistema (Ctrl-C, Ctrl-V), além da primaryárea de transferência padrão do xclip (aquela que você obtém com a seleção do mouse e os cliques do meio do mouse). Para escolher a área de transferência do sistema, você precisa passar o -selection clipboardargumento para xclip.

Além disso, ao copiar um buffer para uma área de transferência, gosto da capacidade de escolher qual buffer quero copiar. Ele é feito usando choose-buffere, em seguida, passando tamponar o argumento 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"

ATUALIZAÇÃO: De alguma forma, com o tmux 1.8 e duas das minhas instalações do openSUSE 12.2, vejo um travamento quando tmux run-shellé invocado com a xclipleitura de stdin sobre um pipe. Em vez disso, decidi xseltentar e isso parece funcionar. Essas são as ligações de teclas equivalentes usando xsel. Eu também costumava &&encadear os comandos em pasta para obter mais 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
fonte
4

Esta é minha resposta bastante demorada que deve corrigir dois grandes problemas com o uso do xclip para copiar o buffer de uma sessão remota (ssh) tmux:

1. xclip sem resposta

Para mim, a resposta de Grauwolf com xclipnão funcionou (torna o painel tmux totalmente irresponsivo). Eu descobri o porquê na página Tmux do wiki do Arch :

O xclip também pode ser usado para esse fim, ao contrário do xsel, ele funciona melhor na impressão de fluxo de bits bruto que não se encaixa no local atual. No entanto, é melhor usar o xsel em vez do xclip, porque o xclip não fecha o STDOUT depois de ler o buffer do tmux. Como tal, o tmux não sabe que a tarefa de cópia foi concluída e continua aguardando o término do xclip, tornando o tmux sem resposta. Uma solução alternativa é redirecionar o STDOUT do xclip para / dev / null

Portanto, a ligação deve ser:

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

Agora, isso funcionará se a sua sessão do tmux for local.

2. xclip incapaz de se conectar ao X

Se você estiver usando o tmux over ssh -X , há grandes chances de isso não funcionar diretamente.

Isso ocorre porque a variável shell $DISPLAYprecisa ser definida corretamente.

Solução completa

Então, para mim, a solução de trabalho completa é colocar as seguintes linhas no meu ~/.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 colar do primário:

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

Eu não entendo completamente por que $DISPLAYnão está definido corretamente durante a fonte .tmux.conf, então é por isso que tenho que extraí-lo com tmux show-enve sed.

Se você possui tmux> = 1.8, pode adaptar este comando com 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
fonte
/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
usuário
@ user o sedcomando que você mostra não é o mesmo que eu escrevi ... Foi isso que você escreveu no seu .tmux.conf?
PlasmaBinturong 23/04
Acabei de copiar e colar seu código.
usuário
@ usuário, estranho. Pode haver muitas fontes de erros. Verifique primeiro se a sua cotação está correta. Então, você está familiarizado sed? O comando deve ser: sed -n s/^DISPLAY=//p. Alternativamente, você poderia usar cut: tmux show-env DISPLAY | cut -d'=' -f2. Também pode valer a pena conferir sua versão do tmux.
PlasmaBinturong 25/04
3

Estou tentando descobrir uma maneira decente de copiar o que tenho em um buffer tmux na minha área de transferência. Eu tentei algumas coisas diferentes, como

Para ligações no estilo emacs, existem algumas opções diferentes. (O estilo Vi deve ser semelhante?) A ligação típica para fazer "seleção de cópia" no emacs é Mw, portanto, seria muito conveniente ter a mesma ligação no tmux.

1 - Seria ideal, mas não funciona (devido à limitação do 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 - Comprometimento que funciona bem para mim : aceite usar uma combinação de teclas diferente para o emacs-copy no tmux. Use, por exemplo, CMw. (Essa ligação será definida "globalmente" - não apenas no modo de cópia - mas apenas útil no modo de cópia)

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

Muitas dessas respostas não funcionaram no meu Ubuntu 14.04 no zsh como está. Não tenho certeza se meu shell teve algo a ver com isso, mas aqui está minha versão de trabalho do uso dessa estratégia para copiar e dessa estratégia para colar.

    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" 

Algumas notas:

  • para pipe de cópia, eu precisava especificar minha área de transferência com -sel clip -i. Essa linha combina o buffer do yank para o tmux e o envia para o xclip.
  • para colá-lo, eu precisava especificar novamente qual área de transferência com -sel clip -o

Isso funciona muito bem agora para minha configuração do vim / zsh / tmux.

brianclements
fonte
obrigado! -sel clip -iresolve o problema. Embora, eu não entendo por que você precisa especificar prancheta novamente para colá-lo (padrão ]funciona para mim)
Melekes
1

E a versão melhorada da resposta @ Leif poderia 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\""

Dessa forma, não há consequências se você sair do modo de cópia de outra maneira, além de], o código acima está envolto em tundle / tmux-yank, um plugin tmux para copiar texto do tmux na área de transferência do sistema, ele tem como alvo tmux> = 1.6 no OS X e Linux.

Javier López
fonte
1

No OS-X com tmux versão 2.2 ou posterior, o seguinte funcionará:

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

Eu uso copyqum gerenciador de área de transferência de várias linhas. (Funciona com Windows, OSX, Linux.)

  • Adicione as seguintes linhas em ~/.tmux.conf:

    set-window-option -g mode-keys vi
    bind C-y run 'out=`tmux save-buffer - ` && copyq add "$out"'
    
  • cygwinexige copyq.exelocalização em ~/.bashrc:

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