Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions pkg/gui/controllers/basic_commits_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
"github.com/jesseduffield/lazygit/pkg/gui/types"
Expand Down Expand Up @@ -235,7 +236,7 @@ func (self *BasicCommitsController) copyCommitHashToClipboard(commit *models.Com
}

func (self *BasicCommitsController) copyCommitURLToClipboard(commit *models.Commit) error {
url, err := self.c.Helpers().Host.GetCommitURL(commit.Hash())
url, err := self.getCommitURL(commit)
if err != nil {
return err
}
Expand Down Expand Up @@ -334,7 +335,7 @@ func (self *BasicCommitsController) copyCommitTagsToClipboard(commit *models.Com
}

func (self *BasicCommitsController) openInBrowser(commit *models.Commit) error {
url, err := self.c.Helpers().Host.GetCommitURL(commit.Hash())
url, err := self.getCommitURL(commit)
if err != nil {
return err
}
Expand Down Expand Up @@ -425,3 +426,21 @@ func (self *BasicCommitsController) selectCommitsOfCurrentBranch() error {
self.context.HandleFocus(types.OnFocusOpts{})
return nil
}

func (self *BasicCommitsController) getCommitURL(commit *models.Commit) (string, error) {
remoteName := self.remoteNameFromContext()
return self.c.Helpers().Host.GetCommitURLForRemote(commit.Hash(), remoteName)
}

// When viewing commits under a specific remote branch, return that remote's
// name so we build the URL from the right remote. Falls back to "origin".
func (self *BasicCommitsController) remoteNameFromContext() string {
if subCommitsCtx, ok := self.context.(*context.SubCommitsContext); ok {
if ref := subCommitsCtx.GetRef(); ref != nil {
if remoteBranch, ok := ref.(*models.RemoteBranch); ok {
return remoteBranch.RemoteName
}
}
}
return "origin"
}
2 changes: 2 additions & 0 deletions pkg/gui/controllers/filtering_menu_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ func (self *FilteringMenuAction) setFiltering() error {
self.c.Modes().Filtering.SetSelectedCommitHash(self.c.Contexts().LocalCommits.GetSelectedCommitHash())

repoState := self.c.State().GetRepoState()
self.c.Modes().Filtering.SetForcedHalfScreen(false)
if repoState.GetScreenMode() == types.SCREEN_NORMAL {
repoState.SetScreenMode(types.SCREEN_HALF)
self.c.Modes().Filtering.SetForcedHalfScreen(true)
}

self.c.Context().Push(self.c.Contexts().LocalCommits, types.OnFocusOpts{})
Expand Down
12 changes: 10 additions & 2 deletions pkg/gui/controllers/helpers/host_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ func (self *HostHelper) GetPullRequestURL(from string, to string) (string, error
}

func (self *HostHelper) GetCommitURL(commitHash string) (string, error) {
mgr, err := self.getHostingServiceMgr()
return self.GetCommitURLForRemote(commitHash, "origin")
}

func (self *HostHelper) GetCommitURLForRemote(commitHash string, remoteName string) (string, error) {
mgr, err := self.getHostingServiceMgrForRemote(remoteName)
if err != nil {
return "", err
}
Expand All @@ -37,7 +41,11 @@ func (self *HostHelper) GetCommitURL(commitHash string) (string, error) {
// getting this on every request rather than storing it in state in case our remoteURL changes
// from one invocation to the next.
func (self *HostHelper) getHostingServiceMgr() (*hosting_service.HostingServiceMgr, error) {
remoteUrl, err := self.c.Git().Remote.GetRemoteURL("origin")
return self.getHostingServiceMgrForRemote("origin")
}

func (self *HostHelper) getHostingServiceMgrForRemote(remoteName string) (*hosting_service.HostingServiceMgr, error) {
remoteUrl, err := self.c.Git().Remote.GetRemoteURL(remoteName)
if err != nil {
return nil, err
}
Expand Down
14 changes: 11 additions & 3 deletions pkg/gui/controllers/helpers/mode_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,10 @@ func (self *ModeHelper) ExitFilterMode() error {

func (self *ModeHelper) ClearFiltering() error {
selectedCommitHash := self.c.Contexts().LocalCommits.GetSelectedCommitHash()
forcedHalfScreen := self.c.Modes().Filtering.GetForcedHalfScreen()
self.c.Modes().Filtering.Reset()
if self.c.State().GetRepoState().GetScreenMode() == types.SCREEN_HALF {
self.c.State().GetRepoState().SetScreenMode(types.SCREEN_NORMAL)
}
repoState := self.c.State().GetRepoState()
repoState.SetScreenMode(screenModeAfterClearingFiltering(repoState.GetScreenMode(), forcedHalfScreen))

self.c.Refresh(types.RefreshOptions{
Scope: ScopesToRefreshWhenFilteringModeChanges(),
Expand All @@ -207,6 +207,14 @@ func (self *ModeHelper) ClearFiltering() error {
return nil
}

func screenModeAfterClearingFiltering(current types.ScreenMode, forcedHalfScreen bool) types.ScreenMode {
if forcedHalfScreen && current == types.SCREEN_HALF {
return types.SCREEN_NORMAL
}

return current
}

// Stashes really only need to be refreshed when filtering by path, not by author, but it's too much
// work to distinguish this, and refreshing stashes is fast, so we don't bother
func ScopesToRefreshWhenFilteringModeChanges() []types.RefreshableView {
Expand Down
48 changes: 48 additions & 0 deletions pkg/gui/controllers/helpers/mode_helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package helpers

import (
"testing"

"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/stretchr/testify/assert"
)

func TestScreenModeAfterClearingFiltering(t *testing.T) {
tests := []struct {
name string
current types.ScreenMode
forcedHalfScreen bool
expected types.ScreenMode
}{
{
name: "restore normal after filtering promoted screen mode",
current: types.SCREEN_HALF,
forcedHalfScreen: true,
expected: types.SCREEN_NORMAL,
},
{
name: "preserve configured half screen mode",
current: types.SCREEN_HALF,
forcedHalfScreen: false,
expected: types.SCREEN_HALF,
},
{
name: "preserve full screen mode chosen while filtering",
current: types.SCREEN_FULL,
forcedHalfScreen: true,
expected: types.SCREEN_FULL,
},
{
name: "preserve normal when user already switched back",
current: types.SCREEN_NORMAL,
forcedHalfScreen: true,
expected: types.SCREEN_NORMAL,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
assert.Equal(t, test.expected, screenModeAfterClearingFiltering(test.current, test.forcedHalfScreen))
})
}
}
10 changes: 10 additions & 0 deletions pkg/gui/modes/filtering/filtering.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type Filtering struct {
path string // the filename that gets passed to git log
author string // the author that gets passed to git log
selectedCommitHash string // the commit that was selected before we entered filtering mode
forcedHalfScreen bool // whether entering filtering switched screen mode from normal to half
}

func New(path string, author string) Filtering {
Expand All @@ -17,6 +18,7 @@ func (m *Filtering) Active() bool {
func (m *Filtering) Reset() {
m.path = ""
m.author = ""
m.forcedHalfScreen = false
}

func (m *Filtering) SetPath(path string) {
Expand All @@ -42,3 +44,11 @@ func (m *Filtering) SetSelectedCommitHash(hash string) {
func (m *Filtering) GetSelectedCommitHash() string {
return m.selectedCommitHash
}

func (m *Filtering) SetForcedHalfScreen(value bool) {
m.forcedHalfScreen = value
}

func (m *Filtering) GetForcedHalfScreen() bool {
return m.forcedHalfScreen
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package filter_by_path

import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)

var PreserveHalfScreenModeOnExit = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Exiting commit filtering preserves configured half screen mode",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Gui.ScreenMode = "half"
},
SetupRepo: func(shell *Shell) {
commonSetup(shell)
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
IsFocused()

t.Views().Files().
IsInvisible()

filterByFilterFile(t, keys)
postFilterTest(t)

t.Views().Files().
IsInvisible()

t.Views().Commits().
PressEscape()

t.Views().Files().
IsInvisible()

t.Views().Commits().
Lines(
Contains(`none of the two`),
Contains(`both files`).IsSelected(),
Contains(`only otherFile`),
Contains(`only filterFile`),
)
},
})
1 change: 1 addition & 0 deletions pkg/integration/tests/test_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ var tests = []*components.IntegrationTest{
filter_by_path.CliArg,
filter_by_path.DropCommitInFilteringMode,
filter_by_path.KeepSameCommitSelectedOnExit,
filter_by_path.PreserveHalfScreenModeOnExit,
filter_by_path.RewordCommitInFilteringMode,
filter_by_path.SelectFile,
filter_by_path.SelectFilteredFileWhenEnteringCommit,
Expand Down