summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/gui/branches_panel.go8
-rw-r--r--pkg/gui/commits_panel.go15
-rw-r--r--pkg/gui/context.go3
-rw-r--r--pkg/gui/files_panel.go32
-rw-r--r--pkg/gui/gui.go37
-rw-r--r--pkg/gui/keybindings.go43
-rw-r--r--pkg/gui/merge_panel.go2
-rw-r--r--pkg/gui/stash_panel.go15
-rw-r--r--pkg/gui/status_panel.go7
-rw-r--r--pkg/gui/view_helpers.go21
-rw-r--r--pkg/utils/utils.go5
11 files changed, 167 insertions, 21 deletions
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index fdc35862f..5024e2b9d 100644
--- a/pkg/gui/branches_panel.go
+++ b/pkg/gui/branches_panel.go
@@ -84,6 +84,10 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error {
}
func (gui *Gui) handleBranchesNextLine(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
panelState := gui.State.Panels.Branches
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Branches), false)
@@ -94,6 +98,10 @@ func (gui *Gui) handleBranchesNextLine(g *gocui.Gui, v *gocui.View) error {
}
func (gui *Gui) handleBranchesPrevLine(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
panelState := gui.State.Panels.Branches
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Branches), true)
diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 6b26d0ef3..7ca68767a 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -24,6 +24,13 @@ func (gui *Gui) getSelectedCommit(g *gocui.Gui) *commands.Commit {
}
func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
+ if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
+ return err
+ }
commit := gui.getSelectedCommit(g)
if commit == nil {
return gui.renderString(g, "main", gui.Tr.SLocalize("NoCommitsThisBranch"))
@@ -73,6 +80,10 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error {
}
func (gui *Gui) handleCommitsNextLine(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
panelState := gui.State.Panels.Commits
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Commits), false)
@@ -83,6 +94,10 @@ func (gui *Gui) handleCommitsNextLine(g *gocui.Gui, v *gocui.View) error {
}
func (gui *Gui) handleCommitsPrevLine(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
panelState := gui.State.Panels.Commits
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Commits), true)
diff --git a/pkg/gui/context.go b/pkg/gui/context.go
index 861ffc0be..b741132ea 100644
--- a/pkg/gui/context.go
+++ b/pkg/gui/context.go
@@ -15,6 +15,7 @@ func (gui *Gui) contextTitleMap() map[string]map[string]string {
"main": {
"staging": gui.Tr.SLocalize("StagingMainTitle"),
"merging": gui.Tr.SLocalize("MergingMainTitle"),
+ "normal": "",
},
}
}
@@ -56,7 +57,7 @@ func (gui *Gui) setInitialContexts() error {
contextMap := gui.GetContextMap()
initialContexts := map[string]string{
- "main": "merging",
+ "main": "normal",
}
for viewName, context := range initialContexts {
diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go
index 4ed8ddb10..b1d1bcb5f 100644
--- a/pkg/gui/files_panel.go
+++ b/pkg/gui/files_panel.go
@@ -26,6 +26,30 @@ func (gui *Gui) getSelectedFile(g *gocui.Gui) (*commands.File, error) {
return gui.State.Files[selectedLine], nil
}
+func (gui *Gui) handleFilesFocus(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
+ cx, cy := v.Cursor()
+ _, oy := v.Origin()
+
+ prevSelectedLine := gui.State.Panels.Files.SelectedLine
+ newSelectedLine := cy - oy
+
+ if newSelectedLine > len(gui.State.Files)-1 || len(utils.Decolorise(gui.State.Files[newSelectedLine].DisplayString)) < cx {
+ return gui.handleFileSelect(gui.g, v, false)
+ }
+
+ gui.State.Panels.Files.SelectedLine = newSelectedLine
+
+ if prevSelectedLine == newSelectedLine && gui.currentViewName() == v.Name() {
+ return gui.handleFilePress(gui.g, v)
+ } else {
+ return gui.handleFileSelect(gui.g, v, true)
+ }
+}
+
func (gui *Gui) handleFileSelect(g *gocui.Gui, v *gocui.View, alreadySelected bool) error {
if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
return err
@@ -87,6 +111,10 @@ func (gui *Gui) refreshFiles() error {
}
func (gui *Gui) handleFilesNextLine(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
panelState := gui.State.Panels.Files
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Files), false)
@@ -94,6 +122,10 @@ func (gui *Gui) handleFilesNextLine(g *gocui.Gui, v *gocui.View) error {
}
func (gui *Gui) handleFilesPrevLine(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
panelState := gui.State.Panels.Files
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Files), true)
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index b4a55cc45..b3b219153 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -23,6 +23,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/i18n"
"github.com/jesseduffield/lazygit/pkg/updates"
+ "github.com/jesseduffield/lazygit/pkg/utils"
"github.com/sirupsen/logrus"
)
@@ -274,13 +275,14 @@ func (gui *Gui) onFocus(v *gocui.View) error {
func (gui *Gui) layout(g *gocui.Gui) error {
g.Highlight = true
width, height := g.Size()
- version := gui.Config.GetVersion()
+ donate := color.New(color.FgMagenta, color.Underline).Sprint(gui.Tr.SLocalize("Donate"))
+ version := donate + " " + gui.Config.GetVersion()
leftSideWidth := width / 3
statusFilesBoundary := 2
filesBranchesBoundary := 2 * height / 5 // height - 20
commitsBranchesBoundary := 3 * height / 5 // height - 10
commitsStashBoundary := height - 5 // height - 5
- optionsVersionBoundary := width - max(len(version), 1)
+ optionsVersionBoundary := width - max(len(utils.Decolorise(version)), 1)
minimumHeight := 16
minimumWidth := 10
@@ -355,20 +357,22 @@ func (gui *Gui) layout(g *gocui.Gui) error {
branchesView.FgColor = gocui.ColorWhite
}
- if v, err := g.SetView("commits", 0, commitsBranchesBoundary+panelSpacing, leftSideWidth, commitsStashBoundary, gocui.TOP|gocui.BOTTOM); err != nil {
+ commitsView, err := g.SetView("commits", 0, commitsBranchesBoundary+panelSpacing, leftSideWidth, commitsStashBoundary, gocui.TOP|gocui.BOTTOM)
+ if err != nil {
if err.Error() != "unknown view" {
return err
}
- v.Title = gui.Tr.SLocalize("CommitsTitle")
- v.FgColor = gocui.ColorWhite
+ commitsView.Title = gui.Tr.SLocalize("CommitsTitle")
+ commitsView.FgColor = gocui.ColorWhite
}
- if v, err := g.SetView("stash", 0, commitsStashBoundary+panelSpacing, leftSideWidth, optionsTop, gocui.TOP|gocui.RIGHT); err != nil {
+ stashView, err := g.SetView("stash", 0, commitsStashBoundary+panelSpacing, leftSideWidth, optionsTop, gocui.TOP|gocui.RIGHT)
+ if err != nil {
if err.Error() != "unknown view" {
return err
}
- v.Title = gui.Tr.SLocalize("StashTitle")
- v.FgColor = gocui.ColorWhite
+ stashView.Title = gui.Tr.SLocalize("StashTitle")
+ stashView.FgColor = gocui.ColorWhite
}
if v, err := g.SetView("options", appStatusOptionsBoundary-1, optionsTop, optionsVersionBoundary-1, optionsTop+2, 0); err != nil {
@@ -465,6 +469,13 @@ func (gui *Gui) layout(g *gocui.Gui) error {
listViews := map[*gocui.View]int{
filesView: gui.State.Panels.Files.SelectedLine,
branchesView: gui.State.Panels.Branches.SelectedLine,
+ commitsView: gui.State.Panels.Commits.SelectedLine,
+ stashView: gui.State.Panels.Stash.SelectedLine,
+ }
+
+ // menu view might not exist so we check to be safe
+ if menuView, err := gui.g.View("menu"); err == nil {
+ listViews[menuView] = gui.State.Panels.Menu.SelectedLine
}
for view, selectedLine := range listViews {
// check if the selected line is now out of view and if so refocus it
@@ -543,6 +554,8 @@ func (gui *Gui) Run() error {
}
defer g.Close()
+ g.Mouse = true
+
gui.g = g // TODO: always use gui.g rather than passing g around everywhere
if err := gui.SetColorScheme(); err != nil {
@@ -622,3 +635,11 @@ func (gui *Gui) quit(g *gocui.Gui, v *gocui.View) error {
}
return gocui.ErrQuit
}
+
+func (gui *Gui) handleDonate(g *gocui.Gui, v *gocui.View) error {
+ cx, _ := v.Cursor()
+ if cx > len(gui.Tr.SLocalize("Donate")) {
+ return nil
+ }
+ return gui.OSCommand.OpenLink("https://donorbox.org/lazygit")
+}
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 3c5862569..3e0e3b1d1 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -400,7 +400,6 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handleStashApply,
Description: gui.Tr.SLocalize("apply"),
}, {
-
ViewName: "stash",
Key: 'g',
Modifier: gocui.ModNone,
@@ -442,6 +441,11 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Key: 'q',
Modifier: gocui.ModNone,
Handler: gui.handleMenuClose,
+ }, {
+ ViewName: "version",
+ Key: gocui.MouseLeft,
+ Modifier: gocui.ModNone,
+ Handler: gui.handleDonate,
},
}
@@ -458,20 +462,25 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
listPanelMap := map[string]struct {
prevLine func(*gocui.Gui, *gocui.View) error
nextLine func(*gocui.Gui, *gocui.View) error
+ focus func(*gocui.Gui, *gocui.View) error
}{
- "menu": {prevLine: gui.handleMenuPrevLine, nextLine: gui.handleMenuNextLine},
- "files": {prevLine: gui.handleFilesPrevLine, nextLine: gui.handleFilesNextLine},
- "branches": {prevLine: gui.handleBranchesPrevLine, nextLine: gui.handleBranchesNextLine},
- "commits": {prevLine: gui.handleCommitsPrevLine, nextLine: gui.handleCommitsNextLine},
- "stash": {prevLine: gui.handleStashPrevLine, nextLine: gui.handleStashNextLine},
+ "menu": {prevLine: gui.handleMenuPrevLine, nextLine: gui.handleMenuNextLine, focus: gui.handleMenuSelect},
+ "files": {prevLine: gui.handleFilesPrevLine, nextLine: gui.handleFilesNextLine, focus: gui.handleFilesFocus},
+ "branches": {prevLine: gui.handleBranchesPrevLine, nextLine: gui.handleBranchesNextLine, focus: gui.handleBranchSelect},
+ "commits": {prevLine: gui.handleCommitsPrevLine, nextLine: gui.handleCommitsNextLine, focus: gui.handleCommitSelect},
+ "stash": {prevLine: gui.handleStashPrevLine, nextLine: gui.handleStashNextLine, focus: gui.handleStashEntrySelect},
+ "status": {focus: gui.handleStatusSelect},
}
for viewName, functions := range listPanelMap {
bindings = append(bindings, []*Binding{
{ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: functions.prevLine},
{ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: functions.prevLine},
+ {ViewName: viewName, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: functions.prevLine},
{ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: functions.nextLine},
{ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: functions.nextLine},
+ {ViewName: viewName, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: functions.nextLine},
+ {ViewName: viewName, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: functions.focus},
}...)
}
@@ -481,7 +490,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
// GetCurrentKeybindings gets the list of keybindings given the current context
func (gui *Gui) GetCurrentKeybindings() []*Binding {
bindings := gui.GetInitialKeybindings()
- viewName := gui.currentViewName(gui.g)
+ viewName := gui.currentViewName()
currentContext := gui.State.Contexts[viewName]
contextBindings := gui.GetContextMap()[viewName][currentContext]
@@ -560,6 +569,16 @@ func (gui *Gui) GetContextMap() map[string]map[string][]*Binding {
Modifier: gocui.ModNone,
Handler: gui.handleStagingNextLine,
}, {
+ ViewName: "main",
+ Key: gocui.KeyArrowLeft,
+ Modifier: gocui.ModNone,
+ Handler: gui.handleStagingPrevLine,
+ }, {
+ ViewName: "main",
+ Key: gocui.MouseWheelDown,
+ Modifier: gocui.ModNone,
+ Handler: gui.handleStagingNextLine,
+ }, {
ViewName: "main",
Key: gocui.KeyArrowLeft,
Modifier: gocui.ModNone,
@@ -642,6 +661,16 @@ func (gui *Gui) GetContextMap() map[string]map[string][]*Binding {
Description: gui.Tr.SLocalize("SelectBottom"),
}, {
ViewName: "main",
+ Key: gocui.MouseWheelUp,
+ Modifier: gocui.ModNone,
+ Handler: gui.handleSelectTop,
+ }, {
+ ViewName: "main",
+ Key: gocui.MouseWheelDown,
+ Modifier: gocui.ModNone,
+ Handler: gui.handleSelectBottom,
+ }, {
+ ViewName: "main",
Key: 'h',
Modifier: gocui.ModNone,
Handler: gui.handleSelectPrevConflict,
diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go
index efb6c5544..0d10ed4d7 100644
--- a/pkg/gui/merge_panel.go
+++ b/pkg/gui/merge_panel.go
@@ -205,7 +205,7 @@ func (gui *Gui) refreshMergePanel() error {
panelState.ConflictIndex = len(panelState.Conflicts) - 1
}
- hasFocus := gui.currentViewName(gui.g) == "main"
+ hasFocus := gui.currentViewName() == "main"
content, err := gui.coloredConflictFile(cat, panelState.Conflicts, panelState.ConflictIndex, panelState.ConflictTop, hasFocus)
if err != nil {
return err
diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go
index ed2f71401..05844f0ac 100644
--- a/pkg/gui/stash_panel.go
+++ b/pkg/gui/stash_panel.go
@@ -20,6 +20,13 @@ func (gui *Gui) getSelectedStashEntry(v *gocui.View) *commands.StashEntry {
}
func (gui *Gui) handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
+ if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
+ return err
+ }
stashEntry := gui.getSelectedStashEntry(v)
if stashEntry == nil {
return gui.renderString(g, "main", gui.Tr.SLocalize("NoStashEntries"))
@@ -60,6 +67,10 @@ func (gui *Gui) refreshStashEntries(g *gocui.Gui) error {
}
func (gui *Gui) handleStashNextLine(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
panelState := gui.State.Panels.Stash
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.StashEntries), false)
@@ -70,6 +81,10 @@ func (gui *Gui) handleStashNextLine(g *gocui.Gui, v *gocui.View) error {
}
func (gui *Gui) handleStashPrevLine(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
panelState := gui.State.Panels.Stash
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.StashEntries), true)
diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go
index 9853760e7..8c03c30de 100644
--- a/pkg/gui/status_panel.go
+++ b/pkg/gui/status_panel.go
@@ -48,6 +48,13 @@ func (gui *Gui) handleCheckForUpdate(g *gocui.Gui, v *gocui.View) error {
}
func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
+ if gui.popupPanelFocused() {
+ return nil
+ }
+
+ if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
+ return err
+ }
magenta := color.New(color.FgMagenta)
dashboardString := strings.Join(
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index 53cf80de5..dcb58c7de 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -287,8 +287,8 @@ func (gui *Gui) trimmedContent(v *gocui.View) string {
return strings.TrimSpace(v.Buffer())
}
-func (gui *Gui) currentViewName(g *gocui.Gui) string {
- currentView := g.CurrentView()
+func (gui *Gui) currentViewName() string {
+ currentView := gui.g.CurrentView()
return currentView.Name()
}
@@ -380,3 +380,20 @@ func (gui *Gui) renderPanelOptions() error {
}
return gui.renderGlobalOptions()
}
+
+func (gui *Gui) handleFocusView(g *gocui.Gui, v *gocui.View) error {
+ _, err := gui.g.SetCurrentView(v.Name())
+ return err
+}
+
+func (gui *Gui) popupPanelFocused() bool {
+ viewNames := []string{"commitMessage",
+ "credentials",
+ "menu"}
+ for _, viewName := range viewNames {
+ if gui.currentViewName() == viewName {
+ return true
+ }
+ }
+ return false
+}
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index b704c2576..cb1648dea 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -160,7 +160,8 @@ func renderDisplayableList(items []Displayable, isFocused bool) (string, error)
return strings.Join(paddedDisplayStrings, "\n"), nil
}
-func decolorise(str string) string {
+// Decolorise strips a string of color
+func Decolorise(str string) string {
re := regexp.MustCompile(`\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]`)
return re.ReplaceAllString(str, "")
}
@@ -172,7 +173,7 @@ func getPadWidths(stringArrays [][]string) []int {
padWidths := make([]int, len(stringArrays[0])-1)
for i := range padWidths {
for _, strings := range stringArrays {
- uncoloredString := decolorise(strings[i])
+ uncoloredString := Decolorise(strings[i])
if len(uncoloredString) > padWidths[i] {
padWidths[i] = len(uncoloredString)
}