2019-11-05 14:21:19 +11:00
package gui
import (
2020-02-29 18:44:08 +11:00
"github.com/jesseduffield/lazygit/pkg/utils"
2019-11-05 14:21:19 +11:00
)
2020-08-22 18:29:09 +10:00
// getFromAndReverseArgsForDiff tells us the from and reverse args to be used in a diff command. If we're not in diff mode we'll end up with the equivalent of a `git show` i.e `git diff blah^..blah`.
func ( gui * Gui ) getFromAndReverseArgsForDiff ( to string ) ( string , bool ) {
from := to + "^"
reverse := false
if gui . State . Modes . Diffing . Active ( ) {
reverse = gui . State . Modes . Diffing . Reverse
from = gui . State . Modes . Diffing . Ref
}
return from , reverse
}
2022-01-08 15:46:35 +11:00
func ( gui * Gui ) refreshPatchBuildingPanel ( selectedLineIdx int ) error {
2022-01-16 14:46:53 +11:00
if ! gui . git . Patch . PatchManager . Active ( ) {
2020-08-15 17:23:16 +10:00
return gui . handleEscapePatchBuildingPanel ( )
2019-11-05 17:57:59 +11:00
}
2021-04-04 23:51:59 +10:00
gui . Views . Main . Title = "Patch"
gui . Views . Secondary . Title = "Custom Patch"
2019-11-10 16:20:35 +11:00
2019-11-05 14:21:19 +11:00
// get diff from commit file that's currently selected
2022-02-05 17:04:10 +11:00
node := gui . State . Contexts . CommitFiles . GetSelectedFileNode ( )
2021-03-31 22:08:55 +11:00
if node == nil {
2020-03-09 11:34:10 +11:00
return nil
2019-11-05 14:21:19 +11:00
}
2022-01-30 16:38:07 +11:00
to := gui . State . Contexts . CommitFiles . CommitFileTreeViewModel . GetRefName ( )
2020-08-22 18:29:09 +10:00
from , reverse := gui . getFromAndReverseArgsForDiff ( to )
2022-01-16 14:46:53 +11:00
diff , err := gui . git . WorkingTree . ShowFileDiff ( from , to , reverse , node . GetPath ( ) , true )
2019-11-05 14:21:19 +11:00
if err != nil {
return err
}
2022-01-16 14:46:53 +11:00
secondaryDiff := gui . git . Patch . PatchManager . RenderPatchForFile ( node . GetPath ( ) , true , false , true )
2019-11-05 14:21:19 +11:00
if err != nil {
return err
}
2021-04-18 16:30:34 +10:00
empty , err := gui . refreshLineByLinePanel ( diff , secondaryDiff , false , selectedLineIdx )
2019-11-05 14:21:19 +11:00
if err != nil {
return err
}
if empty {
2020-08-15 17:23:16 +10:00
return gui . handleEscapePatchBuildingPanel ( )
2019-11-05 14:21:19 +11:00
}
return nil
}
2020-10-08 08:01:04 +11:00
func ( gui * Gui ) handleRefreshPatchBuildingPanel ( selectedLineIdx int ) error {
gui . Mutexes . LineByLinePanelMutex . Lock ( )
defer gui . Mutexes . LineByLinePanelMutex . Unlock ( )
2022-01-08 15:46:35 +11:00
return gui . refreshPatchBuildingPanel ( selectedLineIdx )
2020-10-08 08:01:04 +11:00
}
2022-01-18 20:43:08 +11:00
func ( gui * Gui ) onPatchBuildingFocus ( selectedLineIdx int ) error {
gui . Mutexes . LineByLinePanelMutex . Lock ( )
defer gui . Mutexes . LineByLinePanelMutex . Unlock ( )
if gui . State . Panels . LineByLine == nil || selectedLineIdx != - 1 {
return gui . refreshPatchBuildingPanel ( selectedLineIdx )
}
return nil
}
2020-10-07 17:54:45 +11:00
func ( gui * Gui ) handleToggleSelectionForPatch ( ) error {
2021-04-18 16:30:34 +10:00
err := gui . withLBLActiveCheck ( func ( state * LblPanelState ) error {
2022-01-16 14:46:53 +11:00
toggleFunc := gui . git . Patch . PatchManager . AddFileLineRange
2020-10-07 17:54:45 +11:00
filename := gui . getSelectedCommitFileName ( )
2022-01-16 14:46:53 +11:00
includedLineIndices , err := gui . git . Patch . PatchManager . GetFileIncLineIndices ( filename )
2020-10-07 17:54:45 +11:00
if err != nil {
return err
}
2021-04-18 16:30:34 +10:00
currentLineIsStaged := utils . IncludesInt ( includedLineIndices , state . GetSelectedLineIdx ( ) )
2020-10-07 17:54:45 +11:00
if currentLineIsStaged {
2022-01-16 14:46:53 +11:00
toggleFunc = gui . git . Patch . PatchManager . RemoveFileLineRange
2020-10-07 17:54:45 +11:00
}
2019-11-05 14:21:19 +11:00
2020-10-07 17:54:45 +11:00
// add range of lines to those set for the file
2022-02-05 17:04:10 +11:00
node := gui . State . Contexts . CommitFiles . GetSelectedFileNode ( )
2021-03-31 22:08:55 +11:00
if node == nil {
2020-10-07 17:54:45 +11:00
return nil
}
2019-11-05 14:21:19 +11:00
2021-04-18 16:30:34 +10:00
firstLineIdx , lastLineIdx := state . SelectedRange ( )
if err := toggleFunc ( node . GetPath ( ) , firstLineIdx , lastLineIdx ) ; err != nil {
2020-10-07 17:54:45 +11:00
// might actually want to return an error here
2022-01-16 14:46:53 +11:00
gui . c . Log . Error ( err )
2020-10-07 17:54:45 +11:00
}
2019-11-05 14:21:19 +11:00
2020-10-07 17:54:45 +11:00
return nil
} )
2020-10-08 08:01:04 +11:00
if err != nil {
return err
}
if err := gui . refreshCommitFilesView ( ) ; err != nil {
return err
}
return nil
2019-11-05 14:21:19 +11:00
}
2020-08-15 17:23:16 +10:00
func ( gui * Gui ) handleEscapePatchBuildingPanel ( ) error {
2020-10-02 07:56:14 +10:00
gui . escapeLineByLinePanel ( )
2019-11-05 14:21:19 +11:00
2022-01-16 14:46:53 +11:00
if gui . git . Patch . PatchManager . IsEmpty ( ) {
gui . git . Patch . PatchManager . Reset ( )
2019-11-10 15:24:20 +11:00
}
2021-04-03 15:56:11 +11:00
if gui . currentContext ( ) . GetKey ( ) == gui . State . Contexts . PatchBuilding . GetKey ( ) {
2022-01-16 14:46:53 +11:00
return gui . c . PushContext ( gui . State . Contexts . CommitFiles )
2020-08-23 13:49:05 +10:00
} else {
// need to re-focus in case the secondary view should now be hidden
return gui . currentContext ( ) . HandleFocus ( )
2020-08-21 21:08:06 +10:00
}
2019-11-05 14:21:19 +11:00
}
2019-11-05 15:11:35 +11:00
2020-08-18 22:02:35 +10:00
func ( gui * Gui ) secondaryPatchPanelUpdateOpts ( ) * viewUpdateOpts {
2022-01-16 14:46:53 +11:00
if gui . git . Patch . PatchManager . Active ( ) {
patch := gui . git . Patch . PatchManager . RenderAggregatedPatchColored ( false )
2020-08-18 22:02:35 +10:00
return & viewUpdateOpts {
title : "Custom Patch" ,
noWrap : true ,
highlight : true ,
2022-02-05 16:56:36 +11:00
context : gui . State . Contexts . PatchBuilding ,
2021-04-04 23:51:59 +10:00
task : NewRenderStringWithoutScrollTask ( patch ) ,
2020-08-18 22:02:35 +10:00
}
}
return nil
}