]> git.lizzy.rs Git - micro.git/blobdiff - cmd/micro/util.go
Code optimisation (#1117)
[micro.git] / cmd / micro / util.go
index 9da6aebde098abfe41d0043c6d0792365ef832cb..eb8a1977607df70a0291d012345c82480dc2ce38 100644 (file)
@@ -1,8 +1,8 @@
 package main
 
 import (
-       "bytes"
        "os"
+       "os/user"
        "path/filepath"
        "reflect"
        "runtime"
@@ -12,7 +12,6 @@ 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
@@ -24,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
@@ -131,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
@@ -276,108 +323,44 @@ func ShortFuncName(i interface{}) string {
        return strings.TrimPrefix(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name(), "main.(*View).")
 }
 
-// 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
-
-               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
-                       }
+       var userData *user.User
+       var err error
 
-                       if r == '"' && curQuote == nil {
-                               curQuote = new(bytes.Buffer)
-                               appendRuneToBuff()
+       homeString := strings.Split(path, "/")[0]
+       if homeString == "~" {
+               userData, err = user.Current()
+               if err != nil {
+                       messenger.Error("Could not find user: ", err)
+               }
+       } else {
+               userData, err = user.Lookup(homeString[1:])
+               if err != nil {
+                       if messenger != nil {
+                               messenger.Error("Could not find user: ", err)
                        } else {
-                               if curQuote != nil && !escape {
-                                       if r == '"' {
-                                               appendRuneToBuff()
-                                               finishQuote()
-                                       } else if r == '\\' {
-                                               appendRuneToBuff()
-                                               escape = true
-                                               continue
-                                       }
-                               }
-                       }
-                       if !runeHandled {
-                               appendRuneToBuff()
+                               TermMessage("Could not find user: ", err)
                        }
+                       return ""
                }
-
-               escape = false
        }
-       appendResult()
-       return result
-}
 
-// 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)
-               }
-       }
+       home := userData.HomeDir
 
-       return buf.String()
+       return strings.Replace(path, homeString, home, 1)
 }
 
-// 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
-       }
-
-       home, err := homedir.Dir()
-       if err != nil {
-               messenger.Error("Could not find home directory: ", err)
-               return path
+// 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 strings.Replace(path, "~", home, 1)
+       return path
 }