From 31613f2ab9df56f755b3f005692acc7fd58968d9 Mon Sep 17 00:00:00 2001 From: kyu08 <49891479+kyu08@users.noreply.github.com> Date: Wed, 22 Jul 2026 10:20:46 +0900 Subject: [PATCH] fix: reapply per-buffer gitsigns base on entering commit scope When switching from full PR scope to a commit scope, only the global gitsigns base was updated to `sha^`. Buffers already displayed during full PR scope kept their buffer-local base (the PR base), which takes precedence over the global one, so gitsigns rendered the whole PR diff (all lines shown as added) instead of the single commit's changes. Mirror `apply_full_pr_scope` by looping over loaded buffers and calling `apply_gitsigns_base_for_buffer`, which already resolves the commit-scope base to `sha^`, overwriting the stale buffer-local bases. Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 2 +- lua/fude/scope.lua | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 8e18482..3c8d22f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -50,7 +50,7 @@ All plugin code lives under `lua/fude/`. The plugin entry point is `plugin/fude. - **`ui/sidepanel/tree.lua`** — Pure tree helpers for the sidepanel Files section: `build_tree`, `collapse_singleton_chains`, `compute_aggregate`, and `flatten_tree`. - **`ui/extmarks.lua`** — Extmark management: `flash_line`, `highlight_comment_lines`, `clear_comment_line_highlight`, `refresh_extmarks`, `clear_extmarks`, `clear_all_extmarks`. Uses lazy `require("fude.comments")` to avoid circular dependencies. `refresh_extmarks` also renders the `draft` indicator from `drafts.file_markers(rel_path)` (EOL virt_text, both virtualText and inline modes) and, in virtualText mode, a resolved indicator (`resolved.label`, EOL virt_text, priority 43) on lines where every comment is resolved (`util.all_comments_resolved`). - **`files.lua`** — Changed files display via Telescope picker, snacks.picker, or quickfix list. All pickers show diff preview and viewed state toggle via ``. Shows GitHub viewed status for each file. Exports `apply_viewed_toggle(path, on_done)` as a picker-agnostic state mutator that invokes gh GraphQL mark/unmark, updates `state.viewed_files`, and calls `on_done` with the updated display fields; the Telescope adapter `toggle_viewed_in_telescope` and the snacks adapter `toggle_viewed_in_snacks(picker, item)` both delegate to it. `show()` routes to `show_telescope` / `show_snacks` / `show_quickfix` based on `config.opts.file_list_mode`; snacks falls back to quickfix when snacks.nvim is missing. Also exports `next_file()` / `prev_file()` for jumping between changed files (used by `:FudeReviewNextFile` / `:FudeReviewPrevFile`); both wrap around at the edges and fall back to the first/last entry when the current buffer is not part of the PR. The pure helpers `find_adjacent_file_index(changed_files, current_path, direction)` computes the target index; `count_viewed(viewed_files, changed_files)` counts files with VIEWED state (used by sidepanel header). -- **`scope.lua`** — Review scope selection and navigation. Provides a Telescope picker (or `vim.ui.select` fallback) for choosing between full PR scope and individual commit scope, with commit index display (`[1/10]`) and current scope marker (`▶`). Supports next/prev scope navigation (`next_scope`/`prev_scope`), marking commits as reviewed via `` in the Telescope picker (tracked locally in `state.reviewed_commits`), and statusline integration (`statusline()`). On commit scope: checks out the commit, fetches commit-specific changed files, updates gitsigns base to `sha^` (global), and refreshes the diff preview. On full PR scope: restores the original HEAD, re-fetches PR-wide changed files, and computes merge-base (per-buffer gitsigns base is applied via `GitSignsUpdate` autocmd in init.lua). Exports `apply_reviewed_toggle(sha)` as a picker-agnostic state mutator that toggles `state.reviewed_commits[sha]` and returns the updated display fields `{ is_reviewed, reviewed_icon, reviewed_hl }`; both the Telescope adapter `toggle_reviewed_in_telescope` and the snacks adapter `toggle_reviewed_in_snacks(picker, item)` delegate to it. `select_scope()` routes to `show_telescope` / `show_snacks` / `show_vim_select` based on `config.opts.file_list_mode`; snacks falls back to `vim.ui.select` when snacks.nvim is missing. +- **`scope.lua`** — Review scope selection and navigation. Provides a Telescope picker (or `vim.ui.select` fallback) for choosing between full PR scope and individual commit scope, with commit index display (`[1/10]`) and current scope marker (`▶`). Supports next/prev scope navigation (`next_scope`/`prev_scope`), marking commits as reviewed via `` in the Telescope picker (tracked locally in `state.reviewed_commits`), and statusline integration (`statusline()`). On commit scope: checks out the commit, fetches commit-specific changed files, updates gitsigns base to `sha^` (global) then re-applies per-buffer bases (`apply_gitsigns_base_for_buffer`) to all loaded buffers so stale full-PR-scope buffer-local bases don't override the global one, and refreshes the diff preview. On full PR scope: restores the original HEAD, re-fetches PR-wide changed files, and computes merge-base (per-buffer gitsigns base is applied via `GitSignsUpdate` autocmd in init.lua). Exports `apply_reviewed_toggle(sha)` as a picker-agnostic state mutator that toggles `state.reviewed_commits[sha]` and returns the updated display fields `{ is_reviewed, reviewed_icon, reviewed_hl }`; both the Telescope adapter `toggle_reviewed_in_telescope` and the snacks adapter `toggle_reviewed_in_snacks(picker, item)` delegate to it. `select_scope()` routes to `show_telescope` / `show_snacks` / `show_vim_select` based on `config.opts.file_list_mode`; snacks falls back to `vim.ui.select` when snacks.nvim is missing. - **`overview.lua`** — PR overview display: fetches extended PR info and issue-level comments, renders in a centered float with keymaps for commenting, refreshing, and re-requesting a review (`r` selects a reviewer who already reviewed via `vim.ui.select` and posts to the `requested_reviewers` endpoint through `gh.re_request_review`). - **`completion/init.lua`** — Completion source for comment input buffers. Provides mention (`@user`), issue/PR (`#nnn`), and commit SHA completion candidates via `fetch_mentions`, `fetch_issues`, `fetch_commits`, with a 5-minute TTL cache. `build_commit_items(commit_entries)` is a pure helper that formats commit entries into completion items; `get_context(line_before_cursor)` parses the trigger character (`@`/`#`/sha prefix). Reads `state.pr_commits` (only) for commit completion freshness invalidation. - **`pr.lua`** — PR creation and editing. `M.create()` creates draft PRs from templates: searches for `PULL_REQUEST_TEMPLATE` files in standard GitHub locations, shows Telescope picker when multiple templates exist, and opens a two-pane float (title + body) for composing the PR. Submits via `gh pr create --draft`. `M.edit()` edits existing PR title/body: uses `state.pr_number` when review mode is active, otherwise detects via `gh pr view`. Both functions are independent of review mode (`state.active`). diff --git a/lua/fude/scope.lua b/lua/fude/scope.lua index acf058a..0b905d6 100644 --- a/lua/fude/scope.lua +++ b/lua/fude/scope.lua @@ -674,6 +674,16 @@ function M.apply_commit_scope(sha) gitsigns.change_base(sha .. "^", true) end + -- Overwrite per-buffer bases left over from full PR scope: a buffer-local + -- base (set via change_base(_, false)) takes precedence over the global one, + -- so without this loop already-open buffers keep showing the PR-wide diff. + local init_mod = require("fude.init") + for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do + if vim.api.nvim_buf_is_loaded(bufnr) and vim.bo[bufnr].buftype == "" then + init_mod.apply_gitsigns_base_for_buffer(bufnr) + end + end + -- Refresh preview and sidepanel if open M.refresh_preview() require("fude.ui.sidepanel").refresh()