oh-my-posh/src/regex.go
2021-10-20 17:12:29 +02:00

104 lines
2.3 KiB
Go

package main
import (
"fmt"
"regexp"
"strings"
"sync"
)
var (
regexCache = make(map[string]*regexp.Regexp)
regexCacheLock = sync.RWMutex{}
)
func getCompiledRegex(pattern string) *regexp.Regexp {
// try in cache first
regexCacheLock.RLock()
re := regexCache[pattern]
regexCacheLock.RUnlock()
if re != nil {
return re
}
// should we panic or return the error?
re = regexp.MustCompile(pattern)
// lock for concurrent access and save the compiled expression in cache
regexCacheLock.Lock()
regexCache[pattern] = re
regexCacheLock.Unlock()
return re
}
func findNamedRegexMatch(pattern, text string) map[string]string {
// error ignored because mustCompile will cause a panic
re := getCompiledRegex(pattern)
match := re.FindStringSubmatch(text)
result := make(map[string]string)
if len(match) == 0 {
return result
}
for i, name := range re.SubexpNames() {
if i == 0 {
continue
}
result[name] = match[i]
}
return result
}
func findAllNamedRegexMatch(pattern, text string) []map[string]string {
re := getCompiledRegex(pattern)
match := re.FindAllStringSubmatch(text, -1)
var results []map[string]string
if len(match) == 0 {
return results
}
for _, set := range match {
result := make(map[string]string)
for i, name := range re.SubexpNames() {
if i == 0 {
result["text"] = set[i]
continue
}
result[name] = set[i]
}
results = append(results, result)
}
return results
}
func replaceAllString(pattern, text, replaceText string) string {
re := getCompiledRegex(pattern)
return re.ReplaceAllString(text, replaceText)
}
func matchString(pattern, text string) bool {
re := getCompiledRegex(pattern)
return re.MatchString(text)
}
func dirMatchesOneOf(env environmentInfo, dir string, regexes []string) bool {
normalizedCwd := strings.ReplaceAll(dir, "\\", "/")
normalizedHomeDir := strings.ReplaceAll(env.homeDir(), "\\", "/")
for _, element := range regexes {
normalizedElement := strings.ReplaceAll(element, "\\\\", "/")
if strings.HasPrefix(normalizedElement, "~") {
normalizedElement = normalizedHomeDir + normalizedElement[1:]
}
pattern := fmt.Sprintf("^%s$", normalizedElement)
goos := env.getRuntimeGOOS()
if goos == windowsPlatform || goos == darwinPlatform {
pattern = "(?i)" + pattern
}
matched := matchString(pattern, normalizedCwd)
if matched {
return true
}
}
return false
}