百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
F

fff

> 编程语言
开源

面向 AI 智能体的最快、最精准的文件搜索 SDK,包括 Neovim、Rust、C、Python、Bun 和 NodeJS

9.9K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

面向 AI 智能体的最快、最精准的文件搜索 SDK,包括 Neovim、Rust、C、Python、Bun 和 NodeJS

A file search toolkit for humans and AI agents. Really fast.

Typo-resistant path and content search, frequency-ranked file access, a background watcher, and a lightweight in-memory content index. Way faster than CLIs like ripgrep and fzf in any long-running process that searches more than once.

Powers file search in opencode, nushell, and many more amazing projects!

Originally started as Neovim plugin people loved, but it turned out that plenty of AI harnesses and code editors need the same thing: accurate, fast file search as a library. That is what fff is.


Sponsors

fff is MIT and open source forever. Development is supported by these companies:


DIAMOND
Anomaly
The team behind opencode.

GOLD
Mango Proxy
Fast, secure proxies for all the needs.

Use and enjoy fff? Become a sponsor to get your features/fixes the highest priority.


Pick what you are interested in:

MCP server

Works with Claude Code, Codex, OpenCode, Cursor, Cline, and any MCP-capable client. Fewer grep roundtrips, less wasted context, faster answers.

One-line install

Linux / macOS:

bash
curl -L https://dmtrkovalenko.dev/install-fff-mcp.sh | bash

Windows (PowerShell):

powershell
irm https://raw.githubusercontent.com/dmtrKovalenko/fff/main/install-mcp.ps1 | iex

The scripts live at install-mcp.sh and install-mcp.ps1 if you want to read them first. They print the exact wiring instructions for your client.

Homebrew (macOS / Linux)

bash
brew install dmtrKovalenko/fff/fff-mcp
brew upgrade fff-mcp   # after new stable releases

Formula lives in Formula/fff-mcp.rb in this repo and is auto-bumped on every stable release (see bump-homebrew-formula in .github/workflows/release.yaml). Installs the prebuilt fff-mcp binary from GitHub releases.

Codex setup

Register the installed binary using its absolute path, since Codex desktop sessions may not inherit your interactive shell's PATH.

Homebrew:

bash
codex mcp add fff -- "$(brew --prefix)/bin/fff-mcp"

One-line installer:

bash
codex mcp add fff -- "$HOME/.local/bin/fff-mcp"

This creates an entry in ~/.codex/config.toml similar to:

toml
[mcp_servers.fff]
command = "/opt/homebrew/bin/fff-mcp"

Use the actual installed path for your system, then restart Codex or start a new task so it loads the server.

Once the server is connected, ask the agent to "use fff" and it picks up the ffgrep, fffind, and fff-multi-grep tools.

Recommended agent prompt

Drop this into your project's CLAUDE.md or equivalent:

markdown
For any file search or grep in the current git-indexed directory, use fff tools.

What changes

  • Frecency memory. Files you actually open rank higher next time. Warm-up from git touch history runs automatically.
  • Definition-first hinting. Lines that look like code definitions are classified on the Rust side, no regex overhead in your prompt.
  • Smart-case with auto-fuzzy fallback. IsOffTheRecord finds snake_case variants; zero-match queries retry as fuzzy and surface the best approximate hits.
  • Git-aware annotations. Modified, untracked, and staged files are tagged so the agent reaches for what you are actively changing.

Source: crates/fff-mcp/.

The MCP server gives any agent a file search tool that is faster and more token-efficient than the built-in one.

Pi agent extension

Install

bash
pi install npm:@ff-labs/pi-fff

Modes

Three operating modes, switchable at runtime with /fff-mode:

Mode What it does
tools-and-ui (default) Adds ffgrep and fffind tools, replaces @-mention autocomplete with FFF.
tools-only Only tool injection. Keeps pi's native editor autocomplete.
override Replaces pi's built-in grep, find, and multi_grep with FFF implementations.

Env vars: PI_FFF_MODE, FFF_FRECENCY_DB, FFF_HISTORY_DB. Flags: --fff-mode, --fff-frecency-db, --fff-history-db. The databases default to your existing fff.nvim ones when present, otherwise ~/.pi/agent/fff/.

Agent-facing tools

  • ffgrep. Content search. Accepts path, exclude (comma, space, or array; leading ! optional), caseSensitive, context, and cursor pagination. Auto-detects regex, falls back to fuzzy on zero exact matches, rejects .*-style wildcard-only patterns up front.
  • fffind. Path and filename search. Matches the whole repo-relative path, not just the filename. Frecency-aware. The weak-match detector flags scattered fuzzy noise before it floods the agent's context.

Commands

  • /fff-mode [tools-and-ui | tools-only | override]. Show or switch the mode.
  • /fff-health. Picker, frecency, and git integration status.
  • /fff-rescan. Force a rescan.

Source: packages/pi-fff/.

The Pi extension swaps pi's native tools for FFF implementations and feeds the interactive editor's @-mention autocomplete from the frecency-ranked index.

fff.nvim

Demo on the Linux kernel repo (100k files, 8GB):

https://github.com/user-attachments/assets/5d0e1ce9-642c-4c44-aa88-01b05bb86abb

Installation

lazy.nvim

…

vim.pack

…

Public API

…

file_search(query, opts)

Returns a structured result { items, scores, total_matched, total_files?, total_dirs?, location? }. Each item has a type field ("file" or "directory") and name / relative_path. File items also expose size, modified, git_status, is_binary, and frecency scores.

lua
local r = require('fff').file_search('button', {
  mode             = 'mixed',  -- 'files' (default) | 'directories' | 'mixed'
  max_results      = 50,
  page             = 0,        -- 0-based pagination
  current_file     = nil,      -- path to deprioritize for distance scoring
  max_threads      = 4,
  cwd              = nil,      -- switch indexed root if different (see below)
  wait_for_index_ms = nil,     -- override the default scan wait timeout
})
for _, item in ipairs(r.items) do
  print(item.type, item.relative_path)
end

content_search(query, opts)

Returns a GrepResult { items, total_matched, total_files_searched, total_files, filtered_file_count, next_file_offset, regex_fallback_error? }. Each match item has relative_path, name, line_number, col, line_content, match_ranges, plus the same file metadata as file_search.

…

Both functions accept the same constraint syntax as the UI pickers (e.g. git:modified, *.rs, !test/, glob patterns).

cwd and indexing

Both file_search and content_search honour an optional cwd field. The first call to either function lazily initialises the picker at config.base_path (your Neovim cwd by default).

  • If cwd matches the currently indexed root, the call returns immediately against the existing index.
  • If cwd differs, the picker is re-indexed at the new root and the call blocks (default up to 10 s) until the new picker is installed and its initial scan completes — so callers always get results from the right tree.
  • If the index is still warming up after a change_indexing_directory, you can pass wait_for_index_ms = N to block for up to N ms regardless of whether cwd triggered the swap. Pass 0 to skip waiting entirely (useful for fire-and-forget calls where partial results are acceptable).
  • Invalid or non-existent cwd paths return an empty result and emit an error via vim.notify.

Autocmds

The picker fires User autocmds when it opens and closes. FFFOpen runs with the prompt window focused, FFFClose runs after every picker window is gone — so hide global UI, not window-local options of the picker itself:

lua
vim.api.nvim_create_autocmd('User', {
  pattern = { 'FFFOpen', 'FFFClose' },
  callback = function(ev) vim.o.showtabline = ev.match == 'FFFOpen' and 0 or 2 end,
})

Commands

  • :FFFScan. Rescan files.
  • :FFFRefreshGit. Refresh git status.
  • :FFFClearCache [all|frecency|files]. Clear caches.
  • :FFFHealth. Health check.
  • :FFFDebug [on|off|toggle]. Toggle the scoring display.
  • :FFFOpenLog. Open ~/.local/state/nvim/log/fff.log.

Configuration

Defaults are sensible. Override only what you care about.

…

Live grep modes

<S-Tab> cycles between plain, regex, and fuzzy. The list is configurable via grep.modes, and single-mode setups hide the indicator entirely.

Per-call override:

lua
require('fff').live_grep({ grep = { modes = { 'fuzzy', 'plain' } } })
require('fff').live_grep({ query = 'search term' }) -- pre-fill

Constraints

Both find and grep accept these tokens to refine a query:

  • git:modified. One of modified, staged, deleted, renamed, untracked, ignored.
  • test/. Any deeply nested children of test/.
  • !something, !test/, !git:modified. Exclusion. Text exclusions need at least 3 alphanumeric-containing characters, so operators like != or !== work.
  • ./**/*.{rs,lua}. Any valid glob, powered by zlob.

Grep-only:

  • *.md, *.{c,h}. Extension filter.
  • src/main.rs. Grep inside a single file.

Mix freely: git:modified src/**/*.rs !src/**/mod.rs user controller.

Open in invoking window

By default fff.nvim will try to open a file in the most suitable window, so any non-file buffers are not affected. You can customize or disable this by providing:

lua
require('fff').setup({
  select = {
    select_window = function(_current_buf, _action) return nil end,
  },
})

Caveat: the chosen file replaces the buffer in the invoking window even if it's a non-modifiable / special buftype. winfixbuf windows still fall back to :split to avoid E1513.

Multi-select and quickfix

  • <Tab>. Toggle selection (shows a thick ▊ in the signcolumn).
  • <C-q>. Send selected files to the quickfix list and close the picker.

Git status highlighting

Sign-column indicators are on by default. To color filename text by git status, set git.status_text_color = true and adjust the hl.git_* groups. See :help fff.nvim for the full list.

Float colors

The picker maps its float content to NormalFloat (via hl.normal) and the border to FloatBorder. Default FloatBorder links to NormalFloat, so border and content share a background out of the box and the picker reads

Issues· 83 开放

查看全部 Issues在 GitHub 打开
  • #830

    ffgrep: 以无索引文件为目标的路径限制默认扩展为整个仓库的模糊搜索

    triaged更新于 2026年9月18日
  • #875

    [建议]: 使用 fff 作为 cmdline

    enhancement更新于 2026年9月17日
  • #874

    [错误]: 索引忽略 git 的全局 core.excludesFile

    更新于 2026年9月17日
  • #719

    [建议]:支持扫描 包含

    enhancementtriaged更新于 2026年9月16日
  • #290

    请求 fff cli 工具以在终端中使用

    triagedfeature-request更新于 2026年9月8日
  • #857

    [错误]: 当 cwd 为 `$HOME` 且 `enableHomeDirScanning` 为 `false` 时, pi-fff 会以 `error` 通知中止 init

    bugtriaged更新于 2026年9月8日
  • #855

    pi-fff: 切换模式在 /reload 后会保留过时的工具名称

    triaged更新于 2026年9月7日
  • #853

    fix(pi-fff): 在 `/reload` 后保留 FFF 工具渲染器,用于历史调用

    triaged更新于 2026年9月7日
  • #851

    feat(pi-fff): 为搜索工具添加紧凑的可点击渲染

    triaged更新于 2026年9月7日
  • #850

    [建议]:在不泄露工作树状态的情况下共享 fff-mcp 索引

    triagedfeature-request更新于 2026年9月7日

> 标签

Rustbunffffilesearchfzf

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月19日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言