Skip to content

Commit bc4b50f

Browse files
authored
Add user config to use hunk mode by default when entering staging view (#4685)
- **PR Description** As of #4684, hunk mode has become so useful that I prefer it over line mode now. This PR adds a config that lets you use hunk mode by default in the staging view. I'm not enabling this by default yet, although I do think it's the more useful mode for most people. The biggest issue that I still have with this is that _if_ you need to switch to line mode for some reason, then it's very non-obvious how to do that. New users might not find out at all, and think that lazygit doesn't allow staging individual lines.
2 parents 9f23b89 + 0a73123 commit bc4b50f

File tree

8 files changed

+52
-19
lines changed

8 files changed

+52
-19
lines changed

docs/Config.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ gui:
116116
# paragraphs of markdown text.
117117
wrapLinesInStagingView: true
118118

119+
# If true, hunk selection mode will be enabled by default when entering the staging view.
120+
useHunkModeInStagingView: false
121+
119122
# One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'
120123
language: auto
121124

pkg/config/user_config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ type GuiConfig struct {
107107
// makes it much easier to work with diffs that have long lines, e.g.
108108
// paragraphs of markdown text.
109109
WrapLinesInStagingView bool `yaml:"wrapLinesInStagingView"`
110+
// If true, hunk selection mode will be enabled by default when entering the staging view.
111+
UseHunkModeInStagingView bool `yaml:"useHunkModeInStagingView"`
110112
// One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'
111113
Language string `yaml:"language" jsonschema:"enum=auto,enum=en,enum=zh-TW,enum=zh-CN,enum=pl,enum=nl,enum=ja,enum=ko,enum=ru"`
112114
// Format used when displaying time e.g. commit time.
@@ -745,6 +747,7 @@ func GetDefaultConfig() *UserConfig {
745747
MainPanelSplitMode: "flexible",
746748
EnlargedSideViewLocation: "left",
747749
WrapLinesInStagingView: true,
750+
UseHunkModeInStagingView: false,
748751
Language: "auto",
749752
TimeFormat: "02 Jan 06",
750753
ShortTimeFormat: time.Kitchen,

pkg/gui/controllers/helpers/patch_building_helper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (self *PatchBuildingHelper) RefreshPatchBuildingPanel(opts types.OnFocusOpt
8484

8585
oldState := context.GetState()
8686

87-
state := patch_exploring.NewState(diff, selectedLineIdx, context.GetView(), oldState)
87+
state := patch_exploring.NewState(diff, selectedLineIdx, context.GetView(), oldState, self.c.UserConfig().Gui.UseHunkModeInStagingView)
8888
context.SetState(state)
8989
if state == nil {
9090
self.Escape()

pkg/gui/controllers/helpers/staging_helper.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,13 @@ func (self *StagingHelper) RefreshStagingPanel(focusOpts types.OnFocusOpts) {
6262
mainContext.GetMutex().Lock()
6363
secondaryContext.GetMutex().Lock()
6464

65+
hunkMode := self.c.UserConfig().Gui.UseHunkModeInStagingView
6566
mainContext.SetState(
66-
patch_exploring.NewState(mainDiff, mainSelectedLineIdx, mainContext.GetView(), mainContext.GetState()),
67+
patch_exploring.NewState(mainDiff, mainSelectedLineIdx, mainContext.GetView(), mainContext.GetState(), hunkMode),
6768
)
6869

6970
secondaryContext.SetState(
70-
patch_exploring.NewState(secondaryDiff, secondarySelectedLineIdx, secondaryContext.GetView(), secondaryContext.GetState()),
71+
patch_exploring.NewState(secondaryDiff, secondarySelectedLineIdx, secondaryContext.GetView(), secondaryContext.GetState(), hunkMode),
7172
)
7273

7374
mainState := mainContext.GetState()

pkg/gui/controllers/patch_building_controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func (self *PatchBuildingController) toggleSelection() error {
134134
state := self.context().GetState()
135135

136136
// Get added/deleted lines in the selected patch range
137-
lineIndicesToToggle := state.ChangeLinesInSelectedPatchRange()
137+
lineIndicesToToggle := state.LineIndicesOfAddedOrDeletedLinesInSelectedPatchRange()
138138
if len(lineIndicesToToggle) == 0 {
139139
// Only context lines or header lines selected, so nothing to do
140140
return nil
@@ -170,7 +170,7 @@ func (self *PatchBuildingController) Escape() error {
170170
context := self.c.Contexts().CustomPatchBuilder
171171
state := context.GetState()
172172

173-
if state.SelectingRange() || state.SelectingHunk() {
173+
if state.SelectingRange() || state.SelectingHunkEnabledByUser() {
174174
state.SetLineSelectMode()
175175
self.c.PostRefreshUpdate(context)
176176
return nil

pkg/gui/controllers/staging_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func (self *StagingController) EditFile() error {
168168
}
169169

170170
func (self *StagingController) Escape() error {
171-
if self.context.GetState().SelectingRange() || self.context.GetState().SelectingHunk() {
171+
if self.context.GetState().SelectingRange() || self.context.GetState().SelectingHunkEnabledByUser() {
172172
self.context.GetState().SetLineSelectMode()
173173
self.c.PostRefreshUpdate(self.context)
174174
return nil

pkg/gui/patch_exploring/state.go

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ type State struct {
2828
viewLineIndices []int
2929
// Array of indices of the original patch lines indexed by a wrapped view line index
3030
patchLineIndices []int
31+
32+
// whether the user has switched to hunk mode manually; if hunk mode is on
33+
// but this is false, then hunk mode was enabled because the config makes it
34+
// on by default.
35+
// this makes a difference for whether we want to escape out of hunk mode
36+
userEnabledHunkMode bool
3137
}
3238

3339
// these represent what select mode we're in
@@ -39,7 +45,7 @@ const (
3945
HUNK
4046
)
4147

42-
func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *State) *State {
48+
func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *State, useHunkModeByDefault bool) *State {
4349
if oldState != nil && diff == oldState.diff && selectedLineIdx == -1 {
4450
// if we're here then we can return the old state. If selectedLineIdx was not -1
4551
// then that would mean we were trying to click and potentially drag a range, which
@@ -61,6 +67,15 @@ func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *Stat
6167
}
6268

6369
selectMode := LINE
70+
if useHunkModeByDefault {
71+
selectMode = HUNK
72+
}
73+
74+
userEnabledHunkMode := false
75+
if oldState != nil {
76+
userEnabledHunkMode = oldState.userEnabledHunkMode
77+
}
78+
6479
// if we have clicked from the outside to focus the main view we'll pass in a non-negative line index so that we can instantly select that line
6580
if selectedLineIdx >= 0 {
6681
// Clamp to the number of wrapped view lines; index might be out of
@@ -70,24 +85,25 @@ func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *Stat
7085
selectMode = RANGE
7186
rangeStartLineIdx = selectedLineIdx
7287
} else if oldState != nil {
73-
// if we previously had a selectMode of RANGE, we want that to now be line again
74-
if oldState.selectMode == HUNK {
75-
selectMode = HUNK
88+
// if we previously had a selectMode of RANGE, we want that to now be line again (or hunk, if that's the default)
89+
if oldState.selectMode != RANGE {
90+
selectMode = oldState.selectMode
7691
}
7792
selectedLineIdx = viewLineIndices[patch.GetNextChangeIdx(oldState.patchLineIndices[oldState.selectedLineIdx])]
7893
} else {
7994
selectedLineIdx = viewLineIndices[patch.GetNextChangeIdx(0)]
8095
}
8196

8297
return &State{
83-
patch: patch,
84-
selectedLineIdx: selectedLineIdx,
85-
selectMode: selectMode,
86-
rangeStartLineIdx: rangeStartLineIdx,
87-
rangeIsSticky: false,
88-
diff: diff,
89-
viewLineIndices: viewLineIndices,
90-
patchLineIndices: patchLineIndices,
98+
patch: patch,
99+
selectedLineIdx: selectedLineIdx,
100+
selectMode: selectMode,
101+
rangeStartLineIdx: rangeStartLineIdx,
102+
rangeIsSticky: false,
103+
diff: diff,
104+
viewLineIndices: viewLineIndices,
105+
patchLineIndices: patchLineIndices,
106+
userEnabledHunkMode: userEnabledHunkMode,
91107
}
92108
}
93109

@@ -125,6 +141,7 @@ func (s *State) ToggleSelectHunk() {
125141
s.selectMode = LINE
126142
} else {
127143
s.selectMode = HUNK
144+
s.userEnabledHunkMode = true
128145

129146
// If we are not currently on a change line, select the next one (or the
130147
// previous one if there is no next one):
@@ -155,6 +172,10 @@ func (s *State) SelectingHunk() bool {
155172
return s.selectMode == HUNK
156173
}
157174

175+
func (s *State) SelectingHunkEnabledByUser() bool {
176+
return s.selectMode == HUNK && s.userEnabledHunkMode
177+
}
178+
158179
func (s *State) SelectingRange() bool {
159180
return s.selectMode == RANGE && (s.rangeIsSticky || s.rangeStartLineIdx != s.selectedLineIdx)
160181
}
@@ -335,7 +356,7 @@ func (s *State) SelectedPatchRange() (int, int) {
335356
}
336357

337358
// Returns the line indices of the selected patch range that are changes (i.e. additions or deletions)
338-
func (s *State) ChangeLinesInSelectedPatchRange() []int {
359+
func (s *State) LineIndicesOfAddedOrDeletedLinesInSelectedPatchRange() []int {
339360
viewStart, viewEnd := s.SelectedViewRange()
340361
patchStart, patchEnd := s.patchLineIndices[viewStart], s.patchLineIndices[viewEnd]
341362
lines := s.patch.Lines()

schema/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,11 @@
530530
"description": "If true, wrap lines in the staging view to the width of the view. This\nmakes it much easier to work with diffs that have long lines, e.g.\nparagraphs of markdown text.",
531531
"default": true
532532
},
533+
"useHunkModeInStagingView": {
534+
"type": "boolean",
535+
"description": "If true, hunk selection mode will be enabled by default when entering the staging view.",
536+
"default": false
537+
},
533538
"language": {
534539
"type": "string",
535540
"enum": [

0 commit comments

Comments
 (0)