diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go index 41f9197fe..be3348897 100644 --- a/pkg/gui/controllers/files_controller.go +++ b/pkg/gui/controllers/files_controller.go @@ -130,10 +130,11 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types OpensMenu: true, }, { - Keys: opts.GetKeys(opts.Config.Files.ToggleStagedAll), - Handler: self.toggleStagedAll, - Description: self.c.Tr.ToggleStagedAll, - Tooltip: self.c.Tr.ToggleStagedAllTooltip, + Keys: opts.GetKeys(opts.Config.Files.ToggleStagedAll), + Handler: self.toggleStagedAll, + GetDisabledReason: self.require(self.anyFilesDisplayed), + Description: self.c.Tr.ToggleStagedAll, + Tooltip: self.c.Tr.ToggleStagedAllTooltip, }, { Keys: opts.GetKeys(opts.Config.Universal.GoInto), @@ -916,6 +917,17 @@ func (self *FilesController) openSubmoduleConflictMenu(file *models.File) error }) } +// The stage-all command acts on the file tree as it is displayed, so there has +// to be something in it. This is also the case before the first files refresh +// has come in, when there is no tree at all yet. +func (self *FilesController) anyFilesDisplayed() *types.DisabledReason { + if self.context().FileTreeViewModel.Len() == 0 { + return &types.DisabledReason{Text: self.c.Tr.NoChangedFiles} + } + + return nil +} + func (self *FilesController) toggleStagedAll() error { if err := self.toggleStagedAllWithLock(); err != nil { return err diff --git a/pkg/integration/tests/file/stage_all_without_changed_files.go b/pkg/integration/tests/file/stage_all_without_changed_files.go new file mode 100644 index 000000000..bae54dffe --- /dev/null +++ b/pkg/integration/tests/file/stage_all_without_changed_files.go @@ -0,0 +1,25 @@ +package file + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var StageAllWithoutChangedFiles = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Pressing the stage-all key when there are no changed files says that there are none", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.EmptyCommit("first commit") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + IsEmpty(). + Press(keys.Files.ToggleStagedAll). + Tap(func() { + t.ExpectToast(Contains("No changed files")) + }) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index a945e324d..16de7805a 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -248,6 +248,7 @@ var tests = []*components.IntegrationTest{ file.RenameSimilarityThresholdChange, file.RenamedFiles, file.RenamedFilesNoRootItem, + file.StageAllWithoutChangedFiles, file.StageChildrenRangeSelect, file.StageDeletedRangeSelect, file.StageRangeSelect,