Skip to main content

Neovim and Tmux Integration

fzf Inside Neovim

telescope-fzf-native.nvim

The most common approach is using Telescope with the native fzf sorter for best-in-class fuzzy matching inside Neovim:

lua/plugins/telescope.lua
{
"nvim-telescope/telescope-fzf-native.nvim",
build = "make",
config = function()
require("telescope").load_extension("fzf")
end,
}

This replaces Telescope's default sorter with fzf's v2 algorithm — giving you the same fuzzy scoring you get from fzf in the shell, inside Telescope.

fzf.vim — Classic fzf Inside Vim

For minimal setups (or vim users), fzf.vim runs fzf in a terminal buffer:

" Install with vim-plug
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
~/.config/nvim/init.vim
" Key mappings for fzf.vim
nnoremap <leader>ff :Files<CR>
nnoremap <leader>fg :Rg<CR>
nnoremap <leader>fb :Buffers<CR>
nnoremap <leader>fh :History<CR>
nnoremap <leader>fc :Commands<CR>
nnoremap <leader>fm :Maps<CR>
nnoremap <leader>fW :Windows<CR>
nnoremap <leader>fs :BLines<CR>
nnoremap <leader>fS :Lines<CR>
nnoremap <leader>ft :BTags<CR>
nnoremap <leader>fT :Tags<CR>
nnoremap <leader>fl :Commits<CR>

" Layout
let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.8, 'border': 'rounded' } }

" Colors
let g:fzf_colors = {
\ 'fg': ['fg', 'Normal'],
\ 'bg': ['bg', 'Normal'],
\ 'hl': ['fg', 'Comment'],
\ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
\ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
\ 'hl+': ['fg', 'Statement'],
\ 'info': ['fg', 'PreProc'],
\ 'border': ['fg', 'Ignore'],
\ 'prompt': ['fg', 'Conditional'],
\ 'pointer': ['fg', 'Exception'],
\ 'marker': ['fg', 'Keyword'],
\ 'spinner': ['fg', 'Label'],
\ 'header': ['fg', 'Comment'],
\ }

fzf.vim Commands Reference

CommandAction
:Files [path]Fuzzy file picker
:GFilesGit tracked files
:GFiles?Git status files
:BuffersOpen buffers
:Rg [pattern]RipGrep search
:LinesAll lines in loaded buffers
:BLinesLines in current buffer
:Tagsctags tags
:BTagsTags in current buffer
:HistoryRecently opened files
:History:Command history
:History/Search history
:MarksMarks
:WindowsOpen windows
:CommitsGit commits
:BCommitsBuffer git commits
:Commandsvim commands
:MapsKey mappings
:ColorsColor schemes
:SnippetsUltiSnips snippets

fzf Inside tmux

tmux Popup Mode (--tmux flag)

fzf 0.53+ can run as a tmux popup, floating over your current pane:

# Add to FZF_DEFAULT_OPTS to always use tmux popup
export FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS --tmux center,80%,60%"

# Or per-command
ls | fzf --tmux center,80%,60%
ls | fzf --tmux bottom,50%

tmux Session Switcher

# Switch tmux sessions with fzf
ftmux() {
local session
session=$(tmux list-sessions -F "#{session_name}: #{session_windows} windows #{?session_attached,(attached),}" \
| fzf \
--prompt '🖥 tmux session> ' \
--preview 'tmux list-windows -t $(echo {} | cut -d: -f1)' \
--preview-window 'down:5' \
--header 'Switch tmux session' \
| cut -d: -f1)
[[ -n "$session" ]] && tmux switch-client -t "$session"
}

tmux Window Switcher

ftwin() {
local win
win=$(tmux list-windows -a -F "#{session_name}:#{window_index}: #{window_name}" \
| fzf --prompt '🪟 Window> ' --height=40%)
[[ -n "$win" ]] && tmux switch-client -t "${win%%:*}" \; select-window -t "${win%:*}"
}

Bind fzf Session Picker in tmux

~/.tmux.conf
# CTRL-F in tmux: open fzf session picker
bind-key f display-popup -E \
"tmux list-sessions -F '#{session_name}' | fzf --prompt 'Session> ' | xargs tmux switch-client -t"

# CTRL-G: fzf window picker
bind-key g display-popup -E \
"tmux list-windows -a -F '#{session_name}:#{window_index}: #{window_name}' \
| fzf --prompt 'Window> ' | awk -F: '{print \$1\":\"\$2}' \
| xargs tmux switch-client -t"

What's Next