Standardise on using lo for slice functions (#2846)

This commit is contained in:
Jesse Duffield 2023-07-30 18:55:12 +10:00 committed by GitHub
commit 5c78394299
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 212 additions and 732 deletions

View file

@ -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
}

View file

@ -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 {

View file

@ -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

View file

@ -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,

View file

@ -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)
}

View file

@ -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
}

View file

@ -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],

View file

@ -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,

View file

@ -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)

View file

@ -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]

View file

@ -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)
})
}

View file

@ -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 := ""

View file

@ -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
})

View file

@ -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()
})

View file

@ -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 != ""
})

View file

@ -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]

View file

@ -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}
})
}

View file

@ -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) },

View file

@ -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}
})
}

View file

@ -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)
}

View file

@ -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 {

View file

@ -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()
})
}

View file

@ -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]
})
}

View file

@ -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,

View file

@ -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)

View file

@ -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
})
}

View file

@ -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}
})
}

View file

@ -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,

View file

@ -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 {

View file

@ -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)
})
}

View file

@ -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)
})
}

View file

@ -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()
})
}

View file

@ -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()
})
}

View file

@ -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}
})
}

View file

@ -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)
})

View file

@ -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)
})

View file

@ -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,

View file

@ -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)
})

View file

@ -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)
})

View file

@ -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)
})

View file

@ -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)
})
}

View file

@ -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)
})
}

View file

@ -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)
})

View file

@ -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 {

View file

@ -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)
})

View file

@ -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
})
}

View file

@ -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
})
}

View file

@ -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, ""),

View file

@ -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)
})
}

View file

@ -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)

View file

@ -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()
},
))

View file

@ -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 {

View file

@ -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
})
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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
}

1
vendor/modules.txt vendored
View file

@ -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