Skip to content

Copy the selected diff lines from the focused main view - #6034

Open
stefanhaller wants to merge 2 commits into
show-staged-changes-in-lower-panefrom
copy-diff-lines-from-main-view
Open

stefanhaller wants to merge 2 commits into
show-staged-changes-in-lower-panefrom
copy-diff-lines-from-main-view

Conversation

@stefanhaller

Copy link
Copy Markdown
Collaborator

Sixth PR in the stack of PRs towards staging hunks directly from the main view. This one is stacked on #6033.

ctrl+o in a focused diff copies the selected lines to the clipboard.

What lands on the clipboard is the corresponding lines of the plain diff, not the renderer's own output. You don't want delta's box drawing or difftastic's columns in a paste, and taking the lines from the diff also removes the question of whether a renderer preserved the +/- column. The selected rows are resolved to identities, the plain diff of just those files is fetched, and the contiguous span between the first and last matched line of each file is copied. Lines a renderer chose not to display are included, so the result is a valid patch fragment.

Headers count as selected lines. A hunk header names the first line of its hunk, and a selection touching any row of a file header takes the whole header. So selecting a hunk together with its header copies a patch fragment rather than stripped code. That is how the staging panel's copy behaved.

The rows above the diff — a commit's message and its diffstat — belong to no file, and are copied as they stand on screen. A selection spanning the message and the diff contributes both halves. The +/- column is dropped only when everything came out of the diff, since a message line may well begin with a -.

Known gap: a \ No newline at end of file marker at the very edge of a selection is not copied. It names no line, so it can't be the endpoint of a span.

@stefanhaller
stefanhaller added this pull request to stack #6027 September 20, 2026 08:14
@stefanhaller stefanhaller added the enhancement New feature or request label Sep 20, 2026
@stefanhaller
stefanhaller force-pushed the copy-diff-lines-from-main-view branch from d0b6f37 to a258a6c Compare September 20, 2026 17:51
@stefanhaller
stefanhaller force-pushed the copy-diff-lines-from-main-view branch 2 times, most recently from 2a67d47 to b45894e Compare September 21, 2026 13:46
@stefanhaller
stefanhaller force-pushed the copy-diff-lines-from-main-view branch from b45894e to 557d62b Compare September 25, 2026 09:32
stefanhaller and others added 2 commits September 25, 2026 12:14
The commit files context works out the two ends to diff from the ref (or
range of refs) it was entered for. The panels that hold those refs
themselves — commits, sub-commits, stash, reflog — are about to need the
same two ends, to hand out the diff behind what they render into the
focused main view. Pull the derivation out of the context so they can ask
for it rather than each spelling out the parent-of-from rule again.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The main view shows a diff renderer's picture of a diff, and that is not
what you want on your clipboard: a renderer may drop the +/- column, move
the line numbers into a gutter, group a hunk's deletions before its
additions, or leave lines out altogether. So copying takes the lines from
the diff itself, locating them by the identity of the selected rows.

Only the panel that produced the diff can produce it again, though: the
working tree's staged or unstaged side, a commit's, a stash entry's. The
new seam is there for that. It asks per file, so that copying three lines
of a commit's diff doesn't fetch the whole of it, and it will grow the
actions on a selection as staging and patch building arrive.

The clipboard gets the run of diff lines from the first selected line of
a file to the last, so that lines the renderer hid come along and the
result still reads as a diff. Headers count as selected lines too. A hunk
header names the first line of its hunk, so it is looked for the way a
line of the file is. A file header names no line at all, and a rendering
may draw it over any number of rows, so a selection touching one of them
takes the whole header.

As in the patch explorers, a selection that is all additions or all
deletions loses its +/- column, ready to be pasted into code. One that
reaches into a header keeps the columns, and what comes out is a patch
fragment rather than lines of code.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@stefanhaller
stefanhaller force-pushed the copy-diff-lines-from-main-view branch from 557d62b to d73c978 Compare September 25, 2026 10:14

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant