1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00
wtf/utils/utils.go
2019-08-05 10:50:12 -07:00

216 lines
5.0 KiB
Go

package utils
import (
"fmt"
"io/ioutil"
"os/exec"
"regexp"
"runtime"
"strconv"
"strings"
"github.com/rivo/tview"
)
const (
SimpleDateFormat = "Jan 2"
SimpleTimeFormat = "15:04 MST"
MinimumTimeFormat = "15:04"
FullDateFormat = "Monday, Jan 2"
FriendlyDateFormat = "Mon, Jan 2"
FriendlyDateTimeFormat = "Mon, Jan 2, 15:04"
TimestampFormat = "2006-01-02T15:04:05-0700"
)
// CenterText takes a string and a width and pads the left and right of the string with
// empty spaces to ensure that the string is in the middle of the returned value
//
// Example:
//
// x := CenterText("cat", 11)
// > " cat "
//
func CenterText(str string, width int) string {
if width < 0 {
width = 0
}
return fmt.Sprintf("%[1]*s", -width, fmt.Sprintf("%[1]*s", (width+len(str))/2, str))
}
// ExecuteCommand executes an external command on the local machine as the current user
func ExecuteCommand(cmd *exec.Cmd) string {
if cmd == nil {
return ""
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return fmt.Sprintf("%v\n", err)
}
if err := cmd.Start(); err != nil {
return fmt.Sprintf("%v\n", err)
}
var str string
if b, err := ioutil.ReadAll(stdout); err == nil {
str += string(b)
}
err = cmd.Wait()
if err != nil {
return fmt.Sprintf("%v\n", err)
}
return str
}
// Exclude takes a slice of strings and a target string and returns the contents of the original
// slice of strings without the target string in it
//
// Example:
//
// x := Exclude([]string{"cat", "dog", "rat"}, "dog")
// > []string{"cat", "rat"}
//
func Exclude(strs []string, val string) bool {
for _, str := range strs {
if val == str {
return false
}
}
return true
}
// FindMatch takes a regex pattern and a string of data and returns back all the matches
// in that string
func FindMatch(pattern string, data string) [][]string {
r := regexp.MustCompile(pattern)
return r.FindAllStringSubmatch(data, -1)
}
// NameFromEmail takes an email address and returns the part that comes before the @ symbol
//
// Example:
//
// NameFromEmail("test_user@example.com")
// > "Test_user"
//
func NameFromEmail(email string) string {
parts := strings.Split(email, "@")
return strings.Title(strings.Replace(parts[0], ".", " ", -1))
}
// NamesFromEmails takes a slice of email addresses and returns a slice of the parts that
// come before the @ symbol
//
// Example:
//
// NamesFromEmail("test_user@example.com", "other_user@example.com")
// > []string{"Test_user", "Other_user"}
//
func NamesFromEmails(emails []string) []string {
names := []string{}
for _, email := range emails {
names = append(names, NameFromEmail(email))
}
return names
}
// OpenFile opens the file defined in `path` via the operating system
func OpenFile(path string) {
if (strings.HasPrefix(path, "http://")) || (strings.HasPrefix(path, "https://")) {
switch runtime.GOOS {
case "linux":
exec.Command("xdg-open", path).Start()
case "windows":
exec.Command("rundll32", "url.dll,FileProtocolHandler", path).Start()
case "darwin":
exec.Command("open", path).Start()
default:
}
} else {
filePath, _ := ExpandHomeDir(path)
cmd := exec.Command(OpenFileUtil, filePath)
ExecuteCommand(cmd)
}
}
// PadRow returns a padding for a row to make it the full width of the containing widget.
// Useful for ensurig row highlighting spans the full width (I suspect tcell has a better
// way to do this, but I haven't yet found it)
func PadRow(offset int, max int) string {
padSize := max - offset
if padSize < 0 {
padSize = 0
}
return strings.Repeat(" ", padSize)
}
// ReadFileBytes reads the contents of a file and returns those contents as a slice of bytes
func ReadFileBytes(filePath string) ([]byte, error) {
fileData, err := ioutil.ReadFile(filePath)
if err != nil {
return []byte{}, err
}
return fileData, nil
}
/* -------------------- Map Conversion -------------------- */
// MapToStrs takes a map of interfaces and returns a map of strings
func MapToStrs(aMap map[string]interface{}) map[string]string {
results := make(map[string]string)
for key, val := range aMap {
results[key] = val.(string)
}
return results
}
/* -------------------- Slice Conversion -------------------- */
// ToInts takes a slice of interfaces and returns a slice of ints
func ToInts(slice []interface{}) []int {
results := []int{}
for _, val := range slice {
results = append(results, val.(int))
}
return results
}
// ToStrs takes a slice of interfaces and returns a slice of strings
func ToStrs(slice []interface{}) []string {
results := []string{}
for _, val := range slice {
switch val.(type) {
case int:
results = append(results, strconv.Itoa(val.(int)))
case string:
results = append(results, val.(string))
}
}
return results
}
func HighlightableHelper(view *tview.TextView, input string, idx, offset int) string {
fmtStr := fmt.Sprintf(`["%d"][""]`, idx)
_, _, w, _ := view.GetInnerRect()
fmtStr += input
fmtStr += PadRow(offset, w+1)
fmtStr += `[""]` + "\n"
return fmtStr
}