DEV Community

Rafael Dutra for apsis-cc

Posted on

Fzf com Tmux - integração e pop-ups

1. Retomando: o que é o Fzf

Na primeira parte desta série vimos o que é o fzf, como instalá-lo e como usá-lo direto no shell com Ctrl+R, Ctrl+T e Alt+C. Quem também usa tmux no dia a dia ganha um segundo nível de integração: o fzf pode rodar dentro de janelas flutuantes (pop-ups) do próprio tmux, sem interferir no layout de painéis já aberto, e servir de seletor para operações do próprio tmux — trocar de sessão, de janela, de painel, matar processos em outro painel etc.

2. Por que integrar Fzf com Tmux

Sem integração, usar o fzf dentro de uma sessão tmux funciona normalmente, mas cada busca ocupa o painel inteiro: se o objetivo é só escolher um arquivo ou trocar de branch rapidamente, o conteúdo do painel (um editor, um servidor rodando) é temporariamente coberto e é preciso "voltar" depois. Além disso, o tmux tem sua própria lista de coisas que fazem sentido filtrar de forma fuzzy — sessões, janelas, painéis — e não há um binding nativo do tmux para isso.

O fzf-tmux, incluído na instalação do fzf, resolve o primeiro problema: roda o fzf em uma janela sobreposta (pop-up ou split temporário) que desaparece assim que a seleção é feita, sem afetar o conteúdo do painel original. Combinado com bindings customizados no tmux.conf, também resolve o segundo.

3. fzf-tmux: pop-ups nativos

fzf-tmux é um wrapper de shell em torno do fzf que aceita as mesmas opções, mais flags de posicionamento e tamanho da janela sobreposta:

# pop-up centralizado, 80% da largura e 60% da altura do terminal
fzf-tmux -p 80%,60%

# split na parte de baixo do painel atual, ocupando 40% da altura
fzf-tmux -d 40%

# split lateral à direita, ocupando 50% da largura
fzf-tmux -d 50% -r
Enter fullscreen mode Exit fullscreen mode

A flag -p (disponível a partir do tmux 3.2, que suporta display-popup) é a mais usada hoje: cria uma janela verdadeiramente flutuante, sobreposta ao conteúdo do painel, que não reorganiza o layout existente — diferente do -d, que faz um split real e temporariamente redistribui o espaço entre painéis.

# substitui o Ctrl+T padrão (busca de arquivo) por um pop-up
vim $(fzf-tmux -p 80%,60%)
Enter fullscreen mode Exit fullscreen mode

4. Configurando pop-ups no ~/.tmux.conf

O ganho maior vem de amarrar fzf-tmux a atalhos do próprio tmux, para que buscas fiquem a uma tecla de distância independente do que está rodando no painel atual. Alguns bindings úteis para adicionar ao ~/.tmux.conf:

# trocar de sessão com busca fuzzy em pop-up
bind-key S display-popup -E "tmux list-sessions -F '#S' | fzf --reverse | xargs tmux switch-client -t"

# trocar de janela na sessão atual
bind-key W display-popup -E "tmux list-windows -F '#I: #W' | fzf --reverse | cut -d: -f1 | xargs tmux select-window -t"

# abrir um seletor de painéis de todas as sessões
bind-key P display-popup -E "tmux list-panes -a -F '#S:#I.#P #{pane_current_command}' | fzf --reverse | cut -d' ' -f1 | xargs tmux switch-client -t"
Enter fullscreen mode Exit fullscreen mode

A flag -E do display-popup fecha o pop-up automaticamente assim que o comando termina — importante aqui, já que o próprio fzf já trata Esc como cancelamento e Enter como confirmação; sem -E, o pop-up ficaria aberto esperando mais um Enter para fechar.

Depois de editar o tmux.conf, recarregue a configuração sem precisar reiniciar as sessões:

Ctrl+b :source-file ~/.tmux.conf
Enter fullscreen mode Exit fullscreen mode

5. Casos de uso práticos

Com os bindings acima, o fluxo de trabalho muda de forma sutil mas sensível: em vez de Ctrl+b s (lista de sessões nativa do tmux, sem busca) e navegar com as setas, Ctrl+b S abre o pop-up já filtrável — digitar duas ou três letras do nome do projeto já é suficiente. O mesmo vale para W (janelas) e P (painéis entre sessões, útil quando há muitas sessões abertas simultaneamente, cada uma com vários painéis).

Outro caso comum é buscar e matar um processo específico rodando em qualquer painel, sem precisar navegar até ele manualmente:

bind-key K display-popup -E "ps aux | fzf --reverse --header='Matar processo' | awk '{print \$2}' | xargs -r kill -9"
Enter fullscreen mode Exit fullscreen mode

E, claro, os usos do artigo anterior (buscar arquivo, trocar de branch, navegar no histórico) continuam funcionando igual dentro do tmux — a diferença é que, com fzf-tmux -p, é possível trocar os bindings padrão do shell (Ctrl+T, Ctrl+R) para abrirem em pop-up em vez de ocupar o painel inteiro:

# no .bashrc/.zshrc, quando dentro de uma sessão tmux
export FZF_TMUX_OPTS="-p 80%,60%"
Enter fullscreen mode Exit fullscreen mode

6. Plugins úteis: tmux-fzf

Para quem prefere não escrever os bindings à mão, o plugin tmux-fzf empacota menus fuzzy prontos para sessões, janelas, painéis e até comandos do próprio tmux (matar sessão, renomear janela, mover painel), instalável via TPM — o gerenciador de plugins citado na primeira parte desta série:

# no ~/.tmux.conf
set -g @plugin 'sainnhe/tmux-fzf'
Enter fullscreen mode Exit fullscreen mode

Depois de instalar (Ctrl+b I para o TPM buscar os plugins), o atalho padrão do plugin (Ctrl+b F ou o prefixo configurado) abre um menu principal com todas as categorias — uma alternativa mais completa aos bindings manuais da seção anterior, ao custo de menos controle fino sobre o comportamento de cada um.

7. Conclusão

Com o fzf-tmux e os bindings de pop-up, a busca fuzzy deixa de ser algo que só acontece dentro do shell e passa a fazer parte da navegação do próprio tmux — trocar de sessão, janela ou painel vira tão rápido quanto digitar algumas letras, sem sair do teclado e sem perder de vista o que está rodando nos outros painéis. Combinados, os dois artigos desta série cobrem o suficiente para o fzf virar parte permanente do fluxo de trabalho no terminal, do shell puro até o multiplexador.


Referências:

  1. fzf — GitHub
  2. tmux — display-popup
  3. tmux-fzf — GitHub

Top comments (0)