Compare commits

...

9 Commits

Author SHA1 Message Date
Stefan Haller
cbd23107ef WIP Make it searchable
Doesn't work very well yet, but it gives you a taste of what it could look like.
2024-10-15 16:59:50 +02:00
Stefan Haller
50426cda3a Select line that is in the middle of the screen
TODO: doesn't work the very first time
2024-10-15 16:36:19 +02:00
Stefan Haller
e031f437e9 Add navigation keybindings 2024-10-15 15:35:52 +02:00
Stefan Haller
9bd212aab1 DROPME: change window title for testing 2024-10-15 15:35:52 +02:00
Stefan Haller
9df81067e9 Make Files diff focusable 2024-10-15 15:35:52 +02:00
Stefan Haller
f31037864e Extract code to DiffHelper
TODO: handle the WithDiffModeCheck thing properly
2024-10-15 15:35:52 +02:00
Stefan Haller
03e060d82c Extract helper method mainViews 2024-10-15 15:35:52 +02:00
Stefan Haller
f88b1942ae Remove utils.Clamp, use lo.Clamp instead 2024-10-15 15:35:51 +02:00
Stefan Haller
2e05ea57dc [gocui] Make highlight overwrite the background color
It seems that highlighting has so far only been used in cases where there wasn't
a background color. Or'ing the bits of the color with the existing background
color doesn't make sense.
2024-10-15 15:06:11 +02:00
21 changed files with 403 additions and 68 deletions

View File

@@ -1,7 +1,6 @@
package patch
import (
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
)
@@ -54,7 +53,7 @@ func (self *Patch) Lines() []*PatchLine {
// Returns the patch line index of the first line in the given hunk
func (self *Patch) HunkStartIdx(hunkIndex int) int {
hunkIndex = utils.Clamp(hunkIndex, 0, len(self.hunks)-1)
hunkIndex = lo.Clamp(hunkIndex, 0, len(self.hunks)-1)
result := len(self.header)
for i := 0; i < hunkIndex; i++ {
@@ -65,7 +64,7 @@ func (self *Patch) HunkStartIdx(hunkIndex int) int {
// Returns the patch line index of the last line in the given hunk
func (self *Patch) HunkEndIdx(hunkIndex int) int {
hunkIndex = utils.Clamp(hunkIndex, 0, len(self.hunks)-1)
hunkIndex = lo.Clamp(hunkIndex, 0, len(self.hunks)-1)
return self.HunkStartIdx(hunkIndex) + self.hunks[hunkIndex].lineCount() - 1
}
@@ -118,7 +117,7 @@ func (self *Patch) HunkContainingLine(idx int) int {
// Returns the patch line index of the next change (i.e. addition or deletion).
func (self *Patch) GetNextChangeIdx(idx int) int {
idx = utils.Clamp(idx, 0, self.LineCount()-1)
idx = lo.Clamp(idx, 0, self.LineCount()-1)
lines := self.Lines()

View File

@@ -375,6 +375,7 @@ type KeybindingUniversalConfig struct {
NextBlockAlt2 string `yaml:"nextBlock-alt2"`
PrevBlockAlt2 string `yaml:"prevBlock-alt2"`
JumpToBlock []string `yaml:"jumpToBlock"`
FocusMainView string `yaml:"focusMainView"`
NextMatch string `yaml:"nextMatch"`
PrevMatch string `yaml:"prevMatch"`
StartSearch string `yaml:"startSearch"`
@@ -816,6 +817,7 @@ func GetDefaultConfig() *UserConfig {
PrevBlockAlt2: "<backtab>",
NextBlockAlt2: "<tab>",
JumpToBlock: []string{"1", "2", "3", "4", "5"},
FocusMainView: "0",
NextMatch: "n",
PrevMatch: "N",
StartSearch: "/",

View File

@@ -24,6 +24,8 @@ const (
STASH_CONTEXT_KEY types.ContextKey = "stash"
NORMAL_MAIN_CONTEXT_KEY types.ContextKey = "normal"
NORMAL_SECONDARY_CONTEXT_KEY types.ContextKey = "normalSecondary"
DIFF_MAIN_CONTEXT_KEY types.ContextKey = "diff"
DIFF_SECONDARY_CONTEXT_KEY types.ContextKey = "diffSecondary"
STAGING_MAIN_CONTEXT_KEY types.ContextKey = "staging"
STAGING_SECONDARY_CONTEXT_KEY types.ContextKey = "stagingSecondary"
PATCH_BUILDING_MAIN_CONTEXT_KEY types.ContextKey = "patchBuilding"
@@ -100,6 +102,8 @@ type ContextTree struct {
Suggestions *SuggestionsContext
Normal types.Context
NormalSecondary types.Context
Diff types.Context
DiffSecondary types.Context
Staging *PatchExplorerContext
StagingSecondary *PatchExplorerContext
CustomPatchBuilder *PatchExplorerContext
@@ -149,6 +153,8 @@ func (self *ContextTree) Flatten() []types.Context {
self.Staging,
self.CustomPatchBuilderSecondary,
self.CustomPatchBuilder,
self.Diff,
self.DiffSecondary,
self.NormalSecondary,
self.Normal,

View File

@@ -0,0 +1,53 @@
package context
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
type DiffContext struct {
*SimpleContext
*SearchTrait
c *ContextCommon
}
var _ types.ISearchableContext = (*DiffContext)(nil)
func NewDiffContext(
view *gocui.View,
windowName string,
key types.ContextKey,
c *ContextCommon,
) *DiffContext {
ctx := &DiffContext{
SimpleContext: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.MAIN_CONTEXT,
View: view,
WindowName: windowName,
Key: key,
Focusable: true,
HighlightOnFocus: true,
})),
SearchTrait: NewSearchTrait(c),
c: c,
}
// TODO: copied from PatchExplorerContext. Do we need something like this?
// ctx.GetView().SetOnSelectItem(ctx.SearchTrait.onSelectItemWrapper(
// func(selectedLineIdx int) error {
// ctx.GetMutex().Lock()
// defer ctx.GetMutex().Unlock()
// ctx.NavigateTo(ctx.c.Context().IsCurrent(ctx), selectedLineIdx)
// return nil
// }),
// )
return ctx
}
func (self *DiffContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition {
return nil
}

View File

@@ -52,7 +52,7 @@ func (self *ListRenderer) ModelIndexToViewIndex(modelIndex int) int {
}
func (self *ListRenderer) ViewIndexToModelIndex(viewIndex int) int {
viewIndex = utils.Clamp(viewIndex, 0, self.list.Len()+self.numNonModelItems)
viewIndex = lo.Clamp(viewIndex, 0, self.list.Len()+self.numNonModelItems)
if self.modelIndicesByViewIndex != nil {
return self.modelIndicesByViewIndex[viewIndex]
}

View File

@@ -57,6 +57,8 @@ func NewContextTree(c *ContextCommon) *ContextTree {
Focusable: false,
}),
),
Diff: NewDiffContext(c.Views().Diff, "main", DIFF_MAIN_CONTEXT_KEY, c),
DiffSecondary: NewDiffContext(c.Views().DiffSecondary, "secondary", DIFF_SECONDARY_CONTEXT_KEY, c),
Staging: NewPatchExplorerContext(
c.Views().Staging,
"main",

View File

@@ -3,6 +3,7 @@ package traits
import (
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
)
type RangeSelectMode int
@@ -85,7 +86,7 @@ func (self *ListCursor) clampValue(value int) int {
clampedValue := -1
length := self.getLength()
if length > 0 {
clampedValue = utils.Clamp(value, 0, length-1)
clampedValue = lo.Clamp(value, 0, length-1)
}
return clampedValue

View File

@@ -181,6 +181,7 @@ func (gui *Gui) resetHelpersAndControllers() {
contextLinesController := controllers.NewContextLinesController(common)
renameSimilarityThresholdController := controllers.NewRenameSimilarityThresholdController(common)
verticalScrollControllerFactory := controllers.NewVerticalScrollControllerFactory(common, &gui.viewBufferManagerMap)
viewSelectionControllerFactory := controllers.NewViewSelectionControllerFactory(common, &gui.viewBufferManagerMap)
branchesController := controllers.NewBranchesController(common)
gitFlowController := controllers.NewGitFlowController(common)
@@ -189,6 +190,8 @@ func (gui *Gui) resetHelpersAndControllers() {
patchExplorerControllerFactory := controllers.NewPatchExplorerControllerFactory(common)
stagingController := controllers.NewStagingController(common, gui.State.Contexts.Staging, gui.State.Contexts.StagingSecondary, false)
stagingSecondaryController := controllers.NewStagingController(common, gui.State.Contexts.StagingSecondary, gui.State.Contexts.Staging, true)
diffController := controllers.NewDiffController(common, gui.State.Contexts.Diff, gui.State.Contexts.DiffSecondary, &gui.viewBufferManagerMap)
diffSecondaryController := controllers.NewDiffController(common, gui.State.Contexts.DiffSecondary, gui.State.Contexts.Diff, &gui.viewBufferManagerMap)
patchBuildingController := controllers.NewPatchBuildingController(common)
snakeController := controllers.NewSnakeController(common)
reflogCommitsController := controllers.NewReflogCommitsController(common)
@@ -306,6 +309,18 @@ func (gui *Gui) resetHelpersAndControllers() {
mergeConflictsController,
)
controllers.AttachControllers(gui.State.Contexts.Diff,
diffController,
verticalScrollControllerFactory.Create(gui.State.Contexts.Diff),
viewSelectionControllerFactory.Create(gui.State.Contexts.Diff),
)
controllers.AttachControllers(gui.State.Contexts.DiffSecondary,
diffSecondaryController,
verticalScrollControllerFactory.Create(gui.State.Contexts.DiffSecondary),
viewSelectionControllerFactory.Create(gui.State.Contexts.DiffSecondary),
)
controllers.AttachControllers(gui.State.Contexts.Files,
filesController,
)

View File

@@ -0,0 +1,92 @@
package controllers
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/tasks"
)
type DiffController struct {
baseController
c *ControllerCommon
context types.Context
otherContext types.Context
viewBufferManagerMap *map[string]*tasks.ViewBufferManager
}
var _ types.IController = &DiffController{}
func NewDiffController(
c *ControllerCommon,
context types.Context,
otherContext types.Context,
viewBufferManagerMap *map[string]*tasks.ViewBufferManager,
) *DiffController {
return &DiffController{
baseController: baseController{},
c: c,
context: context,
otherContext: otherContext,
viewBufferManagerMap: viewBufferManagerMap,
}
}
func (self *DiffController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
return []*types.Binding{
{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
Handler: self.TogglePanel,
Description: self.c.Tr.ToggleStagingView,
Tooltip: self.c.Tr.ToggleStagingViewTooltip,
DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: self.Escape,
Description: self.c.Tr.ExitCustomPatchBuilder,
},
}
}
func (self *DiffController) Context() types.Context {
return self.context
}
func (self *DiffController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
return []*gocui.ViewMouseBinding{}
}
func (self *DiffController) GetOnFocus() func(types.OnFocusOpts) {
return func(opts types.OnFocusOpts) {
self.c.Helpers().Diff.RenderFilesViewDiff(self.c.MainViewPairs().Diff)
if opts.ClickedWindowName == "main" {
if manager, ok := (*self.viewBufferManagerMap)[self.context.GetViewName()]; ok {
// TODO: doesn't work the first time after launching. Need to
// find a way to construct the ViewBufferManager for this view
// earlier.
manager.ReadLines(opts.ClickedViewLineIdx - self.context.GetView().LinesHeight() + 1)
}
self.context.GetView().FocusPoint(0, opts.ClickedViewLineIdx)
}
}
}
func (self *DiffController) GetOnFocusLost() func(types.OnFocusLostOpts) {
return func(opts types.OnFocusLostOpts) {
}
}
func (self *DiffController) TogglePanel() error {
if self.otherContext.GetView().Visible {
self.c.Context().Push(self.otherContext)
}
return nil
}
func (self *DiffController) Escape() error {
self.c.Context().Pop()
return nil
}

View File

@@ -112,6 +112,11 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
Handler: self.refresh,
Description: self.c.Tr.RefreshFiles,
},
{
Key: opts.GetKey(opts.Config.Universal.FocusMainView),
Handler: self.focusMainView,
Description: self.c.Tr.FocusMainView,
},
{
Key: opts.GetKey(opts.Config.Files.StashAllChanges),
Handler: self.stash,
@@ -229,19 +234,7 @@ func (self *FilesController) GetOnRenderToMain() func() {
self.c.Helpers().Diff.WithDiffModeCheck(func() {
node := self.context().GetSelected()
if node == nil {
self.c.RenderToMainViews(types.RefreshMainOpts{
Pair: self.c.MainViewPairs().Normal,
Main: &types.ViewUpdateOpts{
Title: self.c.Tr.DiffTitle,
SubTitle: self.c.Helpers().Diff.IgnoringWhitespaceSubTitle(),
Task: types.NewRenderStringTask(self.c.Tr.NoChangedFiles),
},
})
return
}
if node.File != nil && node.File.HasInlineMergeConflicts {
if node != nil && node.File != nil && node.File.HasInlineMergeConflicts {
hasConflicts, err := self.c.Helpers().MergeConflicts.SetMergeState(node.GetPath())
if err != nil {
return
@@ -256,43 +249,11 @@ func (self *FilesController) GetOnRenderToMain() func() {
self.c.Helpers().MergeConflicts.ResetMergeState()
pair := self.c.MainViewPairs().Normal
if node.File != nil {
if node != nil && node.File != nil {
pair = self.c.MainViewPairs().Staging
}
split := self.c.UserConfig().Gui.SplitDiff == "always" || (node.GetHasUnstagedChanges() && node.GetHasStagedChanges())
mainShowsStaged := !split && node.GetHasStagedChanges()
cmdObj := self.c.Git().WorkingTree.WorktreeFileDiffCmdObj(node, false, mainShowsStaged)
title := self.c.Tr.UnstagedChanges
if mainShowsStaged {
title = self.c.Tr.StagedChanges
}
refreshOpts := types.RefreshMainOpts{
Pair: pair,
Main: &types.ViewUpdateOpts{
Task: types.NewRunPtyTask(cmdObj.GetCmd()),
SubTitle: self.c.Helpers().Diff.IgnoringWhitespaceSubTitle(),
Title: title,
},
}
if split {
cmdObj := self.c.Git().WorkingTree.WorktreeFileDiffCmdObj(node, false, true)
title := self.c.Tr.StagedChanges
if mainShowsStaged {
title = self.c.Tr.UnstagedChanges
}
refreshOpts.Secondary = &types.ViewUpdateOpts{
Title: title,
SubTitle: self.c.Helpers().Diff.IgnoringWhitespaceSubTitle(),
Task: types.NewRunPtyTask(cmdObj.GetCmd()),
}
}
self.c.RenderToMainViews(refreshOpts)
self.c.Helpers().Diff.RenderFilesViewDiff(pair)
})
}
}
@@ -659,6 +620,16 @@ func (self *FilesController) refresh() error {
return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}})
}
func (self *FilesController) focusMainView() error {
mainView := self.c.Helpers().Window.TopViewInWindow("main", false)
lineIdx := mainView.OriginY() + mainView.Height()/2
lineIdx = lo.Clamp(lineIdx, 0, mainView.LinesHeight()-1)
self.c.Context().Push(self.c.Contexts().Diff,
types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: lineIdx})
return nil
}
func (self *FilesController) handleAmendCommitPress() error {
self.c.Confirm(types.ConfirmOpts{
Title: self.c.Tr.AmendLastCommitTitle,

View File

@@ -171,3 +171,68 @@ func (self *DiffHelper) OpenDiffToolForRef(selectedRef types.Ref) error {
}))
return err
}
func (self *DiffHelper) RenderFilesViewDiff(pair types.MainContextPair) {
self.WithDiffModeCheck(func() {
node := self.c.Contexts().Files.GetSelected()
if node == nil {
self.c.RenderToMainViews(types.RefreshMainOpts{
Pair: self.c.MainViewPairs().Normal,
Main: &types.ViewUpdateOpts{
Title: self.c.Tr.DiffTitle,
SubTitle: self.IgnoringWhitespaceSubTitle(),
Task: types.NewRenderStringTask(self.c.Tr.NoChangedFiles),
},
})
return
}
split := self.c.UserConfig().Gui.SplitDiff == "always" || (node.GetHasUnstagedChanges() && node.GetHasStagedChanges())
mainShowsStaged := !split && node.GetHasStagedChanges()
cmdObj := self.c.Git().WorkingTree.WorktreeFileDiffCmdObj(node, false, mainShowsStaged)
title := self.c.Tr.UnstagedChanges
if mainShowsStaged {
title = self.c.Tr.StagedChanges
}
// >>>>> HACK
if pair == self.c.MainViewPairs().Diff {
title += " (focused)"
}
// <<<<< HACK
refreshOpts := types.RefreshMainOpts{
Pair: pair,
Main: &types.ViewUpdateOpts{
Task: types.NewRunPtyTask(cmdObj.GetCmd()),
SubTitle: self.IgnoringWhitespaceSubTitle(),
Title: title,
},
}
if split {
cmdObj := self.c.Git().WorkingTree.WorktreeFileDiffCmdObj(node, false, true)
title := self.c.Tr.StagedChanges
if mainShowsStaged {
title = self.c.Tr.UnstagedChanges
}
// >>>>> HACK
if pair == self.c.MainViewPairs().Diff {
title += " (focused)"
}
// <<<<< HACK
refreshOpts.Secondary = &types.ViewUpdateOpts{
Title: title,
SubTitle: self.IgnoringWhitespaceSubTitle(),
Task: types.NewRunPtyTask(cmdObj.GetCmd()),
}
}
self.c.RenderToMainViews(refreshOpts)
})
}

View File

@@ -0,0 +1,108 @@
package controllers
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/tasks"
"github.com/samber/lo"
)
type ViewSelectionControllerFactory struct {
c *ControllerCommon
viewBufferManagerMap *map[string]*tasks.ViewBufferManager
}
func NewViewSelectionControllerFactory(c *ControllerCommon, viewBufferManagerMap *map[string]*tasks.ViewBufferManager) *ViewSelectionControllerFactory {
return &ViewSelectionControllerFactory{
c: c,
viewBufferManagerMap: viewBufferManagerMap,
}
}
func (self *ViewSelectionControllerFactory) Create(context types.Context) types.IController {
return &ViewSelectionController{
baseController: baseController{},
c: self.c,
context: context,
viewBufferManagerMap: self.viewBufferManagerMap,
}
}
type ViewSelectionController struct {
baseController
c *ControllerCommon
context types.Context
viewBufferManagerMap *map[string]*tasks.ViewBufferManager
}
func (self *ViewSelectionController) Context() types.Context {
return self.context
}
func (self *ViewSelectionController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
return []*types.Binding{
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItem), Handler: self.handlePrevLine},
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Handler: self.handlePrevLine},
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItem), Handler: self.handleNextLine},
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Handler: self.handleNextLine},
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevPage), Handler: self.handlePrevPage, Description: self.c.Tr.PrevPage},
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextPage), Handler: self.handleNextPage, Description: self.c.Tr.NextPage},
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.GotoTop), Handler: self.handleGotoTop, Description: self.c.Tr.GotoTop},
{Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.GotoBottom), Description: self.c.Tr.GotoBottom, Handler: self.handleGotoBottom},
}
}
func (self *ViewSelectionController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
return []*gocui.ViewMouseBinding{}
}
func (self *ViewSelectionController) handleLineChange(delta int) {
if delta > 0 {
if manager, ok := (*self.viewBufferManagerMap)[self.context.GetViewName()]; ok {
manager.ReadLines(delta)
}
}
v := self.Context().GetView()
lineIdxBefore := v.CursorY() + v.OriginY()
lineIdxAfter := lo.Clamp(lineIdxBefore+delta, 0, v.LinesHeight()-1)
if delta == -1 {
checkScrollUp(self.Context().GetViewTrait(), self.c.UserConfig(), lineIdxBefore, lineIdxAfter)
} else if delta == 1 {
checkScrollDown(self.Context().GetViewTrait(), self.c.UserConfig(), lineIdxBefore, lineIdxAfter)
}
v.FocusPoint(0, lineIdxAfter)
}
func (self *ViewSelectionController) handlePrevLine() error {
self.handleLineChange(-1)
return nil
}
func (self *ViewSelectionController) handleNextLine() error {
self.handleLineChange(1)
return nil
}
func (self *ViewSelectionController) handlePrevPage() error {
self.handleLineChange(-self.context.GetViewTrait().PageDelta())
return nil
}
func (self *ViewSelectionController) handleNextPage() error {
self.handleLineChange(self.context.GetViewTrait().PageDelta())
return nil
}
func (self *ViewSelectionController) handleGotoTop() error {
v := self.Context().GetView()
v.FocusPoint(0, 0)
return nil
}
func (self *ViewSelectionController) handleGotoBottom() error {
v := self.Context().GetView()
v.FocusPoint(0, v.LinesHeight()-1)
return nil
}

View File

@@ -122,6 +122,7 @@ func (self *guiCommon) RenderToMainViews(opts types.RefreshMainOpts) {
func (self *guiCommon) MainViewPairs() types.MainViewPairs {
return types.MainViewPairs{
Normal: self.gui.normalMainContextPair(),
Diff: self.gui.diffMainContextPair(),
Staging: self.gui.stagingMainContextPair(),
PatchBuilding: self.gui.patchBuildingMainContextPair(),
MergeConflicts: self.gui.mergingMainContextPair(),

View File

@@ -79,6 +79,13 @@ func (gui *Gui) normalMainContextPair() types.MainContextPair {
)
}
func (gui *Gui) diffMainContextPair() types.MainContextPair {
return types.NewMainContextPair(
gui.State.Contexts.Diff,
gui.State.Contexts.DiffSecondary,
)
}
func (gui *Gui) stagingMainContextPair() types.MainContextPair {
return types.NewMainContextPair(
gui.State.Contexts.Staging,

View File

@@ -4,6 +4,7 @@ import (
"strings"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
)
// State represents the selection state of the merge conflict context.
@@ -37,14 +38,14 @@ func (s *State) setConflictIndex(index int) {
if len(s.conflicts) == 0 {
s.conflictIndex = 0
} else {
s.conflictIndex = utils.Clamp(index, 0, len(s.conflicts)-1)
s.conflictIndex = lo.Clamp(index, 0, len(s.conflicts)-1)
}
s.setSelectionIndex(s.selectionIndex)
}
func (s *State) setSelectionIndex(index int) {
if selections := s.availableSelections(); len(selections) != 0 {
s.selectionIndex = utils.Clamp(index, 0, len(selections)-1)
s.selectionIndex = lo.Clamp(index, 0, len(selections)-1)
}
}

View File

@@ -15,6 +15,7 @@ func NewMainContextPair(main Context, secondary Context) MainContextPair {
type MainViewPairs struct {
Normal MainContextPair
Diff MainContextPair
MergeConflicts MainContextPair
Staging MainContextPair
PatchBuilding MainContextPair

View File

@@ -17,6 +17,8 @@ type Views struct {
Main *gocui.View
Secondary *gocui.View
Diff *gocui.View
DiffSecondary *gocui.View
Staging *gocui.View
StagingSecondary *gocui.View
PatchBuilding *gocui.View

View File

@@ -43,6 +43,8 @@ func (gui *Gui) orderedViewNameMappings() []viewNameMapping {
{viewPtr: &gui.Views.PatchBuilding, name: "patchBuilding"},
{viewPtr: &gui.Views.PatchBuildingSecondary, name: "patchBuildingSecondary"},
{viewPtr: &gui.Views.MergeConflicts, name: "mergeConflicts"},
{viewPtr: &gui.Views.Diff, name: "diff"},
{viewPtr: &gui.Views.DiffSecondary, name: "diffSecondary"},
{viewPtr: &gui.Views.Secondary, name: "secondary"},
{viewPtr: &gui.Views.Main, name: "main"},
@@ -72,6 +74,20 @@ func (gui *Gui) orderedViewNameMappings() []viewNameMapping {
}
}
func (gui *Gui) mainViews() []*gocui.View {
return []*gocui.View{
gui.Views.Main,
gui.Views.Secondary,
gui.Views.Diff,
gui.Views.DiffSecondary,
gui.Views.Staging,
gui.Views.StagingSecondary,
gui.Views.PatchBuilding,
gui.Views.PatchBuildingSecondary,
gui.Views.MergeConflicts,
}
}
func (gui *Gui) createAllViews() error {
var err error
for _, mapping := range gui.orderedViewNameMappings() {
@@ -113,7 +129,7 @@ func (gui *Gui) createAllViews() error {
gui.Views.Files.Title = gui.c.Tr.FilesTitle
for _, view := range []*gocui.View{gui.Views.Main, gui.Views.Secondary, gui.Views.Staging, gui.Views.StagingSecondary, gui.Views.PatchBuilding, gui.Views.PatchBuildingSecondary, gui.Views.MergeConflicts} {
for _, view := range gui.mainViews() {
view.Title = gui.c.Tr.DiffTitle
view.Wrap = true
view.IgnoreCarriageReturns = true
@@ -201,7 +217,7 @@ func (gui *Gui) configureViewProperties() {
(*mapping.viewPtr).InactiveViewSelBgColor = theme.GocuiInactiveViewSelectedLineBgColor
}
for _, view := range []*gocui.View{gui.Views.Main, gui.Views.Secondary, gui.Views.Staging, gui.Views.StagingSecondary, gui.Views.PatchBuilding, gui.Views.PatchBuildingSecondary, gui.Views.MergeConflicts} {
for _, view := range gui.mainViews() {
view.CanScrollPastBottom = gui.c.UserConfig().Gui.ScrollPastBottom
}

View File

@@ -237,6 +237,7 @@ type TranslationSet struct {
IgnoreFile string
ExcludeFile string
RefreshFiles string
FocusMainView string
Merge string
RegularMerge string
MergeBranchTooltip string
@@ -1219,6 +1220,7 @@ func EnglishTranslationSet() *TranslationSet {
IgnoreFile: `Add to .gitignore`,
ExcludeFile: `Add to .git/info/exclude`,
RefreshFiles: `Refresh files`,
FocusMainView: "Focus main view",
Merge: `Merge`,
RegularMerge: "Regular merge",
MergeBranchTooltip: "View options for merging the selected item into the current branch (regular merge, squash merge)",

View File

@@ -39,15 +39,6 @@ func SortRange(x int, y int) (int, int) {
return y, x
}
func Clamp(x int, min int, max int) int {
if x < min {
return min
} else if x > max {
return max
}
return x
}
func AsJson(i interface{}) string {
bytes, _ := json.MarshalIndent(i, "", " ")
return string(bytes)

View File

@@ -529,9 +529,9 @@ func (v *View) setRune(x, y int, ch rune, fgColor, bgColor Attribute) {
}
fgColor = fgColor | AttrBold
if v.HighlightInactive {
bgColor = bgColor | v.InactiveViewSelBgColor
bgColor = (bgColor & AttrStyleBits) | v.InactiveViewSelBgColor
} else {
bgColor = bgColor | v.SelBgColor
bgColor = (bgColor & AttrStyleBits) | v.SelBgColor
}
}
}