From e33fe37a99d4b3866970b1b2f40169d1bc9afa2e Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Mon, 24 Jul 2023 13:06:42 +1000 Subject: [PATCH] Standardise on using lo for slice functions We've been sometimes using lo and sometimes using my slices package, and we need to pick one for consistency. Lo is more extensive and better maintained so we're going with that. My slices package was a superset of go's own slices package so in some places I've just used the official one (the methods were just wrappers anyway). I've also moved the remaining methods into the utils package. --- pkg/app/app.go | 11 +- pkg/app/daemon/rebase.go | 6 +- pkg/app/errors.go | 6 +- pkg/cheatsheet/generate.go | 6 +- pkg/commands/git_commands/bisect_info.go | 4 +- pkg/commands/git_commands/branch_loader.go | 12 +- .../git_commands/commit_file_loader.go | 3 +- pkg/commands/git_commands/commit_loader.go | 5 +- pkg/commands/git_commands/rebase.go | 3 +- pkg/commands/git_commands/remote_loader.go | 5 +- pkg/commands/git_commands/stash_loader.go | 4 +- pkg/commands/git_commands/tag_loader.go | 4 +- .../hosting_service/hosting_service.go | 5 +- pkg/commands/oscommands/os.go | 3 +- pkg/commands/patch/patch_builder.go | 5 +- pkg/gui/context.go | 6 +- pkg/gui/context/commit_files_context.go | 4 +- pkg/gui/context/menu_context.go | 11 +- pkg/gui/context/working_tree_context.go | 4 +- pkg/gui/controllers/custom_command_action.go | 3 +- .../helpers/merge_and_rebase_helper.go | 4 +- pkg/gui/controllers/helpers/mode_helper.go | 6 +- pkg/gui/controllers/helpers/refresh_helper.go | 4 +- pkg/gui/controllers/helpers/refs_helper.go | 4 +- pkg/gui/controllers/helpers/repos_helper.go | 4 +- .../controllers/helpers/suggestions_helper.go | 16 +- .../helpers/upstream_helper_test.go | 4 +- pkg/gui/controllers/options_menu_action.go | 3 +- pkg/gui/controllers/status_controller.go | 4 +- pkg/gui/filetree/commit_file_tree.go | 4 +- pkg/gui/filetree/file_tree.go | 6 +- pkg/gui/filetree/node.go | 11 +- pkg/gui/layout.go | 11 +- pkg/gui/modes/cherrypicking/cherry_picking.go | 8 +- pkg/gui/presentation/branches.go | 3 +- pkg/gui/presentation/graph/graph.go | 21 +- pkg/gui/presentation/reflog_commits.go | 4 +- pkg/gui/presentation/remote_branches.go | 4 +- pkg/gui/presentation/remotes.go | 4 +- pkg/gui/presentation/stash_entries.go | 4 +- pkg/gui/presentation/submodules.go | 4 +- pkg/gui/presentation/suggestions.go | 4 +- pkg/gui/presentation/tags.go | 4 +- .../custom_commands/handler_creator.go | 5 +- .../custom_commands/keybinding_creator.go | 4 +- pkg/gui/status/status_manager.go | 4 +- pkg/gui/views.go | 4 +- pkg/integration/clients/cli.go | 3 +- pkg/integration/clients/tui.go | 4 +- pkg/integration/components/test.go | 4 +- pkg/integration/tests/tests.go | 6 +- pkg/utils/formatting.go | 17 +- pkg/utils/search.go | 4 +- pkg/utils/slice.go | 55 +++ .../generics/slices/delegated_slices.go | 117 ----- .../generics/slices/delegated_sort.go | 57 --- .../jesseduffield/generics/slices/slices.go | 408 ------------------ vendor/modules.txt | 1 - 58 files changed, 212 insertions(+), 732 deletions(-) delete mode 100644 vendor/github.com/jesseduffield/generics/slices/delegated_slices.go delete mode 100644 vendor/github.com/jesseduffield/generics/slices/delegated_sort.go delete mode 100644 vendor/github.com/jesseduffield/generics/slices/slices.go diff --git a/pkg/app/app.go b/pkg/app/app.go index 2b7a8457d..f34611b34 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -13,7 +13,6 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/afero" - "github.com/jesseduffield/generics/slices" appTypes "github.com/jesseduffield/lazygit/pkg/app/types" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" @@ -267,7 +266,11 @@ func (app *App) Run(startArgs appTypes.StartArgs) error { // Close closes any resources func (app *App) Close() error { - return slices.TryForEach(app.closers, func(closer io.Closer) error { - return closer.Close() - }) + for _, closer := range app.closers { + if err := closer.Close(); err != nil { + return err + } + } + + return nil } diff --git a/pkg/app/daemon/rebase.go b/pkg/app/daemon/rebase.go index 8702f0f69..50494113a 100644 --- a/pkg/app/daemon/rebase.go +++ b/pkg/app/daemon/rebase.go @@ -6,10 +6,10 @@ import ( "strings" "github.com/fsmiamoto/git-todo-parser/todo" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/env" + "github.com/samber/lo" ) type TodoLine struct { @@ -26,11 +26,11 @@ func (self *TodoLine) ToString() string { } func TodoLinesToString(todoLines []TodoLine) string { - lines := slices.Map(todoLines, func(todoLine TodoLine) string { + lines := lo.Map(todoLines, func(todoLine TodoLine, _ int) string { return todoLine.ToString() }) - return strings.Join(slices.Reverse(lines), "") + return strings.Join(lo.Reverse(lines), "") } type ChangeTodoAction struct { diff --git a/pkg/app/errors.go b/pkg/app/errors.go index 1556e58fe..2561fccb8 100644 --- a/pkg/app/errors.go +++ b/pkg/app/errors.go @@ -3,8 +3,8 @@ package app import ( "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/i18n" + "github.com/samber/lo" ) type errorMapping struct { @@ -18,7 +18,7 @@ func knownError(tr *i18n.TranslationSet, err error) (string, bool) { knownErrorMessages := []string{tr.MinGitVersionError} - if slices.Contains(knownErrorMessages, errorMessage) { + if lo.Contains(knownErrorMessages, errorMessage) { return errorMessage, true } @@ -29,7 +29,7 @@ func knownError(tr *i18n.TranslationSet, err error) (string, bool) { }, } - if mapping, ok := slices.Find(mappings, func(mapping errorMapping) bool { + if mapping, ok := lo.Find(mappings, func(mapping errorMapping) bool { return strings.Contains(errorMessage, mapping.originalError) }); ok { return mapping.newError, true diff --git a/pkg/cheatsheet/generate.go b/pkg/cheatsheet/generate.go index 112e4c4d5..184e84a04 100644 --- a/pkg/cheatsheet/generate.go +++ b/pkg/cheatsheet/generate.go @@ -15,7 +15,6 @@ import ( "strings" "github.com/jesseduffield/generics/maps" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazycore/pkg/utils" "github.com/jesseduffield/lazygit/pkg/app" "github.com/jesseduffield/lazygit/pkg/config" @@ -23,6 +22,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/i18n" "github.com/samber/lo" + "golang.org/x/exp/slices" ) type bindingSection struct { @@ -129,7 +129,7 @@ func localisedTitle(tr *i18n.TranslationSet, str string) string { func getBindingSections(bindings []*types.Binding, tr *i18n.TranslationSet) []*bindingSection { excludedViews := []string{"stagingSecondary", "patchBuildingSecondary"} - bindingsToDisplay := slices.Filter(bindings, func(binding *types.Binding) bool { + bindingsToDisplay := lo.Filter(bindings, func(binding *types.Binding, _ int) bool { if lo.Contains(excludedViews, binding.ViewName) { return false } @@ -162,7 +162,7 @@ func getBindingSections(bindings []*types.Binding, tr *i18n.TranslationSet) []*b return a.header.title < b.header.title }) - return slices.Map(bindingGroups, func(hb headerWithBindings) *bindingSection { + return lo.Map(bindingGroups, func(hb headerWithBindings, _ int) *bindingSection { return &bindingSection{ title: hb.header.title, bindings: hb.bindings, diff --git a/pkg/commands/git_commands/bisect_info.go b/pkg/commands/git_commands/bisect_info.go index ea20d0d38..67293803a 100644 --- a/pkg/commands/git_commands/bisect_info.go +++ b/pkg/commands/git_commands/bisect_info.go @@ -2,7 +2,7 @@ package git_commands import ( "github.com/jesseduffield/generics/maps" - "github.com/jesseduffield/generics/slices" + "github.com/samber/lo" "github.com/sirupsen/logrus" ) @@ -97,5 +97,5 @@ func (self *BisectInfo) Bisecting() bool { return false } - return slices.Contains(maps.Values(self.statusMap), BisectStatusOld) + return lo.Contains(maps.Values(self.statusMap), BisectStatusOld) } diff --git a/pkg/commands/git_commands/branch_loader.go b/pkg/commands/git_commands/branch_loader.go index 7c91c1cbc..094354cad 100644 --- a/pkg/commands/git_commands/branch_loader.go +++ b/pkg/commands/git_commands/branch_loader.go @@ -6,13 +6,13 @@ import ( "strings" "github.com/jesseduffield/generics/set" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/go-git/v5/config" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" + "golang.org/x/exp/slices" ) // context: @@ -75,7 +75,7 @@ outer: if strings.EqualFold(reflogBranch.Name, branch.Name) { branch.Recency = reflogBranch.Recency branchesWithRecency = append(branchesWithRecency, branch) - branches = slices.Remove(branches, j) + branches = utils.Remove(branches, j) continue outer } } @@ -87,14 +87,14 @@ outer: return a.Name < b.Name }) - branches = slices.Prepend(branches, branchesWithRecency...) + branches = utils.Prepend(branches, branchesWithRecency...) foundHead := false for i, branch := range branches { if branch.Head { foundHead = true branch.Recency = " *" - branches = slices.Move(branches, i, 0) + branches = utils.Move(branches, i, 0) break } } @@ -103,7 +103,7 @@ outer: if err != nil { return nil, err } - branches = slices.Prepend(branches, &models.Branch{Name: info.RefName, DisplayName: info.DisplayName, Head: true, DetachedHead: info.DetachedHead, Recency: " *"}) + branches = utils.Prepend(branches, &models.Branch{Name: info.RefName, DisplayName: info.DisplayName, Head: true, DetachedHead: info.DetachedHead, Recency: " *"}) } configBranches, err := self.config.Branches() @@ -131,7 +131,7 @@ func (self *BranchLoader) obtainBranches() []*models.Branch { trimmedOutput := strings.TrimSpace(output) outputLines := strings.Split(trimmedOutput, "\n") - return slices.FilterMap(outputLines, func(line string) (*models.Branch, bool) { + return lo.FilterMap(outputLines, func(line string, _ int) (*models.Branch, bool) { if line == "" { return nil, false } diff --git a/pkg/commands/git_commands/commit_file_loader.go b/pkg/commands/git_commands/commit_file_loader.go index d89c3c578..7abdc74c5 100644 --- a/pkg/commands/git_commands/commit_file_loader.go +++ b/pkg/commands/git_commands/commit_file_loader.go @@ -3,7 +3,6 @@ package git_commands import ( "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/common" @@ -52,7 +51,7 @@ func getCommitFilesFromFilenames(filenames string) []*models.CommitFile { } // typical result looks like 'A my_file' meaning my_file was added - return slices.Map(lo.Chunk(lines, 2), func(chunk []string) *models.CommitFile { + return lo.Map(lo.Chunk(lines, 2), func(chunk []string, _ int) *models.CommitFile { return &models.CommitFile{ ChangeStatus: chunk[0], Name: chunk[1], diff --git a/pkg/commands/git_commands/commit_loader.go b/pkg/commands/git_commands/commit_loader.go index ac0f19363..f138adfaf 100644 --- a/pkg/commands/git_commands/commit_loader.go +++ b/pkg/commands/git_commands/commit_loader.go @@ -11,7 +11,6 @@ import ( "sync" "github.com/fsmiamoto/git-todo-parser/todo" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" @@ -233,7 +232,7 @@ func (self *CommitLoader) getHydratedRebasingCommits(rebaseMode enums.RebaseMode return nil, nil } - commitShas := slices.FilterMap(commits, func(commit *models.Commit) (string, bool) { + commitShas := lo.FilterMap(commits, func(commit *models.Commit, _ int) (string, bool) { return commit.Sha, commit.Sha != "" }) @@ -379,7 +378,7 @@ func (self *CommitLoader) getInteractiveRebasingCommits() ([]*models.Commit, err // Command does not have a commit associated, skip continue } - commits = slices.Prepend(commits, &models.Commit{ + commits = utils.Prepend(commits, &models.Commit{ Sha: t.Commit, Name: t.Msg, Status: models.StatusRebasing, diff --git a/pkg/commands/git_commands/rebase.go b/pkg/commands/git_commands/rebase.go index 66bfbf82d..83c3fbe09 100644 --- a/pkg/commands/git_commands/rebase.go +++ b/pkg/commands/git_commands/rebase.go @@ -7,7 +7,6 @@ import ( "github.com/fsmiamoto/git-todo-parser/todo" "github.com/go-errors/errors" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/app/daemon" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" @@ -158,7 +157,7 @@ func (self *RebaseCommands) EditRebase(branchRef string) error { } func logTodoChanges(changes []daemon.ChangeTodoAction) string { - changeTodoStr := strings.Join(slices.Map(changes, func(c daemon.ChangeTodoAction) string { + changeTodoStr := strings.Join(lo.Map(changes, func(c daemon.ChangeTodoAction, _ int) string { return fmt.Sprintf("%s:%s", c.Sha, c.NewAction) }), "\n") return fmt.Sprintf("Changing TODO actions: %s", changeTodoStr) diff --git a/pkg/commands/git_commands/remote_loader.go b/pkg/commands/git_commands/remote_loader.go index c2a8da025..6551ecb25 100644 --- a/pkg/commands/git_commands/remote_loader.go +++ b/pkg/commands/git_commands/remote_loader.go @@ -4,12 +4,13 @@ import ( "strings" "sync" - "github.com/jesseduffield/generics/slices" gogit "github.com/jesseduffield/go-git/v5" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" + "golang.org/x/exp/slices" ) type RemoteLoader struct { @@ -53,7 +54,7 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) { return nil, remoteBranchesErr } - remotes := slices.Map(goGitRemotes, func(goGitRemote *gogit.Remote) *models.Remote { + remotes := lo.Map(goGitRemotes, func(goGitRemote *gogit.Remote, _ int) *models.Remote { remoteName := goGitRemote.Config().Name branches := remoteBranchesByRemoteName[remoteName] diff --git a/pkg/commands/git_commands/stash_loader.go b/pkg/commands/git_commands/stash_loader.go index e5ea1da49..1ab0e0ad0 100644 --- a/pkg/commands/git_commands/stash_loader.go +++ b/pkg/commands/git_commands/stash_loader.go @@ -5,11 +5,11 @@ import ( "strconv" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) type StashLoader struct { @@ -69,7 +69,7 @@ func (self *StashLoader) getUnfilteredStashEntries() []*models.StashEntry { cmdArgs := NewGitCmd("stash").Arg("list", "-z", "--pretty=%gs").ToArgv() rawString, _ := self.cmd.New(cmdArgs).DontLog().RunWithOutput() - return slices.MapWithIndex(utils.SplitNul(rawString), func(line string, index int) *models.StashEntry { + return lo.Map(utils.SplitNul(rawString), func(line string, index int) *models.StashEntry { return self.stashEntryFromLine(line, index) }) } diff --git a/pkg/commands/git_commands/tag_loader.go b/pkg/commands/git_commands/tag_loader.go index f69ebf79a..bd05fe4b4 100644 --- a/pkg/commands/git_commands/tag_loader.go +++ b/pkg/commands/git_commands/tag_loader.go @@ -3,11 +3,11 @@ package git_commands import ( "regexp" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) type TagLoader struct { @@ -38,7 +38,7 @@ func (self *TagLoader) GetTags() ([]*models.Tag, error) { lineRegex := regexp.MustCompile(`^([^\s]+)(\s+)?(.*)$`) - tags := slices.Map(split, func(line string) *models.Tag { + tags := lo.Map(split, func(line string, _ int) *models.Tag { matches := lineRegex.FindStringSubmatch(line) tagName := matches[1] message := "" diff --git a/pkg/commands/hosting_service/hosting_service.go b/pkg/commands/hosting_service/hosting_service.go index dd06e1cb7..e6f9bef79 100644 --- a/pkg/commands/hosting_service/hosting_service.go +++ b/pkg/commands/hosting_service/hosting_service.go @@ -8,9 +8,10 @@ import ( "github.com/go-errors/errors" "github.com/jesseduffield/lazygit/pkg/i18n" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" "github.com/sirupsen/logrus" - "github.com/jesseduffield/generics/slices" + "golang.org/x/exp/slices" ) // This package is for handling logic specific to a git hosting service like github, gitlab, bitbucket, gitea, etc. @@ -111,7 +112,7 @@ func (self *HostingServiceMgr) getCandidateServiceDomains() []ServiceDomain { serviceDefinition, ok := serviceDefinitionByProvider[provider] if !ok { - providerNames := slices.Map(serviceDefinitions, func(serviceDefinition ServiceDefinition) string { + providerNames := lo.Map(serviceDefinitions, func(serviceDefinition ServiceDefinition, _ int) string { return serviceDefinition.provider }) diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index 3e305a96f..4a77310b5 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -13,7 +13,6 @@ import ( "github.com/samber/lo" "github.com/atotto/clipboard" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/kill" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/config" @@ -189,7 +188,7 @@ func (c *OSCommand) FileExists(path string) (bool, error) { // PipeCommands runs a heap of commands and pipes their inputs/outputs together like A | B | C func (c *OSCommand) PipeCommands(cmdObjs ...ICmdObj) error { - cmds := slices.Map(cmdObjs, func(cmdObj ICmdObj) *exec.Cmd { + cmds := lo.Map(cmdObjs, func(cmdObj ICmdObj, _ int) *exec.Cmd { return cmdObj.GetCmd() }) diff --git a/pkg/commands/patch/patch_builder.go b/pkg/commands/patch/patch_builder.go index b73891911..2f350a40b 100644 --- a/pkg/commands/patch/patch_builder.go +++ b/pkg/commands/patch/patch_builder.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/jesseduffield/generics/maps" - "github.com/jesseduffield/generics/slices" "github.com/samber/lo" "github.com/sirupsen/logrus" ) @@ -209,10 +208,10 @@ func (p *PatchBuilder) renderEachFilePatch(plain bool) []string { filenames := maps.Keys(p.fileInfoMap) sort.Strings(filenames) - patches := slices.Map(filenames, func(filename string) string { + patches := lo.Map(filenames, func(filename string, _ int) string { return p.RenderPatchForFile(filename, plain, false) }) - output := slices.Filter(patches, func(patch string) bool { + output := lo.Filter(patches, func(patch string, _ int) bool { return patch != "" }) diff --git a/pkg/gui/context.go b/pkg/gui/context.go index 90bb78768..d845265a3 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -4,9 +4,9 @@ import ( "errors" "sync" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" ) @@ -134,7 +134,7 @@ func (self *ContextMgr) pushToContextStack(c types.Context) ([]types.Context, ty (topContext.GetKind() == types.MAIN_CONTEXT && c.GetKind() == types.MAIN_CONTEXT) { contextsToDeactivate = append(contextsToDeactivate, topContext) - _, self.ContextStack = slices.Pop(self.ContextStack) + _, self.ContextStack = utils.Pop(self.ContextStack) } self.ContextStack = append(self.ContextStack, c) @@ -154,7 +154,7 @@ func (self *ContextMgr) Pop() error { } var currentContext types.Context - currentContext, self.ContextStack = slices.Pop(self.ContextStack) + currentContext, self.ContextStack = utils.Pop(self.ContextStack) newContext := self.ContextStack[len(self.ContextStack)-1] diff --git a/pkg/gui/context/commit_files_context.go b/pkg/gui/context/commit_files_context.go index 5cb11d9cc..035230e9d 100644 --- a/pkg/gui/context/commit_files_context.go +++ b/pkg/gui/context/commit_files_context.go @@ -1,12 +1,12 @@ package context import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) type CommitFilesContext struct { @@ -34,7 +34,7 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext { } lines := presentation.RenderCommitFileTree(viewModel, c.Modes().Diffing.Ref, c.Git().Patch.PatchBuilder) - return slices.Map(lines, func(line string) []string { + return lo.Map(lines, func(line string, _ int) []string { return []string{line} }) } diff --git a/pkg/gui/context/menu_context.go b/pkg/gui/context/menu_context.go index 4a174c019..353f3d386 100644 --- a/pkg/gui/context/menu_context.go +++ b/pkg/gui/context/menu_context.go @@ -1,7 +1,6 @@ package context import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/gui/keybindings" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" @@ -82,11 +81,11 @@ func (self *MenuViewModel) SetMenuItems(items []*types.MenuItem, columnAlignment // TODO: move into presentation package func (self *MenuViewModel) GetDisplayStrings(_startIdx int, _length int) [][]string { menuItems := self.FilteredListViewModel.GetItems() - showKeys := slices.Some(menuItems, func(item *types.MenuItem) bool { + showKeys := lo.SomeBy(menuItems, func(item *types.MenuItem) bool { return item.Key != nil }) - return slices.Map(menuItems, func(item *types.MenuItem) []string { + return lo.Map(menuItems, func(item *types.MenuItem, _ int) []string { displayStrings := item.LabelColumns if !showKeys { @@ -107,18 +106,18 @@ func (self *MenuViewModel) GetDisplayStrings(_startIdx int, _length int) [][]str keyStyle = style.FgDefault.SetStrikethrough() } - displayStrings = slices.Prepend(displayStrings, keyStyle.Sprint(keyLabel)) + displayStrings = utils.Prepend(displayStrings, keyStyle.Sprint(keyLabel)) return displayStrings }) } func (self *MenuContext) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding { basicBindings := self.ListContextTrait.GetKeybindings(opts) - menuItemsWithKeys := slices.Filter(self.menuItems, func(item *types.MenuItem) bool { + menuItemsWithKeys := lo.Filter(self.menuItems, func(item *types.MenuItem, _ int) bool { return item.Key != nil }) - menuItemBindings := slices.Map(menuItemsWithKeys, func(item *types.MenuItem) *types.Binding { + menuItemBindings := lo.Map(menuItemsWithKeys, func(item *types.MenuItem, _ int) *types.Binding { return &types.Binding{ Key: item.Key, Handler: func() error { return self.OnMenuPress(item) }, diff --git a/pkg/gui/context/working_tree_context.go b/pkg/gui/context/working_tree_context.go index 107228ee8..390c03b33 100644 --- a/pkg/gui/context/working_tree_context.go +++ b/pkg/gui/context/working_tree_context.go @@ -1,11 +1,11 @@ package context import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) type WorkingTreeContext struct { @@ -25,7 +25,7 @@ func NewWorkingTreeContext(c *ContextCommon) *WorkingTreeContext { getDisplayStrings := func(startIdx int, length int) [][]string { lines := presentation.RenderFileTree(viewModel, c.Modes().Diffing.Ref, c.Model().Submodules) - return slices.Map(lines, func(line string) []string { + return lo.Map(lines, func(line string, _ int) []string { return []string{line} }) } diff --git a/pkg/gui/controllers/custom_command_action.go b/pkg/gui/controllers/custom_command_action.go index 4b3aaa885..bd24cda7d 100644 --- a/pkg/gui/controllers/custom_command_action.go +++ b/pkg/gui/controllers/custom_command_action.go @@ -3,7 +3,6 @@ package controllers import ( "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" @@ -41,7 +40,7 @@ func (self *CustomCommandAction) Call() error { func (self *CustomCommandAction) GetCustomCommandsHistorySuggestionsFunc() func(string) []*types.Suggestion { // reversing so that we display the latest command first - history := slices.Reverse(self.c.GetAppState().CustomCommandsHistory) + history := lo.Reverse(self.c.GetAppState().CustomCommandsHistory) return helpers.FuzzySearchFunc(history) } diff --git a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go index 0e83ccf25..e9140e102 100644 --- a/pkg/gui/controllers/helpers/merge_and_rebase_helper.go +++ b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go @@ -4,11 +4,11 @@ import ( "fmt" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) type MergeAndRebaseHelper struct { @@ -51,7 +51,7 @@ func (self *MergeAndRebaseHelper) CreateRebaseOptionsMenu() error { }) } - menuItems := slices.Map(options, func(row optionAndKey) *types.MenuItem { + menuItems := lo.Map(options, func(row optionAndKey, _ int) *types.MenuItem { return &types.MenuItem{ Label: row.option, OnPress: func() error { diff --git a/pkg/gui/controllers/helpers/mode_helper.go b/pkg/gui/controllers/helpers/mode_helper.go index e58fe6cb9..f5f3c738c 100644 --- a/pkg/gui/controllers/helpers/mode_helper.go +++ b/pkg/gui/controllers/helpers/mode_helper.go @@ -4,11 +4,11 @@ import ( "fmt" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) type ModeHelper struct { @@ -135,13 +135,13 @@ func (self *ModeHelper) withResetButton(content string, textStyle style.TextStyl } func (self *ModeHelper) GetActiveMode() (ModeStatus, bool) { - return slices.Find(self.Statuses(), func(mode ModeStatus) bool { + return lo.Find(self.Statuses(), func(mode ModeStatus) bool { return mode.IsActive() }) } func (self *ModeHelper) IsAnyModeActive() bool { - return slices.Some(self.Statuses(), func(mode ModeStatus) bool { + return lo.SomeBy(self.Statuses(), func(mode ModeStatus) bool { return mode.IsActive() }) } diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index 5682bbb1f..182e20d85 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -7,7 +7,6 @@ import ( "time" "github.com/jesseduffield/generics/set" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" @@ -18,6 +17,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) type RefreshHelper struct { @@ -211,7 +211,7 @@ func getScopeNames(scopes []types.RefreshableView) []string { types.MERGE_CONFLICTS: "mergeConflicts", } - return slices.Map(scopes, func(scope types.RefreshableView) string { + return lo.Map(scopes, func(scope types.RefreshableView, _ int) string { return scopeNameMap[scope] }) } diff --git a/pkg/gui/controllers/helpers/refs_helper.go b/pkg/gui/controllers/helpers/refs_helper.go index 3c96add84..765b01cd5 100644 --- a/pkg/gui/controllers/helpers/refs_helper.go +++ b/pkg/gui/controllers/helpers/refs_helper.go @@ -4,13 +4,13 @@ import ( "fmt" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) type IRefsHelper interface { @@ -132,7 +132,7 @@ func (self *RefsHelper) CreateGitResetMenu(ref string) error { {strength: "hard", label: "Hard reset", key: 'h'}, } - menuItems := slices.Map(strengths, func(row strengthWithKey) *types.MenuItem { + menuItems := lo.Map(strengths, func(row strengthWithKey, _ int) *types.MenuItem { return &types.MenuItem{ LabelColumns: []string{ row.label, diff --git a/pkg/gui/controllers/helpers/repos_helper.go b/pkg/gui/controllers/helpers/repos_helper.go index 939d7eb05..d4bd46f40 100644 --- a/pkg/gui/controllers/helpers/repos_helper.go +++ b/pkg/gui/controllers/helpers/repos_helper.go @@ -7,7 +7,6 @@ import ( "strings" "sync" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" appTypes "github.com/jesseduffield/lazygit/pkg/app/types" "github.com/jesseduffield/lazygit/pkg/commands" @@ -18,6 +17,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) type onNewRepoFn func(startArgs appTypes.StartArgs, contextKey types.ContextKey) error @@ -115,7 +115,7 @@ func (self *ReposHelper) CreateRecentReposMenu() error { wg.Wait() - menuItems := slices.Map(recentRepoPaths, func(path string) *types.MenuItem { + menuItems := lo.Map(recentRepoPaths, func(path string, _ int) *types.MenuItem { branchName, _ := currentBranches.Load(path) if icons.IsIconEnabled() { branchName = icons.BRANCH_ICON + " " + fmt.Sprintf("%v", branchName) diff --git a/pkg/gui/controllers/helpers/suggestions_helper.go b/pkg/gui/controllers/helpers/suggestions_helper.go index 65ddf70aa..2ae9d2158 100644 --- a/pkg/gui/controllers/helpers/suggestions_helper.go +++ b/pkg/gui/controllers/helpers/suggestions_helper.go @@ -4,7 +4,6 @@ import ( "fmt" "os" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/presentation" @@ -12,6 +11,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/minimal/gitignore" "github.com/samber/lo" + "golang.org/x/exp/slices" "gopkg.in/ozeidan/fuzzy-patricia.v3/patricia" ) @@ -48,13 +48,13 @@ func NewSuggestionsHelper( } func (self *SuggestionsHelper) getRemoteNames() []string { - return slices.Map(self.c.Model().Remotes, func(remote *models.Remote) string { + return lo.Map(self.c.Model().Remotes, func(remote *models.Remote, _ int) string { return remote.Name }) } func matchesToSuggestions(matches []string) []*types.Suggestion { - return slices.Map(matches, func(match string) *types.Suggestion { + return lo.Map(matches, func(match string, _ int) *types.Suggestion { return &types.Suggestion{ Value: match, Label: match, @@ -69,7 +69,7 @@ func (self *SuggestionsHelper) GetRemoteSuggestionsFunc() func(string) []*types. } func (self *SuggestionsHelper) getBranchNames() []string { - return slices.Map(self.c.Model().Branches, func(branch *models.Branch) string { + return lo.Map(self.c.Model().Branches, func(branch *models.Branch, _ int) string { return branch.Name }) } @@ -85,7 +85,7 @@ func (self *SuggestionsHelper) GetBranchNameSuggestionsFunc() func(string) []*ty matchingBranchNames = utils.FuzzySearch(input, branchNames) } - return slices.Map(matchingBranchNames, func(branchName string) *types.Suggestion { + return lo.Map(matchingBranchNames, func(branchName string, _ int) *types.Suggestion { return &types.Suggestion{ Value: branchName, Label: presentation.GetBranchTextStyle(branchName).Sprint(branchName), @@ -141,8 +141,8 @@ func (self *SuggestionsHelper) GetFilePathSuggestionsFunc() func(string) []*type } func (self *SuggestionsHelper) getRemoteBranchNames(separator string) []string { - return slices.FlatMap(self.c.Model().Remotes, func(remote *models.Remote) []string { - return slices.Map(remote.Branches, func(branch *models.RemoteBranch) string { + return lo.FlatMap(self.c.Model().Remotes, func(remote *models.Remote, _ int) []string { + return lo.Map(remote.Branches, func(branch *models.RemoteBranch, _ int) string { return fmt.Sprintf("%s%s%s", remote.Name, separator, branch.Name) }) }) @@ -153,7 +153,7 @@ func (self *SuggestionsHelper) GetRemoteBranchesSuggestionsFunc(separator string } func (self *SuggestionsHelper) getTagNames() []string { - return slices.Map(self.c.Model().Tags, func(tag *models.Tag) string { + return lo.Map(self.c.Model().Tags, func(tag *models.Tag, _ int) string { return tag.Name }) } diff --git a/pkg/gui/controllers/helpers/upstream_helper_test.go b/pkg/gui/controllers/helpers/upstream_helper_test.go index ac7a6a8bf..9742ef944 100644 --- a/pkg/gui/controllers/helpers/upstream_helper_test.go +++ b/pkg/gui/controllers/helpers/upstream_helper_test.go @@ -3,8 +3,8 @@ package helpers import ( "testing" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/samber/lo" "github.com/stretchr/testify/assert" ) @@ -25,7 +25,7 @@ func TestGetSuggestedRemote(t *testing.T) { } func mkRemoteList(names ...string) []*models.Remote { - return slices.Map(names, func(name string) *models.Remote { + return lo.Map(names, func(name string, _ int) *models.Remote { return &models.Remote{Name: name} }) } diff --git a/pkg/gui/controllers/options_menu_action.go b/pkg/gui/controllers/options_menu_action.go index 7ec75d3f1..f757ba0a1 100644 --- a/pkg/gui/controllers/options_menu_action.go +++ b/pkg/gui/controllers/options_menu_action.go @@ -1,7 +1,6 @@ package controllers import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/gui/keybindings" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" @@ -21,7 +20,7 @@ func (self *OptionsMenuAction) Call() error { bindings := self.getBindings(ctx) - menuItems := slices.Map(bindings, func(binding *types.Binding) *types.MenuItem { + menuItems := lo.Map(bindings, func(binding *types.Binding, _ int) *types.MenuItem { return &types.MenuItem{ OpensMenu: binding.OpensMenu, Label: binding.Description, diff --git a/pkg/gui/controllers/status_controller.go b/pkg/gui/controllers/status_controller.go index af1cb9984..8344dfe76 100644 --- a/pkg/gui/controllers/status_controller.go +++ b/pkg/gui/controllers/status_controller.go @@ -5,12 +5,12 @@ import ( "fmt" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/constants" "github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) type StatusController struct { @@ -155,7 +155,7 @@ func (self *StatusController) askForConfigFile(action func(file string) error) e case 1: return action(confPaths[0]) default: - menuItems := slices.Map(confPaths, func(path string) *types.MenuItem { + menuItems := lo.Map(confPaths, func(path string, _ int) *types.MenuItem { return &types.MenuItem{ Label: path, OnPress: func() error { diff --git a/pkg/gui/filetree/commit_file_tree.go b/pkg/gui/filetree/commit_file_tree.go index 862db26f1..593899443 100644 --- a/pkg/gui/filetree/commit_file_tree.go +++ b/pkg/gui/filetree/commit_file_tree.go @@ -1,8 +1,8 @@ package filetree import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/samber/lo" "github.com/sirupsen/logrus" ) @@ -60,7 +60,7 @@ func (self *CommitFileTree) GetAllItems() []*CommitFileNode { } // ignoring root - return slices.Map(self.tree.Flatten(self.collapsedPaths)[1:], func(node *Node[models.CommitFile]) *CommitFileNode { + return lo.Map(self.tree.Flatten(self.collapsedPaths)[1:], func(node *Node[models.CommitFile], _ int) *CommitFileNode { return NewCommitFileNode(node) }) } diff --git a/pkg/gui/filetree/file_tree.go b/pkg/gui/filetree/file_tree.go index 3f244edfe..45cfeed40 100644 --- a/pkg/gui/filetree/file_tree.go +++ b/pkg/gui/filetree/file_tree.go @@ -3,8 +3,8 @@ package filetree import ( "fmt" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/samber/lo" "github.com/sirupsen/logrus" ) @@ -88,7 +88,7 @@ func (self *FileTree) getFilesForDisplay() []*models.File { } func (self *FileTree) FilterFiles(test func(*models.File) bool) []*models.File { - return slices.Filter(self.getFiles(), test) + return lo.Filter(self.getFiles(), func(file *models.File, _ int) bool { return test(file) }) } func (self *FileTree) SetStatusFilter(filter FileTreeDisplayFilter) { @@ -130,7 +130,7 @@ func (self *FileTree) GetAllItems() []*FileNode { } // ignoring root - return slices.Map(self.tree.Flatten(self.collapsedPaths)[1:], func(node *Node[models.File]) *FileNode { + return lo.Map(self.tree.Flatten(self.collapsedPaths)[1:], func(node *Node[models.File], _ int) *FileNode { return NewFileNode(node) }) } diff --git a/pkg/gui/filetree/node.go b/pkg/gui/filetree/node.go index 8de655b37..3c125bc7d 100644 --- a/pkg/gui/filetree/node.go +++ b/pkg/gui/filetree/node.go @@ -1,9 +1,10 @@ package filetree import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" + "golang.org/x/exp/slices" ) // Represents a file or directory in a file tree. @@ -152,7 +153,7 @@ func (self *Node[T]) Flatten(collapsedPaths *CollapsedPaths) []*Node[T] { result := []*Node[T]{self} if len(self.Children) > 0 && !collapsedPaths.IsCollapsed(self.GetPath()) { - result = append(result, slices.FlatMap(self.Children, func(child *Node[T]) []*Node[T] { + result = append(result, lo.FlatMap(self.Children, func(child *Node[T], _ int) []*Node[T] { return child.Flatten(collapsedPaths) })...) } @@ -273,11 +274,11 @@ func (self *Node[T]) GetPathsMatching(test func(*Node[T]) bool) []string { } func (self *Node[T]) GetFilePathsMatching(test func(*T) bool) []string { - matchingFileNodes := slices.Filter(self.GetLeaves(), func(node *Node[T]) bool { + matchingFileNodes := lo.Filter(self.GetLeaves(), func(node *Node[T], _ int) bool { return test(node.File) }) - return slices.Map(matchingFileNodes, func(node *Node[T]) string { + return lo.Map(matchingFileNodes, func(node *Node[T], _ int) string { return node.GetPath() }) } @@ -287,7 +288,7 @@ func (self *Node[T]) GetLeaves() []*Node[T] { return []*Node[T]{self} } - return slices.FlatMap(self.Children, func(child *Node[T]) []*Node[T] { + return lo.FlatMap(self.Children, func(child *Node[T], _ int) []*Node[T] { return child.GetLeaves() }) } diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index f9daaa5b6..2f6e21b73 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -1,11 +1,12 @@ package gui import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/theme" + "github.com/samber/lo" + "golang.org/x/exp/slices" ) // layout is called for every screen re-render e.g. when the screen is resized @@ -196,11 +197,11 @@ func (gui *Gui) onInitialViewsCreationForRepo() error { } func (gui *Gui) popupViewNames() []string { - popups := slices.Filter(gui.State.Contexts.Flatten(), func(c types.Context) bool { + popups := lo.Filter(gui.State.Contexts.Flatten(), func(c types.Context, _ int) bool { return c.GetKind() == types.PERSISTENT_POPUP || c.GetKind() == types.TEMPORARY_POPUP }) - return slices.Map(popups, func(c types.Context) string { + return lo.Map(popups, func(c types.Context, _ int) string { return c.GetViewName() }) } @@ -223,7 +224,7 @@ func (gui *Gui) onRepoViewReset() error { }) if index != -1 { - view.Tabs = slices.Map(values, func(tabContext context.TabView) string { + view.Tabs = lo.Map(values, func(tabContext context.TabView, _ int) string { return tabContext.Tab }) view.TabIndex = index @@ -287,7 +288,7 @@ func (gui *Gui) onViewFocusLost(oldView *gocui.View) error { } func (gui *Gui) transientContexts() []types.Context { - return slices.Filter(gui.State.Contexts.Flatten(), func(context types.Context) bool { + return lo.Filter(gui.State.Contexts.Flatten(), func(context types.Context, _ int) bool { return context.IsTransient() }) } diff --git a/pkg/gui/modes/cherrypicking/cherry_picking.go b/pkg/gui/modes/cherrypicking/cherry_picking.go index 1fd34d473..ffbe51a80 100644 --- a/pkg/gui/modes/cherrypicking/cherry_picking.go +++ b/pkg/gui/modes/cherrypicking/cherry_picking.go @@ -2,8 +2,8 @@ package cherrypicking import ( "github.com/jesseduffield/generics/set" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/samber/lo" ) type CherryPicking struct { @@ -25,7 +25,7 @@ func (self *CherryPicking) Active() bool { } func (self *CherryPicking) SelectedShaSet() *set.Set[string] { - shas := slices.Map(self.CherryPickedCommits, func(commit *models.Commit) string { + shas := lo.Map(self.CherryPickedCommits, func(commit *models.Commit, _ int) string { return commit.Sha }) return set.NewFromSlice(shas) @@ -46,11 +46,11 @@ func (self *CherryPicking) Remove(selectedCommit *models.Commit, commitsList []* } func (self *CherryPicking) update(selectedShaSet *set.Set[string], commitsList []*models.Commit) { - cherryPickedCommits := slices.Filter(commitsList, func(commit *models.Commit) bool { + cherryPickedCommits := lo.Filter(commitsList, func(commit *models.Commit, _ int) bool { return selectedShaSet.Includes(commit.Sha) }) - self.CherryPickedCommits = slices.Map(cherryPickedCommits, func(commit *models.Commit) *models.Commit { + self.CherryPickedCommits = lo.Map(cherryPickedCommits, func(commit *models.Commit, _ int) *models.Commit { return &models.Commit{Name: commit.Name, Sha: commit.Sha} }) } diff --git a/pkg/gui/presentation/branches.go b/pkg/gui/presentation/branches.go index 6ad4e498e..849a56eba 100644 --- a/pkg/gui/presentation/branches.go +++ b/pkg/gui/presentation/branches.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/config" @@ -26,7 +25,7 @@ func GetBranchListDisplayStrings( userConfig *config.UserConfig, worktrees []*models.Worktree, ) [][]string { - return slices.Map(branches, func(branch *models.Branch) []string { + return lo.Map(branches, func(branch *models.Branch, _ int) []string { diffed := branch.Name == diffName return getBranchDisplayStrings(branch, fullDescription, diffed, tr, userConfig, worktrees) }) diff --git a/pkg/gui/presentation/graph/graph.go b/pkg/gui/presentation/graph/graph.go index 65141946c..a310d98d9 100644 --- a/pkg/gui/presentation/graph/graph.go +++ b/pkg/gui/presentation/graph/graph.go @@ -6,11 +6,11 @@ import ( "sync" "github.com/jesseduffield/generics/set" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" + "golang.org/x/exp/slices" ) type PipeKind uint8 @@ -67,7 +67,7 @@ func GetPipeSets(commits []*models.Commit, getStyle func(c *models.Commit) style pipes := []*Pipe{{fromPos: 0, toPos: 0, fromSha: "START", toSha: commits[0].Sha, kind: STARTS, style: style.FgDefault}} - return slices.Map(commits, func(commit *models.Commit) []*Pipe { + return lo.Map(commits, func(commit *models.Commit, _ int) []*Pipe { pipes = getNextPipes(pipes, commit, getStyle) return pipes }) @@ -108,17 +108,20 @@ func RenderAux(pipeSets [][]*Pipe, commits []*models.Commit, selectedCommitSha s wg.Wait() - return slices.Flatten(chunks) + return lo.Flatten(chunks) } func getNextPipes(prevPipes []*Pipe, commit *models.Commit, getStyle func(c *models.Commit) style.TextStyle) []*Pipe { - maxPos := slices.MaxBy(prevPipes, func(pipe *Pipe) int { - return pipe.toPos - }) + maxPos := 0 + for _, pipe := range prevPipes { + if pipe.toPos > maxPos { + maxPos = pipe.toPos + } + } // a pipe that terminated in the previous line has no bearing on the current line // so we'll filter those out - currentPipes := slices.Filter(prevPipes, func(pipe *Pipe) bool { + currentPipes := lo.Filter(prevPipes, func(pipe *Pipe, _ int) bool { return pipe.kind != TERMINATES }) @@ -299,7 +302,7 @@ func renderPipeSet( } isMerge := startCount > 1 - cells := slices.Map(lo.Range(maxPos+1), func(i int) *Cell { + cells := lo.Map(lo.Range(maxPos+1), func(i int, _ int) *Cell { return &Cell{cellType: CONNECTION, style: style.FgDefault} }) @@ -337,7 +340,7 @@ func renderPipeSet( // so we have our commit pos again, now it's time to build the cells. // we'll handle the one that's sourced from our selected commit last so that it can override the other cells. - selectedPipes, nonSelectedPipes := slices.Partition(pipes, func(pipe *Pipe) bool { + selectedPipes, nonSelectedPipes := utils.Partition(pipes, func(pipe *Pipe) bool { return highlight && equalHashes(pipe.fromSha, selectedCommitSha) }) diff --git a/pkg/gui/presentation/reflog_commits.go b/pkg/gui/presentation/reflog_commits.go index 65e0a27bb..cde774e46 100644 --- a/pkg/gui/presentation/reflog_commits.go +++ b/pkg/gui/presentation/reflog_commits.go @@ -4,12 +4,12 @@ import ( "time" "github.com/jesseduffield/generics/set" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/kyokomi/emoji/v2" + "github.com/samber/lo" ) func GetReflogCommitListDisplayStrings(commits []*models.Commit, fullDescription bool, cherryPickedCommitShaSet *set.Set[string], diffName string, now time.Time, timeFormat string, shortTimeFormat string, parseEmoji bool) [][]string { @@ -20,7 +20,7 @@ func GetReflogCommitListDisplayStrings(commits []*models.Commit, fullDescription displayFunc = getDisplayStringsForReflogCommit } - return slices.Map(commits, func(commit *models.Commit) []string { + return lo.Map(commits, func(commit *models.Commit, _ int) []string { diffed := commit.Sha == diffName cherryPicked := cherryPickedCommitShaSet.Includes(commit.Sha) return displayFunc(commit, diff --git a/pkg/gui/presentation/remote_branches.go b/pkg/gui/presentation/remote_branches.go index 4052d3fed..55e4bc113 100644 --- a/pkg/gui/presentation/remote_branches.go +++ b/pkg/gui/presentation/remote_branches.go @@ -1,14 +1,14 @@ package presentation import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/theme" + "github.com/samber/lo" ) func GetRemoteBranchListDisplayStrings(branches []*models.RemoteBranch, diffName string) [][]string { - return slices.Map(branches, func(branch *models.RemoteBranch) []string { + return lo.Map(branches, func(branch *models.RemoteBranch, _ int) []string { diffed := branch.FullName() == diffName return getRemoteBranchDisplayStrings(branch, diffed) }) diff --git a/pkg/gui/presentation/remotes.go b/pkg/gui/presentation/remotes.go index 7f82fe970..1fbedf9cc 100644 --- a/pkg/gui/presentation/remotes.go +++ b/pkg/gui/presentation/remotes.go @@ -1,15 +1,15 @@ package presentation import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/theme" + "github.com/samber/lo" ) func GetRemoteListDisplayStrings(remotes []*models.Remote, diffName string) [][]string { - return slices.Map(remotes, func(remote *models.Remote) []string { + return lo.Map(remotes, func(remote *models.Remote, _ int) []string { diffed := remote.Name == diffName return getRemoteDisplayStrings(remote, diffed) }) diff --git a/pkg/gui/presentation/stash_entries.go b/pkg/gui/presentation/stash_entries.go index f337a4b3b..c45e91982 100644 --- a/pkg/gui/presentation/stash_entries.go +++ b/pkg/gui/presentation/stash_entries.go @@ -1,14 +1,14 @@ package presentation import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/theme" + "github.com/samber/lo" ) func GetStashEntryListDisplayStrings(stashEntries []*models.StashEntry, diffName string) [][]string { - return slices.Map(stashEntries, func(stashEntry *models.StashEntry) []string { + return lo.Map(stashEntries, func(stashEntry *models.StashEntry, _ int) []string { diffed := stashEntry.RefName() == diffName return getStashEntryDisplayStrings(stashEntry, diffed) }) diff --git a/pkg/gui/presentation/submodules.go b/pkg/gui/presentation/submodules.go index 0fb057ef0..e580ee1f6 100644 --- a/pkg/gui/presentation/submodules.go +++ b/pkg/gui/presentation/submodules.go @@ -1,13 +1,13 @@ package presentation import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/theme" + "github.com/samber/lo" ) func GetSubmoduleListDisplayStrings(submodules []*models.SubmoduleConfig) [][]string { - return slices.Map(submodules, func(submodule *models.SubmoduleConfig) []string { + return lo.Map(submodules, func(submodule *models.SubmoduleConfig, _ int) []string { return getSubmoduleDisplayStrings(submodule) }) } diff --git a/pkg/gui/presentation/suggestions.go b/pkg/gui/presentation/suggestions.go index 5319b40f7..429ce6b5b 100644 --- a/pkg/gui/presentation/suggestions.go +++ b/pkg/gui/presentation/suggestions.go @@ -1,12 +1,12 @@ package presentation import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) func GetSuggestionListDisplayStrings(suggestions []*types.Suggestion) [][]string { - return slices.Map(suggestions, func(suggestion *types.Suggestion) []string { + return lo.Map(suggestions, func(suggestion *types.Suggestion, _ int) []string { return getSuggestionDisplayStrings(suggestion) }) } diff --git a/pkg/gui/presentation/tags.go b/pkg/gui/presentation/tags.go index 944448a8c..13a0c9d77 100644 --- a/pkg/gui/presentation/tags.go +++ b/pkg/gui/presentation/tags.go @@ -1,15 +1,15 @@ package presentation import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/theme" + "github.com/samber/lo" ) func GetTagListDisplayStrings(tags []*models.Tag, diffName string) [][]string { - return slices.Map(tags, func(tag *models.Tag) []string { + return lo.Map(tags, func(tag *models.Tag, _ int) []string { diffed := tag.Name == diffName return getTagDisplayStrings(tag, diffed) }) diff --git a/pkg/gui/services/custom_commands/handler_creator.go b/pkg/gui/services/custom_commands/handler_creator.go index eea596ab8..d5dec287f 100644 --- a/pkg/gui/services/custom_commands/handler_creator.go +++ b/pkg/gui/services/custom_commands/handler_creator.go @@ -5,7 +5,6 @@ import ( "strings" "text/template" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers" @@ -193,7 +192,7 @@ func (self *HandlerCreator) confirmPrompt(prompt *config.CustomCommandPrompt, ha } func (self *HandlerCreator) menuPrompt(prompt *config.CustomCommandPrompt, wrappedF func(string) error) error { - menuItems := slices.Map(prompt.Options, func(option config.CustomCommandMenuOption) *types.MenuItem { + menuItems := lo.Map(prompt.Options, func(option config.CustomCommandMenuOption, _ int) *types.MenuItem { return &types.MenuItem{ LabelColumns: []string{option.Name, style.FgYellow.Sprint(option.Description)}, OnPress: func() error { @@ -218,7 +217,7 @@ func (self *HandlerCreator) menuPromptFromCommand(prompt *config.CustomCommandPr return self.c.Error(err) } - menuItems := slices.Map(candidates, func(candidate *commandMenuItem) *types.MenuItem { + menuItems := lo.Map(candidates, func(candidate *commandMenuItem, _ int) *types.MenuItem { return &types.MenuItem{ LabelColumns: []string{candidate.label}, OnPress: func() error { diff --git a/pkg/gui/services/custom_commands/keybinding_creator.go b/pkg/gui/services/custom_commands/keybinding_creator.go index 2482f03f2..2a65c1324 100644 --- a/pkg/gui/services/custom_commands/keybinding_creator.go +++ b/pkg/gui/services/custom_commands/keybinding_creator.go @@ -4,13 +4,13 @@ import ( "fmt" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers" "github.com/jesseduffield/lazygit/pkg/gui/keybindings" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/samber/lo" ) // KeybindingCreator takes a custom command along with its handler and returns a corresponding keybinding @@ -73,7 +73,7 @@ func (self *KeybindingCreator) contextForContextKey(contextKey types.ContextKey) } func formatUnknownContextError(customCommand config.CustomCommand) error { - allContextKeyStrings := slices.Map(context.AllContextKeys, func(key types.ContextKey) string { + allContextKeyStrings := lo.Map(context.AllContextKeys, func(key types.ContextKey, _ int) string { return string(key) }) diff --git a/pkg/gui/status/status_manager.go b/pkg/gui/status/status_manager.go index 78e4d37e3..d54853c6e 100644 --- a/pkg/gui/status/status_manager.go +++ b/pkg/gui/status/status_manager.go @@ -3,8 +3,8 @@ package status import ( "time" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" "github.com/sasha-s/go-deadlock" ) @@ -88,7 +88,7 @@ func (self *StatusManager) removeStatus(id int) { self.mutex.Lock() defer self.mutex.Unlock() - self.statuses = slices.Filter(self.statuses, func(status appStatus) bool { + self.statuses = lo.Filter(self.statuses, func(status appStatus, _ int) bool { return status.id != id }) } diff --git a/pkg/gui/views.go b/pkg/gui/views.go index 594ca5fb3..9527e4392 100644 --- a/pkg/gui/views.go +++ b/pkg/gui/views.go @@ -1,11 +1,11 @@ package gui import ( - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/gui/keybindings" "github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) type viewNameMapping struct { @@ -14,7 +14,7 @@ type viewNameMapping struct { } func (gui *Gui) orderedViews() []*gocui.View { - return slices.Map(gui.orderedViewNameMappings(), func(v viewNameMapping) *gocui.View { + return lo.Map(gui.orderedViewNameMappings(), func(v viewNameMapping, _ int) *gocui.View { return *v.viewPtr }) } diff --git a/pkg/integration/clients/cli.go b/pkg/integration/clients/cli.go index 8ac9947e9..79853b224 100644 --- a/pkg/integration/clients/cli.go +++ b/pkg/integration/clients/cli.go @@ -8,7 +8,6 @@ import ( "strconv" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/integration/components" "github.com/jesseduffield/lazygit/pkg/integration/tests" "github.com/samber/lo" @@ -58,7 +57,7 @@ func getTestsToRun(testNames []string) []*components.IntegrationTest { return allIntegrationTests } - testNames = slices.Map(testNames, func(name string) string { + testNames = lo.Map(testNames, func(name string, _ int) string { // allowing full test paths to be passed for convenience return strings.TrimSuffix( regexp.MustCompile(`.*pkg/integration/tests/`).ReplaceAllString(name, ""), diff --git a/pkg/integration/clients/tui.go b/pkg/integration/clients/tui.go index 7d82a6630..78180cae6 100644 --- a/pkg/integration/clients/tui.go +++ b/pkg/integration/clients/tui.go @@ -7,7 +7,6 @@ import ( "path/filepath" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazycore/pkg/utils" "github.com/jesseduffield/lazygit/pkg/gui" @@ -15,6 +14,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/integration/components" "github.com/jesseduffield/lazygit/pkg/integration/tests" "github.com/jesseduffield/lazygit/pkg/secureexec" + "github.com/samber/lo" ) // This program lets you run integration tests from a TUI. See pkg/integration/README.md for more info. @@ -245,7 +245,7 @@ func (self *app) filterWithString(needle string) { if needle == "" { self.filteredTests = self.allTests } else { - self.filteredTests = slices.Filter(self.allTests, func(test *components.IntegrationTest) bool { + self.filteredTests = lo.Filter(self.allTests, func(test *components.IntegrationTest, _ int) bool { return strings.Contains(test.Name(), needle) }) } diff --git a/pkg/integration/components/test.go b/pkg/integration/components/test.go index ca73ba805..2520ec47e 100644 --- a/pkg/integration/components/test.go +++ b/pkg/integration/components/test.go @@ -5,11 +5,11 @@ import ( "strconv" "strings" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/config" integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/samber/lo" ) // IntegrationTest describes an integration test that will be run against the lazygit gui. @@ -102,7 +102,7 @@ func (self GitVersionRestriction) shouldRunOnVersion(version *git_commands.GitVe return version.IsOlderThanVersion(before) } if len(self.includes) != 0 { - return slices.Some(self.includes, func(str string) bool { + return lo.SomeBy(self.includes, func(str string) bool { v, err := git_commands.ParseGitVersion(str) if err != nil { panic("Invalid git version string: " + str) diff --git a/pkg/integration/tests/tests.go b/pkg/integration/tests/tests.go index 2134aa302..600c98af6 100644 --- a/pkg/integration/tests/tests.go +++ b/pkg/integration/tests/tests.go @@ -9,18 +9,18 @@ import ( "strings" "github.com/jesseduffield/generics/set" - "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazycore/pkg/utils" "github.com/jesseduffield/lazygit/pkg/integration/components" + "github.com/samber/lo" ) func GetTests() []*components.IntegrationTest { // first we ensure that each test in this directory has actually been added to the above list. testCount := 0 - testNamesSet := set.NewFromSlice(slices.Map( + testNamesSet := set.NewFromSlice(lo.Map( tests, - func(test *components.IntegrationTest) string { + func(test *components.IntegrationTest, _ int) string { return test.Name() }, )) diff --git a/pkg/utils/formatting.go b/pkg/utils/formatting.go index 5d04a16a8..bf4f0debd 100644 --- a/pkg/utils/formatting.go +++ b/pkg/utils/formatting.go @@ -3,7 +3,6 @@ package utils import ( "strings" - "github.com/jesseduffield/generics/slices" "github.com/mattn/go-runewidth" "github.com/samber/lo" ) @@ -117,15 +116,15 @@ func getPaddedDisplayStrings(stringArrays [][]string, columnConfigs []ColumnConf } func getPadWidths(stringArrays [][]string) []int { - maxWidth := slices.MaxBy(stringArrays, func(stringArray []string) int { + maxWidth := MaxFn(stringArrays, func(stringArray []string) int { return len(stringArray) }) if maxWidth-1 < 0 { return []int{} } - return slices.Map(lo.Range(maxWidth-1), func(i int) int { - return slices.MaxBy(stringArrays, func(stringArray []string) int { + return lo.Map(lo.Range(maxWidth-1), func(i int, _ int) int { + return MaxFn(stringArrays, func(stringArray []string) int { uncoloredStr := Decolorise(stringArray[i]) return runewidth.StringWidth(uncoloredStr) @@ -133,6 +132,16 @@ func getPadWidths(stringArrays [][]string) []int { }) } +func MaxFn[T any](items []T, fn func(T) int) int { + max := 0 + for _, item := range items { + if fn(item) > max { + max = fn(item) + } + } + return max +} + // TruncateWithEllipsis returns a string, truncated to a certain length, with an ellipsis func TruncateWithEllipsis(str string, limit int) string { if runewidth.StringWidth(str) > limit && limit <= 3 { diff --git a/pkg/utils/search.go b/pkg/utils/search.go index 14b3d7b3e..c204506f0 100644 --- a/pkg/utils/search.go +++ b/pkg/utils/search.go @@ -4,8 +4,8 @@ import ( "sort" "strings" - "github.com/jesseduffield/generics/slices" "github.com/sahilm/fuzzy" + "github.com/samber/lo" ) func FuzzySearch(needle string, haystack []string) []string { @@ -16,7 +16,7 @@ func FuzzySearch(needle string, haystack []string) []string { matches := fuzzy.Find(needle, haystack) sort.Sort(matches) - return slices.Map(matches, func(match fuzzy.Match) string { + return lo.Map(matches, func(match fuzzy.Match, _ int) string { return match.Str }) } diff --git a/pkg/utils/slice.go b/pkg/utils/slice.go index 4a47f43b1..0dc9e64e4 100644 --- a/pkg/utils/slice.go +++ b/pkg/utils/slice.go @@ -1,5 +1,7 @@ package utils +import "golang.org/x/exp/slices" + // NextIndex returns the index of the element that comes after the given number func NextIndex(numbers []int, currentNumber int) int { for index, number := range numbers { @@ -124,3 +126,56 @@ func ValuesAtIndices[T any](slice []T, indices []int) []T { } return result } + +// returns two slices: the first is for elements that pass the test, the second for those that don't. +func Partition[T any](slice []T, test func(T) bool) ([]T, []T) { + left := make([]T, 0, len(slice)) + right := make([]T, 0, len(slice)) + + for _, value := range slice { + if test(value) { + left = append(left, value) + } else { + right = append(right, value) + } + } + + return left, right +} + +// Prepends items to the beginning of a slice. +// E.g. Prepend([]int{1,2}, 3, 4) = []int{3,4,1,2} +// Mutates original slice. Intended usage is to reassign the slice result to the input slice. +func Prepend[T any](slice []T, values ...T) []T { + return append(values, slice...) +} + +// Removes the element at the given index. Intended usage is to reassign the result to the input slice. +func Remove[T any](slice []T, index int) []T { + return slices.Delete(slice, index, index+1) +} + +// Removes the element at the 'fromIndex' and then inserts it at 'toIndex'. +// Operates on the input slice. Expected use is to reassign the result to the input slice. +func Move[T any](slice []T, fromIndex int, toIndex int) []T { + item := slice[fromIndex] + slice = Remove(slice, fromIndex) + return slices.Insert(slice, toIndex, item) +} + +// Pops item from the end of the slice and returns it, along with the updated slice +// Mutates original slice. Intended usage is to reassign the slice result to the input slice. +func Pop[T any](slice []T) (T, []T) { + index := len(slice) - 1 + value := slice[index] + slice = slice[0:index] + return value, slice +} + +// Shifts item from the beginning of the slice and returns it, along with the updated slice. +// Mutates original slice. Intended usage is to reassign the slice result to the input slice. +func Shift[T any](slice []T) (T, []T) { + value := slice[0] + slice = slice[1:] + return value, slice +} diff --git a/vendor/github.com/jesseduffield/generics/slices/delegated_slices.go b/vendor/github.com/jesseduffield/generics/slices/delegated_slices.go deleted file mode 100644 index 015935331..000000000 --- a/vendor/github.com/jesseduffield/generics/slices/delegated_slices.go +++ /dev/null @@ -1,117 +0,0 @@ -package slices - -import ( - "golang.org/x/exp/constraints" - "golang.org/x/exp/slices" -) - -// This file delegates to the official slices package, so that we end up with a superset of the official API. - -// Equal reports whether two slices are equal: the same length and all -// elements equal. If the lengths are different, Equal returns false. -// Otherwise, the elements are compared in increasing index order, and the -// comparison stops at the first unequal pair. -// Floating point NaNs are not considered equal. -func Equal[E comparable](s1, s2 []E) bool { - return slices.Equal(s1, s2) -} - -// EqualFunc reports whether two slices are equal using a comparison -// function on each pair of elements. If the lengths are different, -// EqualFunc returns false. Otherwise, the elements are compared in -// increasing index order, and the comparison stops at the first index -// for which eq returns false. -func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool { - return slices.EqualFunc(s1, s2, eq) -} - -// Compare compares the elements of s1 and s2. -// The elements are compared sequentially, starting at index 0, -// until one element is not equal to the other. -// The result of comparing the first non-matching elements is returned. -// If both slices are equal until one of them ends, the shorter slice is -// considered less than the longer one. -// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2. -// Comparisons involving floating point NaNs are ignored. -func Compare[E constraints.Ordered](s1, s2 []E) int { - return slices.Compare(s1, s2) -} - -// CompareFunc is like Compare but uses a comparison function -// on each pair of elements. The elements are compared in increasing -// index order, and the comparisons stop after the first time cmp -// returns non-zero. -// The result is the first non-zero result of cmp; if cmp always -// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2), -// and +1 if len(s1) > len(s2). -func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int { - return slices.CompareFunc(s1, s2, cmp) -} - -// Index returns the index of the first occurrence of v in s, -// or -1 if not present. -func Index[E comparable](s []E, v E) int { - return slices.Index(s, v) -} - -// IndexFunc returns the first index i satisfying f(s[i]), -// or -1 if none do. -func IndexFunc[E any](s []E, f func(E) bool) int { - return slices.IndexFunc(s, f) -} - -// Contains reports whether v is present in s. -func Contains[E comparable](s []E, v E) bool { - return slices.Contains(s, v) -} - -// Insert inserts the values v... into s at index i, -// returning the modified slice. -// In the returned slice r, r[i] == v[0]. -// Insert panics if i is out of range. -// This function is O(len(s) + len(v)). -func Insert[S ~[]E, E any](s S, i int, v ...E) S { - return slices.Insert(s, i, v...) -} - -// Delete removes the elements s[i:j] from s, returning the modified slice. -// Delete panics if s[i:j] is not a valid slice of s. -// Delete modifies the contents of the slice s; it does not create a new slice. -// Delete is O(len(s)-(j-i)), so if many items must be deleted, it is better to -// make a single call deleting them all together than to delete one at a time. -func Delete[S ~[]E, E any](s S, i, j int) S { - return slices.Delete(s, i, j) -} - -// Clone returns a copy of the slice. -// The elements are copied using assignment, so this is a shallow clone. -func Clone[S ~[]E, E any](s S) S { - return slices.Clone(s) -} - -// Compact replaces consecutive runs of equal elements with a single copy. -// This is like the uniq command found on Unix. -// Compact modifies the contents of the slice s; it does not create a new slice. -// Intended usage is to assign the result back to the input slice. -func Compact[S ~[]E, E comparable](s S) S { - return slices.Compact(s) -} - -// CompactFunc is like Compact but uses a comparison function. -func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { - return slices.CompactFunc(s, eq) -} - -// Grow increases the slice's capacity, if necessary, to guarantee space for -// another n elements. After Grow(n), at least n elements can be appended -// to the slice without another allocation. Grow may modify elements of the -// slice between the length and the capacity. If n is negative or too large to -// allocate the memory, Grow panics. -func Grow[S ~[]E, E any](s S, n int) S { - return slices.Grow(s, n) -} - -// Clip removes unused capacity from the slice, returning s[:len(s):len(s)]. -func Clip[S ~[]E, E any](s S) S { - return slices.Clip(s) -} diff --git a/vendor/github.com/jesseduffield/generics/slices/delegated_sort.go b/vendor/github.com/jesseduffield/generics/slices/delegated_sort.go deleted file mode 100644 index 0741f0c55..000000000 --- a/vendor/github.com/jesseduffield/generics/slices/delegated_sort.go +++ /dev/null @@ -1,57 +0,0 @@ -package slices - -import ( - "golang.org/x/exp/constraints" - "golang.org/x/exp/slices" -) - -// This file delegates to the official slices package, so that we end up with a superset of the official API. - -// Sort sorts a slice of any ordered type in ascending order. -func Sort[E constraints.Ordered](x []E) { - slices.Sort(x) -} - -// Sort sorts the slice x in ascending order as determined by the less function. -// This sort is not guaranteed to be stable. -func SortFunc[E any](x []E, less func(a, b E) bool) { - slices.SortFunc(x, less) -} - -// SortStable sorts the slice x while keeping the original order of equal -// elements, using less to compare elements. -func SortStableFunc[E any](x []E, less func(a, b E) bool) { - slices.SortStableFunc(x, less) -} - -// IsSorted reports whether x is sorted in ascending order. -func IsSorted[E constraints.Ordered](x []E) bool { - return slices.IsSorted(x) -} - -// IsSortedFunc reports whether x is sorted in ascending order, with less as the -// comparison function. -func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool { - return slices.IsSortedFunc(x, less) -} - -// BinarySearch searches for target in a sorted slice and returns the smallest -// index at which target is found. If the target is not found, the index at -// which it could be inserted into the slice is returned; therefore, if the -// intention is to find target itself a separate check for equality with the -// element at the returned index is required. -func BinarySearch[E constraints.Ordered](x []E, target E) int { - return slices.BinarySearch(x, target) -} - -// BinarySearchFunc uses binary search to find and return the smallest index i -// in [0, n) at which ok(i) is true, assuming that on the range [0, n), -// ok(i) == true implies ok(i+1) == true. That is, BinarySearchFunc requires -// that ok is false for some (possibly empty) prefix of the input range [0, n) -// and then true for the (possibly empty) remainder; BinarySearchFunc returns -// the first true index. If there is no such index, BinarySearchFunc returns n. -// (Note that the "not found" return value is not -1 as in, for instance, -// strings.Index.) Search calls ok(i) only for i in the range [0, n). -func BinarySearchFunc[E any](x []E, ok func(E) bool) int { - return slices.BinarySearchFunc(x, ok) -} diff --git a/vendor/github.com/jesseduffield/generics/slices/slices.go b/vendor/github.com/jesseduffield/generics/slices/slices.go deleted file mode 100644 index 5bfb19968..000000000 --- a/vendor/github.com/jesseduffield/generics/slices/slices.go +++ /dev/null @@ -1,408 +0,0 @@ -package slices - -import ( - "golang.org/x/exp/constraints" - "golang.org/x/exp/slices" -) - -// This file contains the new functions that do not live in the official slices package. - -func Some[T any](slice []T, test func(T) bool) bool { - for _, value := range slice { - if test(value) { - return true - } - } - - return false -} - -func Every[T any](slice []T, test func(T) bool) bool { - for _, value := range slice { - if !test(value) { - return false - } - } - - return true -} - -// Produces a new slice, leaves the input slice untouched. -func Map[T any, V any](slice []T, f func(T) V) []V { - result := make([]V, 0, len(slice)) - for _, value := range slice { - result = append(result, f(value)) - } - - return result -} - -// Produces a new slice, leaves the input slice untouched. -func MapWithIndex[T any, V any](slice []T, f func(T, int) V) []V { - result := make([]V, 0, len(slice)) - for i, value := range slice { - result = append(result, f(value, i)) - } - - return result -} - -func TryMap[T any, V any](slice []T, f func(T) (V, error)) ([]V, error) { - result := make([]V, 0, len(slice)) - for _, value := range slice { - output, err := f(value) - if err != nil { - return nil, err - } - result = append(result, output) - } - - return result, nil -} - -func TryMapWithIndex[T any, V any](slice []T, f func(T, int) (V, error)) ([]V, error) { - result := make([]V, 0, len(slice)) - for i, value := range slice { - output, err := f(value, i) - if err != nil { - return nil, err - } - result = append(result, output) - } - - return result, nil -} - -// Produces a new slice, leaves the input slice untouched. -func FlatMap[T any, V any](slice []T, f func(T) []V) []V { - // impossible to know how long this slice will be in the end but the length - // of the original slice is the lower bound - result := make([]V, 0, len(slice)) - for _, value := range slice { - result = append(result, f(value)...) - } - - return result -} - -func FlatMapWithIndex[T any, V any](slice []T, f func(T, int) []V) []V { - // impossible to know how long this slice will be in the end but the length - // of the original slice is the lower bound - result := make([]V, 0, len(slice)) - for i, value := range slice { - result = append(result, f(value, i)...) - } - - return result -} - -func Flatten[T any](slice [][]T) []T { - result := make([]T, 0, len(slice)) - for _, subSlice := range slice { - result = append(result, subSlice...) - } - return result -} - -func MapInPlace[T any](slice []T, f func(T) T) { - for i, value := range slice { - slice[i] = f(value) - } -} - -// Produces a new slice, leaves the input slice untouched. -func Filter[T any](slice []T, test func(T) bool) []T { - result := make([]T, 0) - for _, element := range slice { - if test(element) { - result = append(result, element) - } - } - return result -} - -// Produces a new slice, leaves the input slice untouched. -func FilterWithIndex[T any](slice []T, f func(T, int) bool) []T { - result := make([]T, 0, len(slice)) - for i, value := range slice { - if f(value, i) { - result = append(result, value) - } - } - - return result -} - -func TryFilter[T any](slice []T, test func(T) (bool, error)) ([]T, error) { - result := make([]T, 0) - for _, element := range slice { - ok, err := test(element) - if err != nil { - return nil, err - } - if ok { - result = append(result, element) - } - } - return result, nil -} - -func TryFilterWithIndex[T any](slice []T, test func(T, int) (bool, error)) ([]T, error) { - result := make([]T, 0) - for i, element := range slice { - ok, err := test(element, i) - if err != nil { - return nil, err - } - if ok { - result = append(result, element) - } - } - return result, nil -} - -// Mutates original slice. Intended usage is to reassign the slice result to the input slice. -func FilterInPlace[T any](slice []T, test func(T) bool) []T { - newLength := 0 - for _, element := range slice { - if test(element) { - slice[newLength] = element - newLength++ - } - } - - return slice[:newLength] -} - -// Produces a new slice, leaves the input slice untouched -func Reverse[T any](slice []T) []T { - result := make([]T, len(slice)) - for i := range slice { - result[i] = slice[len(slice)-1-i] - } - return result -} - -func ReverseInPlace[T any](slice []T) { - for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 { - slice[i], slice[j] = slice[j], slice[i] - } -} - -// Produces a new slice, leaves the input slice untouched. -func FilterMap[T any, E any](slice []T, test func(T) (E, bool)) []E { - result := make([]E, 0, len(slice)) - for _, element := range slice { - mapped, ok := test(element) - if ok { - result = append(result, mapped) - } - } - - return result -} - -func FilterMapWithIndex[T any, E any](slice []T, test func(T, int) (E, bool)) []E { - result := make([]E, 0, len(slice)) - for i, element := range slice { - mapped, ok := test(element, i) - if ok { - result = append(result, mapped) - } - } - - return result -} - -func TryFilterMap[T any, E any](slice []T, test func(T) (E, bool, error)) ([]E, error) { - result := make([]E, 0, len(slice)) - for _, element := range slice { - mapped, ok, err := test(element) - if err != nil { - return nil, err - } - if ok { - result = append(result, mapped) - } - } - - return result, nil -} - -func TryFilterMapWithIndex[T any, E any](slice []T, test func(T, int) (E, bool, error)) ([]E, error) { - result := make([]E, 0, len(slice)) - for i, element := range slice { - mapped, ok, err := test(element, i) - if err != nil { - return nil, err - } - if ok { - result = append(result, mapped) - } - } - - return result, nil -} - -// Prepends items to the beginning of a slice. -// E.g. Prepend([]int{1,2}, 3, 4) = []int{3,4,1,2} -// Mutates original slice. Intended usage is to reassign the slice result to the input slice. -func Prepend[T any](slice []T, values ...T) []T { - return append(values, slice...) -} - -// Removes the element at the given index. Intended usage is to reassign the result to the input slice. -func Remove[T any](slice []T, index int) []T { - return slices.Delete(slice, index, index+1) -} - -// Removes the element at the 'fromIndex' and then inserts it at 'toIndex'. -// Operates on the input slice. Expected use is to reassign the result to the input slice. -func Move[T any](slice []T, fromIndex int, toIndex int) []T { - item := slice[fromIndex] - slice = Remove(slice, fromIndex) - return slices.Insert(slice, toIndex, item) -} - -// Swaps two elements at the given indices. -// Operates on the input slice. -func Swap[T any](slice []T, index1 int, index2 int) { - slice[index1], slice[index2] = slice[index2], slice[index1] -} - -// Similar to Append but we leave the original slice untouched and return a new slice -func Concat[T any](slice []T, values ...T) []T { - newSlice := make([]T, 0, len(slice)+len(values)) - newSlice = append(newSlice, slice...) - newSlice = append(newSlice, values...) - return newSlice -} - -func ContainsFunc[T any](slice []T, f func(T) bool) bool { - return IndexFunc(slice, f) != -1 -} - -// Pops item from the end of the slice and returns it, along with the updated slice -// Mutates original slice. Intended usage is to reassign the slice result to the input slice. -func Pop[T any](slice []T) (T, []T) { - index := len(slice) - 1 - value := slice[index] - slice = slice[0:index] - return value, slice -} - -// Shifts item from the beginning of the slice and returns it, along with the updated slice. -// Mutates original slice. Intended usage is to reassign the slice result to the input slice. -func Shift[T any](slice []T) (T, []T) { - value := slice[0] - slice = slice[1:] - return value, slice -} - -func Partition[T any](slice []T, test func(T) bool) ([]T, []T) { - left := make([]T, 0, len(slice)) - right := make([]T, 0, len(slice)) - - for _, value := range slice { - if test(value) { - left = append(left, value) - } else { - right = append(right, value) - } - } - - return left, right -} - -func MaxBy[T any, V constraints.Ordered](slice []T, f func(T) V) V { - if len(slice) == 0 { - return zero[V]() - } - - max := f(slice[0]) - for _, element := range slice[1:] { - value := f(element) - if value > max { - max = value - } - } - return max -} - -func MinBy[T any, V constraints.Ordered](slice []T, f func(T) V) V { - if len(slice) == 0 { - return zero[V]() - } - - min := f(slice[0]) - for _, element := range slice[1:] { - value := f(element) - if value < min { - min = value - } - } - return min -} - -func Find[T any](slice []T, f func(T) bool) (T, bool) { - for _, element := range slice { - if f(element) { - return element, true - } - } - return zero[T](), false -} - -// Sometimes you need to find an element and then map it to some other value based on -// information you obtained while finding it. This function lets you do that -func FindMap[T any, V any](slice []T, f func(T) (V, bool)) (V, bool) { - for _, element := range slice { - if value, ok := f(element); ok { - return value, true - } - } - return zero[V](), false -} - -func ForEach[T any](slice []T, f func(T)) { - for _, element := range slice { - f(element) - } -} - -func ForEachWithIndex[T any](slice []T, f func(T, int)) { - for i, element := range slice { - f(element, i) - } -} - -func TryForEach[T any](slice []T, f func(T) error) error { - for _, element := range slice { - if err := f(element); err != nil { - return err - } - } - return nil -} - -func TryForEachWithIndex[T any](slice []T, f func(T, int) error) error { - for i, element := range slice { - if err := f(element, i); err != nil { - return err - } - } - return nil -} - -func Sum[T constraints.Ordered](i []T) T { - sum := zero[T]() - for _, value := range i { - sum += value - } - return sum -} - -func zero[T any]() T { - var value T - return value -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 36dc2091d..f42105cd3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -127,7 +127,6 @@ github.com/jbenet/go-context/io ## explicit; go 1.18 github.com/jesseduffield/generics/maps github.com/jesseduffield/generics/set -github.com/jesseduffield/generics/slices # github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d ## explicit; go 1.13 github.com/jesseduffield/go-git/v5