
2026/02/17 4:52
**Fff.nvim – タイポに強いコード検索**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
FFF.nvim は Neovim 用の高性能ファジーファイルピッカーで、Rust で実装されているため高速なインデックス作成、git ステータス統合、およびタイプミスに強い検索機能を提供します。
50 k ファイルで 10 ms 未満の検索時間を実現し、遅延初期化、snacks.nvim を介した画像プレビューが可能です。また、lazy.nvim、
vim.pack、またはパッケージ変更時に Rust モジュールを再構築する自動コマンドからインストールできます。デフォルトのキー割り当て(
ff → ファイル検索、fg → ライブ grep、fz → ファジー grep)は keys テーブルで設定可能です。プラグインは複数のコマンド(:FFFFind、:FFFScan、:FFFRefreshGit など)とメソッド(find_files()、scan_files()、change_indexing_directory())を公開し、高度な使用に対応しています。設定オプションには
base_path、prompt、layout、プレビュー制限、ハイライト、frecency/history データベース、デバッグフラグ、ログ記録、および grep モード(プレーン/正規表現/ファジー)が含まれ、 で切り替えられます。複数行クリップボード貼り付け、マルチセレクト quickfix リスト(
<Tab>、<C-q>)、結果がない場合のクロスモード提案、およびサイン列に git ステータスハイライトとオプションでファイル名カラーリングをサポートしています。本文
FFF.nvim – Neovim 用高速ファジーファイルフィンダー
FFF は freakin’ fast fuzzy file finder(めちゃくちゃ速いファジーファイルフィンダー)の略です。
意見を持った、タイプミスに強いピッカーで、すぐに使えます。
主な機能
- 設定不要
- タイプミスが自動的に許容される
- Git ステータス統合(最終更新日時表示)
- 専用 Rust バックエンド → 5万件以上のファイル検索で10 ms未満
- 画像プレビュー(
経由)snacks.nvim - スマートワークフローサポート
- デフォルトで Lazy‑loaded
必須条件
| 要件 | 備考 |
|---|---|
| Neovim | 以降 |
| Rustup | バックエンドをビルドするには Nightly ツールチェーンが必要 |
インストール方法
lazy.nvim
{ 'dmtrKovalenko/fff.nvim', build = function() require('fff.download').download_or_build_binary() end, opts = { debug = { enabled = true, show_scores = true }, }, lazy = false, keys = { { 'ff', 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
call packadd! fff.nvim nnoremap ff :lua require('fff').find_files()<CR>
設定例
require('fff').setup({ base_path = vim.fn.getcwd(), prompt = '🪿 ', title = 'FFFiles', max_results = 100, max_threads = 4, lazy_sync = true, -- 初回使用時にインデックスを作成 layout = { height = 0.8, width = 0.8, prompt_position = 'bottom', -- または 'top' preview_position = 'right', -- 'left', 'top', 'bottom' preview_size = 0.5, show_scrollbar = true, path_shorten_strategy = 'middle_number', }, preview = { enabled = true, max_size = 10 * 1024 * 1024, -- 10 MB chunk_size = 8192, binary_file_threshold = 1024, 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>', move_up = { '<Up>', '<C-p>' }, move_down = { '<Down>', '<C-n>' }, preview_scroll_up = '<C-u>', preview_scroll_down = '<C-d>', toggle_debug = '<F2>', cycle_previous_query = '<C-Up>', toggle_select = '<Tab>', send_to_quickfix = '<C-q>', 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', directory_path = 'Comment', selected = 'FFFSelected', selected_active = 'FFFSelectedActive', git_staged = 'FFFGitStaged', git_modified = 'FFFGitModified', git_deleted = 'FFFGitDeleted', git_renamed = 'FFFGitRenamed', git_untracked = 'FFFGitUntracked', git_ignored = 'FFFGitIgnored', grep_match = 'IncSearch', grep_line_number = 'LineNr', suggestion_header = 'WarningMsg', }, frecency = { enabled=true, db_path=vim.fn.stdpath('cache') .. '/fff_nvim' }, history = { enabled = true, db_path = vim.fn.stdpath('data') .. '/fff_queries', min_combo_count = 3, combo_boost_score_multiplier = 100, }, git = { status_text_color = false }, debug = { enabled=false, show_scores=false, show_file_info=false }, logging = { enabled = true, log_file = vim.fn.stdpath('log') .. '/fff.log', log_level = 'info', }, grep = { max_file_size = 10 * 1024 * 1024, max_matches_per_file = 200, smart_case = true, time_budget_ms = 150, modes = { 'plain', 'regex', 'fuzzy' }, }, })
利用可能なメソッド
| メソッド | 説明 |
|---|---|
| 現在のディレクトリでファイルを検索 |
| Git リポジトリ内で検索 |
| 再スキャンを開始 |
| Git ステータスを更新 |
| 指定ディレクトリでファイル検索 |
| 基底ディレクトリを変更 |
コマンド
– ピッカーを開く:FFFFind [path|query]
– 手動で再スキャン:FFFScan
– Git ステータス更新:FFFRefreshGit:FFFClearCache [all|frecency|files]
– 健康チェック:FFFHealth
– デバッグスコアを切替:FFFDebug [on|off|toggle]
– ログファイルを開く:FFFOpenLog
主要機能の詳細
複数行ペーストサポート
クリップボードに改行が含まれる場合、すべて単一クエリとして結合されます。
デバッグモード
F2 を押すか
:FFFDebug on で有効化。debug.show_scores = true に設定するとスコアリングを表示します。
マルチセレクト & Quickfix
– 選択の切替(サイン列に太い枠が表示)<Tab>
– 選択したファイルを quickfix に送信しピッカーを閉じる<C-q>
ライブ grep モード
<S‑Tab> で切り替え可能:
| モード | 説明 |
|---|---|
| Plain | 正規表現メタ文字なしのリテラル一致 |
| Regex | 完全な正規表現サポート |
| Fuzzy | Smith–Waterman スコアリング。タイプミスに強い |
現在のモードは入力フィールドに表示されます。
grep.modes をグローバルまたは呼び出しごとに設定できます。
クロスモード提案
検索結果が得られない場合、FFF は自動的に反対側のモードで再クエリを行い提案を表示します。
Git 統合
- サイン列(デフォルト)にステータスインジケーターを表示
- ファイル名テキストカラーオプション:
git.status_text_color = true - ハイライトグループは一般的な git サインとリンクしていますが、上書き可能
例:
vim.api.nvim_set_hl(0, 'CustomGitModified', { fg = '#FFA500' }) require('fff').setup({ git = { status_text_color = true }, hl = { git_modified = 'CustomGitModified', git_untracked = 'CustomGitUntracked', } })
ファイルフィルタリング
FFF は
.gitignore を尊重します。追加パターンを指定したい場合は
.ignore ファイルを作成してください。
# 全ての Markdown ファイルを除外 *.md # docs/archive/**/*.md を除外 docs/archive/**/*.md
:FFFScan で再スキャンを強制します。
トラブルシューティング
健康チェック
:FFFHealth はバックエンド、オプション依存、データベース接続を確認します。
ログ
デフォルトのログ場所:
~/.local/state/nvim/log/fff.log
よくある問題と対処法
| 問題 | 対策 |
|---|---|
| ピッカーが起動しない | Rust バックエンドがビルドされているか確認 ()。Neovim は 0.10 以上であることを確認 |
| 画像プレビューが表示されない | ターミナルは画像出力に対応している必要があります(kitty, iTerm2, WezTerm)。必要なら , または をインストール |
| パフォーマンスが遅い | を調整、プレビューサイズ/行数を減らす、キャッシュをクリア () |
| ファイルがインデックスされない | を実行。 と権限を確認 |
デバッグモードの永続化
require('fff').setup({ debug = { enabled=true, show_scores=true } })
Neovim で高速かつファジーなファイルピックをお楽しみください!