mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-01 13:17:53 +02:00
lots more generics
This commit is contained in:
parent
c7a629c440
commit
eda8f4a5d4
4
go.mod
4
go.mod
@ -14,7 +14,7 @@ require (
|
||||
github.com/gookit/color v1.4.2
|
||||
github.com/imdario/mergo v0.3.11
|
||||
github.com/integrii/flaggy v1.4.0
|
||||
github.com/jesseduffield/generics v0.0.0-20220318214805-3397e5e19e9f
|
||||
github.com/jesseduffield/generics v0.0.0-20220319042131-63614a800d5f
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20220227022729-69f0c798eec8
|
||||
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
|
||||
@ -32,7 +32,6 @@ require (
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778
|
||||
golang.org/x/exp v0.0.0-20220318154914-8dddf5d87bd8
|
||||
gopkg.in/ozeidan/fuzzy-patricia.v3 v3.0.0
|
||||
)
|
||||
|
||||
@ -61,6 +60,7 @@ require (
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect
|
||||
golang.org/x/exp v0.0.0-20220318154914-8dddf5d87bd8 // indirect
|
||||
golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c // indirect
|
||||
golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7 // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
|
4
go.sum
4
go.sum
@ -66,8 +66,8 @@ github.com/integrii/flaggy v1.4.0 h1:A1x7SYx4jqu5NSrY14z8Z+0UyX2S5ygfJJrfolWR3zM
|
||||
github.com/integrii/flaggy v1.4.0/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jesseduffield/generics v0.0.0-20220318214805-3397e5e19e9f h1:9USuZttmg5ioHsjFyXboiGSbncpAqcKkq9qb4ga5PD0=
|
||||
github.com/jesseduffield/generics v0.0.0-20220318214805-3397e5e19e9f/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
|
||||
github.com/jesseduffield/generics v0.0.0-20220319042131-63614a800d5f h1:VZkNxrfkR344djm4Ju7QuKLXxZlaaOaNCrAWVRc1gvU=
|
||||
github.com/jesseduffield/generics v0.0.0-20220319042131-63614a800d5f/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4 h1:GOQrmaE8i+KEdB8NzAegKYd4tPn/inM0I1uo0NXFerg=
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20220227022729-69f0c798eec8 h1:9N08i5kjvOfkzMj6THmIM110wPTQLdVYEOHMHT2DFiI=
|
||||
|
@ -12,8 +12,8 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/app"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui"
|
||||
@ -180,9 +180,9 @@ outer:
|
||||
groupedBindings = append(groupedBindings, groupedBindingsType{contextAndView: contextAndView, bindings: contextBindings})
|
||||
}
|
||||
|
||||
sort.Slice(groupedBindings, func(i, j int) bool {
|
||||
first := groupedBindings[i].contextAndView
|
||||
second := groupedBindings[j].contextAndView
|
||||
slices.SortFunc(groupedBindings, func(a, b groupedBindingsType) bool {
|
||||
first := a.contextAndView
|
||||
second := b.contextAndView
|
||||
if first.title == "" {
|
||||
return true
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
)
|
||||
|
||||
// This package is for handling logic specific to a git hosting service like github, gitlab, bitbucket, etc.
|
||||
|
@ -5,6 +5,7 @@ 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/common"
|
||||
@ -78,8 +79,7 @@ outer:
|
||||
if branch.Head {
|
||||
foundHead = true
|
||||
branch.Recency = " *"
|
||||
branches = append(branches[0:i], branches[i+1:]...)
|
||||
branches = append([]*models.Branch{branch}, branches...)
|
||||
branches = slices.Move(branches, i, 0)
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,7 @@ outer:
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
branches = append([]*models.Branch{{Name: currentBranchName, DisplayName: currentBranchDisplayName, Head: true, Recency: " *"}}, branches...)
|
||||
branches = slices.Prepend(branches, &models.Branch{Name: currentBranchName, DisplayName: currentBranchDisplayName, Head: true, Recency: " *"})
|
||||
}
|
||||
|
||||
configBranches, err := self.config.Branches()
|
||||
@ -158,10 +158,10 @@ func (self *BranchLoader) obtainBranches() []*models.Branch {
|
||||
|
||||
trimmedOutput := strings.TrimSpace(output)
|
||||
outputLines := strings.Split(trimmedOutput, "\n")
|
||||
branches := make([]*models.Branch, 0, len(outputLines))
|
||||
for _, line := range outputLines {
|
||||
|
||||
branches := slices.FilterMap(outputLines, func(line string) (*models.Branch, bool) {
|
||||
if line == "" {
|
||||
continue
|
||||
return nil, false
|
||||
}
|
||||
|
||||
split := strings.Split(line, SEPARATION_CHAR)
|
||||
@ -169,12 +169,11 @@ func (self *BranchLoader) obtainBranches() []*models.Branch {
|
||||
// Ignore line if it isn't separated into 4 parts
|
||||
// This is probably a warning message, for more info see:
|
||||
// https://github.com/jesseduffield/lazygit/issues/1385#issuecomment-885580439
|
||||
continue
|
||||
return nil, false
|
||||
}
|
||||
|
||||
branch := obtainBranch(split)
|
||||
branches = append(branches, branch)
|
||||
}
|
||||
return obtainBranch(split), true
|
||||
})
|
||||
|
||||
return branches
|
||||
}
|
||||
|
@ -3,13 +3,14 @@ package loaders
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"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/samber/lo"
|
||||
)
|
||||
|
||||
type RemoteLoader struct {
|
||||
@ -42,37 +43,35 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) {
|
||||
}
|
||||
|
||||
// first step is to get our remotes from go-git
|
||||
remotes := make([]*models.Remote, len(goGitRemotes))
|
||||
for i, goGitRemote := range goGitRemotes {
|
||||
remotes := lo.Map(goGitRemotes, func(goGitRemote *gogit.Remote, _ int) *models.Remote {
|
||||
remoteName := goGitRemote.Config().Name
|
||||
|
||||
re := regexp.MustCompile(fmt.Sprintf(`(?m)^\s*%s\/([\S]+)`, remoteName))
|
||||
matches := re.FindAllStringSubmatch(remoteBranchesStr, -1)
|
||||
branches := make([]*models.RemoteBranch, len(matches))
|
||||
for j, match := range matches {
|
||||
branches[j] = &models.RemoteBranch{
|
||||
branches := lo.Map(matches, func(match []string, _ int) *models.RemoteBranch {
|
||||
return &models.RemoteBranch{
|
||||
Name: match[1],
|
||||
RemoteName: remoteName,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
remotes[i] = &models.Remote{
|
||||
return &models.Remote{
|
||||
Name: goGitRemote.Config().Name,
|
||||
Urls: goGitRemote.Config().URLs,
|
||||
Branches: branches,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// now lets sort our remotes by name alphabetically
|
||||
sort.Slice(remotes, func(i, j int) bool {
|
||||
slices.SortFunc(remotes, func(a, b *models.Remote) bool {
|
||||
// we want origin at the top because we'll be most likely to want it
|
||||
if remotes[i].Name == "origin" {
|
||||
if a.Name == "origin" {
|
||||
return true
|
||||
}
|
||||
if remotes[j].Name == "origin" {
|
||||
if b.Name == "origin" {
|
||||
return false
|
||||
}
|
||||
return strings.ToLower(remotes[i].Name) < strings.ToLower(remotes[j].Name)
|
||||
return strings.ToLower(a.Name) < strings.ToLower(b.Name)
|
||||
})
|
||||
|
||||
return remotes, nil
|
||||
|
@ -1,7 +1,7 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/generics/list"
|
||||
"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"
|
||||
@ -57,7 +57,7 @@ func (self *GlobalController) customCommand() error {
|
||||
|
||||
func (self *GlobalController) GetCustomCommandsHistorySuggestionsFunc() func(string) []*types.Suggestion {
|
||||
// reversing so that we display the latest command first
|
||||
history := list.Reverse(self.c.GetAppState().CustomCommandsHistory)
|
||||
history := slices.Reverse(self.c.GetAppState().CustomCommandsHistory)
|
||||
|
||||
return helpers.FuzzySearchFunc(history)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package helpers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/generics/set"
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
@ -118,12 +119,12 @@ func (self *CherryPickHelper) add(selectedCommit *models.Commit, commitsList []*
|
||||
commitSet := self.CherryPickedCommitShaSet()
|
||||
commitSet.Add(selectedCommit.Sha)
|
||||
|
||||
commitsInSet := lo.Filter(commitsList, func(commit *models.Commit, _ int) bool {
|
||||
return commitSet.Includes(commit.Sha)
|
||||
})
|
||||
newCommits := lo.Map(commitsInSet, func(commit *models.Commit, _ int) *models.Commit {
|
||||
return &models.Commit{Name: commit.Name, Sha: commit.Sha}
|
||||
})
|
||||
newCommits := slices.FilterThenMap(commitsList,
|
||||
func(commit *models.Commit) bool { return commitSet.Includes(commit.Sha) },
|
||||
func(commit *models.Commit) *models.Commit {
|
||||
return &models.Commit{Name: commit.Name, Sha: commit.Sha}
|
||||
},
|
||||
)
|
||||
|
||||
self.getData().CherryPickedCommits = newCommits
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package filetree
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
import "github.com/jesseduffield/generics/slices"
|
||||
|
||||
type INode interface {
|
||||
IsNil() bool
|
||||
@ -27,19 +25,17 @@ func sortChildren(node INode) {
|
||||
return
|
||||
}
|
||||
|
||||
children := node.GetChildren()
|
||||
sortedChildren := make([]INode, len(children))
|
||||
copy(sortedChildren, children)
|
||||
sortedChildren := slices.Clone(node.GetChildren())
|
||||
|
||||
sort.Slice(sortedChildren, func(i, j int) bool {
|
||||
if !sortedChildren[i].IsLeaf() && sortedChildren[j].IsLeaf() {
|
||||
slices.SortFunc(sortedChildren, func(a, b INode) bool {
|
||||
if !a.IsLeaf() && b.IsLeaf() {
|
||||
return true
|
||||
}
|
||||
if sortedChildren[i].IsLeaf() && !sortedChildren[j].IsLeaf() {
|
||||
if a.IsLeaf() && !b.IsLeaf() {
|
||||
return false
|
||||
}
|
||||
|
||||
return sortedChildren[i].GetPath() < sortedChildren[j].GetPath()
|
||||
return a.GetPath() < b.GetPath()
|
||||
})
|
||||
|
||||
// TODO: think about making this in-place
|
||||
|
@ -2,10 +2,10 @@ package graph
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"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"
|
||||
@ -265,11 +265,11 @@ func getNextPipes(prevPipes []*Pipe, commit *models.Commit, getStyle func(c *mod
|
||||
}
|
||||
|
||||
// not efficient but doing it for now: sorting my pipes by toPos, then by kind
|
||||
sort.Slice(newPipes, func(i, j int) bool {
|
||||
if newPipes[i].toPos == newPipes[j].toPos {
|
||||
return newPipes[i].kind < newPipes[j].kind
|
||||
slices.SortFunc(newPipes, func(a, b *Pipe) bool {
|
||||
if a.toPos == b.toPos {
|
||||
return a.kind < b.kind
|
||||
}
|
||||
return newPipes[i].toPos < newPipes[j].toPos
|
||||
return a.toPos < b.toPos
|
||||
})
|
||||
|
||||
return newPipes
|
||||
|
49
vendor/github.com/jesseduffield/generics/list/comparable_list.go
generated
vendored
49
vendor/github.com/jesseduffield/generics/list/comparable_list.go
generated
vendored
@ -1,49 +0,0 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type ComparableList[T comparable] struct {
|
||||
*List[T]
|
||||
}
|
||||
|
||||
func NewComparable[T comparable]() *ComparableList[T] {
|
||||
return &ComparableList[T]{List: New[T]()}
|
||||
}
|
||||
|
||||
func NewComparableFromSlice[T comparable](slice []T) *ComparableList[T] {
|
||||
return &ComparableList[T]{List: NewFromSlice(slice)}
|
||||
}
|
||||
|
||||
func (l *ComparableList[T]) Equal(other *ComparableList[T]) bool {
|
||||
return l.EqualSlice(other.ToSlice())
|
||||
}
|
||||
|
||||
func (l *ComparableList[T]) EqualSlice(other []T) bool {
|
||||
return slices.Equal(l.ToSlice(), other)
|
||||
}
|
||||
|
||||
func (l *ComparableList[T]) Compact() {
|
||||
l.slice = slices.Compact(l.slice)
|
||||
}
|
||||
|
||||
func (l *ComparableList[T]) Index(needle T) int {
|
||||
return slices.Index(l.slice, needle)
|
||||
}
|
||||
|
||||
func (l *ComparableList[T]) Contains(needle T) bool {
|
||||
return slices.Contains(l.slice, needle)
|
||||
}
|
||||
|
||||
func (l *ComparableList[T]) SortFuncInPlace(test func(a T, b T) bool) {
|
||||
slices.SortFunc(l.slice, test)
|
||||
}
|
||||
|
||||
func (l *ComparableList[T]) SortFunc(test func(a T, b T) bool) *ComparableList[T] {
|
||||
newSlice := slices.Clone(l.slice)
|
||||
|
||||
slices.SortFunc(newSlice, test)
|
||||
|
||||
return NewComparableFromSlice(newSlice)
|
||||
}
|
72
vendor/github.com/jesseduffield/generics/list/functions.go
generated
vendored
72
vendor/github.com/jesseduffield/generics/list/functions.go
generated
vendored
@ -1,72 +0,0 @@
|
||||
package list
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func Map[T any, V any](slice []T, f func(T) V) []V {
|
||||
result := make([]V, len(slice))
|
||||
for i, value := range slice {
|
||||
result[i] = f(value)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func MapInPlace[T any](slice []T, f func(T) T) {
|
||||
for i, value := range slice {
|
||||
slice[i] = f(value)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
117
vendor/github.com/jesseduffield/generics/list/list.go
generated
vendored
117
vendor/github.com/jesseduffield/generics/list/list.go
generated
vendored
@ -1,117 +0,0 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type List[T any] struct {
|
||||
slice []T
|
||||
}
|
||||
|
||||
func New[T any]() *List[T] {
|
||||
return &List[T]{}
|
||||
}
|
||||
|
||||
func NewFromSlice[T any](slice []T) *List[T] {
|
||||
return &List[T]{slice: slice}
|
||||
}
|
||||
|
||||
func (l *List[T]) ToSlice() []T {
|
||||
return l.slice
|
||||
}
|
||||
|
||||
// Mutative methods
|
||||
|
||||
func (l *List[T]) Push(v T) {
|
||||
l.slice = append(l.slice, v)
|
||||
}
|
||||
|
||||
func (l *List[T]) Pop() {
|
||||
l.slice = l.slice[0 : len(l.slice)-1]
|
||||
}
|
||||
|
||||
func (l *List[T]) Insert(index int, values ...T) {
|
||||
l.slice = slices.Insert(l.slice, index, values...)
|
||||
}
|
||||
|
||||
func (l *List[T]) Append(values ...T) {
|
||||
l.slice = append(l.slice, values...)
|
||||
}
|
||||
|
||||
func (l *List[T]) Prepend(values ...T) {
|
||||
l.slice = append(values, l.slice...)
|
||||
}
|
||||
|
||||
func (l *List[T]) Remove(index int) {
|
||||
l.Delete(index, index+1)
|
||||
}
|
||||
|
||||
func (l *List[T]) Delete(from int, to int) {
|
||||
l.slice = slices.Delete(l.slice, from, to)
|
||||
}
|
||||
|
||||
func (l *List[T]) FilterInPlace(test func(value T) bool) {
|
||||
l.slice = FilterInPlace(l.slice, test)
|
||||
}
|
||||
|
||||
func (l *List[T]) MapInPlace(f func(value T) T) {
|
||||
MapInPlace(l.slice, f)
|
||||
}
|
||||
|
||||
func (l *List[T]) ReverseInPlace() {
|
||||
ReverseInPlace(l.slice)
|
||||
}
|
||||
|
||||
// Non-mutative methods
|
||||
|
||||
// Similar to Append but we leave the original slice untouched and return a new list
|
||||
func (l *List[T]) Concat(values ...T) *List[T] {
|
||||
newSlice := make([]T, 0, len(l.slice)+len(values))
|
||||
newSlice = append(newSlice, l.slice...)
|
||||
newSlice = append(newSlice, values...)
|
||||
return &List[T]{slice: newSlice}
|
||||
}
|
||||
|
||||
func (l *List[T]) Filter(test func(value T) bool) *List[T] {
|
||||
return NewFromSlice(Filter(l.slice, test))
|
||||
}
|
||||
|
||||
// Unfortunately this does not support mapping from one type to another
|
||||
// because Go does not yet (and may never) support methods defining their own
|
||||
// type parameters. For that functionality you'll need to use the standalone
|
||||
// Map function instead
|
||||
func (l *List[T]) Map(f func(value T) T) *List[T] {
|
||||
return NewFromSlice(Map(l.slice, f))
|
||||
}
|
||||
|
||||
func (l *List[T]) Clone() *List[T] {
|
||||
return NewFromSlice(slices.Clone(l.slice))
|
||||
}
|
||||
|
||||
func (l *List[T]) Some(test func(value T) bool) bool {
|
||||
return Some(l.slice, test)
|
||||
}
|
||||
|
||||
func (l *List[T]) Every(test func(value T) bool) bool {
|
||||
return Every(l.slice, test)
|
||||
}
|
||||
|
||||
func (l *List[T]) IndexFunc(f func(T) bool) int {
|
||||
return slices.IndexFunc(l.slice, f)
|
||||
}
|
||||
|
||||
func (l *List[T]) ContainsFunc(f func(T) bool) bool {
|
||||
return l.IndexFunc(f) != -1
|
||||
}
|
||||
|
||||
func (l *List[T]) Reverse() *List[T] {
|
||||
return NewFromSlice(Reverse(l.slice))
|
||||
}
|
||||
|
||||
func (l *List[T]) IsEmpty() bool {
|
||||
return len(l.slice) == 0
|
||||
}
|
||||
|
||||
func (l *List[T]) Len() int {
|
||||
return len(l.slice)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package hashmap
|
||||
package maps
|
||||
|
||||
func Keys[Key comparable, Value any](m map[Key]Value) []Key {
|
||||
keys := make([]Key, 0, len(m))
|
4
vendor/github.com/jesseduffield/generics/set/set.go
generated
vendored
4
vendor/github.com/jesseduffield/generics/set/set.go
generated
vendored
@ -1,6 +1,6 @@
|
||||
package set
|
||||
|
||||
import "github.com/jesseduffield/generics/hashmap"
|
||||
import "github.com/jesseduffield/generics/maps"
|
||||
|
||||
type Set[T comparable] struct {
|
||||
hashMap map[T]bool
|
||||
@ -45,5 +45,5 @@ func (s *Set[T]) Includes(value T) bool {
|
||||
|
||||
// output slice is not necessarily in the same order that items were added
|
||||
func (s *Set[T]) ToSlice() []T {
|
||||
return hashmap.Keys(s.hashMap)
|
||||
return maps.Keys(s.hashMap)
|
||||
}
|
||||
|
117
vendor/github.com/jesseduffield/generics/slices/delegated_slices.go
generated
vendored
Normal file
117
vendor/github.com/jesseduffield/generics/slices/delegated_slices.go
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
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)
|
||||
}
|
57
vendor/github.com/jesseduffield/generics/slices/delegated_sort.go
generated
vendored
Normal file
57
vendor/github.com/jesseduffield/generics/slices/delegated_sort.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
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)
|
||||
}
|
154
vendor/github.com/jesseduffield/generics/slices/slices.go
generated
vendored
Normal file
154
vendor/github.com/jesseduffield/generics/slices/slices.go
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
package slices
|
||||
|
||||
import (
|
||||
"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, len(slice))
|
||||
for i, value := range slice {
|
||||
result[i] = f(value)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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) (bool, E)) []E {
|
||||
result := make([]E, 0, len(slice))
|
||||
for _, element := range slice {
|
||||
ok, mapped := test(element)
|
||||
if ok {
|
||||
result = append(result, mapped)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Produces a new slice, leaves the input slice untouched.
|
||||
func FilterThenMap[T any, E any](slice []T, test func(T) bool, mapFn func(T) E) []E {
|
||||
result := make([]E, 0, len(slice))
|
||||
for _, element := range slice {
|
||||
if test(element) {
|
||||
result = append(result, mapFn(element))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -120,11 +120,11 @@ github.com/integrii/flaggy
|
||||
# github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
||||
## explicit
|
||||
github.com/jbenet/go-context/io
|
||||
# github.com/jesseduffield/generics v0.0.0-20220318214805-3397e5e19e9f
|
||||
# github.com/jesseduffield/generics v0.0.0-20220319042131-63614a800d5f
|
||||
## explicit; go 1.18
|
||||
github.com/jesseduffield/generics/hashmap
|
||||
github.com/jesseduffield/generics/list
|
||||
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.20201006095850-341962be15a4
|
||||
## explicit; go 1.13
|
||||
github.com/jesseduffield/go-git/v5
|
||||
|
Loading…
x
Reference in New Issue
Block a user