package gui import ( "github.com/go-errors/errors" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/gui/presentation" ) func (gui *Gui) getSelectedCommitFile() *commands.CommitFile { selectedLine := gui.State.Panels.CommitFiles.SelectedLine if selectedLine == -1 { return nil } return gui.State.CommitFiles[selectedLine] } func (gui *Gui) handleCommitFilesClick(g *gocui.Gui, v *gocui.View) error { itemCount := len(gui.State.CommitFiles) handleSelect := gui.wrappedHandler(gui.handleCommitFileSelect) selectedLine := &gui.State.Panels.CommitFiles.SelectedLine return gui.handleClick(v, itemCount, selectedLine, handleSelect) } func (gui *Gui) handleCommitFileSelect() error { if gui.popupPanelFocused() { return nil } gui.getMainView().Title = "Patch" if gui.currentViewName() == "commitFiles" { gui.handleEscapeLineByLinePanel() } commitFile := gui.getSelectedCommitFile() if commitFile == nil { gui.renderString("commitFiles", gui.Tr.SLocalize("NoCommiteFiles")) return nil } if err := gui.refreshSecondaryPatchPanel(); err != nil { return err } cmd := gui.OSCommand.ExecutableFromString( gui.GitCommand.ShowCommitFileCmdStr(commitFile.Sha, commitFile.Name, false), ) if err := gui.newPtyTask("main", cmd); err != nil { gui.Log.Error(err) } return nil } func (gui *Gui) handleSwitchToCommitsPanel(g *gocui.Gui, v *gocui.View) error { return gui.switchContext(gui.Contexts.BranchCommits.Context) } func (gui *Gui) handleCheckoutCommitFile(g *gocui.Gui, v *gocui.View) error { file := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine] if err := gui.GitCommand.CheckoutFile(file.Sha, file.Name); err != nil { return gui.surfaceError(err) } return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) } func (gui *Gui) handleDiscardOldFileChange(g *gocui.Gui, v *gocui.View) error { if ok, err := gui.validateNormalWorkingTreeState(); !ok { return err } fileName := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine].Name return gui.ask(askOpts{ returnToView: v, returnFocusOnClose: true, title: gui.Tr.SLocalize("DiscardFileChangesTitle"), prompt: gui.Tr.SLocalize("DiscardFileChangesPrompt"), handleConfirm: func() error { return gui.WithWaitingStatus(gui.Tr.SLocalize("RebasingStatus"), func() error { if err := gui.GitCommand.DiscardOldFileChanges(gui.State.Commits, gui.State.Panels.Commits.SelectedLine, fileName); err != nil { if err := gui.handleGenericMergeCommandResult(err); err != nil { return err } } return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI}) }) }, }) } func (gui *Gui) refreshCommitFilesView() error { if err := gui.refreshSecondaryPatchPanel(); err != nil { return err } if err := gui.refreshPatchBuildingPanel(-1); err != nil { return err } commit := gui.getSelectedCommit() if commit == nil { return nil } files, err := gui.GitCommand.GetCommitFiles(commit.Sha, gui.GitCommand.PatchManager) if err != nil { return gui.surfaceError(err) } gui.State.CommitFiles = files gui.refreshSelectedLine(&gui.State.Panels.CommitFiles.SelectedLine, len(gui.State.CommitFiles)) commitsFileView := gui.getCommitFilesView() displayStrings := presentation.GetCommitFileListDisplayStrings(gui.State.CommitFiles, gui.State.Diff.Ref) gui.renderDisplayStrings(commitsFileView, displayStrings) return gui.handleCommitFileSelect() } func (gui *Gui) handleOpenOldCommitFile(g *gocui.Gui, v *gocui.View) error { file := gui.getSelectedCommitFile() if file == nil { return nil } return gui.openFile(file.Name) } func (gui *Gui) handleEditCommitFile(g *gocui.Gui, v *gocui.View) error { file := gui.getSelectedCommitFile() if file == nil { return nil } return gui.editFile(file.Name) } func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error { if ok, err := gui.validateNormalWorkingTreeState(); !ok { return err } commitFile := gui.getSelectedCommitFile() if commitFile == nil { gui.renderString("commitFiles", gui.Tr.SLocalize("NoCommiteFiles")) return nil } toggleTheFile := func() error { if !gui.GitCommand.PatchManager.CommitSelected() { if err := gui.startPatchManager(); err != nil { return err } } gui.GitCommand.PatchManager.ToggleFileWhole(commitFile.Name) return gui.refreshCommitFilesView() } if gui.GitCommand.PatchManager.CommitSelected() && gui.GitCommand.PatchManager.CommitSha != commitFile.Sha { return gui.ask(askOpts{ returnToView: v, returnFocusOnClose: true, title: gui.Tr.SLocalize("DiscardPatch"), prompt: gui.Tr.SLocalize("DiscardPatchConfirm"), handleConfirm: func() error { gui.GitCommand.PatchManager.Reset() return toggleTheFile() }, }) } return toggleTheFile() } func (gui *Gui) startPatchManager() error { diffMap := map[string]string{} for _, commitFile := range gui.State.CommitFiles { commitText, err := gui.GitCommand.ShowCommitFile(commitFile.Sha, commitFile.Name, true) if err != nil { return err } diffMap[commitFile.Name] = commitText } commit := gui.getSelectedCommit() if commit == nil { return errors.New("No commit selected") } gui.GitCommand.PatchManager.Start(commit.Sha, diffMap) return nil } func (gui *Gui) handleEnterCommitFile(g *gocui.Gui, v *gocui.View) error { return gui.enterCommitFile(-1) } func (gui *Gui) enterCommitFile(selectedLineIdx int) error { if ok, err := gui.validateNormalWorkingTreeState(); !ok { return err } commitFile := gui.getSelectedCommitFile() if commitFile == nil { gui.renderString("commitFiles", gui.Tr.SLocalize("NoCommiteFiles")) return nil } enterTheFile := func(selectedLineIdx int) error { if !gui.GitCommand.PatchManager.CommitSelected() { if err := gui.startPatchManager(); err != nil { return err } } gui.changeMainViewsContext("patch-building") // TODO: bring into context code if err := gui.switchContext(gui.Contexts.PatchBuilding.Context); err != nil { return err } return gui.refreshPatchBuildingPanel(selectedLineIdx) } if gui.GitCommand.PatchManager.CommitSelected() && gui.GitCommand.PatchManager.CommitSha != commitFile.Sha { return gui.ask(askOpts{ returnToView: gui.getCommitFilesView(), returnFocusOnClose: false, title: gui.Tr.SLocalize("DiscardPatch"), prompt: gui.Tr.SLocalize("DiscardPatchConfirm"), handleConfirm: func() error { gui.GitCommand.PatchManager.Reset() return enterTheFile(selectedLineIdx) }, handleClose: func() error { return gui.switchContext(gui.Contexts.BranchCommits.Files.Context) }, }) } return enterTheFile(selectedLineIdx) }