mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-11 12:25:47 +02:00
Allow user to filter the files view to only show untracked files
This handles the situation where the user's own config says to not show untracked files, as is often the case with bare repos managing a user's dotfiles.
This commit is contained in:
parent
31e54eadaa
commit
7e85cdd027
7 changed files with 100 additions and 4 deletions
|
@ -32,13 +32,17 @@ func NewFileLoader(gitCommon *GitCommon, cmd oscommands.ICmdObjBuilder, config F
|
|||
|
||||
type GetStatusFileOptions struct {
|
||||
NoRenames bool
|
||||
// If true, we'll show untracked files even if the user has set the config to hide them.
|
||||
// This is useful for users with bare repos for dotfiles who default to hiding untracked files,
|
||||
// but want to occasionally see them to `git add` a new file.
|
||||
ForceShowUntracked bool
|
||||
}
|
||||
|
||||
func (self *FileLoader) GetStatusFiles(opts GetStatusFileOptions) []*models.File {
|
||||
// check if config wants us ignoring untracked files
|
||||
untrackedFilesSetting := self.config.GetShowUntrackedFiles()
|
||||
|
||||
if untrackedFilesSetting == "" {
|
||||
if opts.ForceShowUntracked || untrackedFilesSetting == "" {
|
||||
untrackedFilesSetting = "all"
|
||||
}
|
||||
untrackedFilesArg := fmt.Sprintf("--untracked-files=%s", untrackedFilesSetting)
|
||||
|
|
|
@ -777,6 +777,13 @@ func (self *FilesController) handleStatusFilterPressed() error {
|
|||
},
|
||||
Key: 't',
|
||||
},
|
||||
{
|
||||
Label: self.c.Tr.FilterUntrackedFiles,
|
||||
OnPress: func() error {
|
||||
return self.setStatusFiltering(filetree.DisplayUntracked)
|
||||
},
|
||||
Key: 'T',
|
||||
},
|
||||
{
|
||||
Label: self.c.Tr.ResetFilter,
|
||||
OnPress: func() error {
|
||||
|
@ -789,9 +796,19 @@ func (self *FilesController) handleStatusFilterPressed() error {
|
|||
}
|
||||
|
||||
func (self *FilesController) setStatusFiltering(filter filetree.FileTreeDisplayFilter) error {
|
||||
previousFilter := self.context().GetFilter()
|
||||
|
||||
self.context().FileTreeViewModel.SetStatusFilter(filter)
|
||||
self.c.PostRefreshUpdate(self.context())
|
||||
return nil
|
||||
|
||||
// Whenever we switch between untracked and other filters, we need to refresh the files view
|
||||
// because the untracked files filter applies when running `git status`.
|
||||
if previousFilter != filter && (previousFilter == filetree.DisplayUntracked || filter == filetree.DisplayUntracked) {
|
||||
return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}, Mode: types.ASYNC})
|
||||
} else {
|
||||
self.c.PostRefreshUpdate(self.context())
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (self *FilesController) edit(nodes []*filetree.FileNode) error {
|
||||
|
|
|
@ -570,7 +570,9 @@ func (self *RefreshHelper) refreshStateFiles() error {
|
|||
}
|
||||
|
||||
files := self.c.Git().Loaders.FileLoader.
|
||||
GetStatusFiles(git_commands.GetStatusFileOptions{})
|
||||
GetStatusFiles(git_commands.GetStatusFileOptions{
|
||||
ForceShowUntracked: self.c.Contexts().Files.ForceShowUntracked(),
|
||||
})
|
||||
|
||||
conflictFileCount := 0
|
||||
for _, file := range files {
|
||||
|
|
|
@ -16,6 +16,7 @@ const (
|
|||
DisplayStaged
|
||||
DisplayUnstaged
|
||||
DisplayTracked
|
||||
DisplayUntracked
|
||||
// this shows files with merge conflicts
|
||||
DisplayConflicted
|
||||
)
|
||||
|
@ -40,6 +41,7 @@ type IFileTree interface {
|
|||
|
||||
FilterFiles(test func(*models.File) bool) []*models.File
|
||||
SetStatusFilter(filter FileTreeDisplayFilter)
|
||||
ForceShowUntracked() bool
|
||||
Get(index int) *FileNode
|
||||
GetFile(path string) *models.File
|
||||
GetAllItems() []*FileNode
|
||||
|
@ -87,6 +89,8 @@ func (self *FileTree) getFilesForDisplay() []*models.File {
|
|||
return self.FilterFiles(func(file *models.File) bool { return file.HasUnstagedChanges })
|
||||
case DisplayTracked:
|
||||
return self.FilterFiles(func(file *models.File) bool { return file.Tracked })
|
||||
case DisplayUntracked:
|
||||
return self.FilterFiles(func(file *models.File) bool { return !file.Tracked })
|
||||
case DisplayConflicted:
|
||||
return self.FilterFiles(func(file *models.File) bool { return file.HasMergeConflicts })
|
||||
default:
|
||||
|
@ -94,6 +98,10 @@ func (self *FileTree) getFilesForDisplay() []*models.File {
|
|||
}
|
||||
}
|
||||
|
||||
func (self *FileTree) ForceShowUntracked() bool {
|
||||
return self.filter == DisplayUntracked
|
||||
}
|
||||
|
||||
func (self *FileTree) FilterFiles(test func(*models.File) bool) []*models.File {
|
||||
return lo.Filter(self.getFiles(), func(file *models.File, _ int) bool { return test(file) })
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ type TranslationSet struct {
|
|||
FilterStagedFiles string
|
||||
FilterUnstagedFiles string
|
||||
FilterTrackedFiles string
|
||||
FilterUntrackedFiles string
|
||||
ResetFilter string
|
||||
MergeConflictsTitle string
|
||||
Checkout string
|
||||
|
@ -1113,6 +1114,7 @@ func EnglishTranslationSet() *TranslationSet {
|
|||
FilterStagedFiles: "Show only staged files",
|
||||
FilterUnstagedFiles: "Show only unstaged files",
|
||||
FilterTrackedFiles: "Show only tracked files",
|
||||
FilterUntrackedFiles: "Show only untracked files",
|
||||
ResetFilter: "Reset filter",
|
||||
NoChangedFiles: "No changed files",
|
||||
SoftReset: "Soft reset",
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package filter_and_search
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||
)
|
||||
|
||||
var FilterByFileStatus = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Description: "Filtering to show untracked files in repo that hides them by default",
|
||||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(config *config.AppConfig) {
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
// need to set untracked files to not be displayed in git config
|
||||
shell.SetConfig("status.showUntrackedFiles", "no")
|
||||
|
||||
shell.CreateFileAndAdd("file-tracked", "foo")
|
||||
|
||||
shell.Commit("first commit")
|
||||
|
||||
shell.CreateFile("file-untracked", "bar")
|
||||
shell.UpdateFile("file-tracked", "baz")
|
||||
},
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.Views().Files().
|
||||
Focus().
|
||||
Lines(
|
||||
Contains(`file-tracked`).IsSelected(),
|
||||
).
|
||||
Press(keys.Files.OpenStatusFilter).
|
||||
Tap(func() {
|
||||
t.ExpectPopup().Menu().
|
||||
Title(Equals("Filtering")).
|
||||
Select(Contains("Show only untracked files")).
|
||||
Confirm()
|
||||
}).
|
||||
Lines(
|
||||
Contains(`file-untracked`).IsSelected(),
|
||||
).
|
||||
Press(keys.Files.OpenStatusFilter).
|
||||
Tap(func() {
|
||||
t.ExpectPopup().Menu().
|
||||
Title(Equals("Filtering")).
|
||||
Select(Contains("Show only tracked files")).
|
||||
Confirm()
|
||||
}).
|
||||
Lines(
|
||||
Contains(`file-tracked`).IsSelected(),
|
||||
).
|
||||
Press(keys.Files.OpenStatusFilter).
|
||||
Tap(func() {
|
||||
t.ExpectPopup().Menu().
|
||||
Title(Equals("Filtering")).
|
||||
Select(Contains("Reset filter")).
|
||||
Confirm()
|
||||
}).
|
||||
Lines(
|
||||
Contains(`file-tracked`).IsSelected(),
|
||||
)
|
||||
},
|
||||
})
|
|
@ -186,6 +186,7 @@ var tests = []*components.IntegrationTest{
|
|||
file.StageChildrenRangeSelect,
|
||||
file.StageDeletedRangeSelect,
|
||||
file.StageRangeSelect,
|
||||
filter_and_search.FilterByFileStatus,
|
||||
filter_and_search.FilterCommitFiles,
|
||||
filter_and_search.FilterFiles,
|
||||
filter_and_search.FilterFuzzy,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue