X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Futil.go;h=1888155a8370536fd1cdab3733546cdbd2a53a39;hb=59251ee5d02f0320051a7df32f7220a3d3de442c;hp=ecd6e7cb548179b531f9b136230c2e74397ab3fe;hpb=cfdaf0e3f6dbc1925065efbca6dfd943234a590a;p=micro.git diff --git a/cmd/micro/util.go b/cmd/micro/util.go index ecd6e7cb..1888155a 100644 --- a/cmd/micro/util.go +++ b/cmd/micro/util.go @@ -23,7 +23,7 @@ func Count(s string) int { return utf8.RuneCountInString(s) } -// NumOccurrences counts the number of occurences of a byte in a string +// NumOccurrences counts the number of occurrences of a byte in a string func NumOccurrences(s string, c byte) int { var n int for i := 0; i < len(s); i++ { @@ -91,6 +91,18 @@ func Insert(str string, pos int, value string) string { return string([]rune(str)[:pos]) + value + string([]rune(str)[pos:]) } +// MakeRelative will attempt to make a relative path between path and base +func MakeRelative(path, base string) (string, error) { + if len(path) > 0 { + rel, err := filepath.Rel(base, path) + if err != nil { + return path, err + } + return rel, nil + } + return path, nil +} + // GetLeadingWhitespace returns the leading whitespace of the given string func GetLeadingWhitespace(str string) string { ws := "" @@ -157,7 +169,19 @@ func GetModTime(path string) (time.Time, bool) { // StringWidth returns the width of a string where tabs count as `tabsize` width func StringWidth(str string, tabsize int) int { sw := runewidth.StringWidth(str) - sw += NumOccurrences(str, '\t') * (tabsize - 1) + lineIdx := 0 + for _, ch := range str { + switch ch { + case '\t': + ts := tabsize - (lineIdx % tabsize) + sw += ts - 1 + lineIdx += ts + case '\n': + lineIdx = 0 + default: + lineIdx++ + } + } return sw } @@ -165,16 +189,22 @@ func StringWidth(str string, tabsize int) int { // that have a width larger than 1 (this also counts tabs as `tabsize` width) func WidthOfLargeRunes(str string, tabsize int) int { count := 0 + lineIdx := 0 for _, ch := range str { var w int if ch == '\t' { - w = tabsize + w = tabsize - (lineIdx % tabsize) } else { w = runewidth.RuneWidth(ch) } if w > 1 { count += (w - 1) } + if ch == '\n' { + lineIdx = 0 + } else { + lineIdx += w + } } return count } @@ -226,46 +256,68 @@ func FuncName(i interface{}) string { return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() } -// SplitCommandArgs seperates multiple command arguments which may be quoted. +// 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) - inQuote := false 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() { - str := curArg.String() - inQuote = false + finishQuote() escape = false - if strings.HasPrefix(str, `"`) && strings.HasSuffix(str, `"`) { - if unquoted, err := strconv.Unquote(str); err == nil { - str = unquoted - } - } + + str := curArg.String() result = append(result, str) curArg.Reset() } for _, r := range input { - if r == ' ' && !inQuote { + if r == ' ' && curQuote == nil { appendResult() } else { - curArg.WriteRune(r) + runeHandled := false + appendRuneToBuff := func() { + if curQuote != nil { + curQuote.WriteRune(r) + } else { + curArg.WriteRune(r) + } + runeHandled = true + } - if r == '"' && !inQuote { - inQuote = true + if r == '"' && curQuote == nil { + curQuote = new(bytes.Buffer) + appendRuneToBuff() } else { - if inQuote && !escape { + if curQuote != nil && !escape { if r == '"' { - inQuote = false - } - if r == '\\' { + appendRuneToBuff() + finishQuote() + } else if r == '\\' { + appendRuneToBuff() escape = true continue } } } + if !runeHandled { + appendRuneToBuff() + } } escape = false @@ -294,17 +346,3 @@ func JoinCommandArgs(args ...string) string { return buf.String() } - -func Sub(str string, start, end int) string { - len := Count(str) - if len > start && len > end { - return str[start:end] - } - if len > start && len < end { - return str[start:] - } - if len < start { - return str - } - return "" -}