2018-08-12 19:31:27 +10:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
2018-12-04 19:50:11 +11:00
|
|
|
"encoding/json"
|
2018-08-12 19:31:27 +10:00
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2019-02-24 17:05:17 +11:00
|
|
|
"regexp"
|
2021-04-06 14:21:17 +10:00
|
|
|
"runtime"
|
2020-08-15 11:18:40 +10:00
|
|
|
"strconv"
|
2018-08-12 19:31:27 +10:00
|
|
|
"strings"
|
2018-08-25 15:55:49 +10:00
|
|
|
"time"
|
2018-08-12 19:31:27 +10:00
|
|
|
|
2021-02-09 22:19:49 +11:00
|
|
|
"github.com/jesseduffield/gocui"
|
2018-08-12 19:31:27 +10:00
|
|
|
)
|
|
|
|
|
2018-08-13 21:16:21 +10:00
|
|
|
// GetCurrentRepoName gets the repo's base name
|
|
|
|
func GetCurrentRepoName() string {
|
2018-08-12 19:31:27 +10:00
|
|
|
pwd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln(err.Error())
|
|
|
|
}
|
|
|
|
return filepath.Base(pwd)
|
|
|
|
}
|
2018-08-13 20:26:02 +10:00
|
|
|
|
2018-08-19 14:48:39 +10:00
|
|
|
// GetProjectRoot returns the path to the root of the project. Only to be used
|
|
|
|
// in testing contexts, as with binaries it's unlikely this path will exist on
|
|
|
|
// the machine
|
|
|
|
func GetProjectRoot() string {
|
2018-08-19 15:05:36 +10:00
|
|
|
dir, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return strings.Split(dir, "lazygit")[0] + "lazygit"
|
2018-08-19 14:48:39 +10:00
|
|
|
}
|
2018-08-25 15:55:49 +10:00
|
|
|
|
2018-08-29 13:31:27 +02:00
|
|
|
// Loader dumps a string to be displayed as a loader
|
2018-08-25 15:55:49 +10:00
|
|
|
func Loader() string {
|
|
|
|
characters := "|/-\\"
|
|
|
|
now := time.Now()
|
|
|
|
nanos := now.UnixNano()
|
|
|
|
index := nanos / 50000000 % int64(len(characters))
|
|
|
|
return characters[index : index+1]
|
|
|
|
}
|
2018-08-31 18:43:54 +10:00
|
|
|
|
2018-09-10 20:17:39 +10:00
|
|
|
// Min returns the minimum of two integers
|
|
|
|
func Min(x, y int) int {
|
|
|
|
if x < y {
|
|
|
|
return x
|
|
|
|
}
|
|
|
|
return y
|
|
|
|
}
|
2018-09-17 21:02:30 +10:00
|
|
|
|
2021-10-31 22:29:43 +11:00
|
|
|
func Max(x, y int) int {
|
|
|
|
if x > y {
|
|
|
|
return x
|
|
|
|
}
|
|
|
|
return y
|
|
|
|
}
|
|
|
|
|
2022-01-30 14:46:46 +11:00
|
|
|
func Clamp(x int, min int, max int) int {
|
|
|
|
if x < min {
|
|
|
|
return min
|
|
|
|
} else if x > max {
|
|
|
|
return max
|
|
|
|
}
|
|
|
|
return x
|
|
|
|
}
|
|
|
|
|
2018-12-04 19:50:11 +11:00
|
|
|
func AsJson(i interface{}) string {
|
|
|
|
bytes, _ := json.MarshalIndent(i, "", " ")
|
|
|
|
return string(bytes)
|
|
|
|
}
|
2019-11-04 19:47:25 +11:00
|
|
|
|
2019-11-16 16:20:05 +11:00
|
|
|
// used to keep a number n between 0 and max, allowing for wraparounds
|
|
|
|
func ModuloWithWrap(n, max int) int {
|
2022-06-13 11:01:26 +10:00
|
|
|
if max == 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2019-11-16 16:20:05 +11:00
|
|
|
if n >= max {
|
|
|
|
return n % max
|
|
|
|
} else if n < 0 {
|
|
|
|
return max + n
|
|
|
|
} else {
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
}
|
2020-02-25 08:32:46 +11:00
|
|
|
|
2020-03-24 21:57:53 +11:00
|
|
|
func FindStringSubmatch(str string, regexpStr string) (bool, []string) {
|
|
|
|
re := regexp.MustCompile(regexpStr)
|
|
|
|
match := re.FindStringSubmatch(str)
|
|
|
|
return len(match) > 0, match
|
|
|
|
}
|
2020-08-07 18:27:18 +10:00
|
|
|
|
2020-08-15 11:18:40 +10:00
|
|
|
func MustConvertToInt(s string) int {
|
|
|
|
i, err := strconv.Atoi(s)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return i
|
|
|
|
}
|
2020-09-30 21:12:03 +10:00
|
|
|
|
2021-04-02 20:54:56 +11:00
|
|
|
// Safe will close tcell if a panic occurs so that we don't end up in a malformed
|
2020-10-07 21:19:38 +11:00
|
|
|
// terminal state
|
|
|
|
func Safe(f func()) {
|
2021-04-03 13:43:43 +11:00
|
|
|
_ = SafeWithError(func() error { f(); return nil })
|
|
|
|
}
|
|
|
|
|
|
|
|
func SafeWithError(f func() error) error {
|
2020-10-07 21:19:38 +11:00
|
|
|
panicking := true
|
|
|
|
defer func() {
|
2021-02-09 22:19:49 +11:00
|
|
|
if panicking && gocui.Screen != nil {
|
|
|
|
gocui.Screen.Fini()
|
2020-10-07 21:19:38 +11:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2021-04-03 13:43:43 +11:00
|
|
|
err := f()
|
2020-10-07 21:19:38 +11:00
|
|
|
|
|
|
|
panicking = false
|
2021-04-03 13:43:43 +11:00
|
|
|
|
|
|
|
return err
|
2020-10-07 21:19:38 +11:00
|
|
|
}
|
2021-04-06 14:21:17 +10:00
|
|
|
|
|
|
|
func StackTrace() string {
|
|
|
|
buf := make([]byte, 10000)
|
|
|
|
n := runtime.Stack(buf, false)
|
|
|
|
return fmt.Sprintf("%s\n", buf[:n])
|
|
|
|
}
|
2022-08-07 22:09:39 +10:00
|
|
|
|
|
|
|
// returns the path of the file that calls the function.
|
|
|
|
// 'skip' is the number of stack frames to skip.
|
|
|
|
func FilePath(skip int) string {
|
|
|
|
_, path, _, _ := runtime.Caller(skip)
|
|
|
|
return path
|
|
|
|
}
|