Skip to content

Commit

Permalink
Add StatusPanelView config (jesseduffield#3309)
Browse files Browse the repository at this point in the history
Adds a new config `statusPanelView ` which allows you to select the
default view of the main window: `dashboard` (default),
`allBranchesLog`.
  • Loading branch information
stefanhaller committed Apr 10, 2024
2 parents 4ba8560 + 5616d6a commit 06624e8
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 28 deletions.
1 change: 1 addition & 0 deletions docs/Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ gui:
spinner:
frames: ['|', '/', '-', '\\']
rate: 50 # spinner rate in milliseconds
statusPanelView: 'dashboard' # one of 'dashboard' | 'allBranchesLog'
git:
paging:
colorArg: always
Expand Down
4 changes: 4 additions & 0 deletions pkg/config/app_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ func loadUserConfig(configFiles []string, base *UserConfig) (*UserConfig, error)
if err := yaml.Unmarshal(content, base); err != nil {
return nil, fmt.Errorf("The config at `%s` couldn't be parsed, please inspect it before opening up an issue.\n%w", path, err)
}

if err := base.Validate(); err != nil {
return nil, fmt.Errorf("The config at `%s` has a validation error.\n%w", path, err)
}
}

return base, nil
Expand Down
4 changes: 4 additions & 0 deletions pkg/config/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ type GuiConfig struct {
FilterMode string `yaml:"filterMode" jsonschema:"enum=substring,enum=fuzzy"`
// Config relating to the spinner.
Spinner SpinnerConfig `yaml:"spinner"`
// Status panel view.
// One of 'dashboard' (default) | 'allBranchesLog'
StatusPanelView string `yaml:"statusPanelView" jsonschema:"enum=dashboard,enum=allBranchesLog"`
}

func (c *GuiConfig) UseFuzzySearch() bool {
Expand Down Expand Up @@ -684,6 +687,7 @@ func GetDefaultConfig() *UserConfig {
Frames: []string{"|", "/", "-", "\\"},
Rate: 50,
},
StatusPanelView: "dashboard",
},
Git: GitConfig{
Paging: PagingConfig{
Expand Down
22 changes: 22 additions & 0 deletions pkg/config/user_config_validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package config

import (
"fmt"
"slices"
"strings"
)

func (config *UserConfig) Validate() error {
if err := validateEnum("gui.statusPanelView", config.Gui.StatusPanelView, []string{"dashboard", "allBranchesLog"}); err != nil {
return err
}
return nil
}

func validateEnum(name string, value string, allowedValues []string) error {
if slices.Contains(allowedValues, value) {
return nil
}
allowedValuesStr := strings.Join(allowedValues, ", ")
return fmt.Errorf("Unexpected value '%s' for '%s'. Allowed values: %s", value, name, allowedValuesStr)
}
49 changes: 49 additions & 0 deletions pkg/config/user_config_validation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package config

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestUserConfigValidate_enums(t *testing.T) {
type testCase struct {
value string
valid bool
}

scenarios := []struct {
name string
setup func(config *UserConfig, value string)
testCases []testCase
}{
{
name: "Gui.StatusPanelView",
setup: func(config *UserConfig, value string) {
config.Gui.StatusPanelView = value
},
testCases: []testCase{
{value: "dashboard", valid: true},
{value: "allBranchesLog", valid: true},
{value: "", valid: false},
{value: "invalid_value", valid: false},
},
},
}

for _, s := range scenarios {
t.Run(s.name, func(t *testing.T) {
for _, testCase := range s.testCases {
config := GetDefaultConfig()
s.setup(config, testCase.value)
err := config.Validate()

if testCase.valid {
assert.NoError(t, err)
} else {
assert.Error(t, err)
}
}
})
}
}
67 changes: 39 additions & 28 deletions pkg/gui/controllers/status_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,35 +83,15 @@ func (self *StatusController) onClickMain(opts gocui.ViewMouseBindingOpts) error
}

func (self *StatusController) GetOnRenderToMain() func() error {
versionStr := "master"
version, err := types.ParseVersionNumber(self.c.GetConfig().GetVersion())
if err == nil {
// Don't just take the version string as is, but format it again. This
// way it will be correct even if a distribution omits the "v", or the
// ".0" at the end.
versionStr = fmt.Sprintf("v%d.%d.%d", version.Major, version.Minor, version.Patch)
}
config := self.c.UserConfig.Gui

return func() error {
dashboardString := strings.Join(
[]string{
lazygitTitle(),
"Copyright 2022 Jesse Duffield",
fmt.Sprintf("Keybindings: %s", style.AttrUnderline.Sprint(fmt.Sprintf(constants.Links.Docs.Keybindings, versionStr))),
fmt.Sprintf("Config Options: %s", style.AttrUnderline.Sprint(fmt.Sprintf(constants.Links.Docs.Config, versionStr))),
fmt.Sprintf("Tutorial: %s", style.AttrUnderline.Sprint(constants.Links.Docs.Tutorial)),
fmt.Sprintf("Raise an Issue: %s", style.AttrUnderline.Sprint(constants.Links.Issues)),
fmt.Sprintf("Release Notes: %s", style.AttrUnderline.Sprint(constants.Links.Releases)),
style.FgMagenta.Sprintf("Become a sponsor: %s", style.AttrUnderline.Sprint(constants.Links.Donate)), // caffeine ain't free
}, "\n\n") + "\n"

return self.c.RenderToMainViews(types.RefreshMainOpts{
Pair: self.c.MainViewPairs().Normal,
Main: &types.ViewUpdateOpts{
Title: self.c.Tr.StatusTitle,
Task: types.NewRenderStringTask(dashboardString),
},
})
switch config.StatusPanelView {
case "dashboard":
return self.showDashboard
case "allBranchesLog":
return self.showAllBranchLogs
default:
return self.showDashboard
}
}

Expand Down Expand Up @@ -224,6 +204,37 @@ func (self *StatusController) showAllBranchLogs() error {
})
}

func (self *StatusController) showDashboard() error {
versionStr := "master"
version, err := types.ParseVersionNumber(self.c.GetConfig().GetVersion())
if err == nil {
// Don't just take the version string as is, but format it again. This
// way it will be correct even if a distribution omits the "v", or the
// ".0" at the end.
versionStr = fmt.Sprintf("v%d.%d.%d", version.Major, version.Minor, version.Patch)
}

dashboardString := strings.Join(
[]string{
lazygitTitle(),
fmt.Sprintf("Copyright %d Jesse Duffield", time.Now().Year()),
fmt.Sprintf("Keybindings: %s", style.AttrUnderline.Sprint(fmt.Sprintf(constants.Links.Docs.Keybindings, versionStr))),
fmt.Sprintf("Config Options: %s", style.AttrUnderline.Sprint(fmt.Sprintf(constants.Links.Docs.Config, versionStr))),
fmt.Sprintf("Tutorial: %s", style.AttrUnderline.Sprint(constants.Links.Docs.Tutorial)),
fmt.Sprintf("Raise an Issue: %s", style.AttrUnderline.Sprint(constants.Links.Issues)),
fmt.Sprintf("Release Notes: %s", style.AttrUnderline.Sprint(constants.Links.Releases)),
style.FgMagenta.Sprintf("Become a sponsor: %s", style.AttrUnderline.Sprint(constants.Links.Donate)), // caffeine ain't free
}, "\n\n") + "\n"

return self.c.RenderToMainViews(types.RefreshMainOpts{
Pair: self.c.MainViewPairs().Normal,
Main: &types.ViewUpdateOpts{
Title: self.c.Tr.StatusTitle,
Task: types.NewRenderStringTask(dashboardString),
},
})
}

func (self *StatusController) handleCheckForUpdate() error {
return self.c.Helpers().Update.CheckForUpdateInForeground()
}
9 changes: 9 additions & 0 deletions schema/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,15 @@
"additionalProperties": false,
"type": "object",
"description": "Config relating to the spinner."
},
"statusPanelView": {
"type": "string",
"enum": [
"dashboard",
"allBranchesLog"
],
"description": "Status panel view.\nOne of 'dashboard' (default) | 'allBranchesLog'",
"default": "dashboard"
}
},
"additionalProperties": false,
Expand Down

0 comments on commit 06624e8

Please sign in to comment.