Skip to content

dmtrKovalenko/fff.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FFF.nvim

Finally a smart fuzzy file picker for neovim.

Stars Issues Contributors

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

Installation

Note

Although 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+
  • Rust toolchain (requires nightly for building the native backend)

Package Managers

lazy.nvim

{
  "dmtrKovalenko/fff.nvim",
  build = "cargo build --release",
  -- or if you are using nixos
  -- build = "nix run .#release",
  opts = {
    -- pass here all the options
  },
  keys = {
    {
      "ff", -- try it if you didn't it is a banger keybinding for a picker
      function()
        require("fff").find_files() -- or find_in_git_root() if you only want git files
      end,
      desc = "Open file picker",
    },
  },
}

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,
    layout = {
      height = 0.8,
      width = 0.8,
      prompt_position = 'bottom', -- or 'top'
      preview_position = 'right', -- or 'left', 'right', 'top', 'bottom'
      preview_size = 0.5,
    },
    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,
      show_file_info = true,
      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>',
      move_up = { '<Up>', '<C-p>' },
      move_down = { '<Down>', '<C-n>' },
      preview_scroll_up = '<C-u>',
      preview_scroll_down = '<C-d>',
      toggle_debug = '<F2>',
    },
    hl = {
      border = 'FloatBorder',
      normal = 'Normal',
      cursor = 'CursorLine',
      matched = 'IncSearch',
      title = 'Title',
      prompt = 'Question',
      active_file = 'Visual',
      frecency = 'Number',
      debug = 'Comment',
    },
    frecency = {
      enabled = true,
      db_path = vim.fn.stdpath('cache') .. '/fff_nvim',
    },
    debug = {
      enabled = false, -- Set to true to show scores in the UI
      show_scores = false,
    },
    logging = {
      enabled = true,
      log_file = vim.fn.stdpath('log') .. '/fff.log',
      log_level = 'info',
    }
})

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

Multiple Key Bindings

You can assign multiple key combinations to the same action:

keymaps = {
  move_up = { '<Up>', '<C-p>', '<C-k>' },  -- Three ways to move up
  close = { '<Esc>', '<C-c>' },            -- Two ways to close
  select = '<CR>',                         -- Single binding still works
}

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

Troubleshooting

Health Check

Run :FFFHealth to check the status of FFF.nvim and its dependencies. This will verify:

  • File picker initialization status
  • Optional dependencies (git, image preview tools)
  • Database connectivity

Viewing Logs

If you encounter issues, check the log file:

:FFFOpenLog

Or manually open the log file at ~/.local/state/nvim/log/fff.log (default location).

Common Issues

File picker not initializing:

  • Ensure the Rust backend is compiled: cargo build --release in the plugin directory
  • Check that your Neovim version is 0.10.0 or higher

Image previews not working:

  • Verify your terminal supports images (kitty, iTerm2, WezTerm, etc.)
  • For terminals without native image support, install one of: chafa, viu, or img2txt
  • If using snacks.nvim, ensure it's properly configured

Performance issues:

  • Adjust max_threads in configuration based on your system
  • Reduce preview.max_lines and preview.max_size for large files
  • Clear cache if it becomes too large: :FFFClearCache all

Files not being indexed:

  • Run :FFFScan to manually trigger a file scan
  • Check that the base_path is correctly set
  • Verify you have read permissions for the directory

Debug Mode

Enable debug mode to see scoring information and troubleshoot search results:

  • Press F2 while in the picker
  • Run :FFFDebug on to enable permanently
  • Set debug.show_scores = true in configuration