mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-03-05 20:49:04 -08:00
refactor: named regex captures
This commit is contained in:
parent
56778276b2
commit
fd84a469ef
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Property defines one property of a segment for context
|
// Property defines one property of a segment for context
|
||||||
|
@ -62,8 +61,7 @@ func (p *properties) getColor(property Property, defaultValue string) string {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return colorString
|
return colorString
|
||||||
}
|
}
|
||||||
r := regexp.MustCompile(`(?P<color>#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})`)
|
values := findNamedRegexMatch(`(?P<color>#[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})`, colorString)
|
||||||
values := groupDict(r, colorString)
|
|
||||||
if values != nil && values["color"] != "" {
|
if values != nil && values["color"] != "" {
|
||||||
return values["color"]
|
return values["color"]
|
||||||
}
|
}
|
||||||
|
|
45
regex.go
Normal file
45
regex.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "regexp"
|
||||||
|
|
||||||
|
func findNamedRegexMatch(pattern, text string) map[string]string {
|
||||||
|
re := regexp.MustCompile(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 := regexp.MustCompile(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 := regexp.MustCompile(pattern)
|
||||||
|
return re.ReplaceAllString(text, replaceText)
|
||||||
|
}
|
17
renderer.go
17
renderer.go
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
|
@ -147,18 +146,16 @@ func (r *Renderer) writeAndRemoveText(background, foreground, text, textToRemove
|
||||||
|
|
||||||
func (r *Renderer) write(background, foreground, text string) {
|
func (r *Renderer) write(background, foreground, text string) {
|
||||||
// first we match for any potentially valid colors enclosed in <>
|
// first we match for any potentially valid colors enclosed in <>
|
||||||
rex := regexp.MustCompile(`<([#A-Za-z0-9]+)?(?:,([#A-Za-z0-9]+))?>(.*?)<\/>`)
|
match := findAllNamedRegexMatch(`<(?P<foreground>[^,>]+)?,?(?P<background>[^>]+)?>(?P<content>[^<]*)<\/>`, text)
|
||||||
match := rex.FindAllStringSubmatch(text, -1)
|
|
||||||
for i := range match {
|
for i := range match {
|
||||||
extractedForegroundColor := match[i][1]
|
extractedForegroundColor := match[i]["foreground"]
|
||||||
extractedBackgroundColor := match[i][2]
|
extractedBackgroundColor := match[i]["background"]
|
||||||
if col := r.getAnsiFromColorString(extractedForegroundColor, false); col == "" && extractedForegroundColor != Transparent && len(extractedBackgroundColor) == 0 {
|
if col := r.getAnsiFromColorString(extractedForegroundColor, false); col == "" && extractedForegroundColor != Transparent && len(extractedBackgroundColor) == 0 {
|
||||||
continue // we skip invalid colors
|
continue // we skip invalid colors
|
||||||
}
|
}
|
||||||
if col := r.getAnsiFromColorString(extractedBackgroundColor, false); col == "" && extractedBackgroundColor != Transparent && len(extractedForegroundColor) == 0 {
|
if col := r.getAnsiFromColorString(extractedBackgroundColor, false); col == "" && extractedBackgroundColor != Transparent && len(extractedForegroundColor) == 0 {
|
||||||
continue // we skip invalid colors
|
continue // we skip invalid colors
|
||||||
}
|
}
|
||||||
|
|
||||||
// reuse function colors if only one was specified
|
// reuse function colors if only one was specified
|
||||||
if len(extractedBackgroundColor) == 0 {
|
if len(extractedBackgroundColor) == 0 {
|
||||||
extractedBackgroundColor = background
|
extractedBackgroundColor = background
|
||||||
|
@ -166,9 +163,8 @@ func (r *Renderer) write(background, foreground, text string) {
|
||||||
if len(extractedForegroundColor) == 0 {
|
if len(extractedForegroundColor) == 0 {
|
||||||
extractedForegroundColor = foreground
|
extractedForegroundColor = foreground
|
||||||
}
|
}
|
||||||
|
escapedTextSegment := match[i]["text"]
|
||||||
escapedTextSegment := match[i][0]
|
innerText := match[i]["content"]
|
||||||
innerText := match[i][3]
|
|
||||||
textBeforeColorOverride := strings.Split(text, escapedTextSegment)[0]
|
textBeforeColorOverride := strings.Split(text, escapedTextSegment)[0]
|
||||||
text = r.writeAndRemoveText(background, foreground, textBeforeColorOverride, textBeforeColorOverride, text)
|
text = r.writeAndRemoveText(background, foreground, textBeforeColorOverride, textBeforeColorOverride, text)
|
||||||
text = r.writeAndRemoveText(extractedBackgroundColor, extractedForegroundColor, innerText, escapedTextSegment, text)
|
text = r.writeAndRemoveText(extractedBackgroundColor, extractedForegroundColor, innerText, escapedTextSegment, text)
|
||||||
|
@ -178,8 +174,7 @@ func (r *Renderer) write(background, foreground, text string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Renderer) lenWithoutANSI(str string) int {
|
func (r *Renderer) lenWithoutANSI(str string) int {
|
||||||
re := regexp.MustCompile(r.formats.rANSI)
|
stripped := replaceAllString(r.formats.rANSI, str, "")
|
||||||
stripped := re.ReplaceAllString(str, "")
|
|
||||||
switch r.shell {
|
switch r.shell {
|
||||||
case zsh:
|
case zsh:
|
||||||
stripped = strings.ReplaceAll(stripped, "%{", "")
|
stripped = strings.ReplaceAll(stripped, "%{", "")
|
||||||
|
|
|
@ -85,6 +85,17 @@ func TestWriteColorOverrideBoth16(t *testing.T) {
|
||||||
assert.NotContains(t, renderer.string(), "</>")
|
assert.NotContains(t, renderer.string(), "</>")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriteColorOverrideDouble(t *testing.T) {
|
||||||
|
renderer := &Renderer{
|
||||||
|
Buffer: new(bytes.Buffer),
|
||||||
|
}
|
||||||
|
text := "<#ffffff>jan</>@<#ffffff>Jans-MBP</>"
|
||||||
|
renderer.init("pwsh")
|
||||||
|
renderer.write("#193549", "#ff5733", text)
|
||||||
|
assert.NotContains(t, renderer.string(), "<#ffffff>")
|
||||||
|
assert.NotContains(t, renderer.string(), "</>")
|
||||||
|
}
|
||||||
|
|
||||||
func TestWriteColorTransparent(t *testing.T) {
|
func TestWriteColorTransparent(t *testing.T) {
|
||||||
renderer := &Renderer{
|
renderer := &Renderer{
|
||||||
Buffer: new(bytes.Buffer),
|
Buffer: new(bytes.Buffer),
|
||||||
|
|
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -180,8 +179,7 @@ func (g *git) getStatusDetailString(status *gitStatus, color, icon Property, def
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *git) getUpstreamSymbol() string {
|
func (g *git) getUpstreamSymbol() string {
|
||||||
upstreamRegex := regexp.MustCompile("/.*")
|
upstream := replaceAllString("/.*", g.repo.upstream, "")
|
||||||
upstream := upstreamRegex.ReplaceAllString(g.repo.upstream, "")
|
|
||||||
url := g.getGitCommandOutput("remote", "get-url", upstream)
|
url := g.getGitCommandOutput("remote", "get-url", upstream)
|
||||||
if strings.Contains(url, "github") {
|
if strings.Contains(url, "github") {
|
||||||
return g.props.getString(GithubIcon, "\uF408 ")
|
return g.props.getString(GithubIcon, "\uF408 ")
|
||||||
|
@ -348,19 +346,6 @@ func (g *git) getStashContext() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *git) parseGitStatusInfo(branchInfo string) map[string]string {
|
func (g *git) parseGitStatusInfo(branchInfo string) map[string]string {
|
||||||
var branchRegex = regexp.MustCompile(`^## (?P<local>\S+?)(\.{3}(?P<upstream>\S+?)( \[(?P<upstream_status>(ahead (?P<ahead>\d+)(, )?)?(behind (?P<behind>\d+))?(gone)?)])?)?$`)
|
var branchRegex = `^## (?P<local>\S+?)(\.{3}(?P<upstream>\S+?)( \[(?P<upstream_status>(ahead (?P<ahead>\d+)(, )?)?(behind (?P<behind>\d+))?(gone)?)])?)?$`
|
||||||
return groupDict(branchRegex, branchInfo)
|
return findNamedRegexMatch(branchRegex, branchInfo)
|
||||||
}
|
|
||||||
|
|
||||||
func groupDict(pattern *regexp.Regexp, haystack string) map[string]string {
|
|
||||||
match := pattern.FindStringSubmatch(haystack)
|
|
||||||
result := make(map[string]string)
|
|
||||||
if len(match) > 0 {
|
|
||||||
for i, name := range pattern.SubexpNames() {
|
|
||||||
if i != 0 {
|
|
||||||
result[name] = match[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "regexp"
|
|
||||||
|
|
||||||
type language struct {
|
type language struct {
|
||||||
props *properties
|
props *properties
|
||||||
env environmentInfo
|
env environmentInfo
|
||||||
|
@ -39,8 +37,7 @@ func (l *language) enabled() bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
versionInfo, _ := l.env.runCommand(executable, l.versionParam)
|
versionInfo, _ := l.env.runCommand(executable, l.versionParam)
|
||||||
r := regexp.MustCompile(l.versionRegex)
|
values := findNamedRegexMatch(l.versionRegex, versionInfo)
|
||||||
values := groupDict(r, versionInfo)
|
|
||||||
l.version = values["version"]
|
l.version = values["version"]
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue