Skip to content

feat: FudeEditPR コマンドの追加#100

Merged
kyu08 merged 3 commits intomainfrom
edit-pr-body
Mar 29, 2026
Merged

feat: FudeEditPR コマンドの追加#100
kyu08 merged 3 commits intomainfrom
edit-pr-body

Conversation

@kyu08
Copy link
Copy Markdown
Collaborator

@kyu08 kyu08 commented Mar 23, 2026

概要

既存PRのtitleとbodyを編集する FudeEditPR コマンドを追加。

変更内容

  • gh.lua: get_pr_title_body()edit_pr() 関数を追加
  • pr.lua: open_pr_float() をリファクタリングし opts パラメータを追加、edit() 関数を追加
  • plugin/fude.lua: FudeEditPR コマンドを追加
  • tests/fude/pr_spec.lua: edit() のテストを追加
  • doc/fude.txt: :FudeEditPR コマンドのドキュメントを追加
  • CLAUDE.md: pr.lua のモジュール説明を更新

使用方法

:FudeEditPR
  • レビューモードアクティブ時 → 現在のセッションのPRを編集
  • レビューモード非アクティブ時 → gh pr view でPRを自動検出して編集

キーマップ

  • <Tab>: タイトル/本文間を移動
  • <CR>: PRを更新
  • q: キャンセル

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 23, 2026 14:21
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

Adds a new :FudeEditPR user command to edit an existing GitHub PR’s title/body from Neovim, reusing the existing two-pane PR float UI and integrating with gh pr view / gh pr edit.

Changes:

  • Added FudeEditPR command entrypoint and pr.edit() flow to load current PR content and submit updates.
  • Refactored open_pr_float() to accept an opts table (mode/footer/on_submit) so the same UI can support both create and edit.
  • Added gh.get_pr_title_body() / gh.edit_pr() and corresponding tests + help docs.

Reviewed changes

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

Show a summary per file
File Description
tests/fude/pr_spec.lua Adds test coverage for pr.edit() behavior and submit handling.
plugin/fude.lua Registers new :FudeEditPR user command.
lua/fude/pr.lua Refactors PR float to accept opts; adds M.edit() implementation using new gh helpers.
lua/fude/gh.lua Adds gh wrappers to read PR title/body and edit PR content.
doc/fude.txt Documents :FudeEditPR usage and keybindings.
CLAUDE.md Updates module documentation to include PR editing capability.

lua/fude/gh.lua Outdated
Comment on lines +638 to +646
local args = { "pr", "view", "--json", "title,body" }
if pr_number then
table.insert(args, 3, tostring(pr_number))
end
M.run_json(args, function(err, data)
if err then
return callback(err, nil)
end
callback(nil, { title = data.title or "", body = data.body or "" })
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

pr_number == nil の場合に gh pr view を直接呼んでいますが、このリポジトリでは get_pr_info() 内で「detached HEAD だと gh pr view がハングする可能性がある」ために回避実装があります。編集機能でも同様の状況でハングし得るので、(1) get_pr_info() 相当の detached HEAD 検出を入れる、または (2) 先に PR number を解決してから pr view <number> を呼ぶ等、ハング回避の経路に寄せてください。

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

Choose a reason for hiding this comment

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

dc5e351 で修正 — get_pr_title_body に detached HEAD 検出を追加し、M.edit() では get_pr_info で PR 番号を先に解決してから get_pr_title_body / edit_pr 両方に渡す方式にしました。

lua/fude/pr.lua Outdated
Comment on lines +224 to +232
close_all()

-- Use custom submit handler if provided
if opts.on_submit then
opts.on_submit(parsed.title, parsed.body)
return
end

-- Default: create draft PR
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

submit()close_all()opts.on_submit 実行前に呼んでいるため、編集モードでは更新に失敗した場合でもフロートが閉じてしまい、ユーザーの入力内容をその場で再試行できません(下書き保存もされません)。mode == "edit" のときは成功後に閉じる/失敗時は閉じない、または失敗時に内容を退避(ドラフト保存等)するなど、エラー時の復旧手段を用意してください。

Suggested change
close_all()
-- Use custom submit handler if provided
if opts.on_submit then
opts.on_submit(parsed.title, parsed.body)
return
end
-- Default: create draft PR
-- Use custom submit handler if provided
if opts.on_submit then
-- 編集モードでは on_submit が成功した場合のみフロートを閉じる。
-- エラー時にはフロートを閉じず、ユーザーの入力内容をそのまま残す。
if mode == "edit" then
local ok, err = pcall(opts.on_submit, parsed.title, parsed.body)
if ok then
close_all()
else
vim.notify(
"fude.nvim: Failed to update PR: " .. tostring(err),
vim.log.levels.ERROR
)
end
else
-- 従来どおり、編集モード以外では先にフロートを閉じてからハンドラを呼び出す。
close_all()
opts.on_submit(parsed.title, parsed.body)
end
return
end
-- Default: create draft PR
-- 既存の挙動を維持するため、デフォルト経路では事前にフロートを閉じる。
close_all()

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

Choose a reason for hiding this comment

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

dc5e351 で修正 — edit モードでは close_allon_submit の第3引数として渡し、M.edit() 側で gh.edit_pr 成功時のみ呼ぶようにしました。suggestion の pcall 方式は on_submit 内の処理が非同期のため採用せず、コールバック方式で実装しています。

lua/fude/pr.lua Outdated
Comment on lines +491 to +497
local body_lines = vim.split(data.body or "", "\n", { plain = true })
M.open_pr_float({ data.title }, body_lines, {
mode = "edit",
footer = " <CR> update | q cancel ",
on_submit = function(title, body)
vim.notify("fude.nvim: Updating PR...", vim.log.levels.INFO)
gh.edit_pr(pr_number, title, body, function(edit_err)
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

M.edit() で取得した data.bodyvim.split して open_pr_float() に渡していますが、送信時は parse_pr_buffer() 側で vim.trim(table.concat(body_lines, "\n")) されるため、先頭/末尾の空行や末尾改行などがユーザー操作なしでも削除され得ます(編集コマンドとしては差分が出る原因になります)。編集モードでは body の trim を避ける(例: body は table.concat(body_lines, "\n") のみにする)など、既存本文の体裁を維持できるようにしてください。

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

Choose a reason for hiding this comment

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

dc5e351 で修正 — parse_pr_buffertrim_body オプション(デフォルト true)を追加し、edit モードでは trim_body = false で呼び出すようにしました。

lua/fude/pr.lua Outdated
--- @param body_lines string[]|nil initial body lines (default: {""})
--- @param from_draft boolean|nil true when restoring from a saved draft
function M.open_pr_float(title_lines, body_lines, from_draft)
--- @param opts table|nil options: { mode: "create"|"edit", footer: string, on_submit: fun(title, body) }
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

opts の型注釈コメントに from_draft が含まれていませんが、実装では opts.from_draft を参照しています。opts の想定フィールド(from_draft を含む)と各型をコメントに反映して、呼び出し側が誤解しないようにしてください。

Suggested change
--- @param opts table|nil options: { mode: "create"|"edit", footer: string, on_submit: fun(title, body) }
--- @param opts table|nil options: { mode: "create"|"edit", footer: string, from_draft: boolean, on_submit: fun(title, body) }

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

Choose a reason for hiding this comment

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

dc5e351 で修正 — from_draft: boolean を型注釈に追加しました。

@kyu08 kyu08 linked an issue Mar 24, 2026 that may be closed by this pull request
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add detached HEAD detection to get_pr_title_body (gh.lua)
- Resolve PR number upfront in M.edit() via get_pr_info to avoid
  detached HEAD issues with both get and edit operations
- Keep float open on edit failure so user can retry
- Preserve PR body formatting in edit mode (skip vim.trim)
- Add from_draft to open_pr_float opts type annotation
- Add tests for trim_body option and close_float behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kyu08 kyu08 marked this pull request as ready for review March 29, 2026 11:13
Copilot AI review requested due to automatic review settings March 29, 2026 11:13
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

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

Comment on lines 224 to 229

if parsed.title == "" then
vim.notify("fude.nvim: PR title is required", vim.log.levels.WARN)
return
end

Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

submit()opts.on_submit 実行前に close_all() しているため、編集モードで更新が失敗してもフロートが閉じて入力内容をその場で再試行できません。mode == "edit" の場合は成功後に閉じる(例: on_submitclose_all を渡して成功時のみ呼ぶ)か、失敗時にフロートを維持するように制御を分けてください。

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

Choose a reason for hiding this comment

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

dc5e351 で修正済みです — edit モードでは close_allon_submit の第3引数として渡し、成功時のみ呼ぶ方式にしています。

Comment on lines +491 to +492
--- Uses state.pr_number when review mode is active, otherwise detects via gh pr view.
--- Resolves PR number upfront to avoid detached HEAD issues with both get/edit.
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

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

編集用途の M.edit() でも parse_pr_buffer()vim.trim() が効くため、ユーザーが本文を変更していなくても先頭/末尾の空行や末尾改行が削除され、意図しない更新差分が発生します。編集モードでは body を trim しないオプション(例: trim_body = false)を open_pr_float/parse_pr_buffer に追加して、既存本文の体裁を維持できるようにしてください。

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

Choose a reason for hiding this comment

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

dc5e351 で修正済みです — parse_pr_buffertrim_body オプションを追加し、edit モードでは trim_body = false で呼び出しています。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kyu08 kyu08 merged commit 00cfb26 into main Mar 29, 2026
4 checks passed
@kyu08 kyu08 deleted the edit-pr-body branch March 29, 2026 11:17
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.

feat: edit PR Body and Title

2 participants