X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Futil.go;h=833562941436689ca668456c41ef51c55c89fe06;hb=ea6a87d41a9fcaa9fff81c1a5310726b1e15c548;hp=5b2cfac85392d7a1bb389a5662092170080de568;hpb=9a798fe2208c358865261be19af84d39381f2617;p=micro.git diff --git a/cmd/micro/util.go b/cmd/micro/util.go index 5b2cfac8..83356294 100644 --- a/cmd/micro/util.go +++ b/cmd/micro/util.go @@ -1,7 +1,6 @@ package main import ( - "bytes" "os" "path/filepath" "reflect" @@ -12,6 +11,7 @@ import ( "unicode/utf8" "github.com/mattn/go-runewidth" + homedir "github.com/mitchellh/go-homedir" ) // Util.go is a collection of utility functions that are used throughout @@ -23,6 +23,54 @@ func Count(s string) int { return utf8.RuneCountInString(s) } +// Convert byte array to rune array +func toRunes(b []byte) []rune { + runes := make([]rune, 0, utf8.RuneCount(b)) + + for len(b) > 0 { + r, size := utf8.DecodeRune(b) + runes = append(runes, r) + + b = b[size:] + } + + return runes +} + +func sliceStart(slc []byte, index int) []byte { + len := len(slc) + i := 0 + totalSize := 0 + for totalSize < len { + if i >= index { + return slc[totalSize:] + } + + _, size := utf8.DecodeRune(slc[totalSize:]) + totalSize += size + i++ + } + + return slc[totalSize:] +} + +func sliceEnd(slc []byte, index int) []byte { + len := len(slc) + i := 0 + totalSize := 0 + for totalSize < len { + if i >= index { + return slc[:totalSize] + } + + _, size := utf8.DecodeRune(slc[totalSize:]) + totalSize += size + i++ + } + + return slc[:totalSize] +} + // NumOccurrences counts the number of occurrences of a byte in a string func NumOccurrences(s string, c byte) int { var n int @@ -36,11 +84,7 @@ func NumOccurrences(s string, c byte) int { // Spaces returns a string with n spaces func Spaces(n int) string { - var str string - for i := 0; i < n; i++ { - str += " " - } - return str + return strings.Repeat(" ", n) } // Min takes the min of two ints @@ -59,6 +103,7 @@ func Max(a, b int) int { return b } +// FSize gets the size of a file func FSize(f *os.File) int64 { fi, _ := f.Stat() // get the size @@ -82,6 +127,16 @@ func IsWhitespace(c rune) bool { return c == ' ' || c == '\t' || c == '\n' } +// IsStrWhitespace returns true if the given string is all whitespace +func IsStrWhitespace(str string) bool { + for _, c := range str { + if !IsWhitespace(c) { + return false + } + } + return true +} + // Contains returns whether or not a string array contains a given string func Contains(list []string, a string) bool { for _, b := range list { @@ -123,7 +178,7 @@ func GetLeadingWhitespace(str string) string { } // IsSpaces checks if a given string is only spaces -func IsSpaces(str string) bool { +func IsSpaces(str []byte) bool { for _, c := range str { if c != ' ' { return false @@ -239,6 +294,7 @@ func lcs(a, b string) string { return lcs } +// CommonSubstring gets a common substring among the inputs func CommonSubstring(arr ...string) string { commonStr := arr[0] @@ -257,98 +313,36 @@ func Abs(n int) int { return n } -// FuncName returns the name of a given function object +// FuncName returns the full name of a given function object func FuncName(i interface{}) string { return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() } -// SplitCommandArgs separates multiple command arguments which may be quoted. -// The returned slice contains at least one string -func SplitCommandArgs(input string) []string { - var result []string - var curQuote *bytes.Buffer - - curArg := new(bytes.Buffer) - escape := false - - finishQuote := func() { - if curQuote == nil { - return - } - str := curQuote.String() - if unquoted, err := strconv.Unquote(str); err == nil { - str = unquoted - } - curArg.WriteString(str) - curQuote = nil - } - - appendResult := func() { - finishQuote() - escape = false +// ShortFuncName returns the name only of a given function object +func ShortFuncName(i interface{}) string { + return strings.TrimPrefix(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name(), "main.(*View).") +} - str := curArg.String() - result = append(result, str) - curArg.Reset() +// ReplaceHome takes a path as input and replaces ~ at the start of the path with the user's +// home directory. Does nothing if the path does not start with '~'. +func ReplaceHome(path string) string { + if !strings.HasPrefix(path, "~") { + return path } - for _, r := range input { - if r == ' ' && curQuote == nil { - appendResult() - } else { - runeHandled := false - appendRuneToBuff := func() { - if curQuote != nil { - curQuote.WriteRune(r) - } else { - curArg.WriteRune(r) - } - runeHandled = true - } - - if r == '"' && curQuote == nil { - curQuote = new(bytes.Buffer) - appendRuneToBuff() - } else { - if curQuote != nil && !escape { - if r == '"' { - appendRuneToBuff() - finishQuote() - } else if r == '\\' { - appendRuneToBuff() - escape = true - continue - } - } - } - if !runeHandled { - appendRuneToBuff() - } - } - - escape = false + home, err := homedir.Dir() + if err != nil { + messenger.Error("Could not find home directory: ", err) + return path } - appendResult() - return result + return strings.Replace(path, "~", home, 1) } -// JoinCommandArgs joins multiple command arguments and quote the strings if needed. -func JoinCommandArgs(args ...string) string { - buf := new(bytes.Buffer) - first := true - for _, arg := range args { - if first { - first = false - } else { - buf.WriteRune(' ') - } - quoted := strconv.Quote(arg) - if quoted[1:len(quoted)-1] != arg || strings.ContainsRune(arg, ' ') { - buf.WriteString(quoted) - } else { - buf.WriteString(arg) - } +// GetPath returns a filename without everything following a `:` +// This is used for opening files like util.go:10:5 to specify a line and column +func GetPath(path string) string { + if strings.Contains(path, ":") { + path = strings.Split(path, ":")[0] } - - return buf.String() + return path }