Hacker News · Feb 16, 2026 · Collected from RSS
The new release of fff.nvim showed out the new compatiblity for the code search both for human and agents - typo resistant and usable code search for real codebases It can match query "shcema" only to "schema" and "SortedMap" only to "SortedArrayMap" and "SortedHashMap" without bloating the results Comments URL: https://news.ycombinator.com/item?id=47039440 Points: 13 # Comments: 1
FFF.nvim Finally a smart fuzzy file picker for neovim. FFF stands for freakin fast fuzzy file finder (pick 3) and it is an opinionated fuzzy file picker for neovim. Just for files, but we'll try to solve file picking completely. It comes with a dedicated rust backend runtime that keep tracks of the file index, your file access and modifications, git status, and provides a comprehensive typo-resistant fuzzy search experience. Features Works out of the box with no additional configuration Typo resistant fuzzy search Git status integration allowing to take advantage of last modified times within a worktree Separate file index maintained by a dedicated backend allows <10 milliseconds search time for 50k files codebase Display images in previews (for now requires snacks.nvim) Smart in a plenty of different ways hopefully helpful for your workflow This plugin initializes itself lazily by default Installation NoteAlthough we'll try to make sure to keep 100% backward compatibility, by using you should understand that silly bugs and breaking changes may happen. And also we hope for your contributions and feedback to make this plugin ideal for everyone. Prerequisites FFF.nvim requires: Neovim 0.10.0+ Rustup (we require nightly for building the native backend rustup will handle toolchain automatically) Installation lazy.nvim { 'dmtrKovalenko/fff.nvim', build = function() -- this will download prebuild binary or try to use existing rustup toolchain to build from source -- (if you are using lazy you can use gb for rebuilding a plugin if needed) require("fff.download").download_or_build_binary() end, -- if you are using nixos -- build = "nix run .#release", opts = { -- (optional) debug = { enabled = true, -- we expect your collaboration at least during the beta show_scores = true, -- to help us optimize the scoring system, feel free to share your scores! }, }, -- No need to lazy-load with lazy.nvim. -- This plugin initializes itself lazily. lazy = false, keys = { { "ff", -- try it if you didn't it is a banger keybinding for a picker function() require('fff').find_files() end, desc = 'FFFind files', }, { "fg", function() require('fff').live_grep() end, desc = 'LiFFFe grep', }, { "fz", function() require('fff').live_grep({ grep = { modes = { 'fuzzy', 'plain' } } }) end, desc = 'Live fffuzy grep', } } } vim.pack vim.pack.add({ 'https://github.com/dmtrKovalenko/fff.nvim' }) vim.api.nvim_create_autocmd('PackChanged', { callback = function(event) if event.data.updated then require('fff.download').download_or_build_binary() end end, }) -- the plugin will automatically lazy load vim.g.fff = { lazy_sync = true, -- start syncing only when the picker is open debug = { enabled = true, show_scores = true, }, } vim.keymap.set( 'n', 'ff', function() require('fff').find_files() end, { desc = 'FFFind files' } ) Configuration FFF.nvim comes with sensible defaults. Here's the complete configuration with all available options: require('fff').setup({ base_path = vim.fn.getcwd(), prompt = '🪿 ', title = 'FFFiles', max_results = 100, max_threads = 4, lazy_sync = true, -- set to false if you want file indexing to start on open layout = { height = 0.8, width = 0.8, prompt_position = 'bottom', -- or 'top' preview_position = 'right', -- or 'left', 'right', 'top', 'bottom' preview_size = 0.5, show_scrollbar = true, -- Show scrollbar for pagination -- How to shorten long directory paths in the file list: -- 'middle_number' (default): uses dots for 1-3 hidden (a/./b, a/../b, a/.../b) -- and numbers for 4+ (a/.4./b, a/.5./b) -- 'middle': always uses dots (a/./b, a/../b, a/.../b) -- 'end': truncates from the end (home/user/projects) path_shorten_strategy = 'middle_number', }, preview = { enabled = true, max_size = 10 * 1024 * 1024, -- Do not try to read files larger than 10MB chunk_size = 8192, -- Bytes per chunk for dynamic loading (8kb - fits ~100-200 lines) binary_file_threshold = 1024, -- amount of bytes to scan for binary content (set 0 to disable) imagemagick_info_format_str = '%m: %wx%h, %[colorspace], %q-bit', line_numbers = false, wrap_lines = false, filetypes = { svg = { wrap_lines = true }, markdown = { wrap_lines = true }, text = { wrap_lines = true }, }, }, keymaps = { close = '<Esc>', select = '<CR>', select_split = '<C-s>', select_vsplit = '<C-v>', select_tab = '<C-t>', -- you can assign multiple keys to any action move_up = { '<Up>', '<C-p>' }, move_down = { '<Down>', '<C-n>' }, preview_scroll_up = '<C-u>', preview_scroll_down = '<C-d>', toggle_debug = '<F2>', -- goes to the previous query in history cycle_previous_query = '<C-Up>', -- multi-select keymaps for quickfix toggle_select = '<Tab>', send_to_quickfix = '<C-q>', -- grep mode: cycle between plain text, regex, and fuzzy search toggle_grep_regex = '<S-Tab>', }, hl = { border = 'FloatBorder', normal = 'Normal', cursor = 'CursorLine', matched = 'IncSearch', title = 'Title', prompt = 'Question', active_file = 'Visual', frecency = 'Number', debug = 'Comment', combo_header = 'Number', scrollbar = 'Comment', -- Highlight for scrollbar thumb (track uses border) directory_path = 'Comment', -- Highlight for directory path in file list -- Multi-select highlights selected = 'FFFSelected', selected_active = 'FFFSelectedActive', -- Git text highlights for file names git_staged = 'FFFGitStaged', git_modified = 'FFFGitModified', git_deleted = 'FFFGitDeleted', git_renamed = 'FFFGitRenamed', git_untracked = 'FFFGitUntracked', git_ignored = 'FFFGitIgnored', -- Git sign/border highlights git_sign_staged = 'FFFGitSignStaged', git_sign_modified = 'FFFGitSignModified', git_sign_deleted = 'FFFGitSignDeleted', git_sign_renamed = 'FFFGitSignRenamed', git_sign_untracked = 'FFFGitSignUntracked', git_sign_ignored = 'FFFGitSignIgnored', -- Git sign selected highlights git_sign_staged_selected = 'FFFGitSignStagedSelected', git_sign_modified_selected = 'FFFGitSignModifiedSelected', git_sign_deleted_selected = 'FFFGitSignDeletedSelected', git_sign_renamed_selected = 'FFFGitSignRenamedSelected', git_sign_untracked_selected = 'FFFGitSignUntrackedSelected', git_sign_ignored_selected = 'FFFGitSignIgnoredSelected', -- Grep highlights grep_match = 'IncSearch', -- Highlight for matched text in grep results grep_line_number = 'LineNr', -- Highlight for :line:col location grep_regex_active = 'DiagnosticInfo', -- Highlight for keybind + label when regex is on grep_regex_inactive = 'Comment', -- Highlight for keybind + label when regex is off -- Cross-mode suggestion highlights suggestion_header = 'WarningMsg', -- Highlight for the "No results found. Suggested..." banner }, -- Store file open frecency frecency = { enabled = true, db_path = vim.fn.stdpath('cache') .. '/fff_nvim', }, -- Store successfully opened queries with respective matches history = { enabled = true, db_path = vim.fn.stdpath('data') .. '/fff_queries', min_combo_count = 3, -- file will get a boost if it was selected 3 in a row times per specific query combo_boost_score_multiplier = 100, -- Score multiplier for combo matches }, -- Git integration git = { status_text_color = false, -- Apply git status colors to filename text (default: false, only sign column) }, debug = { enabled = false, -- Set to true to show scores in the UI show_scores = false, show_file_info = false, -- Show file info panel in preview }, logging = { enabled = true, log_file = vim.fn.stdpath('log') .. '/fff.log', log_level = 'info', }, -- Live grep search configuration grep = { max_file_size = 10 * 1024 * 1024, -- Skip files larger than 10MB max_matches_per_file = 200, -- Maximum matches per file smart_case = true, -- Case-insensitive unless query has uppercase time_budget_ms = 150, -- Max search time in ms per call (prevents UI freeze, 0 = no limit) modes = { 'plain', 'regex', 'fuzzy' }, -- Available grep modes and their cycling order } }) Key Features Available Methods require('fff').find_files() -- Find files in current directory require('fff').find_in_git_root() -- Find files in the current git repository require('fff').scan_files() -- Trigger rescan of files in the current directory require('fff').refresh_git_status() -- Refresh git status for the active file lock require('fff').find_files_in_dir(path) -- Find files in a specific directory require('fff').change_indexing_directory(new_path) -- Change the base directory for the file picker Commands FFF.nvim provides several commands for interacting with the file picker: :FFFFind [path|query] - Open file picker. Optional: provide directory path or search query :FFFScan - Manually trigger a rescan of files in the current directory :FFFRefreshGit - Manually refresh git status for all files :FFFClearCache [all|frecency|files] - Clear various caches :FFFHealth - Check FFF health status and dependencies :FFFDebug [on|off|toggle] - Toggle debug scores display :FFFOpenLog - Open the FFF log file in a new tab Multiline Paste Support The input field automatically handles multiline clipboard content by joining all lines into a single search query. This is particularly useful when copying file paths from terminal output. Debug Mode Toggle scoring information display: Press F2 while in the picker Use :FFFDebug command Enable by default with debug.show_scores = true Multi-Select and Quickfix Integration Select multiple files and send them to Neovim's quickfix list (keymaps are configurable): <Tab> - Toggle selection for the current file (shows thick border ▊ in signcolumn) <C-q> - Send selected files to quickfix list and close picker Live Grep Search Modes Live grep supports three search modes, cycled with <S-Tab>: Plain text (default) - The query is matched literally. Special regex characters like ., *, (, ), $ have no special meaning. This is the safest mode for searching code containing regex metacharacters. Regex - The query is interpreted as a regular expression. Supports character classes ([a-z]), quantifiers (+, *, {n}), alternation (foo|bar), anchors (^, $), word boundaries (\b), and more. Fuzzy - The query is fuzzy matched using Smith-Water