Skip to content

feat: snacks.picker 対応を追加 (PR 2/2)#125

Merged
kyu08 merged 10 commits into
flexphere:mainfrom
shusann01116:feat/snacks-picker-support
Apr 22, 2026
Merged

feat: snacks.picker 対応を追加 (PR 2/2)#125
kyu08 merged 10 commits into
flexphere:mainfrom
shusann01116:feat/snacks-picker-support

Conversation

@shusann01116
Copy link
Copy Markdown
Collaborator

@shusann01116 shusann01116 commented Apr 22, 2026

Summary

  • config.opts.file_list_mode"snacks" を追加し、FudeReviewFilesFudeReviewScope の両方で snacks.picker をサポート
  • files.lua / scope.luashow_snacks / toggle_*_in_snacks を新設。PR refactor: picker 非依存な state mutator を抽出 (PR 1/2) #124 で抽出した picker-agnostic コア (apply_viewed_toggle / apply_reviewed_toggle) を再利用し、Telescope 版と完全同等の機能パリティを提供
  • snacks.nvim 未導入時は WARN 通知とともに quickfix / vim.ui.select にフォールバック(既存 Telescope モードと対称のポリシー)
  • Telescope / quickfix モードの挙動に一切の回帰なし

Changes

ファイル 内容
lua/fude/files.lua M.show_snacks() / M.toggle_viewed_in_snacks(picker, item) 新設、show() 分岐に "snacks" 追加
lua/fude/scope.lua M.show_snacks(scope_entries) / M.toggle_reviewed_in_snacks(picker, item) 新設、select_scope() 分岐に "snacks" 追加、async preview race ガード (current_preview_sha)
lua/fude/config.lua コメントを 3 値対応に
README.md Requirements に snacks.nvim (optional) 追加、Configuration 例コメント更新
doc/fude.txt file_list_mode 許可値とフォールバック挙動を記載、helptags 再生成
CLAUDE.md files.lua / scope.lua セクションに snacks 対応と adapter を追記

追加修正 (ローカルテスト中に発見・同 PR で修正)

ローカル環境で file_list_mode = "snacks" を実機検証した際に 2 件の snacks API 誤用バグが見つかったため、同 PR に含めて修正しました。

1. Buffer is not 'modifiable' エラー(preview 描画時)

  • 症状: :FudeReviewFiles / :FudeReviewScope で preview を連続切替すると 2 件目以降で Buffer is not 'modifiable' エラー
  • 原因: snacks の preview バッファは invocation 間で modifiable = false に遷移するが、vim.api.nvim_buf_set_lines を直接呼んでいたため初回以外で書き込み失敗
  • 修正: snacks 公式 API (ctx.preview:reset() / ctx.preview:set_lines() / ctx.preview:highlight()) に置換し、modifiable 状態管理を snacks 側に委譲。snacks 組み込み previewer (snacks/picker/preview.luaM.preview) と同じ呼び出し契約

2. <Tab> 押下でカーソルがリスト先頭にジャンプ

  • 症状: ファイル/コミット一覧の途中行で <Tab> を押すと、viewed/reviewed アイコンは切り替わるがカーソルが先頭に戻る
  • 原因: picker:find({ refresh = true }) は finder/matcher を再実行するだけで cursor 位置を保存しない。snacks の公開 API picker:refresh() は内部で list:set_selected()list:set_target()(現 cursor/top を保存)→ find({ refresh = true }) の順に呼ぶラッパ
  • 修正: picker:refresh() に置換し、cursor 位置の保存・復元を snacks 側に委譲

影響範囲

  • lua/fude/files.lua (+8, -11): preview callback と viewed toggle
  • lua/fude/scope.lua (+9, -12): preview callback と reviewed toggle(async 経路は既存の current_preview_sha ガードを維持)
  • 既存 44 テストすべて pass、回帰なし
  • 該当コミット: fix(picker): stabilize snacks preview and cursor preservation

設計原則

  • picker-agnostic core の再利用: 状態変更 (state.viewed_files / state.reviewed_commits) + gh API 呼び出しはすべて PR refactor: picker 非依存な state mutator を抽出 (PR 1/2) #124apply_* に委譲。snacks adapter は selection 取得 + picker refresh のみを担う薄いラッパ(10 行未満)
  • 未導入時フォールバック: pcall(require, "snacks.picker") で存在確認し、失敗時は既存のフォールバック(files → quickfix、scope → vim.ui.select)を呼ぶ
  • 既存 default 保持: file_list_mode default は "telescope" のまま。opt-in なので既存ユーザーへの影響ゼロ
  • snacks API 契約の遵守: preview/refresh は snacks 公式ヘルパー経由で呼び、バッファ状態・カーソル位置の管理を snacks 側に委譲(追加修正参照)

Test plan

自動

  • make all 全 pass(lint / format-check / 全 spec)
  • 既存 200+ テストに回帰なし
  • PR refactor: picker 非依存な state mutator を抽出 (PR 1/2) #124 で追加した apply_viewed_toggle / apply_reviewed_toggle のユニットテストは引き続き pass
  • toggle_*_in_snacks は spec §7.3 の方針に従い、thin wrapper のため追加テスト省略

手動検証(snacks.nvim インストール済み環境で実施推奨)

  • file_list_mode = "snacks" 設定 + snacks.nvim インストール済み環境で :FudeReviewFiles → snacks.picker が開く
  • ファイル選択 (<CR>) で edit に遷移
  • <Tab> で viewed 状態がトグルされ、行の viewed icon が更新される(insert / list 両モードで確認)
  • <Tab> 後もカーソルが元の行に維持される(追加修正 feat: display CI check status in PR overview #2 の検証)
  • diff preview が右ペインに表示される、連続切替で Buffer is not 'modifiable' が出ない(追加修正 feat: send as review comment #1 の検証)
  • :FudeReviewScope → snacks.picker でコミット選択、<Tab> で reviewed マーク、<CR> で scope 適用
  • commit preview に差分ファイル一覧が表示される、高速切替時に古い結果が残らない(race ガード動作確認)
  • snacks.nvim 未インストール環境で file_list_mode = "snacks" → WARN 通知 + quickfix / vim.ui.select へフォールバック

🤖 Generated with Claude Code

@shusann01116 shusann01116 force-pushed the feat/snacks-picker-support branch 2 times, most recently from 340d014 to 0fb6062 Compare April 22, 2026 12:10
shusann01116 and others added 7 commits April 22, 2026 21:19
Adds M.show_snacks() and M.toggle_viewed_in_snacks(picker, item) which
delegate to the picker-agnostic apply_viewed_toggle introduced in PR 1.
Extends M.show() dispatch to include 'snacks' as a new file_list_mode value,
falling back to quickfix when snacks.nvim is not installed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds M.show_snacks(scope_entries) and M.toggle_reviewed_in_snacks(picker, item)
which delegate to the picker-agnostic apply_reviewed_toggle introduced in PR 1.
Extends M.select_scope() dispatch to include 'snacks' as a new file_list_mode
value, falling back to vim.ui.select when snacks.nvim is not installed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The async commit-files callback in show_snacks could write old preview
results into the current item's buffer if the user switched items before
the fetch completed. Adds current_preview_sha tracking so the callback
only applies preview when the user is still viewing the same sha, matching
the existing telescope-version behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Avoids recomputing format_path(item.path) on every format callback
invocation by reusing the item.text value pre-populated in show_snacks.
DRY cleanup, no behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shusann01116 shusann01116 force-pushed the feat/snacks-picker-support branch from 0fb6062 to f3e764a Compare April 22, 2026 12:19
Use snacks API helpers (preview:reset/set_lines/highlight,
picker:refresh) so the preview buffer's modifiable state and cursor
position are managed by snacks instead of being hand-rolled. Fixes
"Buffer is not 'modifiable'" on preview switches and cursor jumping
to the top when toggling viewed/reviewed via <Tab>.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

config.opts.file_list_mode = "snacks" を追加し、FudeReviewFiles / FudeReviewScope の両方で snacks.picker を利用できるようにするPRです(未導入時は従来どおりフォールバック)。

Changes:

  • lua/fude/files.lua / lua/fude/scope.lua に snacks.picker UI を追加し、<Tab> で viewed/reviewed トグルできるように対応
  • file_list_mode の許可値に "snacks" を追加し、README / help / CLAUDE.md の記載を更新
  • snacks.nvim 未導入時の WARN 通知と quickfix / vim.ui.select フォールバックを実装

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
lua/fude/files.lua file_list_mode="snacks" 時に snacks.picker で変更ファイル一覧 + preview + viewed トグルを提供
lua/fude/scope.lua file_list_mode="snacks" 時に snacks.picker でスコープ選択 + preview + reviewed トグルを提供
lua/fude/config.lua file_list_mode コメントを 3 値(telescope/quickfix/snacks)対応に更新
README.md snacks.nvim を optional 要件に追加、設定例コメントを更新
doc/fude.txt file_list_mode の許可値・snacks のフォールバック挙動を追記
CLAUDE.md files/scope の snacks 対応と adapter 記述を更新

Comment thread doc/fude.txt Outdated
Comment on lines +483 to +485
Controls which picker `:FudeReviewFiles` uses. "snacks"
requires snacks.nvim; it falls back to quickfix if not
installed.
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file_list_mode の説明が :FudeReviewFiles に限定されていますが、実装上は :FudeReviewScope の picker 選択にも同じオプションが使われています(lua/fude/scope.lua の分岐)。ドキュメントでも Files/Scope 両方に影響すること、また "quickfix" は Scope では vim.ui.select にフォールバックすることを明記した方が整合します。

Suggested change
Controls which picker `:FudeReviewFiles` uses. "snacks"
requires snacks.nvim; it falls back to quickfix if not
installed.
Controls which picker `:FudeReviewFiles` and
`:FudeReviewScope` use. "snacks" requires snacks.nvim;
it falls back to quickfix if not installed. For
`:FudeReviewScope`, "quickfix" falls back to
`vim.ui.select`.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

@shusann01116 shusann01116 Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d8f4d86 で修正 — ご指摘の通り、Options セクションを Files/Scope 両対応に拡張し、quickfix の Scope 側 vim.ui.select フォールバックも追記しました。

Comment thread doc/fude.txt Outdated
Default configuration: >lua
require("fude").setup({
-- File list mode: "telescope" or "quickfix"
-- File list mode: "telescope", "quickfix", or "snacks"
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

設定例内の file_list_mode コメントが :FudeReviewFiles のみを想起させますが、Scope ピッカーにも影響します。設定例コメントにも適用範囲(Files/Scope)を追記すると、doc 内の Options セクションと合わせて読みやすくなります。

Suggested change
-- File list mode: "telescope", "quickfix", or "snacks"
-- Files/Scope picker mode: "telescope", "quickfix", or "snacks"

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

@shusann01116 shusann01116 Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d8f4d86 で修正 — 設定例コメントを "Picker mode for changed files and review scope: ..." に統一し、config.lua / README.md と文言を揃えました。

Comment thread lua/fude/config.lua Outdated

M.defaults = {
-- File list mode: "telescope" or "quickfix"
-- File list mode: "telescope", "quickfix", or "snacks"
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file_list_mode:FudeReviewFiles だけでなく :FudeReviewScope の picker 分岐にも使われているため、コメントだと「ファイル一覧専用の設定」に見えて誤解を招きます。README/doc と同様に「picker モード」等、適用範囲(Files/Scope 両方)を明記する文言に修正するのがよいです。

Suggested change
-- File list mode: "telescope", "quickfix", or "snacks"
-- Picker mode for review file/scope views: "telescope", "quickfix", or "snacks"

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

@shusann01116 shusann01116 Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d8f4d86 で修正 — 設定例コメントを "Picker mode for changed files and review scope: ..." に統一し、doc/fude.txt / README.md と文言を揃えました。

Comment thread README.md Outdated
- Neovim >= 0.10
- [GitHub CLI](https://cli.github.com/) (`gh`) installed and authenticated
- Optional: [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) for file picker
- Optional: [snacks.nvim](https://github.com/folke/snacks.nvim) for file picker (alternative to telescope, used when `file_list_mode = "snacks"`)
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional の snacks.nvim が「file picker 用」と書かれていますが、file_list_mode = "snacks" の場合 :FudeReviewScope でも snacks.picker を使うため、用途がファイル一覧に限定されているように読めます。Scope でも使われること(または単に "picker" と表現すること)を追記すると誤解が減ります。

Suggested change
- Optional: [snacks.nvim](https://github.com/folke/snacks.nvim) for file picker (alternative to telescope, used when `file_list_mode = "snacks"`)
- Optional: [snacks.nvim](https://github.com/folke/snacks.nvim) for picker UI (alternative to telescope, used when `file_list_mode = "snacks"` for changed files and review scope)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

@shusann01116 shusann01116 Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d8f4d86 で修正 — snacks.nvim を "picker UI (... for changed files and review scope)" に変更。加えて同種の誤解を招いていた直上 31 行目の Telescope 記載も同じ表現に統一しました。

Comment thread README.md Outdated
```lua
require("fude").setup({
-- File list mode: "telescope" or "quickfix"
-- File list mode: "telescope", "quickfix", or "snacks"
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

設定例のコメントが file_list_mode を「ファイル一覧モード」と説明していますが、このオプションは :FudeReviewScope の picker 分岐にも利用されています。README の設定例でも適用範囲(Files/Scope)を明記した方が利用者が混乱しにくいです。

Suggested change
-- File list mode: "telescope", "quickfix", or "snacks"
-- Picker mode for changed files and :FudeReviewScope: "telescope", "quickfix", or "snacks"

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

@shusann01116 shusann01116 Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d8f4d86 で修正 — 設定例コメントを "Picker mode for changed files and review scope: ..." に統一し、config.lua / doc/fude.txt と文言を揃えました。

Call ctx.preview:minimal() after reset to disable number/relativenumber/
signcolumn on the diff preview buffer. reset() may re-apply picker-wide
wo options that include number, so minimal() must be called explicitly
per preview invocation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shusann01116
Copy link
Copy Markdown
Collaborator Author

動作チェックOK

image

file_list_mode routes both :FudeReviewFiles and :FudeReviewScope, but
the docs/comments only mentioned :FudeReviewFiles. Unify the wording
across README, doc/fude.txt, and config.lua, and add the Scope-side
"quickfix" -> vim.ui.select fallback note in the Options reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shusann01116 shusann01116 marked this pull request as ready for review April 22, 2026 13:23
@kyu08 kyu08 merged commit b07ade1 into flexphere:main Apr 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants