mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-10-05 21:46:49 -04:00
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>
45 lines
1.5 KiB
Go
45 lines
1.5 KiB
Go
package controllers
|
|
|
|
import (
|
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
)
|
|
|
|
// WorkingTreeDiffActions implements what the files panel offers on the diff it renders
|
|
// into the focused main view: the diff itself, for the commands that need to read lines
|
|
// out of it rather than off the screen.
|
|
type WorkingTreeDiffActions struct {
|
|
c *ControllerCommon
|
|
}
|
|
|
|
var _ types.FocusedMainViewDiffSource = &WorkingTreeDiffActions{}
|
|
|
|
func NewWorkingTreeDiffActions(c *ControllerCommon) *WorkingTreeDiffActions {
|
|
return &WorkingTreeDiffActions{c: c}
|
|
}
|
|
|
|
func (self *WorkingTreeDiffActions) context() *context.WorkingTreeContext {
|
|
return self.c.Contexts().Files
|
|
}
|
|
|
|
// PlainDiff hands out the working tree's diff for the given files, taken from the
|
|
// side of the index that the asking pane shows.
|
|
func (self *WorkingTreeDiffActions) PlainDiff(pane types.DiffPaneContext, paths []string) string {
|
|
node := self.context().GetSelected()
|
|
if node == nil {
|
|
return ""
|
|
}
|
|
// An error means there is no diff to be had, which for our purposes is the same as
|
|
// an empty one.
|
|
diff, _ := self.c.Git().WorkingTree.
|
|
WorktreeFileDiffCmdObj(node, true, self.showsStagedSide(pane), paths).
|
|
RunWithOutput()
|
|
return diff
|
|
}
|
|
|
|
// showsStagedSide reports whether the given main pane is the one showing the staged
|
|
// side of a file's diff, which is always the lower one.
|
|
func (self *WorkingTreeDiffActions) showsStagedSide(pane types.DiffPaneContext) bool {
|
|
return pane.GetKey() == self.c.Contexts().NormalSecondary.GetKey()
|
|
}
|