diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2020-03-29 14:34:17 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2020-03-29 18:26:24 +1100 |
commit | 40fbce91ce636eb037c2221946261ce4f4bf4317 (patch) | |
tree | 9c31eb84b24e6e742ef519a4dad89218cca8092e /pkg/gui/diffing.go | |
parent | 33d287d2f0c6335559ac75c1b9a4705dfaa9ad7b (diff) |
add new diff mode
WIP
WIP
WIP
WIP
WIP
WIP
WIP
Diffstat (limited to 'pkg/gui/diffing.go')
-rw-r--r-- | pkg/gui/diffing.go | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/pkg/gui/diffing.go b/pkg/gui/diffing.go new file mode 100644 index 000000000..a42b6b335 --- /dev/null +++ b/pkg/gui/diffing.go @@ -0,0 +1,189 @@ +package gui + +import ( + "fmt" + "strings" + + "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/commands" +) + +func (gui *Gui) inDiffMode() bool { + return gui.State.Diff.Ref != "" +} + +func (gui *Gui) exitDiffMode() error { + gui.State.Diff = DiffState{} + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) +} + +func (gui *Gui) renderDiff() error { + filterArg := "" + if gui.inFilterMode() { + filterArg = fmt.Sprintf(" -- %s", gui.State.FilterPath) + } + + cmd := gui.OSCommand.ExecutableFromString( + fmt.Sprintf("git diff --color %s %s", gui.diffStr(), filterArg), + ) + if err := gui.newPtyTask("main", cmd); err != nil { + gui.Log.Error(err) + } + return nil +} + +// currentDiffTerminals returns the current diff terminals of the currently selected item. +// in the case of a branch it returns both the branch and it's upstream name, +// which becomes an option when you bring up the diff menu, but when you're just +// flicking through branches it will be using the local branch name. +func (gui *Gui) currentDiffTerminals() []string { + names := []string{} + switch gui.g.CurrentView().Name() { + case "files": + file, err := gui.getSelectedFile() + if err == nil { + names = append(names, file.Name) + } + case "commitFiles": + file := gui.getSelectedCommitFile() + if file != nil { + names = append(names, file.Name) + } + case "commits": + var commit *commands.Commit + switch gui.getCommitsView().Context { + case "reflog-commits": + commit = gui.getSelectedReflogCommit() + case "branch-commits": + commit = gui.getSelectedCommit() + } + if commit != nil { + names = append(names, commit.Sha) + } + case "stash": + entry := gui.getSelectedStashEntry() + if entry != nil { + names = append(names, entry.RefName()) + } + case "branches": + switch gui.getBranchesView().Context { + case "local-branches": + branch := gui.getSelectedBranch() + if branch != nil { + names = append(names, branch.Name) + if branch.UpstreamName != "" { + names = append(names, branch.UpstreamName) + } + } + case "remotes": + remote := gui.getSelectedRemote() + if remote != nil { + names = append(names, remote.Name) + } + case "remote-branches": + remoteBranch := gui.getSelectedRemoteBranch() + if remoteBranch != nil { + names = append(names, remoteBranch.FullName()) + } + case "tags": + tag := gui.getSelectedTag() + if tag != nil { + names = append(names, tag.Name) + } + } + } + return names +} + +func (gui *Gui) currentDiffTerminal() string { + names := gui.currentDiffTerminals() + if len(names) == 0 { + return "HEAD" + } + return names[0] +} + +func (gui *Gui) diffStr() string { + left := gui.State.Diff.Ref + right := gui.currentDiffTerminal() + if gui.State.Diff.Reverse { + left, right = right, left + } + return fmt.Sprintf("%s %s", left, right) +} + +func (gui *Gui) handleCreateDiffingMenuPanel(g *gocui.Gui, v *gocui.View) error { + if gui.popupPanelFocused() { + return nil + } + + names := gui.currentDiffTerminals() + + menuItems := []*menuItem{} + for _, name := range names { + name := name + menuItems = append(menuItems, []*menuItem{ + { + displayString: fmt.Sprintf("%s %s", gui.Tr.SLocalize("diffFrom"), name), + onPress: func() error { + gui.State.Diff.Ref = name + gui.State.Diff.Reverse = false + // can scope this down based on current view but too lazy right now + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) + }, + }, + { + displayString: fmt.Sprintf("%s %s", gui.Tr.SLocalize("diffTo"), name), + onPress: func() error { + gui.State.Diff.Ref = name + gui.State.Diff.Reverse = true + // can scope this down based on current view but too lazy right now + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) + }, + }, + }...) + } + + menuItems = append(menuItems, []*menuItem{ + { + displayString: gui.Tr.SLocalize("enterRefToDiffFrom"), + onPress: func() error { + return gui.createPromptPanel(gui.g, v, gui.Tr.SLocalize("enteRefName"), "", func(g *gocui.Gui, promptView *gocui.View) error { + gui.State.Diff.Ref = strings.TrimSpace(promptView.Buffer()) + gui.State.Diff.Reverse = false + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) + }) + }, + }, + { + displayString: gui.Tr.SLocalize("enterRefToDiffTo"), + onPress: func() error { + return gui.createPromptPanel(gui.g, v, gui.Tr.SLocalize("enteRefName"), "", func(g *gocui.Gui, promptView *gocui.View) error { + gui.State.Diff.Ref = strings.TrimSpace(promptView.Buffer()) + gui.State.Diff.Reverse = true + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) + }) + }, + }, + }...) + + menuItems = append(menuItems, &menuItem{ + displayString: gui.Tr.SLocalize("swapDiff"), + onPress: func() error { + gui.State.Diff.Reverse = !gui.State.Diff.Reverse + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) + }, + }) + + if gui.inDiffMode() { + menuItems = append(menuItems, &menuItem{ + displayString: gui.Tr.SLocalize("exitDiffMode"), + onPress: func() error { + gui.State.Diff = DiffState{} + return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) + }, + }) + } + + return gui.createMenu(gui.Tr.SLocalize("DiffingMenuTitle"), menuItems, createMenuOptions{showCancel: true}) +} |