Fff.nvim – Typo-resistant code search
Summary
FFF.nvim is a fast, opinionated fuzzy file picker for Neovim. Its Rust backend delivers typo-resistant search, git status, and live grep for quick, out-of-the-box file finding.
Rust backend delivers fast searches
Developer dmtrKovalenko released fff.nvim, a high-performance fuzzy file picker for Neovim that utilizes a dedicated Rust backend. The plugin aims to provide a comprehensive file-picking solution by prioritizing speed and typo resistance over broad feature sets.
The external Rust runtime maintains a separate file index and tracks file access, modifications, and Git status. This architecture allows the plugin to achieve search times of less than 10 milliseconds even in codebases containing 50,000 files. Users can trigger a manual rescan of the directory using the :FFFScan command if the index falls out of sync.
The tool initializes lazily by default to prevent impact on Neovim startup times. It handles the indexing process in the background, ensuring the editor remains responsive while the Rust backend processes the file tree. Developers can configure lazy_sync to true to delay indexing until the picker actually opens.
Three modes for live grep
The live_grep functionality includes three distinct search modes to handle different developer needs. Users cycle through plain text, regex, and fuzzy search by pressing Shift-Tab within the search interface. The UI displays the active mode on the right side of the input field with specific color-coded highlights.
When a search query returns zero results, fff.nvim automatically attempts to find matches using an alternative search mode. It displays these results under a "No results found. Suggested..." banner. This suggestion system allows users to navigate and select items just like standard results, opening the file at the specific matching line.
- Plain: Performs a standard literal string match across the project.
- Regex: Allows for complex pattern matching using regular expression syntax.
- Fuzzy: Provides typo-resistant searching that finds matches even with character gaps or misspellings.
The plugin allows for per-call configuration of these modes. A developer can invoke require('fff').live_grep({ grep = { modes = { 'fuzzy' } } }) to limit the search to a single algorithm. If only one mode is active, the UI hides the mode indicator and disables the cycling keybind.
Deep integration with Git status
The picker integrates directly with Git to provide visual cues about the state of the workspace. It displays status indicators in the sign column by default, using different characters and colors for staged, modified, and untracked files. These indicators link to common highlight groups like GitSignsAdd and GitSignsChange for visual consistency.
Users can opt into full text coloring for filenames by setting git.status_text_color to true in the setup configuration. This applies specific highlight groups to the entire filename string based on its Git status. The plugin supports specific highlights for several states:
- Staged: Files ready for the next commit.
- Modified: Unstaged changes in existing files.
- Untracked: New files not yet tracked by the repository.
- Deleted: Files removed from the working tree.
- Ignored: Files excluded by
.gitignoreor.ignorepatterns.
The plugin respects .gitignore files automatically to filter the results list. Developers can also create a .ignore file in the project root to exclude specific subdirectories or file types without affecting the Git repository's configuration. This is useful for hiding large build artifacts or documentation folders from the search results.
Smart scoring and frecency tracking
The search engine uses a frecency algorithm to prioritize files that the user opens frequently or recently. It stores this data in a local database located at stdpath('cache')/fff_nvim. This ensures that the most relevant files appear at the top of the list even when the search query is broad.
The system also tracks "combo" matches through a secondary history database. If a user selects the same file three times in a row for a specific query, that file receives a score boost. The default combo_boost_score_multiplier is set to 100 to ensure these preferred matches stay at the top of the interface.
The UI includes a debug mode that reveals exactly how the engine calculates these scores. By setting debug.show_scores to true, users can see the numerical value assigned to each file in the result list. This transparency helps developers understand why certain files rank higher than others during a fuzzy search.
Customizable layout and file previews
The default interface occupies 80 percent of the editor's width and height. Users can position the prompt at the top or bottom and move the preview window to any side of the main list. The path_shorten_strategy option allows users to truncate long directory paths using numbers or dots to keep the list readable.
The preview component includes a safety threshold that prevents the plugin from attempting to read files larger than 10MB. It loads files in 8192-byte chunks to maintain performance and can detect binary content within the first 1024 bytes. For image files, the plugin supports visual previews if the user has snacks.nvim installed.
Keybindings are fully remappable within the setup function. The default configuration includes standard Neovim movements and several specialized actions:
- Control-q: Sends all selected files to the Neovim quickfix list.
- Control-s/v/t: Opens the selected file in a horizontal split, vertical split, or new tab.
- Control-u/d: Scrolls the file preview window up and down.
- Tab: Toggles multi-select mode for batch operations.
Installation and technical health checks
Users can install fff.nvim using popular package managers like lazy.nvim or the built-in vim.pack. The installation process requires running a build function that either downloads a prebuilt binary or compiles the Rust backend from source using rustup. On NixOS, the plugin supports building via nix run .#release.
The plugin includes a :FFFHealth command to verify the environment and dependencies. This check ensures the Rust binary is present, executable, and compatible with the current Neovim version. If the plugin encounters errors, it writes detailed logs to ~/.local/state/nvim/log/fff.log, which users can open directly with :FFFOpenLog.
While the developer maintains a commitment to backward compatibility, the plugin is currently in a beta state. Users should expect occasional breaking changes as the scoring system and backend architecture evolve. The project currently accepts community feedback and contributions on GitHub to refine the search algorithms and UI performance.
Related Articles
Developer abandons Rust web app after years, migrates to Node.js
A programmer's journey from Pascal to C, then web dev in PHP/Python, and finally Rust for a web app. Despite loving Rust's control and safety, they switched to Node.js due to faster iteration, better web ecosystem, and type-safe templates, concluding Rust excels in CPU-heavy tasks but Node.js is more practical for dynamic web development.
A terminal weather app with ASCII animations driven by real-time weather data
Weathr is a terminal weather app with ASCII animations for rain, snow, and more, using real-time data from Open-Meteo. It supports auto-location, configurable units, and offline simulation.
Stay in the loop
Get the best AI-curated news delivered to your inbox. No spam, unsubscribe anytime.
