mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-15 00:15:32 +02:00
Standardise on using lo for slice functions
We've been sometimes using lo and sometimes using my slices package, and we need to pick one for consistency. Lo is more extensive and better maintained so we're going with that. My slices package was a superset of go's own slices package so in some places I've just used the official one (the methods were just wrappers anyway). I've also moved the remaining methods into the utils package.
This commit is contained in:
117
vendor/github.com/jesseduffield/generics/slices/delegated_slices.go
generated
vendored
117
vendor/github.com/jesseduffield/generics/slices/delegated_slices.go
generated
vendored
@ -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)
|
||||
}
|
57
vendor/github.com/jesseduffield/generics/slices/delegated_sort.go
generated
vendored
57
vendor/github.com/jesseduffield/generics/slices/delegated_sort.go
generated
vendored
@ -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)
|
||||
}
|
408
vendor/github.com/jesseduffield/generics/slices/slices.go
generated
vendored
408
vendor/github.com/jesseduffield/generics/slices/slices.go
generated
vendored
@ -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
|
||||
}
|
Reference in New Issue
Block a user