How to Configure fff.nvim Features: A Complete Guide to Customization
Configure fff.nvim by setting a Lua table in vim.g.fff before startup or calling require('fff.conf').setup(), which merges your options with sensible defaults defined in lua/fff/conf.lua to control layout, preview behavior, keymaps, and search algorithms.
fff.nvim is a high-performance file picker backed by a Rust core that provides fuzzy finding, live grep, and file previewing. All customization flows through a single global configuration table that the plugin validates and merges via the get() function in lua/fff/conf.lua (lines 89–103), allowing you to override only the settings you need while maintaining safe defaults for everything else.
Configuration Fundamentals
The plugin reads runtime options from the global variable vim.g.fff. When the plugin initializes, require('fff.conf').get() merges your table with a comprehensive set of defaults, handling deprecated keys automatically.
Set your configuration before requiring the plugin:
-- init.lua
vim.g.fff = {
layout = { height = 0.9, width = 0.9 },
preview = { enabled = true },
}
require('fff').setup()
Alternatively, call the setup function directly at any time:
require('fff.conf').setup({
layout = { preview_position = 'left' }
})
Layout and Window Settings
Control the picker dimensions, preview placement, and responsive behavior using the layout table defined in lua/fff/conf.lua (lines 99–115).
Key options include:
heightandwidth: Fractions of screen size (0–1) defaulting to0.8.preview_position: Place the preview on"right","left","top", or"bottom".flex: Enable responsive layouts that switch preview position based on terminal width.path_shorten_strategy: Truncate long paths using"middle_number","middle", or"end".
vim.g.fff = {
layout = {
height = 0.85,
width = 0.75,
preview_position = 'left',
preview_size = 0.4,
flex = { size = 130, wrap = 'top' },
show_scrollbar = false,
},
}
Preview Pane Configuration
Fine-tune the file preview buffer through the preview table (lines 116–131 in conf.lua).
Critical settings:
enabled: Toggle the preview pane entirely (trueby default).max_size: Skip files larger than 10 MiB to prevent hanging.binary_file_threshold: Bytes scanned to detect binary files (set0to disable).line_numbersandwrap_lines: Control display formatting.filetypes: Override settings per filetype (e.g., force wrap for markdown).
vim.g.fff = {
preview = {
line_numbers = true,
wrap_lines = false,
filetypes = {
markdown = { wrap_lines = true },
svg = { wrap_lines = true },
},
max_size = 5 * 1024 * 1024, -- 5 MiB
},
}
Customizing Keymaps
All interactive commands are configurable via the keymaps table (lines 132–152 in conf.lua). Values can be single strings or lists of alternative keys.
Default actions include:
close:<Esc>select:<CR>select_split/select_vsplit:<C-s>/<C-v>move_up/move_down:{ '<Up>', '<C-p>' }/{ '<Down>', '<C-n>' }preview_scroll_up/preview_scroll_down:<C-u>/<C-d>send_to_quickfix:<C-q>
vim.g.fff = {
keymaps = {
close = '<C-c>',
select = '<CR>',
move_up = '<C-k>',
move_down = '<C-j>',
send_to_quickfix = '<C-q>',
},
}
Frecency and History Settings
Configure smart file ranking and query history persistence in the frecency and history tables (lines 159–171 in conf.lua).
frecency.enabled: Track file open frequencies to boost recently used files.frecency.db_path: SQLite database location (defaults tostdpath('cache')..'/fff_nvim').history.enabled: Store past queries for quick recall.history.combo_boost_score_multiplier: Score multiplier for consecutive selections (default100).
Disable frecency to use pure fuzzy matching:
vim.g.fff = {
frecency = { enabled = false },
history = {
min_combo_count = 3,
combo_boost_score_multiplier = 50,
},
}
Live Grep Configuration
Control the behavior of the integrated grep search through the grep table (lines 292–298 in conf.lua).
Performance and matching options:
modes: Ordered list of search modes available for cycling ({ 'plain', 'regex', 'fuzzy' }).smart_case: Case-insensitive unless pattern contains uppercase (defaulttrue).time_budget_ms: Maximum milliseconds spent per search (default150, set0for unlimited).max_matches_per_file: Limit matches per file to prevent UI overload.
vim.g.fff = {
grep = {
modes = { 'regex', 'fuzzy', 'plain' },
smart_case = true,
time_budget_ms = 0, -- disable time limit
max_matches_per_file = 50,
},
}
Appearance and Git Integration
Override highlight groups and Git status indicators via the hl table (lines 155–190 in conf.lua). Git status can display as signs or colored filenames.
Common highlight groups include:
git_sign_stagedgit_sign_unstagedgit_sign_untracked
vim.g.fff = {
hl = {
git_sign_staged = 'DiffAdd',
git_sign_unstaged = 'DiffChange',
},
}
Debugging and Logging
Activate runtime diagnostics through the debug and logging tables (lines 190–205 in conf.lua).
debug.show_scores: Display match scores in the UI for algorithm tuning.logging.log_level: Set to'debug','info','warn', or'error'.
Toggle debug mode programmatically:
require('fff.conf').toggle_debug() -- Toggles debug.enabled and debug.show_scores
Summary
- Configuration entry point: Set
vim.g.fffbefore startup or callrequire('fff.conf').setup(). - Layout control: Adjust
layout.height,layout.width, andlayout.preview_positionfor window sizing. - Preview behavior: Configure
preview.max_size,preview.line_numbers, and per-filetype overrides. - Keybindings: Remap any action via the
keymapstable using single keys or lists. - Search tuning: Modify
frecency.enabled,grep.modes, andgrep.time_budget_msto optimize performance. - Source authority: All defaults and merge logic reside in
lua/fff/conf.lua.
Frequently Asked Questions
Where does fff.nvim store its configuration?
fff.nvim reads configuration from the global Lua table vim.g.fff. This table is merged with internal defaults in lua/fff/conf.lua (lines 89–103) when the plugin initializes. You can also call require('fff.conf').setup(your_table) at runtime to apply settings dynamically.
How do I disable the file preview entirely?
Set preview.enabled = false in your configuration. You can also disable specific preview features like binary detection by setting preview.binary_file_threshold = 0, or limit resource usage by lowering preview.max_size to prevent large files from being loaded into memory.
Can I change the search modes available in live grep?
Yes. The grep.modes array controls which modes are available and their cycling order. The default is { 'plain', 'regex', 'fuzzy' }, but you can reorder or remove modes. For example, setting grep.modes = { 'regex', 'fuzzy' } removes plain text search and prioritizes regex matching.
How do I customize the appearance of Git status indicators?
Git status is controlled through the hl configuration table. Override highlight group names like git_sign_staged, git_sign_unstaged, and git_sign_untracked to link them to your colorscheme's highlight groups. These definitions are processed in lua/fff/conf.lua (lines 155–190) and applied by the picker UI.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →