Repository: jesseduffield/lazygit
File: pkg/gui/controllers/files_controller.go (Go)

Code before:
				} else if encounteredSubmodule != nil && encounteredSubmodule != f {
					// Already encountered another submodule change -> fail.
					// (It may be the same submodule change because selectedNodes may include both a folder and their children)
					return false
				}
				encounteredSubmodule = f
			} else {
				if encounteredSubmodule != nil {
					// Already encountered a submodule change -> fail.
					return false
				}
				encounteredFile = true
			}
			return true
		})
		if !passed {
			return &types.DisabledReason{Text: self.c.Tr.RangeSelectNotSupportedForSubmodules}
		}
	}

	return nil
}

func (self *FilesController) remove(selectedNodes []*filetree.FileNode) error {
	submodules := self.c.Model().Submodules

	selectedNodes = normalisedSelectedNodes(selectedNodes)

	// If we have one submodule then we must only have one submodule or `canRemove` would have
	// returned an error
	submoduleNode := findSubmoduleNode(selectedNodes, submodules)
	if submoduleNode != nil {
		submodule := submoduleNode.SubmoduleConfig(submodules)

		menuItems := []*types.MenuItem{
			{
				Label: self.c.Tr.SubmoduleStashAndReset,
				OnPress: func() error {
					return self.ResetSubmodule(submodule)
				},
			},
		}

		return self.c.Menu(types.CreateMenuOptions{Title: submoduleNode.GetPath(), Items: menuItems})
	}

	discardAllChangesItem := types.MenuItem{
		Label: self.c.Tr.DiscardAllChanges,
		OnPress: func() error {
			self.c.LogAction(self.c.Tr.Actions.DiscardAllChangesInFile)


Review comment (suggestion):
This feels overly complicated to me, there must be a simpler way to express this logic. Is the following equivalent?

```go
	fileCount := 0
	submoduleCount := 0

	for _, node := range selectedNodes {
		_ = node.ForEachFile(func(f *models.File) error {
			if f.IsSubmodule(submodules) {
				submoduleCount++
			} else {
				fileCount++
			}
			return nil
		})
		if submoduleCount > 0 && (fileCount > 0 || submoduleCount > 1) {
			return &types.DisabledReason{Text: self.c.Tr.MultiSelectNotSupportedForSubmodules}
		}
	}
```

Code after:
		})
		if submoduleNode != nil {
			return submoduleNode
		}
	}
	return nil
}

func (self *FilesController) canRemove(selectedNodes []*filetree.FileNode) *types.DisabledReason {
	// Return disabled if the selection contains multiple changed items and includes a submodule change.
	submodules := self.c.Model().Submodules
	hasFiles := false
	uniqueSelectedSubmodules := set.New[*models.SubmoduleConfig]()

	for _, node := range selectedNodes {
		_ = node.ForEachFile(func(f *models.File) error {
			if submodule := f.SubmoduleConfig(submodules); submodule != nil {
				uniqueSelectedSubmodules.Add(submodule)
			} else {
				hasFiles = true
			}
			return nil
		})
		if uniqueSelectedSubmodules.Len() > 0 && (hasFiles || uniqueSelectedSubmodules.Len() > 1) {
			return &types.DisabledReason{Text: self.c.Tr.MultiSelectNotSupportedForSubmodules}
		}
	}

	return nil
}

func (self *FilesController) remove(selectedNodes []*filetree.FileNode) error {
	submodules := self.c.Model().Submodules

	selectedNodes = normalisedSelectedNodes(selectedNodes)

	// If we have one submodule then we must only have one submodule or `canRemove` would have
	// returned an error
	submoduleNode := findSubmoduleNode(selectedNodes, submodules)
	if submoduleNode != nil {
		submodule := submoduleNode.SubmoduleConfig(submodules)

		menuItems := []*types.MenuItem{
			{
				Label: self.c.Tr.SubmoduleStashAndReset,
				OnPress: func() error {
					return self.ResetSubmodule(submodule)
				},
			},
		}